From a257eb583bcec50ec09d9fd2b5c714516711bb2a Mon Sep 17 00:00:00 2001 From: Vladimir Glazounov Date: Tue, 20 Jan 2009 09:49:16 +0000 Subject: CWS-TOOLING: integrate CWS aw061 2009-01-13 19:18:08 +0100 aw r266250 : #i96669# changed initialisation order in Embedded3DPrimitive2D::Embedded3DPrimitive2D due to TinderBox 2009-01-13 19:15:37 +0100 aw r266249 : #i96669# changed initialisation order in Embedded3DPrimitive2D::Embedded3DPrimitive2D due to TinderBox 2009-01-12 11:53:37 +0100 aw r266141 : #i97874# corrected include for TinderBox build 2009-01-08 17:48:23 +0100 aw r266029 : #i97874# extended SdrTextObj::ImpConvertAddText to copy needed attributes from original object 2009-01-08 14:59:08 +0100 aw r266015 : #i96350# added fallback to solid fill in shadow TabPage when no fill is defined to get a reasonable shadow preview 2009-01-08 12:40:49 +0100 aw r265995 : #i94832# remuved not needed E3DModifySceneSnapRectUpdater usages 2009-01-08 01:53:46 +0100 thb r265982 : #i94860# Blacklisting another ATI card/driver that causes blank screens 2009-01-08 01:46:38 +0100 thb r265981 : #i97853# Changed all gradient texture methods to use basegfx gradienttools. consolidated quite some code 2009-01-08 01:45:09 +0100 thb r265980 : #i97853# Added lerp methods, slight changes to have everything necessary contained in the ODFGradientInfo struct 2009-01-08 00:01:54 +0100 thb r265979 : #i97853# First part of the move - duplicated the stuff to basegfx 2009-01-06 16:23:09 +0100 aw r265930 : #i97197# Changed SwDrawVirtObj to work well with changed aOutRect and bBoundRectValid functionality 2009-01-06 12:41:24 +0100 aw r265909 : #i97784# corrected regression with connectors 2009-01-05 17:30:31 +0100 aw r265881 : #i97772# added missing usage of reduce factor for BitmapPrimitive creation 2009-01-05 12:24:01 +0100 aw r265863 : #i97321# added direct handling of HatchTexturePrimitive3D to not use it's decomposition for HitTest 2008-12-23 13:57:27 +0100 aw r265782 : #i96669# changed SW's FlyFrame paint fallback with primitives to use createLocalDecomposition since get2Decomposition does not have to stay virtual on the long run 2008-12-23 13:47:59 +0100 aw r265781 : #i96669# optimized impCreateTextPortionPrimitive to only create TextDecoratedPortionPrimitive2D when needed 2008-12-23 13:44:45 +0100 aw r265780 : #i96669# added B2DRange buffering to some primitive implementations where it is most necessary 2008-12-19 15:45:45 +0100 aw r265729 : #i96669# prepared TextPrimitives to work without DXarray, too. Had to rework impSplitSingleWords which gets active when a text portion has some word-wise decorations. Tested before committing 2008-12-19 15:44:16 +0100 aw r265728 : #i96669# corrected error in createPolygonFromUnitEllipseSegment which popped up when investigating 2008-12-18 17:45:58 +0100 aw r265708 : #i97149# added ActionChanged() call when visualisation object is modified 2008-12-18 15:34:42 +0100 aw r265695 : #i96598# corrected SdrPageObj's usage of aOutRect 2008-12-17 16:59:37 +0100 aw r265647 : #i96537# exchanged the marker for point number in string with correct one 2008-12-16 17:50:33 +0100 aw r265566 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer 2008-12-16 17:50:17 +0100 aw r265565 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer 2008-12-16 17:50:00 +0100 aw r265564 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer 2008-12-16 17:49:48 +0100 aw r265563 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer 2008-12-16 17:49:35 +0100 aw r265562 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer --- basegfx/inc/basegfx/tools/gradienttools.hxx | 401 ++++++++++++++++++++++++++++ basegfx/prj/d.lst | 1 + basegfx/source/polygon/b2dpolygontools.cxx | 10 +- basegfx/source/tools/gradienttools.cxx | 366 +++++++++++++++++++++++++ basegfx/source/tools/makefile.mk | 1 + 5 files changed, 775 insertions(+), 4 deletions(-) create mode 100644 basegfx/inc/basegfx/tools/gradienttools.hxx create mode 100644 basegfx/source/tools/gradienttools.cxx diff --git a/basegfx/inc/basegfx/tools/gradienttools.hxx b/basegfx/inc/basegfx/tools/gradienttools.hxx new file mode 100644 index 000000000000..0c7f2ab2c060 --- /dev/null +++ b/basegfx/inc/basegfx/tools/gradienttools.hxx @@ -0,0 +1,401 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: canvastools.hxx,v $ + * $Revision: 1.10 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _BGFX_TOOLS_GRADIENTTOOLS_HXX +#define _BGFX_TOOLS_GRADIENTTOOLS_HXX + +#include +#include +#include +#include +#include + +namespace basegfx +{ + /** Gradient definition as used in ODF 1.2 + + This struct collects all data necessary for rendering ODF + 1.2-compatible gradients. Use the createXXXODFGradientInfo() + methods below for initializing from ODF attributes. + */ + struct ODFGradientInfo + { + /** transformation mapping from [0,1]^2 texture coordinate + space to [0,1]^2 shape coordinate space + */ + B2DHomMatrix maTextureTransform; + + /** transformation mapping from [0,1]^2 shape coordinate space + to [0,1]^2 texture coordinate space. This is the + transformation commonly used to create gradients from a + scanline rasterizer (put shape u/v coordinates into it, get + texture s/t coordinates out of it) + */ + B2DHomMatrix maBackTextureTransform; + + /** Aspect ratio of the gradient. Only used in drawinglayer + for generating nested gradient polygons currently. Already + catered for in the transformations above. + */ + double mfAspectRatio; + + /** Requested gradient steps to render. See the + implementations of the getXXXGradientAlpha() methods below, + the semantic differs slightly for the different gradient + types. + */ + sal_uInt32 mnSteps; + }; + + namespace tools + { + /** Create matrix for ODF's linear gradient definition + + @param o_rGradientInfo + Receives the calculated texture transformation matrix (for + use with standard [0,1]x[0,1] texture coordinates) + + @param rTargetArea + Output area, needed for aspect ratio calculations and + texture transformation + + @param nSteps + Number of gradient steps (from ODF) + + @param fBorder + Width of gradient border (from ODF) + + @param fAngle + Gradient angle (from ODF) + */ + ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + sal_uInt32 nSteps, + double fBorder, + double fAngle); + + /** Calculate linear gradient blend value + + This method generates you the lerp alpha value for + blending linearly between gradient start and end color, + according to the formula (startCol*(1.0-alpha) + endCol*alpha) + + @param rUV + Current uv coordinate. Values outside [0,1] will be + clamped. + + @param rGradInfo + Gradient info, for transformation and number of steps + */ + inline double getLinearGradientAlpha(const B2DPoint& rUV, + const ODFGradientInfo& rGradInfo ) + { + const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV); + const double t(clamp(aCoor.getY(), 0.0, 1.0)); + const sal_uInt32 nSteps(rGradInfo.mnSteps); + + if(nSteps > 2L && nSteps < 128L) + return floor(t * nSteps) / double(nSteps + 1L); + + return t; + } + + /** Create matrix for ODF's axial gradient definition + + @param o_rGradientInfo + Receives the calculated texture transformation matrix (for + use with standard [0,1]x[0,1] texture coordinates) + + @param rTargetArea + Output area, needed for aspect ratio calculations and + texture transformation + + @param nSteps + Number of gradient steps (from ODF) + + @param fBorder + Width of gradient border (from ODF) + + @param fAngle + Gradient angle (from ODF) + */ + ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + sal_uInt32 nSteps, + double fBorder, + double fAngle); + + /** Calculate axial gradient blend value + + This method generates you the lerp alpha value for + blending linearly between gradient start and end color, + according to the formula (startCol*(1.0-alpha) + endCol*alpha) + + @param rUV + Current uv coordinate. Values outside [0,1] will be + clamped. + + @param rGradInfo + Gradient info, for transformation and number of steps + */ + inline double getAxialGradientAlpha(const B2DPoint& rUV, + const ODFGradientInfo& rGradInfo ) + { + const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV); + const double t(clamp(fabs(aCoor.getY()), 0.0, 1.0)); + const sal_uInt32 nSteps(rGradInfo.mnSteps); + const double fInternalSteps((nSteps * 2L) - 1L); + + if(nSteps > 2L && nSteps < 128L) + return floor(((t * fInternalSteps) + 1.0) / 2.0) / double(nSteps - 1L); + + return t; + } + + /** Create matrix for ODF's radial gradient definition + + @param o_rGradientInfo + Receives the calculated texture transformation matrix (for + use with standard [0,1]x[0,1] texture coordinates) + + @param rTargetArea + Output area, needed for aspect ratio calculations and + texture transformation + + @param rOffset + Gradient offset value (from ODF) + + @param nSteps + Number of gradient steps (from ODF) + + @param fBorder + Width of gradient border (from ODF) + + @param fAngle + Gradient angle (from ODF) + */ + ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder); + + /** Calculate radial gradient blend value + + This method generates you the lerp alpha value for + blending linearly between gradient start and end color, + according to the formula (startCol*(1.0-alpha) + endCol*alpha) + + @param rUV + Current uv coordinate. Values outside [0,1] will be + clamped. + + @param rGradInfo + Gradient info, for transformation and number of steps + */ + inline double getRadialGradientAlpha(const B2DPoint& rUV, + const ODFGradientInfo& rGradInfo ) + { + const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV); + const double fDist( + clamp(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY(), + 0.0, + 1.0)); + + const double t(1.0 - sqrt(fDist)); + const sal_uInt32 nSteps(rGradInfo.mnSteps); + + if(nSteps > 2L && nSteps < 128L) + return floor(t * nSteps) / double(nSteps - 1L); + + return t; + } + + /** Create matrix for ODF's elliptical gradient definition + + @param o_rGradientInfo + Receives the calculated texture transformation matrix (for + use with standard [0,1]x[0,1] texture coordinates) + + @param rTargetArea + Output area, needed for aspect ratio calculations and + texture transformation + + @param rOffset + Gradient offset value (from ODF) + + @param nSteps + Number of gradient steps (from ODF) + + @param fBorder + Width of gradient border (from ODF) + + @param fAngle + Gradient angle (from ODF) + */ + ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle); + + /** Calculate elliptical gradient blend value + + This method generates you the lerp alpha value for + blending linearly between gradient start and end color, + according to the formula (startCol*(1.0-alpha) + endCol*alpha) + + @param rUV + Current uv coordinate. Values outside [0,1] will be + clamped. + + @param rGradInfo + Gradient info, for transformation and number of steps + */ + inline double getEllipticalGradientAlpha(const B2DPoint& rUV, + const ODFGradientInfo& rGradInfo ) + { + return getRadialGradientAlpha(rUV,rGradInfo); // only matrix setup differs + } + + /** Create matrix for ODF's square gradient definition + + @param o_rGradientInfo + Receives the calculated texture transformation matrix (for + use with standard [0,1]x[0,1] texture coordinates) + + @param rTargetArea + Output area, needed for aspect ratio calculations and + texture transformation + + @param rOffset + Gradient offset value (from ODF) + + @param nSteps + Number of gradient steps (from ODF) + + @param fBorder + Width of gradient border (from ODF) + + @param fAngle + Gradient angle (from ODF) + */ + ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle); + + /** Calculate square gradient blend value + + This method generates you the lerp alpha value for + blending linearly between gradient start and end color, + according to the formula (startCol*(1.0-alpha) + endCol*alpha) + + @param rUV + Current uv coordinate. Values outside [0,1] will be + clamped. + + @param rGradInfo + Gradient info, for transformation and number of steps + */ + inline double getSquareGradientAlpha(const B2DPoint& rUV, + const ODFGradientInfo& rGradInfo ) + { + const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV); + const double fAbsX(fabs(aCoor.getX())); + const double fAbsY(fabs(aCoor.getY())); + + if(fTools::moreOrEqual(fAbsX, 1.0) || fTools::moreOrEqual(fAbsY, 1.0)) + return 0.0; + + const double t(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY)); + const sal_uInt32 nSteps(rGradInfo.mnSteps); + + if(nSteps > 2L && nSteps < 128L) + return floor(t * nSteps) / double(nSteps - 1L); + + return t; + } + + /** Create matrix for ODF's rectangular gradient definition + + @param o_rGradientInfo + Receives the calculated texture transformation matrix (for + use with standard [0,1]x[0,1] texture coordinates) + + @param rTargetArea + Output area, needed for aspect ratio calculations and + texture transformation + + @param rOffset + Gradient offset value (from ODF) + + @param nSteps + Number of gradient steps (from ODF) + + @param fBorder + Width of gradient border (from ODF) + + @param fAngle + Gradient angle (from ODF) + */ + ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle); + + /** Calculate rectangular gradient blend value + + This method generates you the lerp alpha value for + blending linearly between gradient start and end color, + according to the formula (startCol*(1.0-alpha) + endCol*alpha) + + @param rUV + Current uv coordinate. Values outside [0,1] will be + clamped. + + @param rGradInfo + Gradient info, for transformation and number of steps + */ + inline double getRectangularGradientAlpha(const B2DPoint& rUV, + const ODFGradientInfo& rGradInfo ) + { + return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs + } + + } +} + +#endif diff --git a/basegfx/prj/d.lst b/basegfx/prj/d.lst index 7168e6b4c495..9dd6085bbc7f 100644 --- a/basegfx/prj/d.lst +++ b/basegfx/prj/d.lst @@ -92,6 +92,7 @@ mkdir: %_DEST%\inc%_EXT%\basegfx\tools ..\inc\basegfx\tools\unopolypolygon.hxx %_DEST%\inc%_EXT%\basegfx\tools\unopolypolygon.hxx ..\inc\basegfx\tools\rectcliptools.hxx %_DEST%\inc%_EXT%\basegfx\tools\rectcliptools.hxx ..\inc\basegfx\tools\tools.hxx %_DEST%\inc%_EXT%\basegfx\tools\tools.hxx +..\inc\basegfx\tools\gradienttools.hxx %_DEST%\inc%_EXT%\basegfx\tools\gradienttools.hxx mkdir: %_DEST%\inc%_EXT%\basegfx\color ..\inc\basegfx\color\bcolor.hxx %_DEST%\inc%_EXT%\basegfx\color\bcolor.hxx diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx index 7a7a60ae37b5..f4d1f992ad6b 100644 --- a/basegfx/source/polygon/b2dpolygontools.cxx +++ b/basegfx/source/polygon/b2dpolygontools.cxx @@ -1975,14 +1975,16 @@ namespace basegfx { B2DPolygon aRetval; + // truncate fStart, fEnd to a range of [0.0 .. F_2PI[ where F_2PI + // falls back to 0.0 to ensure a unique definition if(fTools::less(fStart, 0.0)) { fStart = 0.0; } - if(fTools::more(fStart, F_2PI)) + if(fTools::moreOrEqual(fStart, F_2PI)) { - fStart = F_2PI; + fStart = 0.0; } if(fTools::less(fEnd, 0.0)) @@ -1990,9 +1992,9 @@ namespace basegfx fEnd = 0.0; } - if(fTools::more(fEnd, F_2PI)) + if(fTools::moreOrEqual(fEnd, F_2PI)) { - fEnd = F_2PI; + fEnd = 0.0; } const sal_uInt32 nQuadrantStart(sal_uInt32(fStart / F_PI2) % 4L); diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx new file mode 100644 index 000000000000..9e78039cd590 --- /dev/null +++ b/basegfx/source/tools/gradienttools.cxx @@ -0,0 +1,366 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: canvastools.cxx,v $ + * $Revision: 1.12 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basegfx.hxx" + +#include + +#include +#include + +namespace basegfx +{ + /** Most of the setup for linear & axial gradient is the same, except + for the border treatment. Factored out here. + */ + static void init1DGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetRange, + sal_uInt32 nSteps, + double fBorder, + double fAngle, + bool bAxial) + { + o_rGradientInfo.maTextureTransform.identity(); + o_rGradientInfo.maBackTextureTransform.identity(); + o_rGradientInfo.mnSteps = nSteps; + + double fTargetSizeX(rTargetRange.getWidth()); + double fTargetSizeY(rTargetRange.getHeight()); + double fTargetOffsetX(rTargetRange.getMinX()); + double fTargetOffsetY(rTargetRange.getMinY()); + + // add object expansion + if(0.0 != fAngle) + { + const double fAbsCos(fabs(cos(fAngle))); + const double fAbsSin(fabs(sin(fAngle))); + const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin); + const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin); + fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0; + fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0; + fTargetSizeX = fNewX; + fTargetSizeY = fNewY; + } + + // add object scale before rotate + o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY); + + // add texture rotate after scale to keep perpendicular angles + if(0.0 != fAngle) + { + B2DPoint aCenter(0.5, 0.5); + aCenter *= o_rGradientInfo.maTextureTransform; + + o_rGradientInfo.maTextureTransform.translate(-aCenter.getX(), -aCenter.getY()); + o_rGradientInfo.maTextureTransform.rotate(fAngle); + o_rGradientInfo.maTextureTransform.translate(aCenter.getX(), aCenter.getY()); + } + + // add object translate + o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY); + + // prepare aspect for texture + o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0; + + // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform + o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform; + o_rGradientInfo.maBackTextureTransform.invert(); + + double fSizeWithoutBorder=0; + if( bAxial ) + { + fSizeWithoutBorder = (1.0 - fBorder) * 0.5; + o_rGradientInfo.maBackTextureTransform.translate(0.0, -0.5); + } + else + { + fSizeWithoutBorder = 1.0 - fBorder; + o_rGradientInfo.maBackTextureTransform.translate(0.0, -fBorder); + } + + if(!fTools::equal(fSizeWithoutBorder, 0.0)) + o_rGradientInfo.maBackTextureTransform.scale(1.0, 1.0 / fSizeWithoutBorder); + } + + /** Most of the setup for radial & ellipsoidal gradient is the same, + except for the border treatment. Factored out here. + */ + static void initEllipticalGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetRange, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle, + bool bCircular) + { + o_rGradientInfo.maTextureTransform.identity(); + o_rGradientInfo.maBackTextureTransform.identity(); + o_rGradientInfo.mnSteps = nSteps; + + double fTargetSizeX(rTargetRange.getWidth()); + double fTargetSizeY(rTargetRange.getHeight()); + double fTargetOffsetX(rTargetRange.getMinX()); + double fTargetOffsetY(rTargetRange.getMinY()); + + // add object expansion + if( bCircular ) + { + const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY))); + fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0; + fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0; + fTargetSizeX = fOriginalDiag; + fTargetSizeY = fOriginalDiag; + } + else + { + fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX; + fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY; + fTargetSizeX = 1.4142 * fTargetSizeX; + fTargetSizeY = 1.4142 * fTargetSizeY; + } + + // add object scale before rotate + o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY); + + if( !bCircular ) + { + // add texture rotate after scale to keep perpendicular angles + if(0.0 != fAngle) + { + B2DPoint aCenter(0.5, 0.5); + aCenter *= o_rGradientInfo.maTextureTransform; + + o_rGradientInfo.maTextureTransform.translate(-aCenter.getX(), -aCenter.getY()); + o_rGradientInfo.maTextureTransform.rotate(fAngle); + o_rGradientInfo.maTextureTransform.translate(aCenter.getX(), aCenter.getY()); + } + } + + // add defined offsets after rotation + if(0.5 != rOffset.getX() || 0.5 != rOffset.getY()) + { + // use original target size + fTargetOffsetX += (rOffset.getX() - 0.5) * rTargetRange.getWidth(); + fTargetOffsetY += (rOffset.getY() - 0.5) * rTargetRange.getHeight(); + } + + // add object translate + o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY); + + // prepare aspect for texture + o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0; + + // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform + o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform; + o_rGradientInfo.maBackTextureTransform.invert(); + o_rGradientInfo.maBackTextureTransform.translate(-0.5, -0.5); + const double fHalfBorder((1.0 - fBorder) * 0.5); + + if(!fTools::equal(fHalfBorder, 0.0)) + { + const double fFactor(1.0 / fHalfBorder); + o_rGradientInfo.maBackTextureTransform.scale(fFactor, fFactor); + } + } + + /** Setup for rect & square gradient is exactly the same. Factored out + here. + */ + static void initRectGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetRange, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle) + { + o_rGradientInfo.maTextureTransform.identity(); + o_rGradientInfo.maBackTextureTransform.identity(); + o_rGradientInfo.mnSteps = nSteps; + + double fTargetSizeX(rTargetRange.getWidth()); + double fTargetSizeY(rTargetRange.getHeight()); + double fTargetOffsetX(rTargetRange.getMinX()); + double fTargetOffsetY(rTargetRange.getMinY()); + + // add object expansion + if(0.0 != fAngle) + { + const double fAbsCos(fabs(cos(fAngle))); + const double fAbsSin(fabs(sin(fAngle))); + const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin); + const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin); + fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0; + fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0; + fTargetSizeX = fNewX; + fTargetSizeY = fNewY; + } + + // add object scale before rotate + o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY); + + // add texture rotate after scale to keep perpendicular angles + if(0.0 != fAngle) + { + B2DPoint aCenter(0.5, 0.5); + aCenter *= o_rGradientInfo.maTextureTransform; + + o_rGradientInfo.maTextureTransform.translate(-aCenter.getX(), -aCenter.getY()); + o_rGradientInfo.maTextureTransform.rotate(fAngle); + o_rGradientInfo.maTextureTransform.translate(aCenter.getX(), aCenter.getY()); + } + + // add defined offsets after rotation + if(0.5 != rOffset.getX() || 0.5 != rOffset.getY()) + { + // use scaled target size + fTargetOffsetX += (rOffset.getX() - 0.5) * fTargetSizeX; + fTargetOffsetY += (rOffset.getY() - 0.5) * fTargetSizeY; + } + + // add object translate + o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY); + + // prepare aspect for texture + o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0; + + // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform + o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform; + o_rGradientInfo.maBackTextureTransform.invert(); + o_rGradientInfo.maBackTextureTransform.translate(-0.5, -0.5); + const double fHalfBorder((1.0 - fBorder) * 0.5); + + if(!fTools::equal(fHalfBorder, 0.0)) + { + const double fFactor(1.0 / fHalfBorder); + o_rGradientInfo.maBackTextureTransform.scale(fFactor, fFactor); + } + } + + namespace tools + { + ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + sal_uInt32 nSteps, + double fBorder, + double fAngle) + { + init1DGradientInfo(o_rGradientInfo, + rTargetArea, + nSteps, + fBorder, + fAngle, + false); + return o_rGradientInfo; + } + + ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + sal_uInt32 nSteps, + double fBorder, + double fAngle) + { + init1DGradientInfo(o_rGradientInfo, + rTargetArea, + nSteps, + fBorder, + fAngle, + true); + return o_rGradientInfo; + } + + ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder) + { + initEllipticalGradientInfo(o_rGradientInfo, + rTargetArea, + rOffset, + nSteps, + fBorder, + 0.0, + true); + return o_rGradientInfo; + } + + ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle) + { + initEllipticalGradientInfo(o_rGradientInfo, + rTargetArea, + rOffset, + nSteps, + fBorder, + fAngle, + false); + return o_rGradientInfo; + } + + ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle) + { + initRectGradientInfo(o_rGradientInfo, + rTargetArea, + rOffset, + nSteps, + fBorder, + fAngle); + return o_rGradientInfo; + } + + ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo, + const B2DRange& rTargetArea, + const B2DVector& rOffset, + sal_uInt32 nSteps, + double fBorder, + double fAngle) + { + initRectGradientInfo(o_rGradientInfo, + rTargetArea, + rOffset, + nSteps, + fBorder, + fAngle); + return o_rGradientInfo; + } + + } // namespace tools + +} // namespace basegfx diff --git a/basegfx/source/tools/makefile.mk b/basegfx/source/tools/makefile.mk index bd233ffbcfc0..1bede8b22d88 100755 --- a/basegfx/source/tools/makefile.mk +++ b/basegfx/source/tools/makefile.mk @@ -42,6 +42,7 @@ ENABLE_EXCEPTIONS=TRUE # --- Files ------------------------------------- SLOFILES= $(SLO)$/canvastools.obj \ + $(SLO)$/gradienttools.obj \ $(SLO)$/debugplotter.obj \ $(SLO)$/liangbarsky.obj \ $(SLO)$/tools.obj \ -- cgit v1.2.3