diff options
Diffstat (limited to 'drawinglayer/source/processor2d')
9 files changed, 248 insertions, 183 deletions
diff --git a/drawinglayer/source/processor2d/canvasprocessor.cxx b/drawinglayer/source/processor2d/canvasprocessor.cxx index 43e40183bc6e..8eb713258b25 100644 --- a/drawinglayer/source/processor2d/canvasprocessor.cxx +++ b/drawinglayer/source/processor2d/canvasprocessor.cxx @@ -76,6 +76,7 @@ #include <helperchartrenderer.hxx> #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx> #include <helperwrongspellrenderer.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -675,7 +676,7 @@ using namespace com::sun::star; // directdraw of text simple portion void canvasProcessor::impRender_STXP(const textSimplePortionPrimitive& rTextCandidate) { - const fontAttributes& rFontAttrs( rTextCandidate.getFontAttributes() ); + const fontAttributes& rFontAttrs( rTextCandidate.getFontAttribute() ); rendering::FontRequest aFontRequest; aFontRequest.FontDescription.FamilyName = rFontAttrs.maFamilyName; @@ -1341,10 +1342,9 @@ namespace drawinglayer // prepare discrete offset for XBitmap, do not forget that the buffer bitmap // may be truncated to discrete visible pixels - basegfx::B2DHomMatrix aDiscreteOffset; - aDiscreteOffset.translate( + const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix( aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0, - aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0); + aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0)); // create new local ViewInformation2D with new transformation const geometry::ViewInformation2D aViewInformation2D( @@ -1517,16 +1517,16 @@ namespace drawinglayer } else { - const primitive2d::FontAttributes& rFontAttrs(rTextCandidate.getFontAttributes()); + const attribute::FontAttribute& rFontAttr(rTextCandidate.getFontAttribute()); rendering::FontRequest aFontRequest; - aFontRequest.FontDescription.FamilyName = rFontAttrs.getFamilyName(); - aFontRequest.FontDescription.StyleName = rFontAttrs.getStyleName(); - aFontRequest.FontDescription.IsSymbolFont = rFontAttrs.getSymbol() ? util::TriState_YES : util::TriState_NO; - aFontRequest.FontDescription.IsVertical = rFontAttrs.getVertical() ? util::TriState_YES : util::TriState_NO; + aFontRequest.FontDescription.FamilyName = rFontAttr.getFamilyName(); + aFontRequest.FontDescription.StyleName = rFontAttr.getStyleName(); + aFontRequest.FontDescription.IsSymbolFont = rFontAttr.getSymbol() ? util::TriState_YES : util::TriState_NO; + aFontRequest.FontDescription.IsVertical = rFontAttr.getVertical() ? util::TriState_YES : util::TriState_NO; // TODO(F2): improve vclenum->panose conversion - aFontRequest.FontDescription.FontDescription.Weight = static_cast< sal_uInt8 >(rFontAttrs.getWeight()); - aFontRequest.FontDescription.FontDescription.Letterform = rFontAttrs.getItalic() ? 9 : 0; + aFontRequest.FontDescription.FontDescription.Weight = static_cast< sal_uInt8 >(rFontAttr.getWeight()); + aFontRequest.FontDescription.FontDescription.Letterform = rFontAttr.getItalic() ? 9 : 0; // init CellSize to 1.0, else a default font height will be used aFontRequest.CellSize = 1.0; @@ -1600,16 +1600,14 @@ namespace drawinglayer // adapt object's transformation to the correct scale basegfx::B2DVector aScale, aTranslate; double fRotate, fShearX; - basegfx::B2DHomMatrix aNewMatrix; const Size aSizePixel(aModifiedBitmapEx.GetSizePixel()); if(0 != aSizePixel.Width() && 0 != aSizePixel.Height()) { rBitmapCandidate.getTransform().decompose(aScale, aTranslate, fRotate, fShearX); - aNewMatrix.scale(aScale.getX() / aSizePixel.Width(), aScale.getY() / aSizePixel.Height()); - aNewMatrix.shearX(fShearX); - aNewMatrix.rotate(fRotate); - aNewMatrix.translate(aTranslate.getX(), aTranslate.getY()); + const basegfx::B2DHomMatrix aNewMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aScale.getX() / aSizePixel.Width(), aScale.getY() / aSizePixel.Height(), + fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); canvas::tools::setRenderStateTransform(maRenderState, getViewInformation2D().getObjectTransformation() * aNewMatrix); @@ -1658,10 +1656,9 @@ namespace drawinglayer // prepare discrete offset for XBitmap, do not forget that the buffer bitmap // may be truncated to discrete visible pixels - basegfx::B2DHomMatrix aDiscreteOffset; - aDiscreteOffset.translate( + const basegfx::B2DHomMatrix aDiscreteOffset(basegfx::tools::createTranslateB2DHomMatrix( aDiscreteRange.getMinX() > 0.0 ? -aDiscreteRange.getMinX() : 0.0, - aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0); + aDiscreteRange.getMinY() > 0.0 ? -aDiscreteRange.getMinY() : 0.0)); // create new local ViewInformation2D with new transformation const geometry::ViewInformation2D aViewInformation2D( @@ -1798,7 +1795,7 @@ namespace drawinglayer if(rFillBitmapAttribute.getTiling()) { // apply possible color modification to Bitmap - const BitmapEx aChangedBitmapEx(impModifyBitmapEx(maBColorModifierStack, BitmapEx(rFillBitmapAttribute.getBitmap()))); + const BitmapEx aChangedBitmapEx(impModifyBitmapEx(maBColorModifierStack, rFillBitmapAttribute.getBitmapEx())); if(aChangedBitmapEx.IsEmpty()) { @@ -1821,13 +1818,9 @@ namespace drawinglayer { // create texture matrix from texture to object (where object is unit square here), // so use values directly - basegfx::B2DHomMatrix aTextureMatrix; - aTextureMatrix.scale( - rFillBitmapAttribute.getSize().getX(), - rFillBitmapAttribute.getSize().getY()); - aTextureMatrix.translate( - rFillBitmapAttribute.getTopLeft().getX(), - rFillBitmapAttribute.getTopLeft().getY()); + const basegfx::B2DHomMatrix aTextureMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix( + rFillBitmapAttribute.getSize().getX(), rFillBitmapAttribute.getSize().getY(), + rFillBitmapAttribute.getTopLeft().getX(), rFillBitmapAttribute.getTopLeft().getY())); // create and fill texture rendering::Texture aTexture; @@ -1883,7 +1876,7 @@ namespace drawinglayer const primitive2d::Primitive2DReference xReference(rChildren[0]); const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get()); - if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitiveID()) + if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) { // direct draw of PolyPolygon with color and transparence const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); @@ -1922,7 +1915,7 @@ namespace drawinglayer void canvasProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : { diff --git a/drawinglayer/source/processor2d/contourextractor2d.cxx b/drawinglayer/source/processor2d/contourextractor2d.cxx index 1f629cb25c9c..3225651a6754 100644 --- a/drawinglayer/source/processor2d/contourextractor2d.cxx +++ b/drawinglayer/source/processor2d/contourextractor2d.cxx @@ -70,7 +70,7 @@ namespace drawinglayer void ContourExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : { diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx index 4ffef7515389..b10e10706520 100644 --- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx +++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx @@ -289,7 +289,7 @@ namespace drawinglayer return; } - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D : { @@ -451,8 +451,9 @@ namespace drawinglayer { if(!getHitTextOnly()) { - const primitive2d::ScenePrimitive2D& rSceneCandidate(static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate)); - check3DHit(rSceneCandidate); + const primitive2d::ScenePrimitive2D& rScenePrimitive2D( + static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate)); + check3DHit(rScenePrimitive2D); } break; diff --git a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx index 5f0ab63ee1b3..cc474b7c0736 100644 --- a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx +++ b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx @@ -66,7 +66,7 @@ namespace drawinglayer void LineGeometryExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D : case PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D : diff --git a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx index 9358c7f39c57..ce53d1e86399 100644 --- a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx +++ b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx @@ -51,7 +51,7 @@ namespace drawinglayer { void TextAsPolygonExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : { diff --git a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx b/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx index 1488cd4fd054..216139653692 100644 --- a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx +++ b/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx @@ -43,6 +43,7 @@ #include <basegfx/range/b2drange.hxx> #include <vcl/outdev.hxx> #include <vclhelperbitmaptransform.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// // support for different kinds of bitmap rendering using vcl @@ -84,10 +85,9 @@ namespace drawinglayer else { // if rotated, create the unrotated output rectangle for the GraphicManager paint - basegfx::B2DHomMatrix aSimpleObjectMatrix; - - aSimpleObjectMatrix.scale(fabs(aScale.getX()), fabs(aScale.getY())); - aSimpleObjectMatrix.translate(aTranslate.getX(), aTranslate.getY()); + const basegfx::B2DHomMatrix aSimpleObjectMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix( + fabs(aScale.getX()), fabs(aScale.getY()), + aTranslate.getX(), aTranslate.getY())); aOutlineRange.transform(aSimpleObjectMatrix); } @@ -190,11 +190,11 @@ namespace drawinglayer } // build transform from pixel in aDestination to pixel in rBitmapEx - basegfx::B2DHomMatrix aTransform; - // from relative in aCroppedRectPixel to relative in aDestRectPixel // No need to take bNeedToReduce into account, TopLeft is unchanged - aTransform.translate(aCroppedRectPixel.Left() - aDestRectPixel.Left(), aCroppedRectPixel.Top() - aDestRectPixel.Top()); + basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( + aCroppedRectPixel.Left() - aDestRectPixel.Left(), + aCroppedRectPixel.Top() - aDestRectPixel.Top())); // from relative in aDestRectPixel to absolute Logic. Here it // is essential to adapt to reduce factor (if used) @@ -207,8 +207,10 @@ namespace drawinglayer fAdaptedDRPHeight *= fReduceFactor; } - aTransform.scale(aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight); - aTransform.translate(aDestRectLogic.Left(), aDestRectLogic.Top()); + aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( + aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight, + aDestRectLogic.Left(), aDestRectLogic.Top()) + * aTransform; // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y) basegfx::B2DHomMatrix aInvBitmapTransform(rTransform); diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index d1190c2d9179..a99115a095c4 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -74,6 +74,7 @@ #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <helperchartrenderer.hxx> #include <drawinglayer/primitive2d/hittestprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // for PDFExtOutDevData Graphic support @@ -592,7 +593,7 @@ namespace drawinglayer void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : { @@ -1008,26 +1009,12 @@ namespace drawinglayer SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(rStrokePrimitive.getB2DPolygon(), 0, &rStrokePrimitive.getLineAttribute(), &rStrokePrimitive.getStrokeAttribute(), 0, 0); - // Adapt OutDev's DrawMode if special ones were used - const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); - adaptLineToFillDrawMode(); - - impStartSvtGraphicStroke(pSvtGraphicStroke); - - // #i101491# - // Change default of fat line generation for MetaFiles: Create MetaPolyLineAction - // instead of decomposing all geometries when the polygon has more than given amount of - // points; else the decomposition will get too expensive quiclky. OTOH - // the decomposition provides the better quality e.g. taking edge roundings - // into account which will NOT be taken into account with LineInfo-based actions - const sal_uInt32 nSubPolygonCount(rStrokePrimitive.getB2DPolygon().count()); - bool bDone(0 == nSubPolygonCount); - - if(!bDone && nSubPolygonCount > 1000) + if(true) { - // create MetaPolyLineActions, but without LINE_DASH + impStartSvtGraphicStroke(pSvtGraphicStroke); const attribute::LineAttribute& rLine = rStrokePrimitive.getLineAttribute(); + // create MetaPolyLineActions, but without LINE_DASH if(basegfx::fTools::more(rLine.getWidth(), 0.0)) { const attribute::StrokeAttribute& rStroke = rStrokePrimitive.getStrokeAttribute(); @@ -1047,10 +1034,9 @@ namespace drawinglayer const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor())); mpOutputDevice->SetLineColor(Color(aHairlineColor)); mpOutputDevice->SetFillColor(); - aHairLinePolyPolygon.transform(maCurrentTransformation); - - const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(rLine.getWidth())); + LineInfo aLineInfo(LINE_SOLID, basegfx::fround(rLine.getWidth())); + aLineInfo.SetLineJoin(rLine.getLineJoin()); for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++) { @@ -1063,22 +1049,88 @@ namespace drawinglayer mpMetaFile->AddAction(new MetaPolyLineAction(aToolsPolygon, aLineInfo)); } } - - bDone = true; } - } + else + { + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } - if(!bDone) - { - // use decomposition (creates line geometry as filled polygon - // geometry) - process(rCandidate.get2DDecomposition(getViewInformation2D())); + impEndSvtGraphicStroke(pSvtGraphicStroke); } + else + { + // Adapt OutDev's DrawMode if special ones were used + const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); + adaptLineToFillDrawMode(); + + impStartSvtGraphicStroke(pSvtGraphicStroke); + + // #i101491# + // Change default of fat line generation for MetaFiles: Create MetaPolyLineAction + // instead of decomposing all geometries when the polygon has more than given amount of + // points; else the decomposition will get too expensive quiclky. OTOH + // the decomposition provides the better quality e.g. taking edge roundings + // into account which will NOT be taken into account with LineInfo-based actions + const sal_uInt32 nSubPolygonCount(rStrokePrimitive.getB2DPolygon().count()); + bool bDone(0 == nSubPolygonCount); + + if(!bDone && nSubPolygonCount > 1000) + { + // create MetaPolyLineActions, but without LINE_DASH + const attribute::LineAttribute& rLine = rStrokePrimitive.getLineAttribute(); - impEndSvtGraphicStroke(pSvtGraphicStroke); + if(basegfx::fTools::more(rLine.getWidth(), 0.0)) + { + const attribute::StrokeAttribute& rStroke = rStrokePrimitive.getStrokeAttribute(); + basegfx::B2DPolyPolygon aHairLinePolyPolygon; - // restore DrawMode - mpOutputDevice->SetDrawMode(nOriginalDrawMode); + if(0.0 == rStroke.getFullDotDashLen()) + { + aHairLinePolyPolygon.append(rStrokePrimitive.getB2DPolygon()); + } + else + { + basegfx::tools::applyLineDashing( + rStrokePrimitive.getB2DPolygon(), rStroke.getDotDashArray(), + &aHairLinePolyPolygon, 0, rStroke.getFullDotDashLen()); + } + + const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor())); + mpOutputDevice->SetLineColor(Color(aHairlineColor)); + mpOutputDevice->SetFillColor(); + + aHairLinePolyPolygon.transform(maCurrentTransformation); + + const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(rLine.getWidth())); + + for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++) + { + const basegfx::B2DPolygon aCandidate(aHairLinePolyPolygon.getB2DPolygon(a)); + + if(aCandidate.count() > 1) + { + const Polygon aToolsPolygon(aCandidate); + + mpMetaFile->AddAction(new MetaPolyLineAction(aToolsPolygon, aLineInfo)); + } + } + + bDone = true; + } + } + + if(!bDone) + { + // use decomposition (creates line geometry as filled polygon + // geometry) + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } + + impEndSvtGraphicStroke(pSvtGraphicStroke); + + // restore DrawMode + mpOutputDevice->SetDrawMode(nOriginalDrawMode); + } break; } @@ -1124,8 +1176,8 @@ namespace drawinglayer const basegfx::B2DPoint aFillBitmapTopLeft(rFillBitmapAttribute.getTopLeft() * aOutlineSize); // the scaling needs scale from pixel to logic coordinate system - const Bitmap& rBitmap = rFillBitmapAttribute.getBitmap(); - Size aBmpSizePixel(rBitmap.GetSizePixel()); + const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx(); + Size aBmpSizePixel(rBitmapEx.GetSizePixel()); if(!aBmpSizePixel.Width()) { @@ -1149,7 +1201,7 @@ namespace drawinglayer aTransform.matrix[5] = aFillBitmapTopLeft.getY(); // setup fill graphic like in impgrfll - Graphic aFillGraphic = Graphic(rBitmap); + Graphic aFillGraphic = Graphic(rBitmapEx); aFillGraphic.SetPrefMapMode(MapMode(MAP_PIXEL)); aFillGraphic.SetPrefSize(aBmpSizePixel); @@ -1456,7 +1508,7 @@ namespace drawinglayer // PolyPolygonGradientPrimitive2D, PolyPolygonHatchPrimitive2D and // PolyPolygonBitmapPrimitive2D are derived from PolyPolygonColorPrimitive2D. // Check also for correct ID to exclude derived implementations - if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitiveID()) + if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) { // single transparent PolyPolygon identified, use directly const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); @@ -1567,7 +1619,7 @@ namespace drawinglayer } // Check also for correct ID to exclude derived implementations - if(pFiGradient && PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D == pFiGradient->getPrimitiveID()) + if(pFiGradient && PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D == pFiGradient->getPrimitive2DID()) { // various content, create content-metafile GDIMetaFile aContentMetafile; @@ -1754,6 +1806,11 @@ namespace drawinglayer break; } + case PRIMITIVE2D_ID_EPSPRIMITIVE2D : + { + RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); + break; + } default : { // process recursively diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index ef351002a1ea..5a74b0471b7f 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -67,6 +67,8 @@ #include <drawinglayer/primitive2d/invertprimitive2d.hxx> #include <cstdio> #include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -111,7 +113,7 @@ namespace drawinglayer void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - switch(rCandidate.getPrimitiveID()) + switch(rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D : { @@ -204,18 +206,8 @@ namespace drawinglayer } case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : { - if(getOptionsDrawinglayer().IsAntiAliasing()) - { - // For AA, direct render has to be avoided since it uses XOR maskings which will not - // work with AA. Instead, the decompose which uses MaskPrimitive2D with fillings is - // used - process(rCandidate.get2DDecomposition(getViewInformation2D())); - } - else - { - // direct draw of gradient - RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); - } + // direct draw of gradient + RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); break; } case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D : @@ -241,8 +233,17 @@ namespace drawinglayer mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); } - // direct draw of MetaFile - RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); + static bool bTestMetaFilePrimitiveDecomposition(true); + if(bTestMetaFilePrimitiveDecomposition) + { + // use new Metafile decomposition + process(rCandidate.get2DDecomposition(getViewInformation2D())); + } + else + { + // direct draw of MetaFile + RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); + } if(bForceLineSnap) { @@ -280,7 +281,7 @@ namespace drawinglayer const primitive2d::Primitive2DReference xReference(rContent[0]); const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = dynamic_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(xReference.get()); - if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitiveID()) + if(pPoPoColor && PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D == pPoPoColor->getPrimitive2DID()) { // single transparent PolyPolygon identified, use directly const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(pPoPoColor->getBColor())); @@ -528,7 +529,6 @@ namespace drawinglayer // restore AA setting mpOutputDevice->SetAntialiasing(nOriginalAA); - break; } case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D : @@ -545,23 +545,23 @@ namespace drawinglayer case PRIMITIVE2D_ID_INVERTPRIMITIVE2D : { // invert primitive (currently only used for HighContrast fallback for selection in SW and SC). - // Set OutDev to XOR + // Set OutDev to XOR and switch AA off (XOR does not work with AA) mpOutputDevice->Push(); mpOutputDevice->SetRasterOp( ROP_XOR ); - - // force paint color to white by using ColorModifierStack - const basegfx::BColor aColWhite(1.0, 1.0, 1.0); - const basegfx::BColorModifier aColorModifier(aColWhite, 0.0, basegfx::BCOLORMODIFYMODE_REPLACE); - maBColorModifierStack.push(aColorModifier); + const sal_uInt16 nAntiAliasing(mpOutputDevice->GetAntialiasing()); + mpOutputDevice->SetAntialiasing(nAntiAliasing & ~ANTIALIASING_ENABLE_B2DDRAW); // process content recursively process(rCandidate.get2DDecomposition(getViewInformation2D())); - // restore ColorModifierStack - maBColorModifierStack.pop(); - // restore OutDev mpOutputDevice->Pop(); + mpOutputDevice->SetAntialiasing(nAntiAliasing); + break; + } + case PRIMITIVE2D_ID_EPSPRIMITIVE2D : + { + RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate)); break; } default : diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 3412b5db5598..bd9439ef9339 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -63,6 +63,8 @@ #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <tools/diagnose_ex.h> #include <vcl/metric.hxx> +#include <drawinglayer/primitive2d/textenumsprimitive2d.hxx> +#include <drawinglayer/primitive2d/epsprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // control support @@ -99,34 +101,6 @@ namespace drawinglayer using ::com::sun::star::awt::XWindow; using ::com::sun::star::awt::PosSize::POSSIZE; - static FontUnderline mapTextLineStyle(primitive2d::FontUnderline eLineStyle) - { - switch(eLineStyle) - { - default: - DBG_WARNING1( "DrawingLayer: Unknown text line style attribute (%d)!", eLineStyle ); - // fall through - case primitive2d::FONT_UNDERLINE_NONE: return UNDERLINE_NONE; - case primitive2d::FONT_UNDERLINE_SINGLE: return UNDERLINE_SINGLE; - case primitive2d::FONT_UNDERLINE_DOUBLE: return UNDERLINE_DOUBLE; - case primitive2d::FONT_UNDERLINE_DOTTED: return UNDERLINE_DOTTED; - case primitive2d::FONT_UNDERLINE_DASH: return UNDERLINE_DASH; - case primitive2d::FONT_UNDERLINE_LONGDASH: return UNDERLINE_LONGDASH; - case primitive2d::FONT_UNDERLINE_DASHDOT: return UNDERLINE_DASHDOT; - case primitive2d::FONT_UNDERLINE_DASHDOTDOT: return UNDERLINE_DASHDOTDOT; - case primitive2d::FONT_UNDERLINE_SMALLWAVE: return UNDERLINE_SMALLWAVE; - case primitive2d::FONT_UNDERLINE_WAVE: return UNDERLINE_WAVE; - case primitive2d::FONT_UNDERLINE_DOUBLEWAVE: return UNDERLINE_DOUBLEWAVE; - case primitive2d::FONT_UNDERLINE_BOLD: return UNDERLINE_BOLD; - case primitive2d::FONT_UNDERLINE_BOLDDOTTED: return UNDERLINE_BOLDDOTTED; - case primitive2d::FONT_UNDERLINE_BOLDDASH: return UNDERLINE_BOLDDASH; - case primitive2d::FONT_UNDERLINE_BOLDLONGDASH: return UNDERLINE_LONGDASH; - case primitive2d::FONT_UNDERLINE_BOLDDASHDOT: return UNDERLINE_BOLDDASHDOT; - case primitive2d::FONT_UNDERLINE_BOLDDASHDOTDOT:return UNDERLINE_BOLDDASHDOT; - case primitive2d::FONT_UNDERLINE_BOLDWAVE: return UNDERLINE_BOLDWAVE; - } - } - ////////////////////////////////////////////////////////////////////////////// // rendering support @@ -157,8 +131,8 @@ namespace drawinglayer if(basegfx::fTools::more(aFontScaling.getX(), 0.0) && basegfx::fTools::more(aFontScaling.getY(), 0.0)) { // Get the VCL font (use FontHeight as FontWidth) - Font aFont(primitive2d::getVclFontFromFontAttributes( - rTextCandidate.getFontAttributes(), + Font aFont(primitive2d::getVclFontFromFontAttribute( + rTextCandidate.getFontAttribute(), aFontScaling.getX(), aFontScaling.getY(), fRotate, @@ -176,7 +150,7 @@ namespace drawinglayer mpOutputDevice->SetTextLineColor( Color(aTextlineColor) ); // set Overline attribute - FontUnderline eFontOverline = mapTextLineStyle( pTCPP->getFontOverline() ); + const FontUnderline eFontOverline(primitive2d::mapTextLineToFontUnderline( pTCPP->getFontOverline() )); if( eFontOverline != UNDERLINE_NONE ) { aFont.SetOverline( eFontOverline ); @@ -187,7 +161,7 @@ namespace drawinglayer } // set Underline attribute - FontUnderline eFontUnderline = mapTextLineStyle( pTCPP->getFontUnderline() ); + const FontUnderline eFontUnderline(primitive2d::mapTextLineToFontUnderline( pTCPP->getFontUnderline() )); if( eFontUnderline != UNDERLINE_NONE ) { aFont.SetUnderline( eFontUnderline ); @@ -198,35 +172,23 @@ namespace drawinglayer } // set Strikeout attribute - FontStrikeout eFontStrikeout = STRIKEOUT_NONE; - switch( pTCPP->getFontStrikeout() ) - { - default: - DBG_WARNING1( "DrawingLayer: Unknown strikeout attribute (%d)!", pTCPP->getFontStrikeout() ); - // fall through - case primitive2d::FONT_STRIKEOUT_NONE: eFontStrikeout = STRIKEOUT_NONE; break; - case primitive2d::FONT_STRIKEOUT_SINGLE: eFontStrikeout = STRIKEOUT_SINGLE; break; - case primitive2d::FONT_STRIKEOUT_DOUBLE: eFontStrikeout = STRIKEOUT_DOUBLE; break; - case primitive2d::FONT_STRIKEOUT_BOLD: eFontStrikeout = STRIKEOUT_BOLD; break; - case primitive2d::FONT_STRIKEOUT_SLASH: eFontStrikeout = STRIKEOUT_SLASH; break; - case primitive2d::FONT_STRIKEOUT_X: eFontStrikeout = STRIKEOUT_X; break; - } + const FontStrikeout eFontStrikeout(primitive2d::mapTextStrikeoutToFontStrikeout(pTCPP->getTextStrikeout())); if( eFontStrikeout != STRIKEOUT_NONE ) aFont.SetStrikeout( eFontStrikeout ); // set EmphasisMark attribute FontEmphasisMark eFontEmphasisMark = EMPHASISMARK_NONE; - switch( pTCPP->getFontEmphasisMark() ) + switch( pTCPP->getTextEmphasisMark() ) { default: - DBG_WARNING1( "DrawingLayer: Unknown EmphasisMark style (%d)!", pTCPP->getFontEmphasisMark() ); + DBG_WARNING1( "DrawingLayer: Unknown EmphasisMark style (%d)!", pTCPP->getTextEmphasisMark() ); // fall through - case primitive2d::FONT_EMPHASISMARK_NONE: eFontEmphasisMark = EMPHASISMARK_NONE; break; - case primitive2d::FONT_EMPHASISMARK_DOT: eFontEmphasisMark = EMPHASISMARK_DOT; break; - case primitive2d::FONT_EMPHASISMARK_CIRCLE: eFontEmphasisMark = EMPHASISMARK_CIRCLE; break; - case primitive2d::FONT_EMPHASISMARK_DISC: eFontEmphasisMark = EMPHASISMARK_DISC; break; - case primitive2d::FONT_EMPHASISMARK_ACCENT: eFontEmphasisMark = EMPHASISMARK_ACCENT; break; + case primitive2d::TEXT_EMPHASISMARK_NONE: eFontEmphasisMark = EMPHASISMARK_NONE; break; + case primitive2d::TEXT_EMPHASISMARK_DOT: eFontEmphasisMark = EMPHASISMARK_DOT; break; + case primitive2d::TEXT_EMPHASISMARK_CIRCLE: eFontEmphasisMark = EMPHASISMARK_CIRCLE; break; + case primitive2d::TEXT_EMPHASISMARK_DISC: eFontEmphasisMark = EMPHASISMARK_DISC; break; + case primitive2d::TEXT_EMPHASISMARK_ACCENT: eFontEmphasisMark = EMPHASISMARK_ACCENT; break; } if( eFontEmphasisMark != EMPHASISMARK_NONE ) @@ -242,14 +204,14 @@ namespace drawinglayer // set Relief attribute FontRelief eFontRelief = RELIEF_NONE; - switch( pTCPP->getFontRelief() ) + switch( pTCPP->getTextRelief() ) { default: - DBG_WARNING1( "DrawingLayer: Unknown Relief style (%d)!", pTCPP->getFontRelief() ); + DBG_WARNING1( "DrawingLayer: Unknown Relief style (%d)!", pTCPP->getTextRelief() ); // fall through - case primitive2d::FONT_RELIEF_NONE: eFontRelief = RELIEF_NONE; break; - case primitive2d::FONT_RELIEF_EMBOSSED: eFontRelief = RELIEF_EMBOSSED; break; - case primitive2d::FONT_RELIEF_ENGRAVED: eFontRelief = RELIEF_ENGRAVED; break; + case primitive2d::TEXT_RELIEF_NONE: eFontRelief = RELIEF_NONE; break; + case primitive2d::TEXT_RELIEF_EMBOSSED: eFontRelief = RELIEF_EMBOSSED; break; + case primitive2d::TEXT_RELIEF_ENGRAVED: eFontRelief = RELIEF_ENGRAVED; break; } if( eFontRelief != RELIEF_NONE ) @@ -282,7 +244,7 @@ namespace drawinglayer const Point aStartPoint(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())); const sal_uInt32 nOldLayoutMode(mpOutputDevice->GetLayoutMode()); - if(rTextCandidate.getFontAttributes().getRTL()) + if(rTextCandidate.getFontAttribute().getRTL()) { sal_uInt32 nRTLLayoutMode(nOldLayoutMode & ~(TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG)); nRTLLayoutMode |= TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_TEXTORIGIN_LEFT; @@ -310,7 +272,7 @@ namespace drawinglayer rTextCandidate.getTextLength()); } - if(rTextCandidate.getFontAttributes().getRTL()) + if(rTextCandidate.getFontAttribute().getRTL()) { mpOutputDevice->SetLayoutMode(nOldLayoutMode); } @@ -428,7 +390,7 @@ namespace drawinglayer { // no shear or rotate, draw direct in pixel coordinates bPrimitiveAccepted = true; - BitmapEx aBitmapEx(rFillBitmapAttribute.getBitmap()); + BitmapEx aBitmapEx(rFillBitmapAttribute.getBitmapEx()); bool bPainted(false); if(maBColorModifierStack.count()) @@ -547,21 +509,32 @@ namespace drawinglayer basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor())); basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor())); basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon()); - aLocalPolyPolygon.transform(maCurrentTransformation); - if(aStartColor == aEndColor) - { - // no gradient at all, draw as polygon - mpOutputDevice->SetLineColor(); - mpOutputDevice->SetFillColor(Color(aStartColor)); - mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); - } - else + if(aLocalPolyPolygon.count()) { - impDrawGradientToOutDev( - *mpOutputDevice, aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(), - aStartColor, aEndColor, rGradient.getBorder(), - -rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), false); + aLocalPolyPolygon.transform(maCurrentTransformation); + + if(aStartColor == aEndColor) + { + // no gradient at all, draw as polygon in AA and non-AA case + mpOutputDevice->SetLineColor(); + mpOutputDevice->SetFillColor(Color(aStartColor)); + mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); + } + else if(getOptionsDrawinglayer().IsAntiAliasing()) + { + // For AA, direct render has to be avoided since it uses XOR maskings which will not + // work with AA. Instead, the decompose which uses MaskPrimitive2D with fillings is + // used + process(rPolygonCandidate.get2DDecomposition(getViewInformation2D())); + } + else + { + impDrawGradientToOutDev( + *mpOutputDevice, aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(), + aStartColor, aEndColor, rGradient.getBorder(), + -rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), false); + } } } @@ -574,9 +547,9 @@ namespace drawinglayer if(rPolyPolygon.count()) { const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPolygonCandidate.getFillBitmap(); - const Bitmap& rBitmap = rFillBitmapAttribute.getBitmap(); + const BitmapEx& rBitmapEx = rFillBitmapAttribute.getBitmapEx(); - if(rBitmap.IsEmpty()) + if(rBitmapEx.IsEmpty()) { // empty bitmap, done bDone = true; @@ -668,7 +641,9 @@ namespace drawinglayer aLocalPolyPolygon.transform(maCurrentTransformation); mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon); - if(mnPolygonStrokePrimitive2D && getOptionsDrawinglayer().IsAntiAliasing()) + if(mnPolygonStrokePrimitive2D + && getOptionsDrawinglayer().IsAntiAliasing() + && (mpOutputDevice->GetAntialiasing() & ANTIALIASING_ENABLE_B2DDRAW)) { // when AA is on and this filled polygons are the result of stroked line geometry, // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons @@ -1256,6 +1231,43 @@ namespace drawinglayer } } + void VclProcessor2D::RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D) + { + // The new decomposition of Metafiles made it necessary to add an Eps + // primitive to handle embedded Eps data. On some devices, this can be + // painted directly (mac, printer). + // To be able to handle the replacement correctly, i need to handle it myself + // since DrawEPS will not be able e.g. to rotate the replacement. To be able + // to do that, i added a boolean return to OutputDevice::DrawEPS(..) + // to know when EPS was handled directly already. + basegfx::B2DRange aRange(0.0, 0.0, 1.0, 1.0); + aRange.transform(maCurrentTransformation * rEpsPrimitive2D.getEpsTransform()); + + if(!aRange.isEmpty()) + { + const Rectangle aRectangle( + (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()), + (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY())); + + if(!aRectangle.IsEmpty()) + { + // try to paint EPS directly without fallback visualisation + const bool bEPSPaintedDirectly(mpOutputDevice->DrawEPS( + aRectangle.TopLeft(), + aRectangle.GetSize(), + rEpsPrimitive2D.getGfxLink(), + 0)); + + if(!bEPSPaintedDirectly) + { + // use the decomposition which will correctly handle the + // fallback visualisation using full transformation (e.g. rotation) + process(rEpsPrimitive2D.get2DDecomposition(getViewInformation2D())); + } + } + } + } + void VclProcessor2D::adaptLineToFillDrawMode() const { const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); |