summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2020-04-29 15:14:54 +0200
committerTomaž Vajngerl <quikee@gmail.com>2020-05-02 21:41:36 +0200
commit47ee147e28ce3af33eb514b601e8d45e546fc84c (patch)
tree242788ab6988f39c28fe9ef50798c24e567a4a5e /drawinglayer
parentf1d90767ead36f4c716255a1e822c97813e18379 (diff)
remove vclprocessor2d.cxx from clang-format blacklist
Change-Id: I359dfb0fe6fdf88e9c8141186a770c4cde777161 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93320 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx2303
1 files changed, 1182 insertions, 1121 deletions
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index f44c85c54eef..c5460f0433e1 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -72,754 +72,783 @@ using namespace com::sun::star;
namespace
{
- sal_uInt32 calculateStepsForSvgGradient(const basegfx::BColor& rColorA, const basegfx::BColor& rColorB, double fDelta, double fDiscreteUnit)
- {
- // use color distance, assume to do every color step
- sal_uInt32 nSteps(basegfx::fround(rColorA.getDistance(rColorB) * 255.0));
+sal_uInt32 calculateStepsForSvgGradient(const basegfx::BColor& rColorA,
+ const basegfx::BColor& rColorB, double fDelta,
+ double fDiscreteUnit)
+{
+ // use color distance, assume to do every color step
+ sal_uInt32 nSteps(basegfx::fround(rColorA.getDistance(rColorB) * 255.0));
- if(nSteps)
- {
- // calc discrete length to change color each discrete unit (pixel)
- const sal_uInt32 nDistSteps(basegfx::fround(fDelta / fDiscreteUnit));
+ if (nSteps)
+ {
+ // calc discrete length to change color each discrete unit (pixel)
+ const sal_uInt32 nDistSteps(basegfx::fround(fDelta / fDiscreteUnit));
- nSteps = std::min(nSteps, nDistSteps);
- }
+ nSteps = std::min(nSteps, nDistSteps);
+ }
- // reduce quality to 3 discrete units or every 3rd color step for rendering
- nSteps /= 2;
+ // reduce quality to 3 discrete units or every 3rd color step for rendering
+ nSteps /= 2;
- // roughly cut when too big or too small (not full quality, reduce complexity)
- nSteps = std::min(nSteps, sal_uInt32(255));
- nSteps = std::max(nSteps, sal_uInt32(1));
+ // roughly cut when too big or too small (not full quality, reduce complexity)
+ nSteps = std::min(nSteps, sal_uInt32(255));
+ nSteps = std::max(nSteps, sal_uInt32(1));
- return nSteps;
- }
+ return nSteps;
+}
}
namespace drawinglayer::processor2d
{
- // rendering support
+// rendering support
+
+// directdraw of text simple portion or decorated portion primitive. When decorated, all the extra
+// information is translated to VCL parameters and set at the font.
+// Acceptance is restricted to no shearing and positive scaling in X and Y (no font mirroring
+// for VCL)
+void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
+ const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate)
+{
+ // decompose matrix to have position and size of text
+ basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation
+ * rTextCandidate.getTextTransform());
+ basegfx::B2DVector aFontScaling, aTranslate;
+ double fRotate, fShearX;
+ aLocalTransform.decompose(aFontScaling, aTranslate, fRotate, fShearX);
+ bool bPrimitiveAccepted(false);
+
+ // tdf#95581: Assume tiny shears are rounding artefacts or whatever and can be ignored,
+ // especially if the effect is less than a pixel.
+ if (std::abs(aFontScaling.getY() * fShearX) < 1)
+ {
+ if (basegfx::fTools::less(aFontScaling.getX(), 0.0)
+ && basegfx::fTools::less(aFontScaling.getY(), 0.0))
+ {
+ // handle special case: If scale is negative in (x,y) (3rd quadrant), it can
+ // be expressed as rotation by PI. Use this since the Font rendering will not
+ // apply the negative scales in any form
+ aFontScaling = basegfx::absolute(aFontScaling);
+ fRotate += F_PI;
+ }
- // directdraw of text simple portion or decorated portion primitive. When decorated, all the extra
- // information is translated to VCL parameters and set at the font.
- // Acceptance is restricted to no shearing and positive scaling in X and Y (no font mirroring
- // for VCL)
- void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate)
+ if (basegfx::fTools::more(aFontScaling.getX(), 0.0)
+ && basegfx::fTools::more(aFontScaling.getY(), 0.0))
{
- // decompose matrix to have position and size of text
- basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rTextCandidate.getTextTransform());
- basegfx::B2DVector aFontScaling, aTranslate;
- double fRotate, fShearX;
- aLocalTransform.decompose(aFontScaling, aTranslate, fRotate, fShearX);
- bool bPrimitiveAccepted(false);
+ // Get the VCL font (use FontHeight as FontWidth)
+ vcl::Font aFont(primitive2d::getVclFontFromFontAttribute(
+ rTextCandidate.getFontAttribute(), aFontScaling.getX(), aFontScaling.getY(),
+ fRotate, rTextCandidate.getLocale()));
+
+ // set FillColor Attribute
+ const Color aFillColor(rTextCandidate.getTextFillColor());
+ if (aFillColor != COL_TRANSPARENT)
+ {
+ aFont.SetFillColor(aFillColor);
+ aFont.SetTransparent(false);
+ }
+
+ // Don't draw fonts without height
+ if (aFont.GetFontHeight() <= 0)
+ return;
- // tdf#95581: Assume tiny shears are rounding artefacts or whatever and can be ignored,
- // especially if the effect is less than a pixel.
- if(std::abs(aFontScaling.getY() * fShearX) < 1)
+ // handle additional font attributes
+ const primitive2d::TextDecoratedPortionPrimitive2D* pTCPP
+ = dynamic_cast<const primitive2d::TextDecoratedPortionPrimitive2D*>(
+ &rTextCandidate);
+
+ if (pTCPP != nullptr)
{
- if(basegfx::fTools::less(aFontScaling.getX(), 0.0) && basegfx::fTools::less(aFontScaling.getY(), 0.0))
+ // set the color of text decorations
+ const basegfx::BColor aTextlineColor
+ = maBColorModifierStack.getModifiedColor(pTCPP->getTextlineColor());
+ mpOutputDevice->SetTextLineColor(Color(aTextlineColor));
+
+ // set Overline attribute
+ const FontLineStyle eFontOverline(
+ primitive2d::mapTextLineToFontLineStyle(pTCPP->getFontOverline()));
+ if (eFontOverline != LINESTYLE_NONE)
{
- // handle special case: If scale is negative in (x,y) (3rd quadrant), it can
- // be expressed as rotation by PI. Use this since the Font rendering will not
- // apply the negative scales in any form
- aFontScaling = basegfx::absolute(aFontScaling);
- fRotate += F_PI;
+ aFont.SetOverline(eFontOverline);
+ const basegfx::BColor aOverlineColor
+ = maBColorModifierStack.getModifiedColor(pTCPP->getOverlineColor());
+ mpOutputDevice->SetOverlineColor(Color(aOverlineColor));
+ if (pTCPP->getWordLineMode())
+ aFont.SetWordLineMode(true);
}
- if(basegfx::fTools::more(aFontScaling.getX(), 0.0) && basegfx::fTools::more(aFontScaling.getY(), 0.0))
+ // set Underline attribute
+ const FontLineStyle eFontLineStyle(
+ primitive2d::mapTextLineToFontLineStyle(pTCPP->getFontUnderline()));
+ if (eFontLineStyle != LINESTYLE_NONE)
{
- // Get the VCL font (use FontHeight as FontWidth)
- vcl::Font aFont(primitive2d::getVclFontFromFontAttribute(
- rTextCandidate.getFontAttribute(),
- aFontScaling.getX(),
- aFontScaling.getY(),
- fRotate,
- rTextCandidate.getLocale()));
-
- // set FillColor Attribute
- const Color aFillColor( rTextCandidate.getTextFillColor() );
- if( aFillColor != COL_TRANSPARENT )
- {
- aFont.SetFillColor(aFillColor);
- aFont.SetTransparent(false);
- }
-
- // Don't draw fonts without height
- if( aFont.GetFontHeight() <= 0 )
- return;
-
- // handle additional font attributes
- const primitive2d::TextDecoratedPortionPrimitive2D* pTCPP =
- dynamic_cast<const primitive2d::TextDecoratedPortionPrimitive2D*>( &rTextCandidate );
-
- if( pTCPP != nullptr )
- {
-
- // set the color of text decorations
- const basegfx::BColor aTextlineColor = maBColorModifierStack.getModifiedColor(pTCPP->getTextlineColor());
- mpOutputDevice->SetTextLineColor( Color(aTextlineColor) );
-
- // set Overline attribute
- const FontLineStyle eFontOverline(primitive2d::mapTextLineToFontLineStyle( pTCPP->getFontOverline() ));
- if( eFontOverline != LINESTYLE_NONE )
- {
- aFont.SetOverline( eFontOverline );
- const basegfx::BColor aOverlineColor = maBColorModifierStack.getModifiedColor(pTCPP->getOverlineColor());
- mpOutputDevice->SetOverlineColor( Color(aOverlineColor) );
- if( pTCPP->getWordLineMode() )
- aFont.SetWordLineMode( true );
- }
-
- // set Underline attribute
- const FontLineStyle eFontLineStyle(primitive2d::mapTextLineToFontLineStyle( pTCPP->getFontUnderline() ));
- if( eFontLineStyle != LINESTYLE_NONE )
- {
- aFont.SetUnderline( eFontLineStyle );
- if( pTCPP->getWordLineMode() )
- aFont.SetWordLineMode( true );
- }
-
- // set Strikeout attribute
- const FontStrikeout eFontStrikeout(primitive2d::mapTextStrikeoutToFontStrikeout(pTCPP->getTextStrikeout()));
-
- if( eFontStrikeout != STRIKEOUT_NONE )
- aFont.SetStrikeout( eFontStrikeout );
-
-
- // set EmphasisMark attribute
- FontEmphasisMark eFontEmphasisMark = FontEmphasisMark::NONE;
- switch( pTCPP->getTextEmphasisMark() )
- {
- default:
- SAL_WARN("drawinglayer", "Unknown EmphasisMark style " << pTCPP->getTextEmphasisMark() );
- [[fallthrough]];
- case primitive2d::TEXT_FONT_EMPHASIS_MARK_NONE: eFontEmphasisMark = FontEmphasisMark::NONE; break;
- case primitive2d::TEXT_FONT_EMPHASIS_MARK_DOT: eFontEmphasisMark = FontEmphasisMark::Dot; break;
- case primitive2d::TEXT_FONT_EMPHASIS_MARK_CIRCLE: eFontEmphasisMark = FontEmphasisMark::Circle; break;
- case primitive2d::TEXT_FONT_EMPHASIS_MARK_DISC: eFontEmphasisMark = FontEmphasisMark::Disc; break;
- case primitive2d::TEXT_FONT_EMPHASIS_MARK_ACCENT: eFontEmphasisMark = FontEmphasisMark::Accent; break;
- }
+ aFont.SetUnderline(eFontLineStyle);
+ if (pTCPP->getWordLineMode())
+ aFont.SetWordLineMode(true);
+ }
- if( eFontEmphasisMark != FontEmphasisMark::NONE )
- {
- DBG_ASSERT( (pTCPP->getEmphasisMarkAbove() != pTCPP->getEmphasisMarkBelow()),
- "DrawingLayer: Bad EmphasisMark position!" );
- if( pTCPP->getEmphasisMarkAbove() )
- eFontEmphasisMark |= FontEmphasisMark::PosAbove;
- else
- eFontEmphasisMark |= FontEmphasisMark::PosBelow;
- aFont.SetEmphasisMark( eFontEmphasisMark );
- }
+ // set Strikeout attribute
+ const FontStrikeout eFontStrikeout(
+ primitive2d::mapTextStrikeoutToFontStrikeout(pTCPP->getTextStrikeout()));
- // set Relief attribute
- FontRelief eFontRelief = FontRelief::NONE;
- switch( pTCPP->getTextRelief() )
- {
- default:
- SAL_WARN( "drawinglayer", "Unknown Relief style " << pTCPP->getTextRelief() );
- [[fallthrough]];
- case primitive2d::TEXT_RELIEF_NONE: eFontRelief = FontRelief::NONE; break;
- case primitive2d::TEXT_RELIEF_EMBOSSED: eFontRelief = FontRelief::Embossed; break;
- case primitive2d::TEXT_RELIEF_ENGRAVED: eFontRelief = FontRelief::Engraved; break;
- }
+ if (eFontStrikeout != STRIKEOUT_NONE)
+ aFont.SetStrikeout(eFontStrikeout);
- if( eFontRelief != FontRelief::NONE )
- aFont.SetRelief( eFontRelief );
+ // set EmphasisMark attribute
+ FontEmphasisMark eFontEmphasisMark = FontEmphasisMark::NONE;
+ switch (pTCPP->getTextEmphasisMark())
+ {
+ default:
+ SAL_WARN("drawinglayer",
+ "Unknown EmphasisMark style " << pTCPP->getTextEmphasisMark());
+ [[fallthrough]];
+ case primitive2d::TEXT_FONT_EMPHASIS_MARK_NONE:
+ eFontEmphasisMark = FontEmphasisMark::NONE;
+ break;
+ case primitive2d::TEXT_FONT_EMPHASIS_MARK_DOT:
+ eFontEmphasisMark = FontEmphasisMark::Dot;
+ break;
+ case primitive2d::TEXT_FONT_EMPHASIS_MARK_CIRCLE:
+ eFontEmphasisMark = FontEmphasisMark::Circle;
+ break;
+ case primitive2d::TEXT_FONT_EMPHASIS_MARK_DISC:
+ eFontEmphasisMark = FontEmphasisMark::Disc;
+ break;
+ case primitive2d::TEXT_FONT_EMPHASIS_MARK_ACCENT:
+ eFontEmphasisMark = FontEmphasisMark::Accent;
+ break;
+ }
- // set Shadow attribute
- if( pTCPP->getShadow() )
- aFont.SetShadow( true );
- }
+ if (eFontEmphasisMark != FontEmphasisMark::NONE)
+ {
+ DBG_ASSERT((pTCPP->getEmphasisMarkAbove() != pTCPP->getEmphasisMarkBelow()),
+ "DrawingLayer: Bad EmphasisMark position!");
+ if (pTCPP->getEmphasisMarkAbove())
+ eFontEmphasisMark |= FontEmphasisMark::PosAbove;
+ else
+ eFontEmphasisMark |= FontEmphasisMark::PosBelow;
+ aFont.SetEmphasisMark(eFontEmphasisMark);
+ }
- // create transformed integer DXArray in view coordinate system
- std::vector< long > aTransformedDXArray;
+ // set Relief attribute
+ FontRelief eFontRelief = FontRelief::NONE;
+ switch (pTCPP->getTextRelief())
+ {
+ default:
+ SAL_WARN("drawinglayer", "Unknown Relief style " << pTCPP->getTextRelief());
+ [[fallthrough]];
+ case primitive2d::TEXT_RELIEF_NONE:
+ eFontRelief = FontRelief::NONE;
+ break;
+ case primitive2d::TEXT_RELIEF_EMBOSSED:
+ eFontRelief = FontRelief::Embossed;
+ break;
+ case primitive2d::TEXT_RELIEF_ENGRAVED:
+ eFontRelief = FontRelief::Engraved;
+ break;
+ }
- if(!rTextCandidate.getDXArray().empty())
- {
- aTransformedDXArray.reserve(rTextCandidate.getDXArray().size());
- const basegfx::B2DVector aPixelVector(maCurrentTransformation * basegfx::B2DVector(1.0, 0.0));
- const double fPixelVectorFactor(aPixelVector.getLength());
+ if (eFontRelief != FontRelief::NONE)
+ aFont.SetRelief(eFontRelief);
- for (auto const& elem : rTextCandidate.getDXArray())
- {
- aTransformedDXArray.push_back(basegfx::fround(elem * fPixelVectorFactor));
- }
- }
+ // set Shadow attribute
+ if (pTCPP->getShadow())
+ aFont.SetShadow(true);
+ }
- // set parameters and paint text snippet
- const basegfx::BColor aRGBFontColor(maBColorModifierStack.getModifiedColor(rTextCandidate.getFontColor()));
- const basegfx::B2DPoint aPoint(aLocalTransform * basegfx::B2DPoint(0.0, 0.0));
- const Point aStartPoint(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()));
- const ComplexTextLayoutFlags nOldLayoutMode(mpOutputDevice->GetLayoutMode());
+ // create transformed integer DXArray in view coordinate system
+ std::vector<long> aTransformedDXArray;
- if(rTextCandidate.getFontAttribute().getRTL())
- {
- ComplexTextLayoutFlags nRTLLayoutMode(nOldLayoutMode & ~ComplexTextLayoutFlags::BiDiStrong);
- nRTLLayoutMode |= ComplexTextLayoutFlags::BiDiRtl|ComplexTextLayoutFlags::TextOriginLeft;
- mpOutputDevice->SetLayoutMode(nRTLLayoutMode);
- }
+ if (!rTextCandidate.getDXArray().empty())
+ {
+ aTransformedDXArray.reserve(rTextCandidate.getDXArray().size());
+ const basegfx::B2DVector aPixelVector(maCurrentTransformation
+ * basegfx::B2DVector(1.0, 0.0));
+ const double fPixelVectorFactor(aPixelVector.getLength());
- mpOutputDevice->SetFont(aFont);
- mpOutputDevice->SetTextColor(Color(aRGBFontColor));
+ for (auto const& elem : rTextCandidate.getDXArray())
+ {
+ aTransformedDXArray.push_back(basegfx::fround(elem * fPixelVectorFactor));
+ }
+ }
- OUString aText( rTextCandidate.getText() );
- sal_Int32 nPos = rTextCandidate.getTextPosition();
- sal_Int32 nLen = rTextCandidate.getTextLength();
+ // set parameters and paint text snippet
+ const basegfx::BColor aRGBFontColor(
+ maBColorModifierStack.getModifiedColor(rTextCandidate.getFontColor()));
+ const basegfx::B2DPoint aPoint(aLocalTransform * basegfx::B2DPoint(0.0, 0.0));
+ const Point aStartPoint(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()));
+ const ComplexTextLayoutFlags nOldLayoutMode(mpOutputDevice->GetLayoutMode());
- long* pDXArray = !aTransformedDXArray.empty() ? aTransformedDXArray.data() : nullptr ;
+ if (rTextCandidate.getFontAttribute().getRTL())
+ {
+ ComplexTextLayoutFlags nRTLLayoutMode(nOldLayoutMode
+ & ~ComplexTextLayoutFlags::BiDiStrong);
+ nRTLLayoutMode
+ |= ComplexTextLayoutFlags::BiDiRtl | ComplexTextLayoutFlags::TextOriginLeft;
+ mpOutputDevice->SetLayoutMode(nRTLLayoutMode);
+ }
- if ( rTextCandidate.isFilled() )
- {
- basegfx::B2DVector aOldFontScaling, aOldTranslate;
- double fOldRotate, fOldShearX;
- rTextCandidate.getTextTransform().decompose(aOldFontScaling, aOldTranslate, fOldRotate, fOldShearX);
-
- long nWidthToFill = static_cast<long>(rTextCandidate.getWidthToFill( ) * aFontScaling.getX() / aOldFontScaling.getX());
-
- long nWidth = mpOutputDevice->GetTextArray( rTextCandidate.getText(), pDXArray, 0, 1 );
- long nChars = 2;
- if ( nWidth )
- nChars = nWidthToFill / nWidth;
-
- OUStringBuffer aFilled;
- comphelper::string::padToLength(aFilled, nChars, aText[0]);
- aText = aFilled.makeStringAndClear();
- nPos = 0;
- nLen = nChars;
- }
+ mpOutputDevice->SetFont(aFont);
+ mpOutputDevice->SetTextColor(Color(aRGBFontColor));
- if(!aTransformedDXArray.empty())
- {
- mpOutputDevice->DrawTextArray(
- aStartPoint,
- aText,
- pDXArray,
- nPos,
- nLen);
- }
- else
- {
- mpOutputDevice->DrawText(
- aStartPoint,
- aText,
- nPos,
- nLen);
- }
+ OUString aText(rTextCandidate.getText());
+ sal_Int32 nPos = rTextCandidate.getTextPosition();
+ sal_Int32 nLen = rTextCandidate.getTextLength();
- if(rTextCandidate.getFontAttribute().getRTL())
- {
- mpOutputDevice->SetLayoutMode(nOldLayoutMode);
- }
+ long* pDXArray = !aTransformedDXArray.empty() ? aTransformedDXArray.data() : nullptr;
- bPrimitiveAccepted = true;
- }
+ if (rTextCandidate.isFilled())
+ {
+ basegfx::B2DVector aOldFontScaling, aOldTranslate;
+ double fOldRotate, fOldShearX;
+ rTextCandidate.getTextTransform().decompose(aOldFontScaling, aOldTranslate,
+ fOldRotate, fOldShearX);
+
+ long nWidthToFill = static_cast<long>(
+ rTextCandidate.getWidthToFill() * aFontScaling.getX() / aOldFontScaling.getX());
+
+ long nWidth
+ = mpOutputDevice->GetTextArray(rTextCandidate.getText(), pDXArray, 0, 1);
+ long nChars = 2;
+ if (nWidth)
+ nChars = nWidthToFill / nWidth;
+
+ OUStringBuffer aFilled;
+ comphelper::string::padToLength(aFilled, nChars, aText[0]);
+ aText = aFilled.makeStringAndClear();
+ nPos = 0;
+ nLen = nChars;
}
- if(!bPrimitiveAccepted)
+ if (!aTransformedDXArray.empty())
{
- // let break down
- process(rTextCandidate);
+ mpOutputDevice->DrawTextArray(aStartPoint, aText, pDXArray, nPos, nLen);
+ }
+ else
+ {
+ mpOutputDevice->DrawText(aStartPoint, aText, nPos, nLen);
}
- }
-
- // direct draw of hairline
- void VclProcessor2D::RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased)
- {
- const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor()));
- mpOutputDevice->SetLineColor(Color(aHairlineColor));
- mpOutputDevice->SetFillColor();
-
- basegfx::B2DPolygon aLocalPolygon(rPolygonCandidate.getB2DPolygon());
- aLocalPolygon.transform(maCurrentTransformation);
- if(bPixelBased && getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete())
+ if (rTextCandidate.getFontAttribute().getRTL())
{
- // #i98289#
- // when a Hairline is painted and AntiAliasing is on the option SnapHorVerLinesToDiscrete
- // allows to suppress AntiAliasing for pure horizontal or vertical lines. This is done since
- // not-AntiAliased such lines look more pleasing to the eye (e.g. 2D chart content). This
- // NEEDS to be done in discrete coordinates, so only useful for pixel based rendering.
- aLocalPolygon = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aLocalPolygon);
+ mpOutputDevice->SetLayoutMode(nOldLayoutMode);
}
- mpOutputDevice->DrawPolyLine(aLocalPolygon, 0.0);
+ bPrimitiveAccepted = true;
}
+ }
- // direct draw of transformed BitmapEx primitive
- void VclProcessor2D::RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate)
- {
- BitmapEx aBitmapEx(VCLUnoHelper::GetBitmap(rBitmapCandidate.getXBitmap()));
- const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rBitmapCandidate.getTransform());
+ if (!bPrimitiveAccepted)
+ {
+ // let break down
+ process(rTextCandidate);
+ }
+}
- if(maBColorModifierStack.count())
- {
- aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack);
+// direct draw of hairline
+void VclProcessor2D::RenderPolygonHairlinePrimitive2D(
+ const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased)
+{
+ const basegfx::BColor aHairlineColor(
+ maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor()));
+ mpOutputDevice->SetLineColor(Color(aHairlineColor));
+ mpOutputDevice->SetFillColor();
- if(aBitmapEx.IsEmpty())
- {
- // color gets completely replaced, get it
- const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor()));
- basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
- aPolygon.transform(aLocalTransform);
+ basegfx::B2DPolygon aLocalPolygon(rPolygonCandidate.getB2DPolygon());
+ aLocalPolygon.transform(maCurrentTransformation);
- mpOutputDevice->SetFillColor(Color(aModifiedColor));
- mpOutputDevice->SetLineColor();
- mpOutputDevice->DrawPolygon(aPolygon);
+ if (bPixelBased && getOptionsDrawinglayer().IsAntiAliasing()
+ && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete())
+ {
+ // #i98289#
+ // when a Hairline is painted and AntiAliasing is on the option SnapHorVerLinesToDiscrete
+ // allows to suppress AntiAliasing for pure horizontal or vertical lines. This is done since
+ // not-AntiAliased such lines look more pleasing to the eye (e.g. 2D chart content). This
+ // NEEDS to be done in discrete coordinates, so only useful for pixel based rendering.
+ aLocalPolygon = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aLocalPolygon);
+ }
- return;
- }
- }
+ mpOutputDevice->DrawPolyLine(aLocalPolygon, 0.0);
+}
+
+// direct draw of transformed BitmapEx primitive
+void VclProcessor2D::RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate)
+{
+ BitmapEx aBitmapEx(VCLUnoHelper::GetBitmap(rBitmapCandidate.getXBitmap()));
+ const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation
+ * rBitmapCandidate.getTransform());
+
+ if (maBColorModifierStack.count())
+ {
+ aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack);
+
+ if (aBitmapEx.IsEmpty())
+ {
+ // color gets completely replaced, get it
+ const basegfx::BColor aModifiedColor(
+ maBColorModifierStack.getModifiedColor(basegfx::BColor()));
+ basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
+ aPolygon.transform(aLocalTransform);
- // #122923# do no longer add Alpha channel here; the right place to do this is when really
- // the own transformer is used (see OutputDevice::DrawTransformedBitmapEx).
+ mpOutputDevice->SetFillColor(Color(aModifiedColor));
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawPolygon(aPolygon);
- // draw using OutputDevice'sDrawTransformedBitmapEx
- mpOutputDevice->DrawTransformedBitmapEx(aLocalTransform, aBitmapEx);
+ return;
}
+ }
+
+ // #122923# do no longer add Alpha channel here; the right place to do this is when really
+ // the own transformer is used (see OutputDevice::DrawTransformedBitmapEx).
+
+ // draw using OutputDevice'sDrawTransformedBitmapEx
+ mpOutputDevice->DrawTransformedBitmapEx(aLocalTransform, aBitmapEx);
+}
- void VclProcessor2D::RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate)
+void VclProcessor2D::RenderFillGraphicPrimitive2D(
+ const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate)
+{
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute(
+ rFillBitmapCandidate.getFillGraphic());
+ bool bPrimitiveAccepted(false);
+
+ // #121194# when tiling is used and content is bitmap-based, do direct tiling in the
+ // renderer on pixel base to ensure tight fitting. Do not do this when
+ // the fill is rotated or sheared.
+ if (rFillGraphicAttribute.getTiling())
+ {
+ // content is bitmap(ex)
+ //
+ // for Vector Graphic Data (SVG, EMF+) support, force decomposition when present. This will lead to use
+ // the primitive representation of the vector data directly.
+ //
+ // when graphic is animated, force decomposition to use the correct graphic, else
+ // fill style will not be animated
+ if (GraphicType::Bitmap == rFillGraphicAttribute.getGraphic().GetType()
+ && !rFillGraphicAttribute.getGraphic().getVectorGraphicData().get()
+ && !rFillGraphicAttribute.getGraphic().IsAnimated())
{
- const attribute::FillGraphicAttribute& rFillGraphicAttribute(rFillBitmapCandidate.getFillGraphic());
- bool bPrimitiveAccepted(false);
+ // decompose matrix to check for shear, rotate and mirroring
+ basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation
+ * rFillBitmapCandidate.getTransformation());
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
- // #121194# when tiling is used and content is bitmap-based, do direct tiling in the
- // renderer on pixel base to ensure tight fitting. Do not do this when
- // the fill is rotated or sheared.
- if(rFillGraphicAttribute.getTiling())
+ // when nopt rotated/sheared
+ if (basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX))
{
- // content is bitmap(ex)
- //
- // for Vector Graphic Data (SVG, EMF+) support, force decomposition when present. This will lead to use
- // the primitive representation of the vector data directly.
- //
- // when graphic is animated, force decomposition to use the correct graphic, else
- // fill style will not be animated
- if(GraphicType::Bitmap == rFillGraphicAttribute.getGraphic().GetType()
- && !rFillGraphicAttribute.getGraphic().getVectorGraphicData().get()
- && !rFillGraphicAttribute.getGraphic().IsAnimated())
- {
- // decompose matrix to check for shear, rotate and mirroring
- basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rFillBitmapCandidate.getTransformation());
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
- aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
-
- // when nopt rotated/sheared
- if(basegfx::fTools::equalZero(fRotate) && basegfx::fTools::equalZero(fShearX))
- {
- // no shear or rotate, draw direct in pixel coordinates
- bPrimitiveAccepted = true;
+ // no shear or rotate, draw direct in pixel coordinates
+ bPrimitiveAccepted = true;
- // transform object range to device coordinates (pixels). Use
- // the device transformation for better accuracy
- basegfx::B2DRange aObjectRange(aTranslate, aTranslate + aScale);
- aObjectRange.transform(mpOutputDevice->GetViewTransformation());
+ // transform object range to device coordinates (pixels). Use
+ // the device transformation for better accuracy
+ basegfx::B2DRange aObjectRange(aTranslate, aTranslate + aScale);
+ aObjectRange.transform(mpOutputDevice->GetViewTransformation());
- // extract discrete size of object
- const sal_Int32 nOWidth(basegfx::fround(aObjectRange.getWidth()));
- const sal_Int32 nOHeight(basegfx::fround(aObjectRange.getHeight()));
+ // extract discrete size of object
+ const sal_Int32 nOWidth(basegfx::fround(aObjectRange.getWidth()));
+ const sal_Int32 nOHeight(basegfx::fround(aObjectRange.getHeight()));
- // only do something when object has a size in discrete units
- if(nOWidth > 0 && nOHeight > 0)
+ // only do something when object has a size in discrete units
+ if (nOWidth > 0 && nOHeight > 0)
+ {
+ // transform graphic range to device coordinates (pixels). Use
+ // the device transformation for better accuracy
+ basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
+ aGraphicRange.transform(mpOutputDevice->GetViewTransformation()
+ * aLocalTransform);
+
+ // extract discrete size of graphic
+ // caution: when getting to zero, nothing would be painted; thus, do not allow this
+ const sal_Int32 nBWidth(
+ std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getWidth())));
+ const sal_Int32 nBHeight(
+ std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getHeight())));
+
+ // only do something when bitmap fill has a size in discrete units
+ if (nBWidth > 0 && nBHeight > 0)
+ {
+ // nBWidth, nBHeight is the pixel size of the needed bitmap. To not need to scale it
+ // in vcl many times, create a size-optimized version
+ const Size aNeededBitmapSizePixel(nBWidth, nBHeight);
+ BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
+ const bool bPreScaled(nBWidth * nBHeight < (250 * 250));
+
+ // ... but only up to a maximum size, else it gets too expensive
+ if (bPreScaled)
{
- // transform graphic range to device coordinates (pixels). Use
- // the device transformation for better accuracy
- basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange());
- aGraphicRange.transform(mpOutputDevice->GetViewTransformation() * aLocalTransform);
-
- // extract discrete size of graphic
- // caution: when getting to zero, nothing would be painted; thus, do not allow this
- const sal_Int32 nBWidth(std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getWidth())));
- const sal_Int32 nBHeight(std::max(sal_Int32(1), basegfx::fround(aGraphicRange.getHeight())));
-
- // only do something when bitmap fill has a size in discrete units
- if(nBWidth > 0 && nBHeight > 0)
+ // if color depth is below 24bit, expand before scaling for better quality.
+ // This is even needed for low colors, else the scale will produce
+ // a bitmap in gray or Black/White (!)
+ if (aBitmapEx.GetBitCount() < 24)
{
- // nBWidth, nBHeight is the pixel size of the needed bitmap. To not need to scale it
- // in vcl many times, create a size-optimized version
- const Size aNeededBitmapSizePixel(nBWidth, nBHeight);
- BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
- const bool bPreScaled(nBWidth * nBHeight < (250 * 250));
-
- // ... but only up to a maximum size, else it gets too expensive
- if(bPreScaled)
- {
- // if color depth is below 24bit, expand before scaling for better quality.
- // This is even needed for low colors, else the scale will produce
- // a bitmap in gray or Black/White (!)
- if(aBitmapEx.GetBitCount() < 24)
- {
- aBitmapEx.Convert(BmpConversion::N24Bit);
- }
+ aBitmapEx.Convert(BmpConversion::N24Bit);
+ }
- aBitmapEx.Scale(aNeededBitmapSizePixel, BmpScaleFlag::Interpolate);
- }
+ aBitmapEx.Scale(aNeededBitmapSizePixel, BmpScaleFlag::Interpolate);
+ }
- bool bPainted(false);
+ bool bPainted(false);
- if(maBColorModifierStack.count())
- {
- // when color modifier, apply to bitmap
- aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack);
+ if (maBColorModifierStack.count())
+ {
+ // when color modifier, apply to bitmap
+ aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack);
- // impModifyBitmapEx uses empty bitmap as sign to return that
- // the content will be completely replaced to mono color, use shortcut
- if(aBitmapEx.IsEmpty())
- {
- // color gets completely replaced, get it
- const basegfx::BColor aModifiedColor(maBColorModifierStack.getModifiedColor(basegfx::BColor()));
- basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
- aPolygon.transform(aLocalTransform);
+ // impModifyBitmapEx uses empty bitmap as sign to return that
+ // the content will be completely replaced to mono color, use shortcut
+ if (aBitmapEx.IsEmpty())
+ {
+ // color gets completely replaced, get it
+ const basegfx::BColor aModifiedColor(
+ maBColorModifierStack.getModifiedColor(basegfx::BColor()));
+ basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
+ aPolygon.transform(aLocalTransform);
- mpOutputDevice->SetFillColor(Color(aModifiedColor));
- mpOutputDevice->SetLineColor();
- mpOutputDevice->DrawPolygon(aPolygon);
+ mpOutputDevice->SetFillColor(Color(aModifiedColor));
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->DrawPolygon(aPolygon);
- bPainted = true;
- }
- }
+ bPainted = true;
+ }
+ }
- if(!bPainted)
- {
- sal_Int32 nBLeft(basegfx::fround(aGraphicRange.getMinX()));
- sal_Int32 nBTop(basegfx::fround(aGraphicRange.getMinY()));
- const sal_Int32 nOLeft(basegfx::fround(aObjectRange.getMinX()));
- const sal_Int32 nOTop(basegfx::fround(aObjectRange.getMinY()));
- sal_Int32 nPosX(0);
- sal_Int32 nPosY(0);
-
- if(nBLeft > nOLeft)
- {
- const sal_Int32 nDiff((nBLeft / nBWidth) + 1);
+ if (!bPainted)
+ {
+ sal_Int32 nBLeft(basegfx::fround(aGraphicRange.getMinX()));
+ sal_Int32 nBTop(basegfx::fround(aGraphicRange.getMinY()));
+ const sal_Int32 nOLeft(basegfx::fround(aObjectRange.getMinX()));
+ const sal_Int32 nOTop(basegfx::fround(aObjectRange.getMinY()));
+ sal_Int32 nPosX(0);
+ sal_Int32 nPosY(0);
+
+ if (nBLeft > nOLeft)
+ {
+ const sal_Int32 nDiff((nBLeft / nBWidth) + 1);
- nPosX -= nDiff;
- nBLeft -= nDiff * nBWidth;
- }
+ nPosX -= nDiff;
+ nBLeft -= nDiff * nBWidth;
+ }
- if(nBLeft + nBWidth <= nOLeft)
- {
- const sal_Int32 nDiff(-nBLeft / nBWidth);
+ if (nBLeft + nBWidth <= nOLeft)
+ {
+ const sal_Int32 nDiff(-nBLeft / nBWidth);
- nPosX += nDiff;
- nBLeft += nDiff * nBWidth;
- }
+ nPosX += nDiff;
+ nBLeft += nDiff * nBWidth;
+ }
- if(nBTop > nOTop)
- {
- const sal_Int32 nDiff((nBTop / nBHeight) + 1);
+ if (nBTop > nOTop)
+ {
+ const sal_Int32 nDiff((nBTop / nBHeight) + 1);
- nPosY -= nDiff;
- nBTop -= nDiff * nBHeight;
- }
+ nPosY -= nDiff;
+ nBTop -= nDiff * nBHeight;
+ }
- if(nBTop + nBHeight <= nOTop)
- {
- const sal_Int32 nDiff(-nBTop / nBHeight);
+ if (nBTop + nBHeight <= nOTop)
+ {
+ const sal_Int32 nDiff(-nBTop / nBHeight);
- nPosY += nDiff;
- nBTop += nDiff * nBHeight;
- }
+ nPosY += nDiff;
+ nBTop += nDiff * nBHeight;
+ }
- // prepare OutDev
- const Point aEmptyPoint(0, 0);
- const ::tools::Rectangle aVisiblePixel(aEmptyPoint, mpOutputDevice->GetOutputSizePixel());
- const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
- mpOutputDevice->EnableMapMode(false);
+ // prepare OutDev
+ const Point aEmptyPoint(0, 0);
+ const ::tools::Rectangle aVisiblePixel(
+ aEmptyPoint, mpOutputDevice->GetOutputSizePixel());
+ const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
+ mpOutputDevice->EnableMapMode(false);
- // check if offset is used
- const sal_Int32 nOffsetX(basegfx::fround(rFillGraphicAttribute.getOffsetX() * nBWidth));
+ // check if offset is used
+ const sal_Int32 nOffsetX(
+ basegfx::fround(rFillGraphicAttribute.getOffsetX() * nBWidth));
- if(nOffsetX)
+ if (nOffsetX)
+ {
+ // offset in X, so iterate over Y first and draw lines
+ for (sal_Int32 nYPos(nBTop); nYPos < nOTop + nOHeight;
+ nYPos += nBHeight, nPosY++)
+ {
+ for (sal_Int32 nXPos((nPosY % 2) ? nBLeft - nBWidth + nOffsetX
+ : nBLeft);
+ nXPos < nOLeft + nOWidth; nXPos += nBWidth)
{
- // offset in X, so iterate over Y first and draw lines
- for(sal_Int32 nYPos(nBTop); nYPos < nOTop + nOHeight; nYPos += nBHeight, nPosY++)
+ const ::tools::Rectangle aOutRectPixel(
+ Point(nXPos, nYPos), aNeededBitmapSizePixel);
+
+ if (aOutRectPixel.IsOver(aVisiblePixel))
{
- for(sal_Int32 nXPos((nPosY % 2) ? nBLeft - nBWidth + nOffsetX : nBLeft);
- nXPos < nOLeft + nOWidth; nXPos += nBWidth)
+ if (bPreScaled)
+ {
+ mpOutputDevice->DrawBitmapEx(
+ aOutRectPixel.TopLeft(), aBitmapEx);
+ }
+ else
{
- const ::tools::Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel);
-
- if(aOutRectPixel.IsOver(aVisiblePixel))
- {
- if(bPreScaled)
- {
- mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
- }
- else
- {
- mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aNeededBitmapSizePixel, aBitmapEx);
- }
- }
+ mpOutputDevice->DrawBitmapEx(
+ aOutRectPixel.TopLeft(), aNeededBitmapSizePixel,
+ aBitmapEx);
}
}
}
- else
+ }
+ }
+ else
+ {
+ // check if offset is used
+ const sal_Int32 nOffsetY(
+ basegfx::fround(rFillGraphicAttribute.getOffsetY() * nBHeight));
+
+ // possible offset in Y, so iterate over X first and draw columns
+ for (sal_Int32 nXPos(nBLeft); nXPos < nOLeft + nOWidth;
+ nXPos += nBWidth, nPosX++)
+ {
+ for (sal_Int32 nYPos((nPosX % 2) ? nBTop - nBHeight + nOffsetY
+ : nBTop);
+ nYPos < nOTop + nOHeight; nYPos += nBHeight)
{
- // check if offset is used
- const sal_Int32 nOffsetY(basegfx::fround(rFillGraphicAttribute.getOffsetY() * nBHeight));
+ const ::tools::Rectangle aOutRectPixel(
+ Point(nXPos, nYPos), aNeededBitmapSizePixel);
- // possible offset in Y, so iterate over X first and draw columns
- for(sal_Int32 nXPos(nBLeft); nXPos < nOLeft + nOWidth; nXPos += nBWidth, nPosX++)
+ if (aOutRectPixel.IsOver(aVisiblePixel))
{
- for(sal_Int32 nYPos((nPosX % 2) ? nBTop - nBHeight + nOffsetY : nBTop);
- nYPos < nOTop + nOHeight; nYPos += nBHeight)
+ if (bPreScaled)
+ {
+ mpOutputDevice->DrawBitmapEx(
+ aOutRectPixel.TopLeft(), aBitmapEx);
+ }
+ else
{
- const ::tools::Rectangle aOutRectPixel(Point(nXPos, nYPos), aNeededBitmapSizePixel);
-
- if(aOutRectPixel.IsOver(aVisiblePixel))
- {
- if(bPreScaled)
- {
- mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
- }
- else
- {
- mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aNeededBitmapSizePixel, aBitmapEx);
- }
- }
+ mpOutputDevice->DrawBitmapEx(
+ aOutRectPixel.TopLeft(), aNeededBitmapSizePixel,
+ aBitmapEx);
}
}
}
-
- // restore OutDev
- mpOutputDevice->EnableMapMode(bWasEnabled);
}
}
+
+ // restore OutDev
+ mpOutputDevice->EnableMapMode(bWasEnabled);
}
}
}
}
-
- if(!bPrimitiveAccepted)
- {
- // do not accept, use decomposition
- process(rFillBitmapCandidate);
- }
}
+ }
- // direct draw of Graphic
- void VclProcessor2D::RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate)
- {
- bool bDone(false);
- const basegfx::B2DPolyPolygon& rPolyPolygon = rPolygonCandidate.getB2DPolyPolygon();
+ if (!bPrimitiveAccepted)
+ {
+ // do not accept, use decomposition
+ process(rFillBitmapCandidate);
+ }
+}
+
+// direct draw of Graphic
+void VclProcessor2D::RenderPolyPolygonGraphicPrimitive2D(
+ const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate)
+{
+ bool bDone(false);
+ const basegfx::B2DPolyPolygon& rPolyPolygon = rPolygonCandidate.getB2DPolyPolygon();
+
+ // #121194# Todo: check if this works
+ if (!rPolyPolygon.count())
+ {
+ // empty polyPolygon, done
+ bDone = true;
+ }
+ else
+ {
+ const attribute::FillGraphicAttribute& rFillGraphicAttribute
+ = rPolygonCandidate.getFillGraphic();
- // #121194# Todo: check if this works
- if(!rPolyPolygon.count())
+ // try to catch cases where the graphic will be color-modified to a single
+ // color (e.g. shadow)
+ switch (rFillGraphicAttribute.getGraphic().GetType())
+ {
+ case GraphicType::GdiMetafile:
{
- // empty polyPolygon, done
- bDone = true;
+ // metafiles are potentially transparent, cannot optimize, not done
+ break;
}
- else
+ case GraphicType::Bitmap:
{
- const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPolygonCandidate.getFillGraphic();
-
- // try to catch cases where the graphic will be color-modified to a single
- // color (e.g. shadow)
- switch(rFillGraphicAttribute.getGraphic().GetType())
+ if (!rFillGraphicAttribute.getGraphic().IsTransparent()
+ && !rFillGraphicAttribute.getGraphic().IsAlpha())
{
- case GraphicType::GdiMetafile:
- {
- // metafiles are potentially transparent, cannot optimize, not done
- break;
- }
- case GraphicType::Bitmap:
+ // bitmap is not transparent and has no alpha
+ const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count());
+
+ if (nBColorModifierStackCount)
{
- if(!rFillGraphicAttribute.getGraphic().IsTransparent() && !rFillGraphicAttribute.getGraphic().IsAlpha())
+ const basegfx::BColorModifierSharedPtr& rTopmostModifier
+ = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount
+ - 1);
+ const basegfx::BColorModifier_replace* pReplacer
+ = dynamic_cast<const basegfx::BColorModifier_replace*>(
+ rTopmostModifier.get());
+
+ if (pReplacer)
{
- // bitmap is not transparent and has no alpha
- const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count());
-
- if(nBColorModifierStackCount)
+ // the bitmap fill is in unified color, so we can replace it with
+ // a single polygon fill. The form of the fill depends on tiling
+ if (rFillGraphicAttribute.getTiling())
{
- const basegfx::BColorModifierSharedPtr& rTopmostModifier = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount - 1);
- const basegfx::BColorModifier_replace* pReplacer = dynamic_cast< const basegfx::BColorModifier_replace* >(rTopmostModifier.get());
+ // with tiling, fill the whole tools::PolyPolygon with the modifier color
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon);
- if(pReplacer)
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->SetFillColor(Color(pReplacer->getBColor()));
+ mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
+ }
+ else
+ {
+ // without tiling, only the area common to the bitmap tile and the
+ // tools::PolyPolygon is filled. Create the bitmap tile area in object
+ // coordinates. For this, the object transformation needs to be created
+ // from the already scaled PolyPolygon. The tile area in object
+ // coordinates will always be non-rotated, so it's not necessary to
+ // work with a polygon here
+ basegfx::B2DRange aTileRange(
+ rFillGraphicAttribute.getGraphicRange());
+ const basegfx::B2DRange aPolyPolygonRange(
+ rPolyPolygon.getB2DRange());
+ const basegfx::B2DHomMatrix aNewObjectTransform(
+ basegfx::utils::createScaleTranslateB2DHomMatrix(
+ aPolyPolygonRange.getRange(),
+ aPolyPolygonRange.getMinimum()));
+
+ aTileRange.transform(aNewObjectTransform);
+
+ // now clip the object polyPolygon against the tile range
+ // to get the common area
+ basegfx::B2DPolyPolygon aTarget
+ = basegfx::utils::clipPolyPolygonOnRange(
+ rPolyPolygon, aTileRange, true, false);
+
+ if (aTarget.count())
{
- // the bitmap fill is in unified color, so we can replace it with
- // a single polygon fill. The form of the fill depends on tiling
- if(rFillGraphicAttribute.getTiling())
- {
- // with tiling, fill the whole tools::PolyPolygon with the modifier color
- basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon);
-
- aLocalPolyPolygon.transform(maCurrentTransformation);
- mpOutputDevice->SetLineColor();
- mpOutputDevice->SetFillColor(Color(pReplacer->getBColor()));
- mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
- }
- else
- {
- // without tiling, only the area common to the bitmap tile and the
- // tools::PolyPolygon is filled. Create the bitmap tile area in object
- // coordinates. For this, the object transformation needs to be created
- // from the already scaled PolyPolygon. The tile area in object
- // coordinates will always be non-rotated, so it's not necessary to
- // work with a polygon here
- basegfx::B2DRange aTileRange(rFillGraphicAttribute.getGraphicRange());
- const basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange());
- const basegfx::B2DHomMatrix aNewObjectTransform(
- basegfx::utils::createScaleTranslateB2DHomMatrix(
- aPolyPolygonRange.getRange(),
- aPolyPolygonRange.getMinimum()));
-
- aTileRange.transform(aNewObjectTransform);
-
- // now clip the object polyPolygon against the tile range
- // to get the common area
- basegfx::B2DPolyPolygon aTarget = basegfx::utils::clipPolyPolygonOnRange(
- rPolyPolygon,
- aTileRange,
- true,
- false);
-
- if(aTarget.count())
- {
- aTarget.transform(maCurrentTransformation);
- mpOutputDevice->SetLineColor();
- mpOutputDevice->SetFillColor(Color(pReplacer->getBColor()));
- mpOutputDevice->DrawPolyPolygon(aTarget);
- }
- }
-
- // simplified output executed, we are done
- bDone = true;
+ aTarget.transform(maCurrentTransformation);
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->SetFillColor(Color(pReplacer->getBColor()));
+ mpOutputDevice->DrawPolyPolygon(aTarget);
}
}
+
+ // simplified output executed, we are done
+ bDone = true;
}
- break;
- }
- default: //GraphicType::NONE, GraphicType::Default
- {
- // empty graphic, we are done
- bDone = true;
- break;
}
}
+ break;
}
-
- if(!bDone)
+ default: //GraphicType::NONE, GraphicType::Default
{
- // use default decomposition
- process(rPolygonCandidate);
+ // empty graphic, we are done
+ bDone = true;
+ break;
}
}
+ }
- // mask group. Force output to VDev and create mask from given mask
- void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate)
- {
- if(rMaskCandidate.getChildren().empty())
- return;
-
- basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask());
+ if (!bDone)
+ {
+ // use default decomposition
+ process(rPolygonCandidate);
+ }
+}
- if(!aMask.count())
- return;
+// mask group. Force output to VDev and create mask from given mask
+void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate)
+{
+ if (rMaskCandidate.getChildren().empty())
+ return;
- aMask.transform(maCurrentTransformation);
- const basegfx::B2DRange aRange(basegfx::utils::getRange(aMask));
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
+ basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask());
- if(!aBufferDevice.isVisible())
- return;
+ if (!aMask.count())
+ return;
- // remember last OutDev and set to content
- OutputDevice* pLastOutputDevice = mpOutputDevice;
- mpOutputDevice = &aBufferDevice.getContent();
+ aMask.transform(maCurrentTransformation);
+ const basegfx::B2DRange aRange(basegfx::utils::getRange(aMask));
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
- // paint to it
- process(rMaskCandidate.getChildren());
+ if (!aBufferDevice.isVisible())
+ return;
- // back to old OutDev
- mpOutputDevice = pLastOutputDevice;
+ // remember last OutDev and set to content
+ OutputDevice* pLastOutputDevice = mpOutputDevice;
+ mpOutputDevice = &aBufferDevice.getContent();
- // if the mask fills the whole area we can skip
- // creating a transparent vd and filling it.
- if (!basegfx::utils::isRectangle(aMask))
- {
- // draw mask
- if(getOptionsDrawinglayer().IsAntiAliasing())
- {
- // with AA, use 8bit AlphaMask to get nice borders
- VirtualDevice& rTransparence = aBufferDevice.getTransparence();
- rTransparence.SetLineColor();
- rTransparence.SetFillColor(COL_BLACK);
- rTransparence.DrawPolyPolygon(aMask);
- }
- else
- {
- // No AA, use 1bit mask
- VirtualDevice& rMask = aBufferDevice.getMask();
- rMask.SetLineColor();
- rMask.SetFillColor(COL_BLACK);
- rMask.DrawPolyPolygon(aMask);
- }
- }
+ // paint to it
+ process(rMaskCandidate.getChildren());
- // dump buffer to outdev
- aBufferDevice.paint();
- }
+ // back to old OutDev
+ mpOutputDevice = pLastOutputDevice;
- // modified color group. Force output to unified color.
- void VclProcessor2D::RenderModifiedColorPrimitive2D(const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate)
+ // if the mask fills the whole area we can skip
+ // creating a transparent vd and filling it.
+ if (!basegfx::utils::isRectangle(aMask))
+ {
+ // draw mask
+ if (getOptionsDrawinglayer().IsAntiAliasing())
{
- if(!rModifiedCandidate.getChildren().empty())
- {
- maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
- process(rModifiedCandidate.getChildren());
- maBColorModifierStack.pop();
- }
+ // with AA, use 8bit AlphaMask to get nice borders
+ VirtualDevice& rTransparence = aBufferDevice.getTransparence();
+ rTransparence.SetLineColor();
+ rTransparence.SetFillColor(COL_BLACK);
+ rTransparence.DrawPolyPolygon(aMask);
}
-
- // unified sub-transparence. Draw to VDev first.
- void VclProcessor2D::RenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate)
+ else
{
- if(rTransCandidate.getChildren().empty())
- return;
-
- if(0.0 == rTransCandidate.getTransparence())
- {
- // no transparence used, so just use the content
- process(rTransCandidate.getChildren());
- }
- else if(rTransCandidate.getTransparence() > 0.0 && rTransCandidate.getTransparence() < 1.0)
- {
- // transparence is in visible range
- basegfx::B2DRange aRange(rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
- aRange.transform(maCurrentTransformation);
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
+ // No AA, use 1bit mask
+ VirtualDevice& rMask = aBufferDevice.getMask();
+ rMask.SetLineColor();
+ rMask.SetFillColor(COL_BLACK);
+ rMask.DrawPolyPolygon(aMask);
+ }
+ }
- if(aBufferDevice.isVisible())
- {
- // remember last OutDev and set to content
- OutputDevice* pLastOutputDevice = mpOutputDevice;
- mpOutputDevice = &aBufferDevice.getContent();
+ // dump buffer to outdev
+ aBufferDevice.paint();
+}
- // paint content to it
- process(rTransCandidate.getChildren());
+// modified color group. Force output to unified color.
+void VclProcessor2D::RenderModifiedColorPrimitive2D(
+ const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate)
+{
+ if (!rModifiedCandidate.getChildren().empty())
+ {
+ maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
+ process(rModifiedCandidate.getChildren());
+ maBColorModifierStack.pop();
+ }
+}
- // back to old OutDev
- mpOutputDevice = pLastOutputDevice;
+// unified sub-transparence. Draw to VDev first.
+void VclProcessor2D::RenderUnifiedTransparencePrimitive2D(
+ const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate)
+{
+ if (rTransCandidate.getChildren().empty())
+ return;
- // dump buffer to outdev using given transparence
- aBufferDevice.paint(rTransCandidate.getTransparence());
- }
- }
- }
+ if (0.0 == rTransCandidate.getTransparence())
+ {
+ // no transparence used, so just use the content
+ process(rTransCandidate.getChildren());
+ }
+ else if (rTransCandidate.getTransparence() > 0.0 && rTransCandidate.getTransparence() < 1.0)
+ {
+ // transparence is in visible range
+ basegfx::B2DRange aRange(rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
+ aRange.transform(maCurrentTransformation);
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
- // sub-transparence group. Draw to VDev first.
- void VclProcessor2D::RenderTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& rTransCandidate)
+ if (aBufferDevice.isVisible())
{
- if(rTransCandidate.getChildren().empty())
- return;
-
- basegfx::B2DRange aRange(rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
- aRange.transform(maCurrentTransformation);
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
-
- if(!aBufferDevice.isVisible())
- return;
-
// remember last OutDev and set to content
OutputDevice* pLastOutputDevice = mpOutputDevice;
mpOutputDevice = &aBufferDevice.getContent();
@@ -827,618 +856,650 @@ namespace drawinglayer::processor2d
// paint content to it
process(rTransCandidate.getChildren());
- // set to mask
- mpOutputDevice = &aBufferDevice.getTransparence();
-
- // when painting transparence masks, reset the color stack
- basegfx::BColorModifierStack aLastBColorModifierStack(maBColorModifierStack);
- maBColorModifierStack = basegfx::BColorModifierStack();
-
- // paint mask to it (always with transparence intensities, evtl. with AA)
- process(rTransCandidate.getTransparence());
-
- // back to old color stack
- maBColorModifierStack = aLastBColorModifierStack;
-
// back to old OutDev
mpOutputDevice = pLastOutputDevice;
- // dump buffer to outdev
- aBufferDevice.paint();
+ // dump buffer to outdev using given transparence
+ aBufferDevice.paint(rTransCandidate.getTransparence());
}
+ }
+}
- // transform group.
- void VclProcessor2D::RenderTransformPrimitive2D(const primitive2d::TransformPrimitive2D& rTransformCandidate)
- {
- // remember current transformation and ViewInformation
- const basegfx::B2DHomMatrix aLastCurrentTransformation(maCurrentTransformation);
- const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
-
- // create new transformations for CurrentTransformation
- // and for local ViewInformation2D
- maCurrentTransformation = maCurrentTransformation * rTransformCandidate.getTransformation();
- const geometry::ViewInformation2D aViewInformation2D(
- getViewInformation2D().getObjectTransformation() * rTransformCandidate.getTransformation(),
- getViewInformation2D().getViewTransformation(),
- getViewInformation2D().getViewport(),
- getViewInformation2D().getVisualizedPage(),
- getViewInformation2D().getViewTime(),
- getViewInformation2D().getExtendedInformationSequence());
- updateViewInformation(aViewInformation2D);
-
- // process content
- process(rTransformCandidate.getChildren());
-
- // restore transformations
- maCurrentTransformation = aLastCurrentTransformation;
- updateViewInformation(aLastViewInformation2D);
- }
+// sub-transparence group. Draw to VDev first.
+void VclProcessor2D::RenderTransparencePrimitive2D(
+ const primitive2d::TransparencePrimitive2D& rTransCandidate)
+{
+ if (rTransCandidate.getChildren().empty())
+ return;
- // new XDrawPage for ViewInformation2D
- void VclProcessor2D::RenderPagePreviewPrimitive2D(const primitive2d::PagePreviewPrimitive2D& rPagePreviewCandidate)
- {
- // remember current transformation and ViewInformation
- const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
-
- // create new local ViewInformation2D
- const geometry::ViewInformation2D aViewInformation2D(
- getViewInformation2D().getObjectTransformation(),
- getViewInformation2D().getViewTransformation(),
- getViewInformation2D().getViewport(),
- rPagePreviewCandidate.getXDrawPage(),
- getViewInformation2D().getViewTime(),
- getViewInformation2D().getExtendedInformationSequence());
- updateViewInformation(aViewInformation2D);
-
- // process decomposed content
- process(rPagePreviewCandidate);
-
- // restore transformations
- updateViewInformation(aLastViewInformation2D);
- }
+ basegfx::B2DRange aRange(rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
+ aRange.transform(maCurrentTransformation);
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
- // marker
- void VclProcessor2D::RenderMarkerArrayPrimitive2D(const primitive2d::MarkerArrayPrimitive2D& rMarkArrayCandidate)
- {
- // get data
- const std::vector< basegfx::B2DPoint >& rPositions = rMarkArrayCandidate.getPositions();
- const sal_uInt32 nCount(rPositions.size());
+ if (!aBufferDevice.isVisible())
+ return;
- if(!(nCount && !rMarkArrayCandidate.getMarker().IsEmpty()))
- return;
+ // remember last OutDev and set to content
+ OutputDevice* pLastOutputDevice = mpOutputDevice;
+ mpOutputDevice = &aBufferDevice.getContent();
- // get pixel size
- const BitmapEx& rMarker(rMarkArrayCandidate.getMarker());
- const Size aBitmapSize(rMarker.GetSizePixel());
+ // paint content to it
+ process(rTransCandidate.getChildren());
- if(!(aBitmapSize.Width() && aBitmapSize.Height()))
- return;
+ // set to mask
+ mpOutputDevice = &aBufferDevice.getTransparence();
- // get discrete half size
- const basegfx::B2DVector aDiscreteHalfSize(
- (aBitmapSize.getWidth() - 1.0) * 0.5,
- (aBitmapSize.getHeight() - 1.0) * 0.5);
- const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
+ // when painting transparence masks, reset the color stack
+ basegfx::BColorModifierStack aLastBColorModifierStack(maBColorModifierStack);
+ maBColorModifierStack = basegfx::BColorModifierStack();
- // do not forget evtl. moved origin in target device MapMode when
- // switching it off; it would be missing and lead to wrong positions.
- // All his could be done using logic sizes and coordinates, too, but
- // we want a 1:1 bitmap rendering here, so it's more safe and faster
- // to work with switching off MapMode usage completely.
- const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin());
+ // paint mask to it (always with transparence intensities, evtl. with AA)
+ process(rTransCandidate.getTransparence());
- mpOutputDevice->EnableMapMode(false);
+ // back to old color stack
+ maBColorModifierStack = aLastBColorModifierStack;
- for (auto const& pos : rPositions)
- {
- const basegfx::B2DPoint aDiscreteTopLeft((maCurrentTransformation * pos) - aDiscreteHalfSize);
- const Point aDiscretePoint(basegfx::fround(aDiscreteTopLeft.getX()), basegfx::fround(aDiscreteTopLeft.getY()));
+ // back to old OutDev
+ mpOutputDevice = pLastOutputDevice;
- mpOutputDevice->DrawBitmapEx(aDiscretePoint + aOrigin, rMarker);
- }
+ // dump buffer to outdev
+ aBufferDevice.paint();
+}
- mpOutputDevice->EnableMapMode(bWasEnabled);
- }
+// transform group.
+void VclProcessor2D::RenderTransformPrimitive2D(
+ const primitive2d::TransformPrimitive2D& rTransformCandidate)
+{
+ // remember current transformation and ViewInformation
+ const basegfx::B2DHomMatrix aLastCurrentTransformation(maCurrentTransformation);
+ const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
+
+ // create new transformations for CurrentTransformation
+ // and for local ViewInformation2D
+ maCurrentTransformation = maCurrentTransformation * rTransformCandidate.getTransformation();
+ const geometry::ViewInformation2D aViewInformation2D(
+ getViewInformation2D().getObjectTransformation() * rTransformCandidate.getTransformation(),
+ getViewInformation2D().getViewTransformation(), getViewInformation2D().getViewport(),
+ getViewInformation2D().getVisualizedPage(), getViewInformation2D().getViewTime(),
+ getViewInformation2D().getExtendedInformationSequence());
+ updateViewInformation(aViewInformation2D);
+
+ // process content
+ process(rTransformCandidate.getChildren());
+
+ // restore transformations
+ maCurrentTransformation = aLastCurrentTransformation;
+ updateViewInformation(aLastViewInformation2D);
+}
- // point
- void VclProcessor2D::RenderPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate)
- {
- const std::vector< basegfx::B2DPoint >& rPositions = rPointArrayCandidate.getPositions();
- const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(rPointArrayCandidate.getRGBColor()));
- const Color aVCLColor(aRGBColor);
+// new XDrawPage for ViewInformation2D
+void VclProcessor2D::RenderPagePreviewPrimitive2D(
+ const primitive2d::PagePreviewPrimitive2D& rPagePreviewCandidate)
+{
+ // remember current transformation and ViewInformation
+ const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
+
+ // create new local ViewInformation2D
+ const geometry::ViewInformation2D aViewInformation2D(
+ getViewInformation2D().getObjectTransformation(),
+ getViewInformation2D().getViewTransformation(), getViewInformation2D().getViewport(),
+ rPagePreviewCandidate.getXDrawPage(), getViewInformation2D().getViewTime(),
+ getViewInformation2D().getExtendedInformationSequence());
+ updateViewInformation(aViewInformation2D);
+
+ // process decomposed content
+ process(rPagePreviewCandidate);
+
+ // restore transformations
+ updateViewInformation(aLastViewInformation2D);
+}
- for (auto const& pos : rPositions)
- {
- const basegfx::B2DPoint aViewPosition(maCurrentTransformation * pos);
- const Point aPos(basegfx::fround(aViewPosition.getX()), basegfx::fround(aViewPosition.getY()));
+// marker
+void VclProcessor2D::RenderMarkerArrayPrimitive2D(
+ const primitive2d::MarkerArrayPrimitive2D& rMarkArrayCandidate)
+{
+ // get data
+ const std::vector<basegfx::B2DPoint>& rPositions = rMarkArrayCandidate.getPositions();
+ const sal_uInt32 nCount(rPositions.size());
- mpOutputDevice->DrawPixel(aPos, aVCLColor);
- }
- }
+ if (!(nCount && !rMarkArrayCandidate.getMarker().IsEmpty()))
+ return;
- void VclProcessor2D::RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate)
- {
- // #i101491# method restructured to clearly use the DrawPolyLine
- // calls starting from a defined line width
- const attribute::LineAttribute& rLineAttribute = rPolygonStrokeCandidate.getLineAttribute();
- const double fLineWidth(rLineAttribute.getWidth());
- bool bDone(false);
+ // get pixel size
+ const BitmapEx& rMarker(rMarkArrayCandidate.getMarker());
+ const Size aBitmapSize(rMarker.GetSizePixel());
- if(basegfx::fTools::more(fLineWidth, 0.0))
- {
- const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(fLineWidth, 0.0));
- const double fDiscreteLineWidth(aDiscreteUnit.getLength());
- const attribute::StrokeAttribute& rStrokeAttribute = rPolygonStrokeCandidate.getStrokeAttribute();
- const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLineAttribute.getColor()));
- basegfx::B2DPolyPolygon aHairlinePolyPolygon;
+ if (!(aBitmapSize.Width() && aBitmapSize.Height()))
+ return;
- mpOutputDevice->SetLineColor(Color(aHairlineColor));
- mpOutputDevice->SetFillColor();
+ // get discrete half size
+ const basegfx::B2DVector aDiscreteHalfSize((aBitmapSize.getWidth() - 1.0) * 0.5,
+ (aBitmapSize.getHeight() - 1.0) * 0.5);
+ const bool bWasEnabled(mpOutputDevice->IsMapModeEnabled());
- if(0.0 == rStrokeAttribute.getFullDotDashLen())
- {
- // no line dashing, just copy
- aHairlinePolyPolygon.append(rPolygonStrokeCandidate.getB2DPolygon());
- }
- else
- {
- // else apply LineStyle
- basegfx::utils::applyLineDashing(rPolygonStrokeCandidate.getB2DPolygon(),
- rStrokeAttribute.getDotDashArray(),
- &aHairlinePolyPolygon, nullptr, rStrokeAttribute.getFullDotDashLen());
- }
+ // do not forget evtl. moved origin in target device MapMode when
+ // switching it off; it would be missing and lead to wrong positions.
+ // All his could be done using logic sizes and coordinates, too, but
+ // we want a 1:1 bitmap rendering here, so it's more safe and faster
+ // to work with switching off MapMode usage completely.
+ const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin());
- const sal_uInt32 nCount(aHairlinePolyPolygon.count());
+ mpOutputDevice->EnableMapMode(false);
- if(nCount)
- {
- const bool bAntiAliased(getOptionsDrawinglayer().IsAntiAliasing());
- aHairlinePolyPolygon.transform(maCurrentTransformation);
-
- if(bAntiAliased)
- {
- if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.0))
- {
- // line in range ]0.0 .. 1.0[
- // paint as simple hairline
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- mpOutputDevice->DrawPolyLine(aHairlinePolyPolygon.getB2DPolygon(a), 0.0);
- }
+ for (auto const& pos : rPositions)
+ {
+ const basegfx::B2DPoint aDiscreteTopLeft((maCurrentTransformation * pos)
+ - aDiscreteHalfSize);
+ const Point aDiscretePoint(basegfx::fround(aDiscreteTopLeft.getX()),
+ basegfx::fround(aDiscreteTopLeft.getY()));
- bDone = true;
- }
- else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.0))
- {
- // line in range [1.0 .. 2.0[
- // paint as 2x2 with dynamic line distance
- basegfx::B2DHomMatrix aMat;
- const double fDistance(fDiscreteLineWidth - 1.0);
- const double fHalfDistance(fDistance * 0.5);
+ mpOutputDevice->DrawBitmapEx(aDiscretePoint + aOrigin, rMarker);
+ }
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
-
- aMat.set(0, 2, -fHalfDistance);
- aMat.set(1, 2, -fHalfDistance);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-
- aMat.set(0, 2, fDistance);
- aMat.set(1, 2, 0.0);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-
- aMat.set(0, 2, 0.0);
- aMat.set(1, 2, fDistance);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-
- aMat.set(0, 2, -fDistance);
- aMat.set(1, 2, 0.0);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- }
+ mpOutputDevice->EnableMapMode(bWasEnabled);
+}
- bDone = true;
- }
- else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 3.0))
- {
- // line in range [2.0 .. 3.0]
- // paint as cross in a 3x3 with dynamic line distance
- basegfx::B2DHomMatrix aMat;
- const double fDistance((fDiscreteLineWidth - 1.0) * 0.5);
+// point
+void VclProcessor2D::RenderPointArrayPrimitive2D(
+ const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate)
+{
+ const std::vector<basegfx::B2DPoint>& rPositions = rPointArrayCandidate.getPositions();
+ const basegfx::BColor aRGBColor(
+ maBColorModifierStack.getModifiedColor(rPointArrayCandidate.getRGBColor()));
+ const Color aVCLColor(aRGBColor);
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
+ for (auto const& pos : rPositions)
+ {
+ const basegfx::B2DPoint aViewPosition(maCurrentTransformation * pos);
+ const Point aPos(basegfx::fround(aViewPosition.getX()),
+ basegfx::fround(aViewPosition.getY()));
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ mpOutputDevice->DrawPixel(aPos, aVCLColor);
+ }
+}
- aMat.set(0, 2, -fDistance);
- aMat.set(1, 2, 0.0);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+void VclProcessor2D::RenderPolygonStrokePrimitive2D(
+ const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate)
+{
+ // #i101491# method restructured to clearly use the DrawPolyLine
+ // calls starting from a defined line width
+ const attribute::LineAttribute& rLineAttribute = rPolygonStrokeCandidate.getLineAttribute();
+ const double fLineWidth(rLineAttribute.getWidth());
+ bool bDone(false);
- aMat.set(0, 2, fDistance);
- aMat.set(1, 2, -fDistance);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ if (basegfx::fTools::more(fLineWidth, 0.0))
+ {
+ const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation
+ * basegfx::B2DVector(fLineWidth, 0.0));
+ const double fDiscreteLineWidth(aDiscreteUnit.getLength());
+ const attribute::StrokeAttribute& rStrokeAttribute
+ = rPolygonStrokeCandidate.getStrokeAttribute();
+ const basegfx::BColor aHairlineColor(
+ maBColorModifierStack.getModifiedColor(rLineAttribute.getColor()));
+ basegfx::B2DPolyPolygon aHairlinePolyPolygon;
+
+ mpOutputDevice->SetLineColor(Color(aHairlineColor));
+ mpOutputDevice->SetFillColor();
+
+ if (0.0 == rStrokeAttribute.getFullDotDashLen())
+ {
+ // no line dashing, just copy
+ aHairlinePolyPolygon.append(rPolygonStrokeCandidate.getB2DPolygon());
+ }
+ else
+ {
+ // else apply LineStyle
+ basegfx::utils::applyLineDashing(
+ rPolygonStrokeCandidate.getB2DPolygon(), rStrokeAttribute.getDotDashArray(),
+ &aHairlinePolyPolygon, nullptr, rStrokeAttribute.getFullDotDashLen());
+ }
- aMat.set(0, 2, fDistance);
- aMat.set(1, 2, fDistance);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ const sal_uInt32 nCount(aHairlinePolyPolygon.count());
- aMat.set(0, 2, -fDistance);
- aMat.set(1, 2, fDistance);
- aCandidate.transform(aMat);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- }
+ if (nCount)
+ {
+ const bool bAntiAliased(getOptionsDrawinglayer().IsAntiAliasing());
+ aHairlinePolyPolygon.transform(maCurrentTransformation);
- bDone = true;
- }
- else
- {
- // #i101491# line width above 3.0
- }
- }
- else
+ if (bAntiAliased)
+ {
+ if (basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.0))
+ {
+ // line in range ]0.0 .. 1.0[
+ // paint as simple hairline
+ for (sal_uInt32 a(0); a < nCount; a++)
{
- if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.5))
- {
- // line width below 1.5, draw the basic hairline polygon
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- mpOutputDevice->DrawPolyLine(aHairlinePolyPolygon.getB2DPolygon(a), 0.0);
- }
+ mpOutputDevice->DrawPolyLine(aHairlinePolyPolygon.getB2DPolygon(a), 0.0);
+ }
- bDone = true;
- }
- else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.5))
- {
- // line width is in range ]1.5 .. 2.5], use four hairlines
- // drawn in a square
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
- basegfx::B2DHomMatrix aMat;
+ bDone = true;
+ }
+ else if (basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.0))
+ {
+ // line in range [1.0 .. 2.0[
+ // paint as 2x2 with dynamic line distance
+ basegfx::B2DHomMatrix aMat;
+ const double fDistance(fDiscreteLineWidth - 1.0);
+ const double fHalfDistance(fDistance * 0.5);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ for (sal_uInt32 a(0); a < nCount; a++)
+ {
+ basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
+
+ aMat.set(0, 2, -fHalfDistance);
+ aMat.set(1, 2, -fHalfDistance);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+
+ aMat.set(0, 2, fDistance);
+ aMat.set(1, 2, 0.0);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+
+ aMat.set(0, 2, 0.0);
+ aMat.set(1, 2, fDistance);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+
+ aMat.set(0, 2, -fDistance);
+ aMat.set(1, 2, 0.0);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ }
- aMat.set(0, 2, 1.0);
- aMat.set(1, 2, 0.0);
- aCandidate.transform(aMat);
+ bDone = true;
+ }
+ else if (basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 3.0))
+ {
+ // line in range [2.0 .. 3.0]
+ // paint as cross in a 3x3 with dynamic line distance
+ basegfx::B2DHomMatrix aMat;
+ const double fDistance((fDiscreteLineWidth - 1.0) * 0.5);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ for (sal_uInt32 a(0); a < nCount; a++)
+ {
+ basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
- aMat.set(0, 2, 0.0);
- aMat.set(1, 2, 1.0);
- aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ aMat.set(0, 2, -fDistance);
+ aMat.set(1, 2, 0.0);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- aMat.set(0, 2, -1.0);
- aMat.set(1, 2, 0.0);
- aCandidate.transform(aMat);
+ aMat.set(0, 2, fDistance);
+ aMat.set(1, 2, -fDistance);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- }
+ aMat.set(0, 2, fDistance);
+ aMat.set(1, 2, fDistance);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- bDone = true;
- }
- else
- {
- // #i101491# line width is above 2.5
- }
+ aMat.set(0, 2, -fDistance);
+ aMat.set(1, 2, fDistance);
+ aCandidate.transform(aMat);
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
}
- if(!bDone && rPolygonStrokeCandidate.getB2DPolygon().count() > 1000)
+ bDone = true;
+ }
+ else
+ {
+ // #i101491# line width above 3.0
+ }
+ }
+ else
+ {
+ if (basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.5))
+ {
+ // line width below 1.5, draw the basic hairline polygon
+ for (sal_uInt32 a(0); a < nCount; a++)
{
- // #i101491# If the polygon complexity uses more than a given amount, do
- // use OutputDevice::DrawPolyLine directly; this will avoid buffering all
- // decompositions in primitives (memory) and fallback to old line painting
- // for very complex polygons, too
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- mpOutputDevice->DrawPolyLine(
- aHairlinePolyPolygon.getB2DPolygon(a),
- fDiscreteLineWidth,
- rLineAttribute.getLineJoin(),
- rLineAttribute.getLineCap(),
- rLineAttribute.getMiterMinimumAngle());
- }
-
- bDone = true;
+ mpOutputDevice->DrawPolyLine(aHairlinePolyPolygon.getB2DPolygon(a), 0.0);
}
+
+ bDone = true;
}
- }
+ else if (basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.5))
+ {
+ // line width is in range ]1.5 .. 2.5], use four hairlines
+ // drawn in a square
+ for (sal_uInt32 a(0); a < nCount; a++)
+ {
+ basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
+ basegfx::B2DHomMatrix aMat;
- if(!bDone)
- {
- // remember that we enter a PolygonStrokePrimitive2D decomposition,
- // used for AA thick line drawing
- mnPolygonStrokePrimitive2D++;
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- // line width is big enough for standard filled polygon visualisation or zero
- process(rPolygonStrokeCandidate);
+ aMat.set(0, 2, 1.0);
+ aMat.set(1, 2, 0.0);
+ aCandidate.transform(aMat);
- // leave PolygonStrokePrimitive2D
- mnPolygonStrokePrimitive2D--;
- }
- }
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- 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())
- return;
+ aMat.set(0, 2, 0.0);
+ aMat.set(1, 2, 1.0);
+ aCandidate.transform(aMat);
- const ::tools::Rectangle aRectangle(
- static_cast<sal_Int32>(floor(aRange.getMinX())), static_cast<sal_Int32>(floor(aRange.getMinY())),
- static_cast<sal_Int32>(ceil(aRange.getMaxX())), static_cast<sal_Int32>(ceil(aRange.getMaxY())));
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
- if(aRectangle.IsEmpty())
- return;
+ aMat.set(0, 2, -1.0);
+ aMat.set(1, 2, 0.0);
+ aCandidate.transform(aMat);
+
+ mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+ }
- bool bWillReallyRender = mpOutputDevice->IsDeviceOutputNecessary();
- // try to paint EPS directly without fallback visualisation
- const bool bEPSPaintedDirectly = bWillReallyRender &&
- mpOutputDevice->DrawEPS(
- aRectangle.TopLeft(),
- aRectangle.GetSize(),
- rEpsPrimitive2D.getGfxLink());
+ bDone = true;
+ }
+ else
+ {
+ // #i101491# line width is above 2.5
+ }
+ }
- if(!bEPSPaintedDirectly)
+ if (!bDone && rPolygonStrokeCandidate.getB2DPolygon().count() > 1000)
{
- // use the decomposition which will correctly handle the
- // fallback visualisation using full transformation (e.g. rotation)
- process(rEpsPrimitive2D);
+ // #i101491# If the polygon complexity uses more than a given amount, do
+ // use OutputDevice::DrawPolyLine directly; this will avoid buffering all
+ // decompositions in primitives (memory) and fallback to old line painting
+ // for very complex polygons, too
+ for (sal_uInt32 a(0); a < nCount; a++)
+ {
+ mpOutputDevice->DrawPolyLine(aHairlinePolyPolygon.getB2DPolygon(a),
+ fDiscreteLineWidth, rLineAttribute.getLineJoin(),
+ rLineAttribute.getLineCap(),
+ rLineAttribute.getMiterMinimumAngle());
+ }
+
+ bDone = true;
}
}
+ }
- void VclProcessor2D::RenderObjectInfoPrimitive2D(const primitive2d::ObjectInfoPrimitive2D& rObjectInfoPrimitive2D)
- {
- // remember current ObjectInfoPrimitive2D and set new current one (build a stack - push)
- const primitive2d::ObjectInfoPrimitive2D* pLast(getObjectInfoPrimitive2D());
- mpObjectInfoPrimitive2D = &rObjectInfoPrimitive2D;
+ if (!bDone)
+ {
+ // remember that we enter a PolygonStrokePrimitive2D decomposition,
+ // used for AA thick line drawing
+ mnPolygonStrokePrimitive2D++;
- // process content
- process(rObjectInfoPrimitive2D.getChildren());
+ // line width is big enough for standard filled polygon visualisation or zero
+ process(rPolygonStrokeCandidate);
- // restore current ObjectInfoPrimitive2D (pop)
- mpObjectInfoPrimitive2D = pLast;
- }
+ // leave PolygonStrokePrimitive2D
+ mnPolygonStrokePrimitive2D--;
+ }
+}
- void VclProcessor2D::RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D& rCandidate)
- {
- const double fDelta(rCandidate.getOffsetB() - rCandidate.getOffsetA());
+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())
+ return;
+
+ const ::tools::Rectangle aRectangle(static_cast<sal_Int32>(floor(aRange.getMinX())),
+ static_cast<sal_Int32>(floor(aRange.getMinY())),
+ static_cast<sal_Int32>(ceil(aRange.getMaxX())),
+ static_cast<sal_Int32>(ceil(aRange.getMaxY())));
+
+ if (aRectangle.IsEmpty())
+ return;
+
+ bool bWillReallyRender = mpOutputDevice->IsDeviceOutputNecessary();
+ // try to paint EPS directly without fallback visualisation
+ const bool bEPSPaintedDirectly
+ = bWillReallyRender
+ && mpOutputDevice->DrawEPS(aRectangle.TopLeft(), aRectangle.GetSize(),
+ rEpsPrimitive2D.getGfxLink());
+
+ if (!bEPSPaintedDirectly)
+ {
+ // use the decomposition which will correctly handle the
+ // fallback visualisation using full transformation (e.g. rotation)
+ process(rEpsPrimitive2D);
+ }
+}
- if(!basegfx::fTools::more(fDelta, 0.0))
- return;
+void VclProcessor2D::RenderObjectInfoPrimitive2D(
+ const primitive2d::ObjectInfoPrimitive2D& rObjectInfoPrimitive2D)
+{
+ // remember current ObjectInfoPrimitive2D and set new current one (build a stack - push)
+ const primitive2d::ObjectInfoPrimitive2D* pLast(getObjectInfoPrimitive2D());
+ mpObjectInfoPrimitive2D = &rObjectInfoPrimitive2D;
- const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA()));
- const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB()));
+ // process content
+ process(rObjectInfoPrimitive2D.getChildren());
- // calculate discrete unit in WorldCoordinates; use diagonal (1.0, 1.0) and divide by sqrt(2)
- const basegfx::B2DVector aDiscreteVector(getViewInformation2D().getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
- const double fDiscreteUnit(aDiscreteVector.getLength() * (1.0 / 1.414213562373));
+ // restore current ObjectInfoPrimitive2D (pop)
+ mpObjectInfoPrimitive2D = pLast;
+}
- // use color distance and discrete lengths to calculate step count
- const sal_uInt32 nSteps(calculateStepsForSvgGradient(aColorA, aColorB, fDelta, fDiscreteUnit));
+void VclProcessor2D::RenderSvgLinearAtomPrimitive2D(
+ const primitive2d::SvgLinearAtomPrimitive2D& rCandidate)
+{
+ const double fDelta(rCandidate.getOffsetB() - rCandidate.getOffsetA());
- // switch off line painting
- mpOutputDevice->SetLineColor();
+ if (!basegfx::fTools::more(fDelta, 0.0))
+ return;
- // prepare polygon in needed width at start position (with discrete overlap)
- const basegfx::B2DPolygon aPolygon(
- basegfx::utils::createPolygonFromRect(
- basegfx::B2DRange(
- rCandidate.getOffsetA() - fDiscreteUnit,
- 0.0,
- rCandidate.getOffsetA() + (fDelta / nSteps) + fDiscreteUnit,
- 1.0)));
+ const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA()));
+ const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB()));
+ // calculate discrete unit in WorldCoordinates; use diagonal (1.0, 1.0) and divide by sqrt(2)
+ const basegfx::B2DVector aDiscreteVector(
+ getViewInformation2D().getInverseObjectToViewTransformation()
+ * basegfx::B2DVector(1.0, 1.0));
+ const double fDiscreteUnit(aDiscreteVector.getLength() * (1.0 / 1.414213562373));
- // prepare loop ([0.0 .. 1.0[)
- double fUnitScale(0.0);
- const double fUnitStep(1.0 / nSteps);
+ // use color distance and discrete lengths to calculate step count
+ const sal_uInt32 nSteps(calculateStepsForSvgGradient(aColorA, aColorB, fDelta, fDiscreteUnit));
- // loop and paint
- for(sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep)
- {
- basegfx::B2DPolygon aNew(aPolygon);
+ // switch off line painting
+ mpOutputDevice->SetLineColor();
- aNew.transform(maCurrentTransformation * basegfx::utils::createTranslateB2DHomMatrix(fDelta * fUnitScale, 0.0));
- mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorA, aColorB, fUnitScale)));
- mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew));
- }
- }
+ // prepare polygon in needed width at start position (with discrete overlap)
+ const basegfx::B2DPolygon aPolygon(basegfx::utils::createPolygonFromRect(
+ basegfx::B2DRange(rCandidate.getOffsetA() - fDiscreteUnit, 0.0,
+ rCandidate.getOffsetA() + (fDelta / nSteps) + fDiscreteUnit, 1.0)));
- void VclProcessor2D::RenderSvgRadialAtomPrimitive2D(const primitive2d::SvgRadialAtomPrimitive2D& rCandidate)
- {
- const double fDeltaScale(rCandidate.getScaleB() - rCandidate.getScaleA());
+ // prepare loop ([0.0 .. 1.0[)
+ double fUnitScale(0.0);
+ const double fUnitStep(1.0 / nSteps);
- if(!basegfx::fTools::more(fDeltaScale, 0.0))
- return;
+ // loop and paint
+ for (sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep)
+ {
+ basegfx::B2DPolygon aNew(aPolygon);
- const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA()));
- const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB()));
+ aNew.transform(maCurrentTransformation
+ * basegfx::utils::createTranslateB2DHomMatrix(fDelta * fUnitScale, 0.0));
+ mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorA, aColorB, fUnitScale)));
+ mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew));
+ }
+}
- // calculate discrete unit in WorldCoordinates; use diagonal (1.0, 1.0) and divide by sqrt(2)
- const basegfx::B2DVector aDiscreteVector(getViewInformation2D().getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
- const double fDiscreteUnit(aDiscreteVector.getLength() * (1.0 / 1.414213562373));
+void VclProcessor2D::RenderSvgRadialAtomPrimitive2D(
+ const primitive2d::SvgRadialAtomPrimitive2D& rCandidate)
+{
+ const double fDeltaScale(rCandidate.getScaleB() - rCandidate.getScaleA());
- // use color distance and discrete lengths to calculate step count
- const sal_uInt32 nSteps(calculateStepsForSvgGradient(aColorA, aColorB, fDeltaScale, fDiscreteUnit));
+ if (!basegfx::fTools::more(fDeltaScale, 0.0))
+ return;
- // switch off line painting
- mpOutputDevice->SetLineColor();
+ const basegfx::BColor aColorA(maBColorModifierStack.getModifiedColor(rCandidate.getColorA()));
+ const basegfx::BColor aColorB(maBColorModifierStack.getModifiedColor(rCandidate.getColorB()));
- // prepare loop ([0.0 .. 1.0[, full polygons, no polypolygons with holes)
- double fUnitScale(0.0);
- const double fUnitStep(1.0 / nSteps);
+ // calculate discrete unit in WorldCoordinates; use diagonal (1.0, 1.0) and divide by sqrt(2)
+ const basegfx::B2DVector aDiscreteVector(
+ getViewInformation2D().getInverseObjectToViewTransformation()
+ * basegfx::B2DVector(1.0, 1.0));
+ const double fDiscreteUnit(aDiscreteVector.getLength() * (1.0 / 1.414213562373));
- for(sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep)
- {
- basegfx::B2DHomMatrix aTransform;
- const double fEndScale(rCandidate.getScaleB() - (fDeltaScale * fUnitScale));
+ // use color distance and discrete lengths to calculate step count
+ const sal_uInt32 nSteps(
+ calculateStepsForSvgGradient(aColorA, aColorB, fDeltaScale, fDiscreteUnit));
- if(rCandidate.isTranslateSet())
- {
- const basegfx::B2DVector aTranslate(
- basegfx::interpolate(
- rCandidate.getTranslateB(),
- rCandidate.getTranslateA(),
- fUnitScale));
-
- aTransform = basegfx::utils::createScaleTranslateB2DHomMatrix(
- fEndScale,
- fEndScale,
- aTranslate.getX(),
- aTranslate.getY());
- }
- else
- {
- aTransform = basegfx::utils::createScaleB2DHomMatrix(
- fEndScale,
- fEndScale);
- }
+ // switch off line painting
+ mpOutputDevice->SetLineColor();
- basegfx::B2DPolygon aNew(basegfx::utils::createPolygonFromUnitCircle());
+ // prepare loop ([0.0 .. 1.0[, full polygons, no polypolygons with holes)
+ double fUnitScale(0.0);
+ const double fUnitStep(1.0 / nSteps);
- aNew.transform(maCurrentTransformation * aTransform);
- mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorB, aColorA, fUnitScale)));
- mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew));
- }
- }
+ for (sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep)
+ {
+ basegfx::B2DHomMatrix aTransform;
+ const double fEndScale(rCandidate.getScaleB() - (fDeltaScale * fUnitScale));
- void VclProcessor2D::adaptLineToFillDrawMode() const
+ if (rCandidate.isTranslateSet())
{
- const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
+ const basegfx::B2DVector aTranslate(basegfx::interpolate(
+ rCandidate.getTranslateB(), rCandidate.getTranslateA(), fUnitScale));
- if(!(nOriginalDrawMode & (DrawModeFlags::BlackLine|DrawModeFlags::GrayLine|DrawModeFlags::WhiteLine|DrawModeFlags::SettingsLine)))
- return;
+ aTransform = basegfx::utils::createScaleTranslateB2DHomMatrix(
+ fEndScale, fEndScale, aTranslate.getX(), aTranslate.getY());
+ }
+ else
+ {
+ aTransform = basegfx::utils::createScaleB2DHomMatrix(fEndScale, fEndScale);
+ }
- DrawModeFlags nAdaptedDrawMode(nOriginalDrawMode);
+ basegfx::B2DPolygon aNew(basegfx::utils::createPolygonFromUnitCircle());
- if(nOriginalDrawMode & DrawModeFlags::BlackLine)
- {
- nAdaptedDrawMode |= DrawModeFlags::BlackFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::BlackFill;
- }
+ aNew.transform(maCurrentTransformation * aTransform);
+ mpOutputDevice->SetFillColor(Color(basegfx::interpolate(aColorB, aColorA, fUnitScale)));
+ mpOutputDevice->DrawPolyPolygon(basegfx::B2DPolyPolygon(aNew));
+ }
+}
- if(nOriginalDrawMode & DrawModeFlags::GrayLine)
- {
- nAdaptedDrawMode |= DrawModeFlags::GrayFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::GrayFill;
- }
+void VclProcessor2D::adaptLineToFillDrawMode() const
+{
+ const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
- if(nOriginalDrawMode & DrawModeFlags::WhiteLine)
- {
- nAdaptedDrawMode |= DrawModeFlags::WhiteFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::WhiteFill;
- }
+ if (!(nOriginalDrawMode
+ & (DrawModeFlags::BlackLine | DrawModeFlags::GrayLine | DrawModeFlags::WhiteLine
+ | DrawModeFlags::SettingsLine)))
+ return;
- if(nOriginalDrawMode & DrawModeFlags::SettingsLine)
- {
- nAdaptedDrawMode |= DrawModeFlags::SettingsFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::SettingsFill;
- }
+ DrawModeFlags nAdaptedDrawMode(nOriginalDrawMode);
- mpOutputDevice->SetDrawMode(nAdaptedDrawMode);
- }
+ if (nOriginalDrawMode & DrawModeFlags::BlackLine)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::BlackFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::BlackFill;
+ }
- void VclProcessor2D::adaptTextToFillDrawMode() const
- {
- const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
- if(!(nOriginalDrawMode & (DrawModeFlags::BlackText|DrawModeFlags::GrayText|DrawModeFlags::WhiteText|DrawModeFlags::SettingsText)))
- return;
+ if (nOriginalDrawMode & DrawModeFlags::GrayLine)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::GrayFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::GrayFill;
+ }
- DrawModeFlags nAdaptedDrawMode(nOriginalDrawMode);
+ if (nOriginalDrawMode & DrawModeFlags::WhiteLine)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::WhiteFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::WhiteFill;
+ }
- if(nOriginalDrawMode & DrawModeFlags::BlackText)
- {
- nAdaptedDrawMode |= DrawModeFlags::BlackFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::BlackFill;
- }
+ if (nOriginalDrawMode & DrawModeFlags::SettingsLine)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::SettingsFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::SettingsFill;
+ }
- if(nOriginalDrawMode & DrawModeFlags::GrayText)
- {
- nAdaptedDrawMode |= DrawModeFlags::GrayFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::GrayFill;
- }
+ mpOutputDevice->SetDrawMode(nAdaptedDrawMode);
+}
- if(nOriginalDrawMode & DrawModeFlags::WhiteText)
- {
- nAdaptedDrawMode |= DrawModeFlags::WhiteFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::WhiteFill;
- }
+void VclProcessor2D::adaptTextToFillDrawMode() const
+{
+ const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
+ if (!(nOriginalDrawMode
+ & (DrawModeFlags::BlackText | DrawModeFlags::GrayText | DrawModeFlags::WhiteText
+ | DrawModeFlags::SettingsText)))
+ return;
- if(nOriginalDrawMode & DrawModeFlags::SettingsText)
- {
- nAdaptedDrawMode |= DrawModeFlags::SettingsFill;
- }
- else
- {
- nAdaptedDrawMode &= ~DrawModeFlags::SettingsFill;
- }
+ DrawModeFlags nAdaptedDrawMode(nOriginalDrawMode);
- mpOutputDevice->SetDrawMode(nAdaptedDrawMode);
- }
+ if (nOriginalDrawMode & DrawModeFlags::BlackText)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::BlackFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::BlackFill;
+ }
- // process support
-
- VclProcessor2D::VclProcessor2D(
- const geometry::ViewInformation2D& rViewInformation,
- OutputDevice& rOutDev)
- : BaseProcessor2D(rViewInformation),
- mpOutputDevice(&rOutDev),
- maBColorModifierStack(),
- maCurrentTransformation(),
- maDrawinglayerOpt(),
- mnPolygonStrokePrimitive2D(0),
- mpObjectInfoPrimitive2D(nullptr)
- {
- // set digit language, derived from SvtCTLOptions to have the correct
- // number display for arabic/hindi numerals
- rOutDev.SetDigitLanguage(drawinglayer::detail::getDigitLanguage());
- }
+ if (nOriginalDrawMode & DrawModeFlags::GrayText)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::GrayFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::GrayFill;
+ }
- VclProcessor2D::~VclProcessor2D()
- {
- }
+ if (nOriginalDrawMode & DrawModeFlags::WhiteText)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::WhiteFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::WhiteFill;
+ }
+
+ if (nOriginalDrawMode & DrawModeFlags::SettingsText)
+ {
+ nAdaptedDrawMode |= DrawModeFlags::SettingsFill;
+ }
+ else
+ {
+ nAdaptedDrawMode &= ~DrawModeFlags::SettingsFill;
+ }
+
+ mpOutputDevice->SetDrawMode(nAdaptedDrawMode);
+}
+
+// process support
+
+VclProcessor2D::VclProcessor2D(const geometry::ViewInformation2D& rViewInformation,
+ OutputDevice& rOutDev)
+ : BaseProcessor2D(rViewInformation)
+ , mpOutputDevice(&rOutDev)
+ , maBColorModifierStack()
+ , maCurrentTransformation()
+ , maDrawinglayerOpt()
+ , mnPolygonStrokePrimitive2D(0)
+ , mpObjectInfoPrimitive2D(nullptr)
+{
+ // set digit language, derived from SvtCTLOptions to have the correct
+ // number display for arabic/hindi numerals
+ rOutDev.SetDigitLanguage(drawinglayer::detail::getDigitLanguage());
+}
+
+VclProcessor2D::~VclProcessor2D() {}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */