summaryrefslogtreecommitdiff
path: root/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx')
-rw-r--r--drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx610
1 files changed, 610 insertions, 0 deletions
diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
new file mode 100644
index 000000000000..6c60b3f22281
--- /dev/null
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -0,0 +1,610 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/attribute/strokeattribute.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <drawinglayer/primitive2d/texteffectprimitive2d.hxx>
+#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlineprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ void TextDecoratedPortionPrimitive2D::impCreateGeometryContent(
+ std::vector< Primitive2DReference >& rTarget,
+ basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans,
+ const String& rText,
+ xub_StrLen aTextPosition,
+ xub_StrLen aTextLength,
+ const ::std::vector< double >& rDXArray,
+ const attribute::FontAttribute& rFontAttribute) const
+ {
+ // create the SimpleTextPrimitive needed in any case
+ rTarget.push_back(Primitive2DReference(
+ new TextSimplePortionPrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ rText,
+ aTextPosition,
+ aTextLength,
+ rDXArray,
+ rFontAttribute,
+ getLocale(),
+ getFontColor())));
+
+ // see if something else needs to be done
+ const bool bOverlineUsed(TEXT_LINE_NONE != getFontOverline());
+ const bool bUnderlineUsed(TEXT_LINE_NONE != getFontUnderline());
+ const bool bStrikeoutUsed(TEXT_STRIKEOUT_NONE != getTextStrikeout());
+
+ if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed)
+ {
+ // common preparations
+ TextLayouterDevice aTextLayouter;
+
+ // TextLayouterDevice is needed to get metrics for text decorations like
+ // underline/strikeout/emphasis marks from it. For setup, the font size is needed
+ aTextLayouter.setFontAttribute(
+ getFontAttribute(),
+ rDecTrans.getScale().getX(),
+ rDecTrans.getScale().getY(),
+ getLocale());
+
+ // get text width
+ double fTextWidth(0.0);
+
+ if(rDXArray.empty())
+ {
+ fTextWidth = aTextLayouter.getTextWidth(rText, aTextPosition, aTextLength);
+ }
+ else
+ {
+ fTextWidth = rDXArray.back() * rDecTrans.getScale().getX();
+ const double fFontScaleX(rDecTrans.getScale().getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ // need to take FontScaling out of the DXArray
+ fTextWidth /= fFontScaleX;
+ }
+ }
+
+ if(bOverlineUsed)
+ {
+ // create primitive geometry for overline
+ rTarget.push_back(Primitive2DReference(
+ new TextLinePrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ fTextWidth,
+ aTextLayouter.getOverlineOffset(),
+ aTextLayouter.getOverlineHeight(),
+ getFontOverline(),
+ getOverlineColor())));
+ }
+
+ if(bUnderlineUsed)
+ {
+ // create primitive geometry for underline
+ rTarget.push_back(Primitive2DReference(
+ new TextLinePrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ fTextWidth,
+ aTextLayouter.getUnderlineOffset(),
+ aTextLayouter.getUnderlineHeight(),
+ getFontUnderline(),
+ getTextlineColor())));
+ }
+
+ if(bStrikeoutUsed)
+ {
+ // create primitive geometry for strikeout
+ if(TEXT_STRIKEOUT_SLASH == getTextStrikeout() || TEXT_STRIKEOUT_X == getTextStrikeout())
+ {
+ // strikeout with character
+ const sal_Unicode aStrikeoutChar(TEXT_STRIKEOUT_SLASH == getTextStrikeout() ? '/' : 'X');
+
+ rTarget.push_back(Primitive2DReference(
+ new TextCharacterStrikeoutPrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ fTextWidth,
+ getFontColor(),
+ aStrikeoutChar,
+ getFontAttribute(),
+ getLocale())));
+ }
+ else
+ {
+ // strikeout with geometry
+ rTarget.push_back(Primitive2DReference(
+ new TextGeometryStrikeoutPrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ fTextWidth,
+ getFontColor(),
+ aTextLayouter.getUnderlineHeight(),
+ aTextLayouter.getStrikeoutOffset(),
+ getTextStrikeout())));
+ }
+ }
+ }
+
+ // TODO: Handle Font Emphasis Above/Below
+ }
+
+ void TextDecoratedPortionPrimitive2D::impCorrectTextBoundary(::com::sun::star::i18n::Boundary& rNextWordBoundary) const
+ {
+ // truncate aNextWordBoundary to min/max possible values. This is necessary since the word start may be
+ // before/after getTextPosition() when a long string is the content and getTextPosition()
+ // is right inside a word. Same for end.
+ const sal_Int32 aMinPos(static_cast< sal_Int32 >(getTextPosition()));
+ const sal_Int32 aMaxPos(aMinPos + static_cast< sal_Int32 >(getTextLength()));
+
+ if(rNextWordBoundary.startPos < aMinPos)
+ {
+ rNextWordBoundary.startPos = aMinPos;
+ }
+ else if(rNextWordBoundary.startPos > aMaxPos)
+ {
+ rNextWordBoundary.startPos = aMaxPos;
+ }
+
+ if(rNextWordBoundary.endPos < aMinPos)
+ {
+ rNextWordBoundary.endPos = aMinPos;
+ }
+ else if(rNextWordBoundary.endPos > aMaxPos)
+ {
+ rNextWordBoundary.endPos = aMaxPos;
+ }
+ }
+
+ void TextDecoratedPortionPrimitive2D::impSplitSingleWords(
+ std::vector< Primitive2DReference >& rTarget,
+ basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans) const
+ {
+ // break iterator support
+ // made static so it only needs to be fetched once, even with many single
+ // constructed VclMetafileProcessor2D. It's still incarnated on demand,
+ // but exists for OOo runtime now by purpose.
+ static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > xLocalBreakIterator;
+
+ if(!xLocalBreakIterator.is())
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(::comphelper::getProcessServiceFactory());
+ xLocalBreakIterator.set(xMSF->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.BreakIterator"))), ::com::sun::star::uno::UNO_QUERY);
+ }
+
+ if(xLocalBreakIterator.is() && getTextLength())
+ {
+ // init word iterator, get first word and truncate to possibilities
+ ::com::sun::star::i18n::Boundary aNextWordBoundary(xLocalBreakIterator->getWordBoundary(
+ getText(), getTextPosition(), getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True));
+
+ if(aNextWordBoundary.endPos == getTextPosition())
+ {
+ // backward hit, force next word
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), getTextPosition() + 1, getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
+ }
+
+ impCorrectTextBoundary(aNextWordBoundary);
+
+ // prepare new font attributes WITHOUT outline
+ const attribute::FontAttribute aNewFontAttribute(
+ getFontAttribute().getFamilyName(),
+ getFontAttribute().getStyleName(),
+ getFontAttribute().getWeight(),
+ getFontAttribute().getSymbol(),
+ getFontAttribute().getVertical(),
+ getFontAttribute().getItalic(),
+ getFontAttribute().getMonospaced(),
+ false, // no outline anymore, handled locally
+ getFontAttribute().getRTL(),
+ getFontAttribute().getBiDiStrong());
+
+ if(aNextWordBoundary.startPos == getTextPosition() && aNextWordBoundary.endPos == getTextLength())
+ {
+ // it IS only a single word, handle as one word
+ impCreateGeometryContent(rTarget, rDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttribute);
+ }
+ else
+ {
+ // prepare TextLayouter
+ const bool bNoDXArray(getDXArray().empty());
+ TextLayouterDevice aTextLayouter;
+
+ if(bNoDXArray)
+ {
+ // ..but only completely when no DXArray
+ aTextLayouter.setFontAttribute(
+ getFontAttribute(),
+ rDecTrans.getScale().getX(),
+ rDecTrans.getScale().getY(),
+ getLocale());
+ }
+
+ // do iterate over single words
+ while(aNextWordBoundary.startPos != aNextWordBoundary.endPos)
+ {
+ // prepare values for new portion
+ const xub_StrLen nNewTextStart(static_cast< xub_StrLen >(aNextWordBoundary.startPos));
+ const xub_StrLen nNewTextEnd(static_cast< xub_StrLen >(aNextWordBoundary.endPos));
+
+ // prepare transform for the single word
+ basegfx::B2DHomMatrix aNewTransform;
+ ::std::vector< double > aNewDXArray;
+ const bool bNewStartIsNotOldStart(nNewTextStart > getTextPosition());
+
+ if(!bNoDXArray)
+ {
+ // prepare new DXArray for the single word
+ aNewDXArray = ::std::vector< double >(
+ getDXArray().begin() + static_cast< sal_uInt32 >(nNewTextStart - getTextPosition()),
+ getDXArray().begin() + static_cast< sal_uInt32 >(nNewTextEnd - getTextPosition()));
+ }
+
+ if(bNewStartIsNotOldStart)
+ {
+ // needs to be moved to a new start position
+ double fOffset(0.0);
+
+ if(bNoDXArray)
+ {
+ // evaluate using TextLayouter
+ fOffset = aTextLayouter.getTextWidth(getText(), getTextPosition(), nNewTextStart);
+ }
+ else
+ {
+ // get from DXArray
+ const sal_uInt32 nIndex(static_cast< sal_uInt32 >(nNewTextStart - getTextPosition()));
+ fOffset = getDXArray()[nIndex - 1];
+ }
+
+ // need offset without FontScale for building the new transformation. The
+ // new transformation will be multiplied with the current text transformation
+ // so FontScale would be double
+ double fOffsetNoScale(fOffset);
+ const double fFontScaleX(rDecTrans.getScale().getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ fOffsetNoScale /= fFontScaleX;
+ }
+
+ // apply needed offset to transformation
+ aNewTransform.translate(fOffsetNoScale, 0.0);
+
+ if(!bNoDXArray)
+ {
+ // DXArray values need to be corrected with the offset, too. Here,
+ // take the scaled offset since the DXArray is scaled
+ const sal_uInt32 nArraySize(aNewDXArray.size());
+
+ for(sal_uInt32 a(0); a < nArraySize; a++)
+ {
+ aNewDXArray[a] -= fOffset;
+ }
+ }
+ }
+
+ // add text transformation to new transformation
+ aNewTransform *= rDecTrans.getB2DHomMatrix();
+
+ // create geometry content for the single word. Do not forget
+ // to use the new transformation
+ basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose aDecTrans(aNewTransform);
+
+ impCreateGeometryContent(rTarget, aDecTrans, getText(), nNewTextStart,
+ nNewTextEnd - nNewTextStart, aNewDXArray, aNewFontAttribute);
+
+ if(aNextWordBoundary.endPos >= getTextPosition() + getTextLength())
+ {
+ // end reached
+ aNextWordBoundary.startPos = aNextWordBoundary.endPos;
+ }
+ else
+ {
+ // get new word portion
+ const sal_Int32 nLastEndPos(aNextWordBoundary.endPos);
+
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), aNextWordBoundary.endPos, getLocale(),
+ ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
+
+ if(nLastEndPos == aNextWordBoundary.endPos)
+ {
+ // backward hit, force next word
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), nLastEndPos + 1, getLocale(),
+ ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
+ }
+
+ impCorrectTextBoundary(aNextWordBoundary);
+ }
+ }
+ }
+ }
+ }
+
+ Primitive2DSequence TextDecoratedPortionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ std::vector< Primitive2DReference > aNewPrimitives;
+ basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose aDecTrans(getTextTransform());
+ Primitive2DSequence aRetval;
+
+ // create basic geometry such as SimpleTextPrimitive, Overline, Underline,
+ // Strikeout, etc...
+ if(getWordLineMode())
+ {
+ // support for single word mode
+ impSplitSingleWords(aNewPrimitives, aDecTrans);
+ }
+ else
+ {
+ // prepare new font attributes WITHOUT outline
+ const attribute::FontAttribute aNewFontAttribute(
+ getFontAttribute().getFamilyName(),
+ getFontAttribute().getStyleName(),
+ getFontAttribute().getWeight(),
+ getFontAttribute().getSymbol(),
+ getFontAttribute().getVertical(),
+ getFontAttribute().getItalic(),
+ false, // no outline anymore, handled locally
+ getFontAttribute().getRTL(),
+ getFontAttribute().getBiDiStrong());
+
+ // handle as one word
+ impCreateGeometryContent(aNewPrimitives, aDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttribute);
+ }
+
+ // convert to Primitive2DSequence
+ const sal_uInt32 nMemberCount(aNewPrimitives.size());
+
+ if(nMemberCount)
+ {
+ aRetval.realloc(nMemberCount);
+
+ for(sal_uInt32 a(0); a < nMemberCount; a++)
+ {
+ aRetval[a] = aNewPrimitives[a];
+ }
+ }
+
+ // Handle Shadow, Outline and TextRelief
+ if(aRetval.hasElements())
+ {
+ // outline AND shadow depend on NO TextRelief (see dialog)
+ const bool bHasTextRelief(TEXT_RELIEF_NONE != getTextRelief());
+ const bool bHasShadow(!bHasTextRelief && getShadow());
+ const bool bHasOutline(!bHasTextRelief && getFontAttribute().getOutline());
+
+ if(bHasShadow || bHasTextRelief || bHasOutline)
+ {
+ Primitive2DReference aShadow;
+
+ if(bHasShadow)
+ {
+ // create shadow with current content (in aRetval). Text shadow
+ // 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
+ const basegfx::B2DHomMatrix aShadowTransform(basegfx::tools::createTranslateB2DHomMatrix(
+ fTextShadowOffset, fTextShadowOffset));
+
+ // create shadow primitive
+ aShadow = Primitive2DReference(new ShadowPrimitive2D(
+ aShadowTransform,
+ aShadowColor,
+ aRetval));
+ }
+
+ if(bHasTextRelief)
+ {
+ // create emboss using an own helper primitive since this will
+ // be view-dependent
+ const basegfx::BColor aBBlack(0.0, 0.0, 0.0);
+ const bool bDefaultTextColor(aBBlack == getFontColor());
+ TextEffectStyle2D aTextEffectStyle2D(TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED);
+
+ if(bDefaultTextColor)
+ {
+ if(TEXT_RELIEF_ENGRAVED == getTextRelief())
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT;
+ }
+ else
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT;
+ }
+ }
+ else
+ {
+ if(TEXT_RELIEF_ENGRAVED == getTextRelief())
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED;
+ }
+ else
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED;
+ }
+ }
+
+ Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D(
+ aRetval,
+ aDecTrans.getTranslate(),
+ aDecTrans.getRotate(),
+ aTextEffectStyle2D));
+ aRetval = Primitive2DSequence(&aNewTextEffect, 1);
+ }
+ else if(bHasOutline)
+ {
+ // create outline using an own helper primitive since this will
+ // be view-dependent
+ Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D(
+ aRetval,
+ aDecTrans.getTranslate(),
+ aDecTrans.getRotate(),
+ TEXTEFFECTSTYLE2D_OUTLINE));
+ aRetval = Primitive2DSequence(&aNewTextEffect, 1);
+ }
+
+ if(aShadow.is())
+ {
+ // put shadow in front if there is one to paint timely before
+ // but placed behind content
+ const Primitive2DSequence aContent(aRetval);
+ aRetval = Primitive2DSequence(&aShadow, 1);
+ appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aContent);
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ TextDecoratedPortionPrimitive2D::TextDecoratedPortionPrimitive2D(
+
+ // TextSimplePortionPrimitive2D parameters
+ const basegfx::B2DHomMatrix& rNewTransform,
+ const String& rText,
+ xub_StrLen aTextPosition,
+ xub_StrLen aTextLength,
+ const ::std::vector< double >& rDXArray,
+ const attribute::FontAttribute& rFontAttribute,
+ const ::com::sun::star::lang::Locale& rLocale,
+ const basegfx::BColor& rFontColor,
+
+ // local parameters
+ const basegfx::BColor& rOverlineColor,
+ const basegfx::BColor& rTextlineColor,
+ TextLine eFontOverline,
+ TextLine eFontUnderline,
+ bool bUnderlineAbove,
+ TextStrikeout eTextStrikeout,
+ bool bWordLineMode,
+ TextEmphasisMark eTextEmphasisMark,
+ bool bEmphasisMarkAbove,
+ bool bEmphasisMarkBelow,
+ TextRelief eTextRelief,
+ bool bShadow)
+ : TextSimplePortionPrimitive2D(rNewTransform, rText, aTextPosition, aTextLength, rDXArray, rFontAttribute, rLocale, rFontColor),
+ maOverlineColor(rOverlineColor),
+ maTextlineColor(rTextlineColor),
+ meFontOverline(eFontOverline),
+ meFontUnderline(eFontUnderline),
+ meTextStrikeout(eTextStrikeout),
+ meTextEmphasisMark(eTextEmphasisMark),
+ meTextRelief(eTextRelief),
+ mbUnderlineAbove(bUnderlineAbove),
+ mbWordLineMode(bWordLineMode),
+ mbEmphasisMarkAbove(bEmphasisMarkAbove),
+ mbEmphasisMarkBelow(bEmphasisMarkBelow),
+ mbShadow(bShadow)
+ {
+ }
+
+ bool TextDecoratedPortionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(TextSimplePortionPrimitive2D::operator==(rPrimitive))
+ {
+ const TextDecoratedPortionPrimitive2D& rCompare = (TextDecoratedPortionPrimitive2D&)rPrimitive;
+
+ return (getOverlineColor() == rCompare.getOverlineColor()
+ && getTextlineColor() == rCompare.getTextlineColor()
+ && getFontOverline() == rCompare.getFontOverline()
+ && getFontUnderline() == rCompare.getFontUnderline()
+ && getTextStrikeout() == rCompare.getTextStrikeout()
+ && getTextEmphasisMark() == rCompare.getTextEmphasisMark()
+ && getTextRelief() == rCompare.getTextRelief()
+ && getUnderlineAbove() == rCompare.getUnderlineAbove()
+ && getWordLineMode() == rCompare.getWordLineMode()
+ && getEmphasisMarkAbove() == rCompare.getEmphasisMarkAbove()
+ && getEmphasisMarkBelow() == rCompare.getEmphasisMarkBelow()
+ && getShadow() == rCompare.getShadow());
+ }
+
+ return false;
+ }
+
+ // #i96475#
+ // Added missing implementation. Decorations may (will) stick out of the text's
+ // inking area, so add them if needed
+ basegfx::B2DRange TextDecoratedPortionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ const bool bDecoratedIsNeeded(
+ TEXT_LINE_NONE != getFontOverline()
+ || TEXT_LINE_NONE != getFontUnderline()
+ || TEXT_STRIKEOUT_NONE != getTextStrikeout()
+ || TEXT_EMPHASISMARK_NONE != getTextEmphasisMark()
+ || TEXT_RELIEF_NONE != getTextRelief()
+ || getShadow());
+
+ if(bDecoratedIsNeeded)
+ {
+ // decoration is used, fallback to BufferedDecompositionPrimitive2D::getB2DRange which uses
+ // the own local decomposition for computation and thus creates all necessary
+ // geometric objects
+ return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation);
+ }
+ else
+ {
+ // no relevant decoration used, fallback to TextSimplePortionPrimitive2D::getB2DRange
+ return TextSimplePortionPrimitive2D::getB2DRange(rViewInformation);
+ }
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextDecoratedPortionPrimitive2D, PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */