diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-01-05 17:49:45 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-01-05 17:49:45 +0000 |
commit | 0c478a57c3e92805a5ba4d4a534117cf24f6bec6 (patch) | |
tree | e98d61db3671b47bb0aebed6a5885295666fa146 /drawinglayer | |
parent | 91b4358ce216334236fe25a165ba85e08de89234 (diff) |
CWS-TOOLING: integrate CWS overline3
2008-12-11 15:24:46 +0100 fredrikh r265314 : i97099
2008-12-11 15:20:37 +0100 fredrikh r265313 : i97099
2008-12-11 15:18:00 +0100 fredrikh r265312 : i97099
2008-12-11 15:17:00 +0100 fredrikh r265311 : i97099
2008-12-11 15:13:20 +0100 fredrikh r265309 : i97144
2008-12-11 15:06:24 +0100 fredrikh r265306 : i97099
2008-11-24 10:41:42 +0100 fme r264213 : #i5991# Overline support
2008-11-24 10:39:53 +0100 fme r264212 : #i5991# Overline support
2008-11-24 10:02:13 +0100 fme r264209 : #5991# Overline support
2008-11-24 10:01:26 +0100 fme r264208 : #5991# Overline support
2008-11-24 09:59:11 +0100 fme r264207 : #5991# Overline support
2008-11-24 09:57:11 +0100 fme r264206 : #5991# Overline support
2008-11-14 10:36:44 +0100 fme r263667 : CWS-TOOLING: rebase CWS overline3 to trunk@263288 (milestone: DEV300:m35)
2008-11-13 16:12:13 +0100 fme r263649 : #i5991# migrate CWS overline3 to SVN.
Diffstat (limited to 'drawinglayer')
5 files changed, 416 insertions, 345 deletions
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx index f91fb7aab2..c4c0fa09b3 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx @@ -55,31 +55,32 @@ namespace drawinglayer { namespace primitive2d { + // This is used for both underline and overline enum FontUnderline { - FONT_UNDERLINE_NONE, - FONT_UNDERLINE_SINGLE, + FONT_UNDERLINE_NONE, + FONT_UNDERLINE_SINGLE, FONT_UNDERLINE_DOUBLE, - FONT_UNDERLINE_DOTTED, - FONT_UNDERLINE_DASH, + FONT_UNDERLINE_DOTTED, + FONT_UNDERLINE_DASH, FONT_UNDERLINE_LONGDASH, - FONT_UNDERLINE_DASHDOT, + FONT_UNDERLINE_DASHDOT, FONT_UNDERLINE_DASHDOTDOT, FONT_UNDERLINE_SMALLWAVE, - FONT_UNDERLINE_WAVE, + FONT_UNDERLINE_WAVE, FONT_UNDERLINE_DOUBLEWAVE, - FONT_UNDERLINE_BOLD, + FONT_UNDERLINE_BOLD, FONT_UNDERLINE_BOLDDOTTED, - FONT_UNDERLINE_BOLDDASH, + FONT_UNDERLINE_BOLDDASH, FONT_UNDERLINE_BOLDLONGDASH, - FONT_UNDERLINE_BOLDDASHDOT, + FONT_UNDERLINE_BOLDDASHDOT, FONT_UNDERLINE_BOLDDASHDOTDOT, FONT_UNDERLINE_BOLDWAVE }; enum FontStrikeout { - FONT_STRIKEOUT_NONE, + FONT_STRIKEOUT_NONE, FONT_STRIKEOUT_SINGLE, FONT_STRIKEOUT_DOUBLE, FONT_STRIKEOUT_BOLD, @@ -98,16 +99,18 @@ namespace drawinglayer enum FontRelief { - FONT_RELIEF_NONE, - FONT_RELIEF_EMBOSSED, + FONT_RELIEF_NONE, + FONT_RELIEF_EMBOSSED, FONT_RELIEF_ENGRAVED }; class TextDecoratedPortionPrimitive2D : public TextSimplePortionPrimitive2D { private: - basegfx::BColor maTextlineColor; - FontUnderline meFontUnderline; + basegfx::BColor maOverlineColor; + basegfx::BColor maTextlineColor; + FontUnderline meFontOverline; + FontUnderline meFontUnderline; FontStrikeout meFontStrikeout; FontEmphasisMark meFontEmphasisMark; FontRelief meFontRelief; @@ -120,8 +123,18 @@ namespace drawinglayer unsigned mbShadow : 1; // helper methods + void impCreateTextLine( + std::vector< Primitive2DReference >& rTarget, + basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, + const basegfx::B2DHomMatrix &rUnscaledTransform, + FontUnderline eLineStyle, + double fLineOffset, + double fLineHeight, + double fLineWidth, + const basegfx::BColor& rLineColor) const; + void impCreateGeometryContent( - std::vector< Primitive2DReference >& rTarget, + std::vector< Primitive2DReference >& rTarget, basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, const String& rText, xub_StrLen aTextPosition, @@ -154,7 +167,9 @@ namespace drawinglayer const basegfx::BColor& rFontColor, // local parameters + const basegfx::BColor& rOverlineColor, const basegfx::BColor& rTextlineColor, + FontUnderline eFontOverline = FONT_UNDERLINE_NONE, FontUnderline eFontUnderline = FONT_UNDERLINE_NONE, bool bUnderlineAbove = false, FontStrikeout eFontStrikeout = FONT_STRIKEOUT_NONE, @@ -166,10 +181,12 @@ namespace drawinglayer bool bShadow = false); // get data + FontUnderline getFontOverline() const { return meFontOverline; } FontUnderline getFontUnderline() const { return meFontUnderline; } FontStrikeout getFontStrikeout() const { return meFontStrikeout; } FontEmphasisMark getFontEmphasisMark() const { return meFontEmphasisMark; } FontRelief getFontRelief() const { return meFontRelief; } + basegfx::BColor getOverlineColor() const { return maOverlineColor; } basegfx::BColor getTextlineColor() const { return maTextlineColor; } bool getUnderlineAbove() const { return mbUnderlineAbove; } diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx index f339c58e7e..bbdc3df86c 100644 --- a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx +++ b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx @@ -73,12 +73,14 @@ namespace drawinglayer public: TextLayouterDevice(); ~TextLayouterDevice(); - + void setFont(const Font& rFont); void setFontAttributes(const FontAttributes& rFontAttributes, const basegfx::B2DHomMatrix& rTransform); void setFontAttributes(const FontAttributes& rFontAttributes, double fFontScaleX, double fFontScaleY); double getTextHeight() const; + double getOverlineHeight() const; + double getOverlineOffset() const; double getUnderlineHeight() const; double getUnderlineOffset() const; double getStrikeoutOffset() const; @@ -87,19 +89,19 @@ namespace drawinglayer #endif double getTextWidth( - const String& rText, - xub_StrLen nIndex, + const String& rText, + xub_StrLen nIndex, xub_StrLen nLength) const; - bool getTextOutlines( + bool getTextOutlines( basegfx::B2DPolyPolygonVector&, const String& rText, - xub_StrLen nIndex, + xub_StrLen nIndex, xub_StrLen nLength); basegfx::B2DRange getTextBoundRect( - const String& rText, - xub_StrLen nIndex, + const String& rText, + xub_StrLen nIndex, xub_StrLen nLength) const; }; } // end of namespace primitive2d @@ -113,17 +115,17 @@ namespace drawinglayer { // helper methods for vcl font handling Font getVclFontFromFontAttributes( - const FontAttributes& rFontAttributes, - double fFontScaleX, + const FontAttributes& rFontAttributes, + double fFontScaleX, double fFontScaleY, - double fFontRotation, + double fFontRotation, const OutputDevice& rOutDev); - + Font getVclFontFromFontAttributes( - const FontAttributes& rFontAttributes, + const FontAttributes& rFontAttributes, const basegfx::B2DHomMatrix& rTransform, const OutputDevice& rOutDev); - + FontAttributes getFontAttributesFromVclFont(basegfx::B2DVector& rSize, const Font& rFont, bool bRTL, bool bBiDiStrong); } // end of namespace primitive2d diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx index b321dac20d..367976df07 100644 --- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx @@ -55,8 +55,214 @@ namespace drawinglayer { namespace primitive2d { + void TextDecoratedPortionPrimitive2D::impCreateTextLine( + std::vector< Primitive2DReference >& rTarget, + basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, + const basegfx::B2DHomMatrix &rUnscaledTransform, + FontUnderline eLineStyle, + double fLineOffset, + double fLineHeight, + double fLineWidth, + const basegfx::BColor& rLineColor) const + { + bool bDoubleLine(false); + bool bWaveLine(false); + bool bBoldLine(false); + const int* pDotDashArray(0); + basegfx::B2DLineJoin eLineJoin(basegfx::B2DLINEJOIN_NONE); + + static const int aDottedArray[] = { 1, 1, 0}; // DOTTED LINE + static const int aDotDashArray[] = { 1, 1, 4, 1, 0}; // DASHDOT + static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0}; // DASHDOTDOT + static const int aDashedArray[] = { 5, 2, 0}; // DASHED LINE + static const int aLongDashArray[] = { 7, 2, 0}; // LONGDASH + + switch(eLineStyle) + { + default: // case FONT_UNDERLINE_SINGLE: + { + break; + } + case FONT_UNDERLINE_DOUBLE: + { + bDoubleLine = true; + break; + } + case FONT_UNDERLINE_DOTTED: + { + pDotDashArray = aDottedArray; + break; + } + case FONT_UNDERLINE_DASH: + { + pDotDashArray = aDashedArray; + break; + } + case FONT_UNDERLINE_LONGDASH: + { + pDotDashArray = aLongDashArray; + break; + } + case FONT_UNDERLINE_DASHDOT: + { + pDotDashArray = aDotDashArray; + break; + } + case FONT_UNDERLINE_DASHDOTDOT: + { + pDotDashArray = aDashDotDotArray; + break; + } + case FONT_UNDERLINE_SMALLWAVE: + { + bWaveLine = true; + break; + } + case FONT_UNDERLINE_WAVE: + { + bWaveLine = true; + break; + } + case FONT_UNDERLINE_DOUBLEWAVE: + { + bDoubleLine = true; + bWaveLine = true; + break; + } + case FONT_UNDERLINE_BOLD: + { + bBoldLine = true; + break; + } + case FONT_UNDERLINE_BOLDDOTTED: + { + bBoldLine = true; + pDotDashArray = aDottedArray; + break; + } + case FONT_UNDERLINE_BOLDDASH: + { + bBoldLine = true; + pDotDashArray = aDashedArray; + break; + } + case FONT_UNDERLINE_BOLDLONGDASH: + { + bBoldLine = true; + pDotDashArray = aLongDashArray; + break; + } + case FONT_UNDERLINE_BOLDDASHDOT: + { + bBoldLine = true; + pDotDashArray = aDotDashArray; + break; + } + case FONT_UNDERLINE_BOLDDASHDOTDOT: + { + bBoldLine = true; + pDotDashArray = aDashDotDotArray; + break; + } + case FONT_UNDERLINE_BOLDWAVE: + { + bWaveLine = true; + bBoldLine = true; + break; + } + } + + if(bBoldLine) + { + fLineHeight *= 2.0; + } + + if(bDoubleLine) + { + fLineOffset -= 0.50 * fLineHeight; + fLineHeight *= 0.64; + } + + if(bWaveLine) + { + eLineJoin = basegfx::B2DLINEJOIN_ROUND; + fLineHeight *= 0.5; + } + + // prepare Line and Stroke Attributes + const attribute::LineAttribute aLineAttribute(rLineColor, fLineHeight, eLineJoin); + attribute::StrokeAttribute aStrokeAttribute; + + if(pDotDashArray) + { + ::std::vector< double > aDoubleArray; + + for(const int* p = pDotDashArray; *p; ++p) + { + aDoubleArray.push_back((double)(*p) * fLineHeight); + } + + aStrokeAttribute = attribute::StrokeAttribute(aDoubleArray); + } + + // create base polygon and new primitive + basegfx::B2DPolygon aLine; + Primitive2DReference aNewPrimitive; + + aLine.append(basegfx::B2DPoint(0.0, fLineOffset)); + aLine.append(basegfx::B2DPoint(fLineWidth, fLineOffset)); + aLine.transform(rUnscaledTransform); + + if(bWaveLine) + { + double fWaveWidth(4.0 * fLineHeight); + + if(FONT_UNDERLINE_SMALLWAVE == eLineStyle) + { + fWaveWidth *= 0.7; + } + else if(FONT_UNDERLINE_WAVE == eLineStyle) + { + // extra multiply to get the same WaveWidth as with the bold version + fWaveWidth *= 2.0; + } + + aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, 0.5 * fWaveWidth)); + } + else + { + aNewPrimitive = Primitive2DReference(new PolygonStrokePrimitive2D(aLine, aLineAttribute, aStrokeAttribute)); + } + + // add primitive + rTarget.push_back(aNewPrimitive); + + if(bDoubleLine) + { + // double line, create 2nd primitive with offset using TransformPrimitive based on + // already created NewPrimitive + const double fLineDist((bWaveLine ? 3.0 : 2.0) * fLineHeight); + basegfx::B2DHomMatrix aTransform; + + // move base point of text to 0.0 and de-rotate + aTransform.translate(-rDecTrans.getTranslate().getX(), -rDecTrans.getTranslate().getY()); + aTransform.rotate(-rDecTrans.getRotate()); + + // translate in Y by offset + aTransform.translate(0.0, fLineDist); + + // move back and rotate + aTransform.rotate(rDecTrans.getRotate()); + aTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY()); + + // add transform primitive + const Primitive2DSequence aContent(&aNewPrimitive, 1); + rTarget.push_back(Primitive2DReference(new TransformPrimitive2D(aTransform, aContent))); + } + } + void TextDecoratedPortionPrimitive2D::impCreateGeometryContent( - std::vector< Primitive2DReference >& rTarget, + std::vector< Primitive2DReference >& rTarget, basegfx::DecomposedB2DHomMatrixContainer& rDecTrans, const String& rText, xub_StrLen aTextPosition, @@ -66,31 +272,32 @@ namespace drawinglayer { // create the SimpleTextPrimitive needed in any case rTarget.push_back(Primitive2DReference(new TextSimplePortionPrimitive2D( - rDecTrans.getB2DHomMatrix(), - rText, + rDecTrans.getB2DHomMatrix(), + rText, aTextPosition, aTextLength, - rDXArray, - rFontAttributes, - getLocale(), + rDXArray, + rFontAttributes, + getLocale(), getFontColor()))); // see if something else needs to be done + const bool bOverlineUsed(FONT_UNDERLINE_NONE != getFontOverline()); const bool bUnderlineUsed(FONT_UNDERLINE_NONE != getFontUnderline()); const bool bStrikeoutUsed(FONT_STRIKEOUT_NONE != getFontStrikeout()); - if(bUnderlineUsed || bStrikeoutUsed) + if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed) { // common preparations basegfx::B2DHomMatrix aUnscaledTransform; TextLayouterDevice aTextLayouter; - + // unscaled is needed since scale contains already the font size aUnscaledTransform.shearX(rDecTrans.getShearX()); aUnscaledTransform.rotate(rDecTrans.getRotate()); aUnscaledTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY()); - // TextLayouterDevice is needed to get metrics for text decorations like + // TextLayouterDevice is needed to get metrics for text decorations like // underline/strikeout/emphasis marks from it. For setup, the font size is needed aTextLayouter.setFontAttributes(getFontAttributes(), rDecTrans.getScale().getX(), rDecTrans.getScale().getY()); @@ -106,205 +313,18 @@ namespace drawinglayer fTextWidth = rDXArray.back() * rDecTrans.getScale().getX(); } + if(bOverlineUsed) + { + // create primitive geometry for overline + impCreateTextLine(rTarget, rDecTrans, aUnscaledTransform, getFontOverline(), aTextLayouter.getOverlineOffset(), + aTextLayouter.getOverlineHeight(), fTextWidth, getOverlineColor()); + } + if(bUnderlineUsed) { // create primitive geometry for underline - bool bDoubleLine(false); - bool bWaveLine(false); - bool bBoldLine(false); - const int* pDotDashArray(0); - basegfx::B2DLineJoin eLineJoin(basegfx::B2DLINEJOIN_NONE); - double fUnderlineOffset(aTextLayouter.getUnderlineOffset()); - double fUnderlineHeight(aTextLayouter.getUnderlineHeight()); - - static const int aDottedArray[] = { 1, 1, 0}; // DOTTED LINE - static const int aDotDashArray[] = { 1, 1, 4, 1, 0}; // DASHDOT - static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0}; // DASHDOTDOT - static const int aDashedArray[] = { 5, 2, 0}; // DASHED LINE - static const int aLongDashArray[] = { 7, 2, 0}; // LONGDASH - - switch(getFontUnderline()) - { - default: // case FONT_UNDERLINE_SINGLE: - { - break; - } - case FONT_UNDERLINE_DOUBLE: - { - bDoubleLine = true; - break; - } - case FONT_UNDERLINE_DOTTED: - { - pDotDashArray = aDottedArray; - break; - } - case FONT_UNDERLINE_DASH: - { - pDotDashArray = aDashedArray; - break; - } - case FONT_UNDERLINE_LONGDASH: - { - pDotDashArray = aLongDashArray; - break; - } - case FONT_UNDERLINE_DASHDOT: - { - pDotDashArray = aDotDashArray; - break; - } - case FONT_UNDERLINE_DASHDOTDOT: - { - pDotDashArray = aDashDotDotArray; - break; - } - case FONT_UNDERLINE_SMALLWAVE: - { - bWaveLine = true; - break; - } - case FONT_UNDERLINE_WAVE: - { - bWaveLine = true; - break; - } - case FONT_UNDERLINE_DOUBLEWAVE: - { - bDoubleLine = true; - bWaveLine = true; - break; - } - case FONT_UNDERLINE_BOLD: - { - bBoldLine = true; - break; - } - case FONT_UNDERLINE_BOLDDOTTED: - { - bBoldLine = true; - pDotDashArray = aDottedArray; - break; - } - case FONT_UNDERLINE_BOLDDASH: - { - bBoldLine = true; - pDotDashArray = aDashedArray; - break; - } - case FONT_UNDERLINE_BOLDLONGDASH: - { - bBoldLine = true; - pDotDashArray = aLongDashArray; - break; - } - case FONT_UNDERLINE_BOLDDASHDOT: - { - bBoldLine = true; - pDotDashArray = aDotDashArray; - break; - } - case FONT_UNDERLINE_BOLDDASHDOTDOT: - { - bBoldLine = true; - pDotDashArray = aDashDotDotArray; - break; - } - case FONT_UNDERLINE_BOLDWAVE: - { - bWaveLine = true; - bBoldLine = true; - break; - } - } - - if(bBoldLine) - { - fUnderlineHeight *= 2.0; - } - - if(bDoubleLine) - { - fUnderlineOffset -= 0.50 * fUnderlineHeight; - fUnderlineHeight *= 0.64; - } - - if(bWaveLine) - { - eLineJoin = basegfx::B2DLINEJOIN_ROUND; - fUnderlineHeight *= 0.5; - } - - // prepare Line and Stroke Attributes - const attribute::LineAttribute aLineAttribute(getTextlineColor(), fUnderlineHeight, eLineJoin); - attribute::StrokeAttribute aStrokeAttribute; - - if(pDotDashArray) - { - ::std::vector< double > aDoubleArray; - - for(const int* p = pDotDashArray; *p; ++p) - { - aDoubleArray.push_back((double)(*p) * fUnderlineHeight); - } - - aStrokeAttribute = attribute::StrokeAttribute(aDoubleArray); - } - - // create base polygon and new primitive - basegfx::B2DPolygon aUnderline; - Primitive2DReference aNewPrimitive; - - aUnderline.append(basegfx::B2DPoint(0.0, fUnderlineOffset)); - aUnderline.append(basegfx::B2DPoint(fTextWidth, fUnderlineOffset)); - aUnderline.transform(aUnscaledTransform); - - if(bWaveLine) - { - double fWaveWidth(4.0 * fUnderlineHeight); - - if(primitive2d::FONT_UNDERLINE_SMALLWAVE == getFontUnderline()) - { - fWaveWidth *= 0.7; - } - else if(primitive2d::FONT_UNDERLINE_WAVE == getFontUnderline()) - { - // extra multiply to get the same WaveWidth as with the bold version - fWaveWidth *= 2.0; - } - - aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aUnderline, aLineAttribute, aStrokeAttribute, fWaveWidth, 0.5 * fWaveWidth)); - } - else - { - aNewPrimitive = Primitive2DReference(new PolygonStrokePrimitive2D(aUnderline, aLineAttribute, aStrokeAttribute)); - } - - // add primitive - rTarget.push_back(aNewPrimitive); - - if(bDoubleLine) - { - // double line, create 2nd primitive with offset using TransformPrimitive based on - // already created NewPrimitive - const double fLineDist((bWaveLine ? 3.0 : 2.0) * fUnderlineHeight); - basegfx::B2DHomMatrix aTransform; - - // move base point of text to 0.0 and de-rotate - aTransform.translate(-rDecTrans.getTranslate().getX(), -rDecTrans.getTranslate().getY()); - aTransform.rotate(-rDecTrans.getRotate()); - - // translate in Y by offset - aTransform.translate(0.0, fLineDist); - - // move back and rotate - aTransform.rotate(rDecTrans.getRotate()); - aTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY()); - - // add transform primitive - const Primitive2DSequence aContent(&aNewPrimitive, 1); - rTarget.push_back(Primitive2DReference(new TransformPrimitive2D(aTransform, aContent))); - } + impCreateTextLine(rTarget, rDecTrans, aUnscaledTransform, getFontUnderline(), aTextLayouter.getUnderlineOffset(), + aTextLayouter.getUnderlineHeight(), fTextWidth, getTextlineColor()); } if(bStrikeoutUsed) @@ -320,7 +340,7 @@ namespace drawinglayer const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.9)); const double fScaleX(rDecTrans.getScale().getX()); const double fStrikeCharWidthUnscaled(basegfx::fTools::equalZero(fScaleX) ? fStrikeCharWidth : fStrikeCharWidth/fScaleX); - + std::vector<double> aDXArray(nStrikeCharCount); String aStrikeoutString; @@ -329,15 +349,15 @@ namespace drawinglayer aStrikeoutString += aSingleCharString; aDXArray[a] = (a + 1) * fStrikeCharWidthUnscaled; } - + rTarget.push_back(Primitive2DReference(new TextSimplePortionPrimitive2D( - rDecTrans.getB2DHomMatrix(), - aStrikeoutString, + rDecTrans.getB2DHomMatrix(), + aStrikeoutString, 0, aStrikeoutString.Len(), - aDXArray, - rFontAttributes, - getLocale(), + aDXArray, + rFontAttributes, + getLocale(), getFontColor()))); } else @@ -347,7 +367,7 @@ namespace drawinglayer double fStrikeoutOffset(aTextLayouter.getStrikeoutOffset()); bool bDoubleLine(false); - // set Underline attribute + // set line attribute switch(getFontStrikeout()) { default : // case primitive2d::FONT_STRIKEOUT_SINGLE: @@ -378,7 +398,7 @@ namespace drawinglayer aStrikeoutLine.append(basegfx::B2DPoint(0.0, -fStrikeoutOffset)); aStrikeoutLine.append(basegfx::B2DPoint(fTextWidth, -fStrikeoutOffset)); aStrikeoutLine.transform(aUnscaledTransform); - + const attribute::LineAttribute aLineAttribute(getFontColor(), fStrikeoutHeight, basegfx::B2DLINEJOIN_NONE); Primitive2DReference aNewPrimitive(new PolygonStrokePrimitive2D(aStrikeoutLine, aLineAttribute)); @@ -507,7 +527,7 @@ namespace drawinglayer // prepare new DXArray for the single word ::std::vector< double > aNewDXArray( - getDXArray().begin() + static_cast< sal_uInt32 >(nNewTextStart - getTextPosition()), + getDXArray().begin() + static_cast< sal_uInt32 >(nNewTextStart - getTextPosition()), getDXArray().begin() + static_cast< sal_uInt32 >(nNewTextEnd - getTextPosition())); if(bNewStartIsNotOldStart) @@ -520,15 +540,15 @@ namespace drawinglayer aNewDXArray[a] -= fDistance; } } - + // create geometry content for the single word basegfx::DecomposedB2DHomMatrixContainer aDecTrans(aNewTransform); - impCreateGeometryContent(rTarget, aDecTrans, getText(), nNewTextStart, + impCreateGeometryContent(rTarget, aDecTrans, getText(), nNewTextStart, nNewTextEnd - nNewTextStart, aNewDXArray, aNewFontAttributes); // prepare next word and truncate to possibilities aNextWordBoundary = xLocalBreakIterator->nextWord( - getText(), aNextWordBoundary.endPos, getLocale(), + getText(), aNextWordBoundary.endPos, getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES); impCorrectTextBoundary(aNextWordBoundary); } @@ -542,8 +562,8 @@ namespace drawinglayer basegfx::DecomposedB2DHomMatrixContainer aDecTrans(getTextTransform()); Primitive2DSequence aRetval; - // create basic geometry such as SimpleTextPrimitive, Underline, - // Strikeuot, etc... + // create basic geometry such as SimpleTextPrimitive, Overline, Underline, + // Strikeout, etc... if(getWordLineMode()) { // support for single word mode @@ -569,7 +589,7 @@ namespace drawinglayer // convert to Primitive2DSequence const sal_uInt32 nMemberCount(aNewPrimitives.size()); - + if(nMemberCount) { aRetval.realloc(nMemberCount); @@ -595,13 +615,13 @@ namespace drawinglayer if(bHasShadow) { // create shadow with current content (in aRetval). Text shadow - // is constant, relative to font size, rotated with the text and has a + // is constant, relative to font size, rotated with the text and has a // constant color. // shadow parameter values static double fFactor(1.0 / 24.0); const double fTextShadowOffset(aDecTrans.getScale().getY() * fFactor); static basegfx::BColor aShadowColor(0.3, 0.3, 0.3); - + // preapare shadow transform matrix basegfx::B2DHomMatrix aShadowTransform; aShadowTransform.translate(fTextShadowOffset, fTextShadowOffset); @@ -645,9 +665,9 @@ namespace drawinglayer } Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D( - aRetval, + aRetval, aDecTrans.getTranslate(), - aDecTrans.getRotate(), + aDecTrans.getRotate(), aTextEffectStyle2D)); aRetval = Primitive2DSequence(&aNewTextEffect, 1); } @@ -656,9 +676,9 @@ namespace drawinglayer // create outline using an own helper primitive since this will // be view-dependent Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D( - aRetval, - aDecTrans.getTranslate(), - aDecTrans.getRotate(), + aRetval, + aDecTrans.getTranslate(), + aDecTrans.getRotate(), TEXTEFFECTSTYLE2D_OUTLINE)); aRetval = Primitive2DSequence(&aNewTextEffect, 1); } @@ -681,7 +701,7 @@ namespace drawinglayer // TextSimplePortionPrimitive2D parameters const basegfx::B2DHomMatrix& rNewTransform, - const String& rText, + const String& rText, xub_StrLen aTextPosition, xub_StrLen aTextLength, const ::std::vector< double >& rDXArray, @@ -690,7 +710,9 @@ namespace drawinglayer const basegfx::BColor& rFontColor, // local parameters + const basegfx::BColor& rOverlineColor, const basegfx::BColor& rTextlineColor, + FontUnderline eFontOverline, FontUnderline eFontUnderline, bool bUnderlineAbove, FontStrikeout eFontStrikeout, @@ -701,7 +723,9 @@ namespace drawinglayer FontRelief eFontRelief, bool bShadow) : TextSimplePortionPrimitive2D(rNewTransform, rText, aTextPosition, aTextLength, rDXArray, rFontAttributes, rLocale, rFontColor), + maOverlineColor(rOverlineColor), maTextlineColor(rTextlineColor), + meFontOverline(eFontOverline), meFontUnderline(eFontUnderline), meFontStrikeout(eFontStrikeout), meFontEmphasisMark(eFontEmphasisMark), @@ -719,8 +743,10 @@ namespace drawinglayer if(TextSimplePortionPrimitive2D::operator==(rPrimitive)) { const TextDecoratedPortionPrimitive2D& rCompare = (TextDecoratedPortionPrimitive2D&)rPrimitive; - - return (getTextlineColor() == rCompare.getTextlineColor() + + return (getOverlineColor() == rCompare.getOverlineColor() + && getTextlineColor() == rCompare.getTextlineColor() + && getFontOverline() == rCompare.getFontOverline() && getFontUnderline() == rCompare.getFontUnderline() && getFontStrikeout() == rCompare.getFontStrikeout() && getFontEmphasisMark() == rCompare.getFontEmphasisMark() diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx index dff471c9c1..60df24c1e1 100644 --- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx +++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx @@ -115,7 +115,7 @@ namespace { OSL_ENSURE(mnUseCount, "mismatch call number to releaseVirtualDevice() (!)"); mnUseCount--; - + if(!mnUseCount) { Start(); @@ -175,6 +175,13 @@ namespace drawinglayer setFont(getVclFontFromFontAttributes(rFontAttributes, fFontScaleX, fFontScaleY, 0.0, mrDevice)); } + double TextLayouterDevice::getOverlineOffset() const + { + const ::FontMetric& rMetric = mrDevice.GetFontMetric(); + double fRet = (rMetric.GetIntLeading() / 2.0) - rMetric.GetAscent(); + return fRet; + } + double TextLayouterDevice::getUnderlineOffset() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); @@ -201,6 +208,13 @@ namespace drawinglayer } #endif + double TextLayouterDevice::getOverlineHeight() const + { + const ::FontMetric& rMetric = mrDevice.GetFontMetric(); + double fRet = rMetric.GetIntLeading() / 2.5; + return fRet; + } + double TextLayouterDevice::getUnderlineHeight() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); @@ -214,44 +228,44 @@ namespace drawinglayer } double TextLayouterDevice::getTextWidth( - const String& rText, - xub_StrLen nIndex, + const String& rText, + xub_StrLen nIndex, xub_StrLen nLength) const { return mrDevice.GetTextWidth(rText, nIndex, nLength); } - bool TextLayouterDevice::getTextOutlines( - basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector, - const String& rText, - xub_StrLen nIndex, + bool TextLayouterDevice::getTextOutlines( + basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector, + const String& rText, + xub_StrLen nIndex, xub_StrLen nLength) { - return mrDevice.GetTextOutlines( - rB2DPolyPolyVector, - rText, - nIndex, - nIndex, - nLength, - true, - 0, + return mrDevice.GetTextOutlines( + rB2DPolyPolyVector, + rText, + nIndex, + nIndex, + nLength, + true, + 0, 0); } basegfx::B2DRange TextLayouterDevice::getTextBoundRect( - const String& rText, - xub_StrLen nIndex, + const String& rText, + xub_StrLen nIndex, xub_StrLen nLength) const { if(nLength) { Rectangle aRect; - + mrDevice.GetTextBoundRect( - aRect, - rText, - nIndex, - nIndex, + aRect, + rText, + nIndex, + nIndex, nLength); return basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom()); @@ -272,31 +286,31 @@ namespace drawinglayer namespace primitive2d { Font getVclFontFromFontAttributes( - const FontAttributes& rFontAttributes, + const FontAttributes& rFontAttributes, const basegfx::B2DHomMatrix& rTransform, const OutputDevice& rOutDev) { // decompose matrix to have position and size of text basegfx::B2DVector aScale, aTranslate; double fRotate, fShearX; - + rTransform.decompose(aScale, aTranslate, fRotate, fShearX); - + return getVclFontFromFontAttributes(rFontAttributes, aScale.getX(), aScale.getY(), fRotate, rOutDev); } Font getVclFontFromFontAttributes( - const FontAttributes& rFontAttributes, - double fFontScaleX, - double fFontScaleY, + const FontAttributes& rFontAttributes, + double fFontScaleX, + double fFontScaleY, double fFontRotation, const OutputDevice& /*rOutDev*/) { sal_uInt32 nWidth(basegfx::fround(fabs(fFontScaleX))); sal_uInt32 nHeight(basegfx::fround(fabs(fFontScaleY))); Font aRetval( - rFontAttributes.getFamilyName(), - rFontAttributes.getStyleName(), + rFontAttributes.getFamilyName(), + rFontAttributes.getStyleName(), #ifdef WIN32 Size(0, nHeight)); #else @@ -364,7 +378,7 @@ namespace drawinglayer rSize.setX(nWidth ? nWidth : nHeight); rSize.setY(nHeight); - + return aRetval; } } // end of namespace primitive2d diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index caba69769c..9c499990f8 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -102,6 +102,34 @@ 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 @@ -140,33 +168,17 @@ namespace drawinglayer if( pTCPP != NULL ) { - // set Underline attribute - FontUnderline eFontUnderline = UNDERLINE_NONE; - switch( pTCPP->getFontUnderline() ) + // set Overline attribute + FontUnderline eFontOverline = mapTextLineStyle( pTCPP->getFontOverline() ); + if( eFontOverline != UNDERLINE_NONE ) { - default: - DBG_WARNING1( "DrawingLayer: Unknown underline attribute (%d)!", pTCPP->getFontUnderline() ); - // fall through - case primitive2d::FONT_UNDERLINE_NONE: eFontUnderline = UNDERLINE_NONE; break; - case primitive2d::FONT_UNDERLINE_SINGLE: eFontUnderline = UNDERLINE_SINGLE; break; - case primitive2d::FONT_UNDERLINE_DOUBLE: eFontUnderline = UNDERLINE_DOUBLE; break; - case primitive2d::FONT_UNDERLINE_DOTTED: eFontUnderline = UNDERLINE_DOTTED; break; - case primitive2d::FONT_UNDERLINE_DASH: eFontUnderline = UNDERLINE_DASH; break; - case primitive2d::FONT_UNDERLINE_LONGDASH: eFontUnderline = UNDERLINE_LONGDASH; break; - case primitive2d::FONT_UNDERLINE_DASHDOT: eFontUnderline = UNDERLINE_DASHDOT; break; - case primitive2d::FONT_UNDERLINE_DASHDOTDOT:eFontUnderline = UNDERLINE_DASHDOTDOT; break; - case primitive2d::FONT_UNDERLINE_SMALLWAVE: eFontUnderline = UNDERLINE_SMALLWAVE; break; - case primitive2d::FONT_UNDERLINE_WAVE: eFontUnderline = UNDERLINE_WAVE; break; - case primitive2d::FONT_UNDERLINE_DOUBLEWAVE:eFontUnderline = UNDERLINE_DOUBLEWAVE; break; - case primitive2d::FONT_UNDERLINE_BOLD: eFontUnderline = UNDERLINE_BOLD; break; - case primitive2d::FONT_UNDERLINE_BOLDDOTTED:eFontUnderline = UNDERLINE_BOLDDOTTED; break; - case primitive2d::FONT_UNDERLINE_BOLDDASH: eFontUnderline = UNDERLINE_BOLDDASH; break; - case primitive2d::FONT_UNDERLINE_BOLDLONGDASH:eFontUnderline = UNDERLINE_LONGDASH; break; - case primitive2d::FONT_UNDERLINE_BOLDDASHDOT:eFontUnderline = UNDERLINE_BOLDDASHDOT; break; - case primitive2d::FONT_UNDERLINE_BOLDDASHDOTDOT:eFontUnderline = UNDERLINE_BOLDDASHDOT; break; - case primitive2d::FONT_UNDERLINE_BOLDWAVE: eFontUnderline = UNDERLINE_BOLDWAVE; break; + aFont.SetOverline( eFontOverline ); + if( pTCPP->getWordLineMode() ) + aFont.SetWordLineMode( true ); } + // set Underline attribute + FontUnderline eFontUnderline = mapTextLineStyle( pTCPP->getFontUnderline() ); if( eFontUnderline != UNDERLINE_NONE ) { aFont.SetUnderline( eFontUnderline ); @@ -181,7 +193,7 @@ namespace drawinglayer switch( pTCPP->getFontStrikeout() ) { default: - DBG_WARNING1( "DrawingLayer: Unknown strikeout attribute (%d)!", pTCPP->getFontUnderline() ); + 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; @@ -259,7 +271,7 @@ namespace drawinglayer const basegfx::B2DPoint aPoint(aLocalTransform * basegfx::B2DPoint(0.0, 0.0)); const Point aStartPoint(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())); const sal_uInt32 nOldLayoutMode(mpOutputDevice->GetLayoutMode()); - + if(rTextCandidate.getFontAttributes().getRTL()) { sal_uInt32 nRTLLayoutMode(nOldLayoutMode & ~(TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG)); @@ -269,10 +281,10 @@ namespace drawinglayer mpOutputDevice->SetFont(aFont); mpOutputDevice->SetTextColor(Color(aRGBFontColor)); - + mpOutputDevice->DrawTextArray( - aStartPoint, - rTextCandidate.getText(), + aStartPoint, + rTextCandidate.getText(), aTransformedDXArray.size() ? &(aTransformedDXArray[0]) : NULL, rTextCandidate.getTextPosition(), rTextCandidate.getTextLength()); @@ -417,10 +429,10 @@ namespace drawinglayer const basegfx::B2DPoint aBmpBottomRight(aLocalTransform * basegfx::B2DPoint(rFillBitmapAttribute.getTopLeft() + rFillBitmapAttribute.getSize())); const Point aBmpTL(mpOutputDevice->LogicToPixel(Point((sal_Int32)aBmpTopLeft.getX(), (sal_Int32)aBmpTopLeft.getY()))); const Point aBmpBR(mpOutputDevice->LogicToPixel(Point((sal_Int32)aBmpBottomRight.getX(), (sal_Int32)aBmpBottomRight.getY()))); - + sal_Int32 nOWidth(aObjBR.X() - aObjTL.X()); sal_Int32 nOHeight(aObjBR.Y() - aObjTL.Y()); - + // only do something when object has a size in discrete units if(nOWidth > 0 && nOHeight > 0) { @@ -516,7 +528,7 @@ namespace drawinglayer { impDrawGradientToOutDev( *mpOutputDevice, aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(), - aStartColor, aEndColor, rGradient.getBorder(), + aStartColor, aEndColor, rGradient.getBorder(), -rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), false); } } @@ -534,7 +546,7 @@ namespace drawinglayer if(mnPolygonStrokePrimitive2D && getOptionsDrawinglayer().IsAntiAliasing()) { - // when AA is on and this filled polygons are the result of stroked line geometry, + // 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 mpOutputDevice->SetFillColor(); mpOutputDevice->SetLineColor(Color(aPolygonColor)); @@ -552,14 +564,14 @@ namespace drawinglayer static bool bInside(true); static bool bFilled(false); static bool bLine(false); - + basegfx::B2DRange aRange(aLocalPolyPolygon.getB2DRange()); aRange.grow(aRange.getWidth() * -0.1); - + if(bFilled) { basegfx::B2DPolyPolygon aFilledClipped(basegfx::tools::clipPolyPolygonOnRange(aLocalPolyPolygon, aRange, bInside, false)); - basegfx::BColor aRand(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0); + basegfx::BColor aRand(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0); mpOutputDevice->SetFillColor(Color(aRand)); mpOutputDevice->SetLineColor(); mpOutputDevice->DrawPolyPolygon(aFilledClipped); @@ -568,7 +580,7 @@ namespace drawinglayer if(bLine) { basegfx::B2DPolyPolygon aLineClipped(basegfx::tools::clipPolyPolygonOnRange(aLocalPolyPolygon, aRange, bInside, true)); - basegfx::BColor aRand(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0); + basegfx::BColor aRand(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0); mpOutputDevice->SetFillColor(); mpOutputDevice->SetLineColor(Color(aRand)); @@ -592,22 +604,22 @@ namespace drawinglayer // get BoundRect basegfx::B2DRange aOutlineRange(rMetaCandidate.getB2DRange(getViewInformation2D())); aOutlineRange.transform(maCurrentTransformation); - + // Due to the integer MapModes used from VCL aind inside MetaFiles errors of up to three // pixels in size may happen. As long as there is no better way (e.g. convert the MetaFile - // to primitives) it is necessary to reduce maximum pixel size by 1 in X and Y and to use - // the inner pixel bounds accordingly (ceil resp. floor). This will also be done for logic - // units e.g. when creating a new MetaFile, but since much huger value ranges are used + // to primitives) it is necessary to reduce maximum pixel size by 1 in X and Y and to use + // the inner pixel bounds accordingly (ceil resp. floor). This will also be done for logic + // units e.g. when creating a new MetaFile, but since much huger value ranges are used // there typically will be okay for this compromize. Rectangle aDestRectView( (sal_Int32)ceil(aOutlineRange.getMinX()), (sal_Int32)ceil(aOutlineRange.getMinY()), (sal_Int32)floor(aOutlineRange.getMaxX()), (sal_Int32)floor(aOutlineRange.getMaxY())); - + if(aDestRectView.Right() > aDestRectView.Left()) { aDestRectView.Right()--; } - + if(aDestRectView.Bottom() > aDestRectView.Top()) { aDestRectView.Bottom()--; @@ -766,7 +778,7 @@ namespace drawinglayer // paint content to it process(rTransCandidate.getChildren()); - + // set to mask mpOutputDevice = &aBufferDevice.getAlpha(); @@ -801,7 +813,7 @@ namespace drawinglayer maCurrentTransformation = maCurrentTransformation * rTransformCandidate.getTransformation(); const geometry::ViewInformation2D aViewInformation2D( getViewInformation2D().getObjectTransformation() * rTransformCandidate.getTransformation(), - getViewInformation2D().getViewTransformation(), + getViewInformation2D().getViewTransformation(), getViewInformation2D().getViewport(), getViewInformation2D().getVisualizedPage(), getViewInformation2D().getViewTime(), @@ -824,8 +836,8 @@ namespace drawinglayer // create new local ViewInformation2D const geometry::ViewInformation2D aViewInformation2D( - getViewInformation2D().getObjectTransformation(), - getViewInformation2D().getViewTransformation(), + getViewInformation2D().getObjectTransformation(), + getViewInformation2D().getViewTransformation(), getViewInformation2D().getViewport(), rPagePreviewCandidate.getXDrawPage(), getViewInformation2D().getViewTime(), @@ -934,8 +946,8 @@ namespace drawinglayer else { // else apply LineStyle - basegfx::tools::applyLineDashing(rPolygonStrokeCandidate.getB2DPolygon(), - rStrokeAttribute.getDotDashArray(), + basegfx::tools::applyLineDashing(rPolygonStrokeCandidate.getB2DPolygon(), + rStrokeAttribute.getDotDashArray(), &aHairlinePolyPolygon, 0, rStrokeAttribute.getFullDotDashLen()); } @@ -955,23 +967,23 @@ namespace drawinglayer { basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a)); mpOutputDevice->DrawPolyLine(aCandidate, 0.0); - + aMat.set(0, 2, 1.0); aMat.set(1, 2, 0.0); aCandidate.transform(aMat); - + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); - + aMat.set(0, 2, 0.0); aMat.set(1, 2, 1.0); aCandidate.transform(aMat); - + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); - + aMat.set(0, 2, -1.0); aMat.set(1, 2, 0.0); aCandidate.transform(aMat); - + mpOutputDevice->DrawPolyLine(aCandidate, 0.0); } } |