summaryrefslogtreecommitdiff
path: root/canvas/source/vcl/impltools.cxx
diff options
context:
space:
mode:
authorRüdiger Timm <rt@openoffice.org>2004-11-26 16:13:05 +0000
committerRüdiger Timm <rt@openoffice.org>2004-11-26 16:13:05 +0000
commit68530643d9d8d2a8805cf8692617a9fd712faaa2 (patch)
tree1e6d7083d47393557be5def1aeab9b6031772d0b /canvas/source/vcl/impltools.cxx
parent67490613cad577ebc33df98cec33fd2cbd5491b8 (diff)
INTEGRATION: CWS presentationengine01 (1.2.2); FILE MERGED
2004/11/22 15:19:14 thb 1.2.2.12: #110496# Ensuring similar types for ternary operator 2004/11/17 17:00:30 thb 1.2.2.11: #118514# Canvas module reorg 2004/11/01 22:19:09 thb 1.2.2.10: #10496# Performance optimizations: added profiling traces 2004/10/11 00:00:06 thb 1.2.2.9: #i34997# Added new method XCanvas::drawBitmapModulated(), to facilitate global alpha channel changes when rendering bitmaps 2004/09/27 20:12:31 thb 1.2.2.8: #110496# Fixed problem with CanvasBitmap instances with alpha channel (simply ignored that before) 2004/08/31 17:50:47 thb 1.2.2.7: #110496# Fixed typo in coordinate range check (compared twice with X) 2004/08/03 19:45:36 thb 1.2.2.6: #110496# Changed vcl canvas to use B2DPolygons, and transforming clip polys before setting them 2004/07/20 19:23:56 thb 1.2.2.5: #110496# Removed self-references to various interface implementations, along the lines, factored out common base implementation for all c++ canvases 2004/07/01 16:56:47 thb 1.2.2.4: #110496# Switched to math.h for PI 2004/06/17 10:33:26 thb 1.2.2.3: #110496# Handle huge shrinks correctly for font scaling; added some more debug code 2004/05/27 20:51:24 thb 1.2.2.2: #110496# Added classification code to all TODO/HACK/FIXME comments. There are four categories: - code quality (C) - performance (P) - missing functionality (F) - and missing/incomplete error handling (E) Furthermore, every category has a severity number between 1 and 3 associated, where 1 is lowest and 3 highest severity 2004/04/05 15:57:58 thb 1.2.2.1: Resync with canvas01 changes
Diffstat (limited to 'canvas/source/vcl/impltools.cxx')
-rw-r--r--canvas/source/vcl/impltools.cxx359
1 files changed, 257 insertions, 102 deletions
diff --git a/canvas/source/vcl/impltools.cxx b/canvas/source/vcl/impltools.cxx
index 75a492665a74..ae63d04e05d4 100644
--- a/canvas/source/vcl/impltools.cxx
+++ b/canvas/source/vcl/impltools.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: impltools.cxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: thb $ $Date: 2004-03-18 10:38:41 $
+ * last change: $Author: rt $ $Date: 2004-11-26 17:13:05 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -59,6 +59,17 @@
*
************************************************************************/
+#include <canvas/debug.hxx>
+
+#ifndef _USE_MATH_DEFINES
+#define _USE_MATH_DEFINES // needed by Visual C++ for math constants
+#endif
+#include <math.h> // M_PI definition
+
+#ifndef _RTL_LOGFILE_HXX_
+#include <rtl/logfile.hxx>
+#endif
+
#ifndef _DRAFTS_COM_SUN_STAR_GEOMETRY_REALSIZE2D_HPP__
#include <drafts/com/sun/star/geometry/RealSize2D.hpp>
#endif
@@ -88,9 +99,6 @@
#include <drafts/com/sun/star/rendering/XIntegerBitmap.hpp>
#endif
-#ifndef _TL_POLY_HXX
-#include <tools/poly.hxx>
-#endif
#ifndef _SV_SALBTYPE_HXX
#include <vcl/salbtype.hxx>
#endif
@@ -107,22 +115,29 @@
#include <vcl/canvastools.hxx>
#endif
+#ifndef _BGFX_POINT_B2DPOINT_HXX
+#include <basegfx/point/b2dpoint.hxx>
+#endif
#ifndef _BGFX_TUPLE_B2DTUPLE_HXX
#include <basegfx/tuple/b2dtuple.hxx>
#endif
+#ifndef _BGFX_RANGE_B2DRECTANGLE_HXX
+#include <basegfx/range/b2drectangle.hxx>
+#endif
#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
#include <basegfx/matrix/b2dhommatrix.hxx>
#endif
#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
#include <basegfx/tools/canvastools.hxx>
#endif
+#ifndef _BGFX_NUMERIC_FTOOLS_HXX
+#include <basegfx/numeric/ftools.hxx>
+#endif
#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif
-#include <cmath> // for fmod
-
#include <canvas/canvastools.hxx>
#include "impltools.hxx"
@@ -137,7 +152,7 @@ namespace vclcanvas
{
namespace tools
{
- ::PolyPolygon polyPolygonFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly )
+ ::basegfx::B2DPolyPolygon polyPolygonFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly )
{
uno::Reference< lang::XServiceInfo > xRef( xPoly,
uno::UNO_QUERY );
@@ -145,17 +160,19 @@ namespace vclcanvas
if( xRef.is() &&
xRef->getImplementationName().equals( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(LINEPOLYPOLYGON_IMPLEMENTATION_NAME))) )
{
- // TODO: Maybe use dynamic_cast here
+ // TODO(Q1): Maybe use dynamic_cast here
- // TODO: Provide true beziers here!
- return static_cast<LinePolyPolygon*>(xPoly.get())->getVCLPolyPolygon();
+ // TODO(F1): Provide true beziers here!
+ return static_cast<LinePolyPolygon*>(xPoly.get())->getPolyPolygon();
}
else
{
- // TODO: extract points from polygon interface
+ // TODO(F1): extract points from polygon interface
+ ENSURE_AND_THROW( false,
+ "polyPolygonFromXPolyPolygon2D(): could not extract points" );
}
- return ::PolyPolygon();
+ return ::basegfx::B2DPolyPolygon();
}
::BitmapEx bitmapExFromXBitmap( const uno::Reference< rendering::XBitmap >& xBitmap )
@@ -166,26 +183,24 @@ namespace vclcanvas
if( xRef.is() &&
xRef->getImplementationName().equals( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CANVASBITMAP_IMPLEMENTATION_NAME))) )
{
- // TODO: Maybe use dynamic_cast here
- VirtualDevice& rVDev( static_cast<CanvasBitmap*>(xBitmap.get())->getVirDev() );
- const Point aEmptyPoint(0,0);
- const Size aBmpSize(rVDev.GetOutputSizePixel());
-
- // TODO: handle alpha vDev here
- return rVDev.GetBitmap(aEmptyPoint, aBmpSize);
+ // TODO(Q1): Maybe use dynamic_cast here
+ return static_cast<CanvasBitmap*>(xBitmap.get())->getBitmap();
}
else
{
- // TODO: extract points from polygon interface
+ // TODO(F1): extract pixel from XBitmap interface
+ ENSURE_AND_THROW( false,
+ "bitmapExFromXBitmap(): could not extract bitmap" );
}
return ::BitmapEx();
}
- ::Point setupFontTransform( ::Font& aVCLFont,
- const rendering::ViewState& rViewState,
- const rendering::RenderState& rRenderState,
- OutputDevice& rOutDev )
+ bool setupFontTransform( ::Point& o_rPoint,
+ ::Font& io_rVCLFont,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ ::OutputDevice& rOutDev )
{
::basegfx::B2DHomMatrix aMatrix;
@@ -203,22 +218,33 @@ namespace vclcanvas
if( !::rtl::math::approxEqual(aScale.getX(), aScale.getY()) )
{
// retrieve true font width
- const int aFontWidth( rOutDev.GetFontMetric( aVCLFont ).GetWidth() );
+ const int nFontWidth( rOutDev.GetFontMetric( io_rVCLFont ).GetWidth() );
+
+ const int nScaledFontWidth( ::basegfx::fround(nFontWidth * aScale.getX()) );
+
+ if( !nScaledFontWidth )
+ {
+ // scale is smaller than one pixel - disable text
+ // output altogether
+ return false;
+ }
- aVCLFont.SetWidth( static_cast<long>(aFontWidth * aScale.getX() + .5) );
+ io_rVCLFont.SetWidth( nScaledFontWidth );
}
if( !::rtl::math::approxEqual(aScale.getY(), 1.0) )
{
- const int nFontHeight( aVCLFont.GetHeight() );
- aVCLFont.SetHeight( static_cast<long>(nFontHeight * aScale.getY() + .5) );
+ const int nFontHeight( io_rVCLFont.GetHeight() );
+ io_rVCLFont.SetHeight( ::basegfx::fround(nFontHeight * aScale.getY()) );
}
- aVCLFont.SetOrientation( static_cast< short >(-fmod(nRotate, 2*F_PI)*(1800.0/F_PI) + .5) );
+ io_rVCLFont.SetOrientation( static_cast< short >( ::basegfx::fround(-fmod(nRotate, 2*M_PI)*(1800.0/M_PI)) ) );
- // TODO: Missing functionality in VCL: shearing
- return ::Point( static_cast<long>(aTranslate.getX() + .5),
- static_cast<long>(aTranslate.getY() + .5) );
+ // TODO(F2): Missing functionality in VCL: shearing
+ o_rPoint.X() = ::basegfx::fround(aTranslate.getX());
+ o_rPoint.Y() = ::basegfx::fround(aTranslate.getY());
+
+ return true;
}
// VCL-Canvas related
@@ -238,40 +264,30 @@ namespace vclcanvas
return ::vcl::unotools::pointFromB2DPoint( aPoint );
}
- ::PolyPolygon mapPolyPolygon( const ::PolyPolygon& rPoly,
- const rendering::ViewState& rViewState,
- const rendering::RenderState& rRenderState )
+ ::PolyPolygon mapPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState )
{
- PolyPolygon aRes;
::basegfx::B2DHomMatrix aMatrix;
::canvas::tools::mergeViewAndRenderTransform(aMatrix,
rViewState,
rRenderState);
- int nCurrPoly, nCurrPoint;
- for( nCurrPoly=0; nCurrPoly<rPoly.Count(); ++nCurrPoly )
- {
- Polygon aDest(rPoly[nCurrPoly].GetSize());
-
- for( nCurrPoint=0; nCurrPoint<aDest.GetSize(); ++nCurrPoint )
- {
- ::basegfx::B2DPoint aPoint( ::vcl::unotools::b2DPointFromPoint( rPoly[nCurrPoly][nCurrPoint] ) );
-
- aPoint *= aMatrix;
+ ::basegfx::B2DPolyPolygon aTemp( rPoly );
- aDest[nCurrPoint] = ::vcl::unotools::pointFromB2DPoint( aPoint );
- }
-
- aRes.Insert(aDest);
- }
+ aTemp.transform( aMatrix );
- return aRes;
+ return ::PolyPolygon( aTemp );
}
::BitmapEx transformBitmap( const BitmapEx& rBitmap,
const rendering::ViewState& rViewState,
- const rendering::RenderState& rRenderState )
+ const rendering::RenderState& rRenderState,
+ ModulationMode eModulationMode )
{
+ RTL_LOGFILE_CONTEXT( aLog, "::vclcanvas::tools::transformBitmap()" );
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::vclcanvas::tools::transformBitmap: 0x%X", &rBitmap );
+
// calc transformation and size of bitmap to be
// generated. Note, that the translational components are
// deleted from the transformation; this can be handled by
@@ -295,6 +311,14 @@ namespace vclcanvas
aBmpSize.Height()),
aTransform );
+ const bool bModulateColors( eModulationMode == MODULATE_WITH_DEVICECOLOR &&
+ rRenderState.DeviceColor.getLength() > 2 );
+ const double nRedModulation( bModulateColors ? rRenderState.DeviceColor[0] : 1.0 );
+ const double nGreenModulation( bModulateColors ? rRenderState.DeviceColor[1] : 1.0 );
+ const double nBlueModulation( bModulateColors ? rRenderState.DeviceColor[2] : 1.0 );
+ const double nAlphaModulation( bModulateColors && rRenderState.DeviceColor.getLength() > 3 ?
+ rRenderState.DeviceColor[3] : 1.0 );
+
Bitmap aSrcBitmap( rBitmap.GetBitmap() );
Bitmap aSrcAlpha;
@@ -308,32 +332,40 @@ namespace vclcanvas
aSrcAlpha = rBitmap.GetMask();
}
- Bitmap aDstBitmap( aSrcBitmap );
- Bitmap aDstAlpha( rBitmap.IsTransparent() ? aSrcAlpha : Bitmap( Size(1,1), 8) );
- aDstBitmap.SetSizePixel( Size( FRound( aDestRect.getMaxX() ),
- FRound( aDestRect.getMaxY() ) ) );
- aDstAlpha.SetSizePixel( Size(FRound( aDestRect.getMaxX() ),
- FRound( aDestRect.getMaxY() ) ) );
+ ScopedBitmapReadAccess pReadAccess( aSrcBitmap.AcquireReadAccess(),
+ aSrcBitmap );
+ ScopedBitmapReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ?
+ aSrcAlpha.AcquireReadAccess() :
+ (BitmapReadAccess*)NULL,
+ aSrcAlpha );
+
+ if( pReadAccess.get() == NULL ||
+ (pAlphaReadAccess.get() == NULL && rBitmap.IsTransparent()) )
+ {
+ // TODO(E2): Error handling!
+ ENSURE_AND_THROW( false,
+ "transformBitmap(): could not access source bitmap" );
+ }
+
+ const Size aDestBmpSize( ::basegfx::fround( aDestRect.getMaxX() ),
+ ::basegfx::fround( aDestRect.getMaxY() ) );
+
+ Bitmap aDstBitmap( aDestBmpSize, aSrcBitmap.GetBitCount(), &pReadAccess->GetPalette() );
+ Bitmap aDstAlpha( AlphaMask( aDestBmpSize ).GetBitmap() );
+
{
// just to be on the safe side: let the
// ScopedAccessors get destructed before
// copy-constructing the resulting bitmap. This will
// rule out the possibility that cached accessor data
// is not yet written back.
- ScopedBitmapReadAccess pReadAccess( aSrcBitmap.AcquireReadAccess(),
- aSrcBitmap );
- ScopedBitmapReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ? aSrcAlpha.AcquireReadAccess() : NULL,
- aSrcAlpha );
-
ScopedBitmapWriteAccess pWriteAccess( aDstBitmap.AcquireWriteAccess(),
aDstBitmap );
ScopedBitmapWriteAccess pAlphaWriteAccess( aDstAlpha.AcquireWriteAccess(),
aDstAlpha );
- if( pReadAccess.get() != NULL &&
- (pAlphaReadAccess.get() != NULL || !rBitmap.IsTransparent()) &&
- pWriteAccess.get() != NULL &&
+ if( pWriteAccess.get() != NULL &&
pAlphaWriteAccess.get() != NULL &&
aTransform.isInvertible() )
{
@@ -342,56 +374,177 @@ namespace vclcanvas
// source
aTransform.invert();
- const Size aDestBmpSize( aDstBitmap.GetSizePixel() );
-
// for the time being, always read as ARGB
for( int y=0; y<aDestBmpSize.Height(); ++y )
{
- // differentiate mask and alpha channel (on-off
- // vs. multi-level transparency)
- if( rBitmap.IsTransparent() )
+ if( bModulateColors )
{
- // Handling alpha and mask just the same...
- for( int x=0; x<aDestBmpSize.Width(); ++x )
- {
- ::basegfx::B2DPoint aPoint(x,y);
- aPoint *= aTransform;
+ // TODO(P2): Have different branches for
+ // alpha-only modulation (color
+ // modulations eq. 1.0)
+
+ // modulate all color channels with given
+ // values
- const int nSrcX( FRound( aPoint.getX() + .5 ) );
- const int nSrcY( FRound( aPoint.getY() + .5 ) );
- if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
- nSrcY < 0 || nSrcX >= aBmpSize.Height() )
+ // differentiate mask and alpha channel (on-off
+ // vs. multi-level transparency)
+ if( rBitmap.IsTransparent() )
+ {
+ // Handling alpha and mask just the same...
+ for( int x=0; x<aDestBmpSize.Width(); ++x )
{
- pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ ::basegfx::B2DPoint aPoint(x,y);
+ aPoint *= aTransform;
+
+ const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
+ const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
+ if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+ nSrcY < 0 || nSrcY >= aBmpSize.Height() )
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ }
+ else
+ {
+ // modulate alpha with
+ // nAlphaModulation. This is a
+ // little bit verbose, formula
+ // is 255 - (255-pixAlpha)*nAlphaModulation
+ // (invert 'alpha' pixel value,
+ // to get the standard alpha
+ // channel behaviour)
+ pAlphaWriteAccess->SetPixel( y, x,
+ BitmapColor(
+ 255U -
+ static_cast<BYTE>(
+ nAlphaModulation*
+ (255U
+ - pAlphaReadAccess->GetPixel(
+ nSrcY,
+ nSrcX ).GetIndex() ) + .5 ) ) );
+
+ BitmapColor aColor( pReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+
+ aColor.SetRed(
+ static_cast<BYTE>(
+ nRedModulation *
+ aColor.GetRed() + .5 ));
+ aColor.SetGreen(
+ static_cast<BYTE>(
+ nGreenModulation *
+ aColor.GetGreen() + .5 ));
+ aColor.SetBlue(
+ static_cast<BYTE>(
+ nBlueModulation *
+ aColor.GetBlue() + .5 ));
+
+ pWriteAccess->SetPixel( y, x,
+ aColor );
+ }
}
- else
+ }
+ else
+ {
+ for( int x=0; x<aDestBmpSize.Width(); ++x )
{
- pAlphaWriteAccess->SetPixel( y, x, pAlphaReadAccess->GetPixel( nSrcY,
- nSrcX ) );
- pWriteAccess->SetPixel( y, x, pReadAccess->GetPixel( nSrcY,
- nSrcX ) );
+ ::basegfx::B2DPoint aPoint(x,y);
+ aPoint *= aTransform;
+
+ const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
+ const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
+ if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+ nSrcY < 0 || nSrcY >= aBmpSize.Height() )
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ }
+ else
+ {
+ // modulate alpha with
+ // nAlphaModulation. This is a
+ // little bit verbose, formula
+ // is 255 - 255*nAlphaModulation
+ // (invert 'alpha' pixel value,
+ // to get the standard alpha
+ // channel behaviour)
+ pAlphaWriteAccess->SetPixel( y, x,
+ BitmapColor(
+ 255U -
+ static_cast<BYTE>(
+ nAlphaModulation*255.0
+ + .5 ) ) );
+
+ BitmapColor aColor( pReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+
+ aColor.SetRed(
+ static_cast<BYTE>(
+ nRedModulation *
+ aColor.GetRed() + .5 ));
+ aColor.SetGreen(
+ static_cast<BYTE>(
+ nGreenModulation *
+ aColor.GetGreen() + .5 ));
+ aColor.SetBlue(
+ static_cast<BYTE>(
+ nBlueModulation *
+ aColor.GetBlue() + .5 ));
+
+ pWriteAccess->SetPixel( y, x,
+ aColor );
+ }
}
}
}
else
{
- for( int x=0; x<aDestBmpSize.Width(); ++x )
+ // differentiate mask and alpha channel (on-off
+ // vs. multi-level transparency)
+ if( rBitmap.IsTransparent() )
{
- ::basegfx::B2DPoint aPoint(x,y);
- aPoint *= aTransform;
-
- const int nSrcX( FRound( aPoint.getX() + .5 ) );
- const int nSrcY( FRound( aPoint.getY() + .5 ) );
- if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
- nSrcY < 0 || nSrcX >= aBmpSize.Height() )
+ // Handling alpha and mask just the same...
+ for( int x=0; x<aDestBmpSize.Width(); ++x )
{
- pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ ::basegfx::B2DPoint aPoint(x,y);
+ aPoint *= aTransform;
+
+ const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
+ const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
+ if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+ nSrcY < 0 || nSrcY >= aBmpSize.Height() )
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ }
+ else
+ {
+ pAlphaWriteAccess->SetPixel( y, x,
+ pAlphaReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+
+ pWriteAccess->SetPixel( y, x, pReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+ }
}
- else
+ }
+ else
+ {
+ for( int x=0; x<aDestBmpSize.Width(); ++x )
{
- pAlphaWriteAccess->SetPixel( y, x, BitmapColor(0) );
- pWriteAccess->SetPixel( y, x, pReadAccess->GetPixel( nSrcY,
- nSrcX ) );
+ ::basegfx::B2DPoint aPoint(x,y);
+ aPoint *= aTransform;
+
+ const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
+ const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
+ if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+ nSrcY < 0 || nSrcY >= aBmpSize.Height() )
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ }
+ else
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(0) );
+ pWriteAccess->SetPixel( y, x, pReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+ }
}
}
}
@@ -401,7 +554,9 @@ namespace vclcanvas
}
else
{
- // TODO: Error handling!
+ // TODO(E2): Error handling!
+ ENSURE_AND_THROW( false,
+ "transformBitmap(): could not access bitmap" );
}
}