1464702f4SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3464702f4SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4464702f4SAndrew Rist * or more contributor license agreements. See the NOTICE file 5464702f4SAndrew Rist * distributed with this work for additional information 6464702f4SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7464702f4SAndrew Rist * to you under the Apache License, Version 2.0 (the 8464702f4SAndrew Rist * "License"); you may not use this file except in compliance 9464702f4SAndrew Rist * with the License. You may obtain a copy of the License at 10464702f4SAndrew Rist * 11464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12464702f4SAndrew Rist * 13464702f4SAndrew Rist * Unless required by applicable law or agreed to in writing, 14464702f4SAndrew Rist * software distributed under the License is distributed on an 15464702f4SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16464702f4SAndrew Rist * KIND, either express or implied. See the License for the 17464702f4SAndrew Rist * specific language governing permissions and limitations 18464702f4SAndrew Rist * under the License. 19464702f4SAndrew Rist * 20464702f4SAndrew Rist *************************************************************/ 21464702f4SAndrew Rist 22464702f4SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> 28cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 29cdf0e10cSrcweir #include <drawinglayer/attribute/strokeattribute.hxx> 30cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 31cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx> 32cdf0e10cSrcweir #include <drawinglayer/primitive2d/texteffectprimitive2d.hxx> 33cdf0e10cSrcweir #include <drawinglayer/primitive2d/shadowprimitive2d.hxx> 34cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 35cdf0e10cSrcweir #include <drawinglayer/primitive2d/textlineprimitive2d.hxx> 36cdf0e10cSrcweir #include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx> 37*693be7f6SArmin Le Grand #include <drawinglayer/primitive2d/textbreakuphelper.hxx> 38cdf0e10cSrcweir 39cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 40cdf0e10cSrcweir 41cdf0e10cSrcweir namespace drawinglayer 42cdf0e10cSrcweir { 43cdf0e10cSrcweir namespace primitive2d 44cdf0e10cSrcweir { 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) const45cdf0e10cSrcweir void TextDecoratedPortionPrimitive2D::impCreateGeometryContent( 46cdf0e10cSrcweir std::vector< Primitive2DReference >& rTarget, 47cdf0e10cSrcweir basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose& rDecTrans, 48cdf0e10cSrcweir const String& rText, 49cdf0e10cSrcweir xub_StrLen aTextPosition, 50cdf0e10cSrcweir xub_StrLen aTextLength, 51cdf0e10cSrcweir const ::std::vector< double >& rDXArray, 52cdf0e10cSrcweir const attribute::FontAttribute& rFontAttribute) const 53cdf0e10cSrcweir { 54cdf0e10cSrcweir // create the SimpleTextPrimitive needed in any case 55cdf0e10cSrcweir rTarget.push_back(Primitive2DReference( 56cdf0e10cSrcweir new TextSimplePortionPrimitive2D( 57cdf0e10cSrcweir rDecTrans.getB2DHomMatrix(), 58cdf0e10cSrcweir rText, 59cdf0e10cSrcweir aTextPosition, 60cdf0e10cSrcweir aTextLength, 61cdf0e10cSrcweir rDXArray, 62cdf0e10cSrcweir rFontAttribute, 63cdf0e10cSrcweir getLocale(), 64cdf0e10cSrcweir getFontColor()))); 65cdf0e10cSrcweir 66cdf0e10cSrcweir // see if something else needs to be done 67cdf0e10cSrcweir const bool bOverlineUsed(TEXT_LINE_NONE != getFontOverline()); 68cdf0e10cSrcweir const bool bUnderlineUsed(TEXT_LINE_NONE != getFontUnderline()); 69cdf0e10cSrcweir const bool bStrikeoutUsed(TEXT_STRIKEOUT_NONE != getTextStrikeout()); 70cdf0e10cSrcweir 71cdf0e10cSrcweir if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir // common preparations 74cdf0e10cSrcweir TextLayouterDevice aTextLayouter; 75cdf0e10cSrcweir 76cdf0e10cSrcweir // TextLayouterDevice is needed to get metrics for text decorations like 77cdf0e10cSrcweir // underline/strikeout/emphasis marks from it. For setup, the font size is needed 78cdf0e10cSrcweir aTextLayouter.setFontAttribute( 79cdf0e10cSrcweir getFontAttribute(), 80cdf0e10cSrcweir rDecTrans.getScale().getX(), 81cdf0e10cSrcweir rDecTrans.getScale().getY(), 82cdf0e10cSrcweir getLocale()); 83cdf0e10cSrcweir 84cdf0e10cSrcweir // get text width 85cdf0e10cSrcweir double fTextWidth(0.0); 86cdf0e10cSrcweir 87cdf0e10cSrcweir if(rDXArray.empty()) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir fTextWidth = aTextLayouter.getTextWidth(rText, aTextPosition, aTextLength); 90cdf0e10cSrcweir } 91cdf0e10cSrcweir else 92cdf0e10cSrcweir { 93cdf0e10cSrcweir fTextWidth = rDXArray.back() * rDecTrans.getScale().getX(); 94cdf0e10cSrcweir const double fFontScaleX(rDecTrans.getScale().getX()); 95cdf0e10cSrcweir 96cdf0e10cSrcweir if(!basegfx::fTools::equal(fFontScaleX, 1.0) 97cdf0e10cSrcweir && !basegfx::fTools::equalZero(fFontScaleX)) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir // need to take FontScaling out of the DXArray 100cdf0e10cSrcweir fTextWidth /= fFontScaleX; 101cdf0e10cSrcweir } 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir if(bOverlineUsed) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir // create primitive geometry for overline 107cdf0e10cSrcweir rTarget.push_back(Primitive2DReference( 108cdf0e10cSrcweir new TextLinePrimitive2D( 109cdf0e10cSrcweir rDecTrans.getB2DHomMatrix(), 110cdf0e10cSrcweir fTextWidth, 111cdf0e10cSrcweir aTextLayouter.getOverlineOffset(), 112cdf0e10cSrcweir aTextLayouter.getOverlineHeight(), 113cdf0e10cSrcweir getFontOverline(), 114cdf0e10cSrcweir getOverlineColor()))); 115cdf0e10cSrcweir } 116cdf0e10cSrcweir 117cdf0e10cSrcweir if(bUnderlineUsed) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir // create primitive geometry for underline 120cdf0e10cSrcweir rTarget.push_back(Primitive2DReference( 121cdf0e10cSrcweir new TextLinePrimitive2D( 122cdf0e10cSrcweir rDecTrans.getB2DHomMatrix(), 123cdf0e10cSrcweir fTextWidth, 124cdf0e10cSrcweir aTextLayouter.getUnderlineOffset(), 125cdf0e10cSrcweir aTextLayouter.getUnderlineHeight(), 126cdf0e10cSrcweir getFontUnderline(), 127cdf0e10cSrcweir getTextlineColor()))); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir if(bStrikeoutUsed) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir // create primitive geometry for strikeout 133cdf0e10cSrcweir if(TEXT_STRIKEOUT_SLASH == getTextStrikeout() || TEXT_STRIKEOUT_X == getTextStrikeout()) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir // strikeout with character 136cdf0e10cSrcweir const sal_Unicode aStrikeoutChar(TEXT_STRIKEOUT_SLASH == getTextStrikeout() ? '/' : 'X'); 137cdf0e10cSrcweir 138cdf0e10cSrcweir rTarget.push_back(Primitive2DReference( 139cdf0e10cSrcweir new TextCharacterStrikeoutPrimitive2D( 140cdf0e10cSrcweir rDecTrans.getB2DHomMatrix(), 141cdf0e10cSrcweir fTextWidth, 142cdf0e10cSrcweir getFontColor(), 143cdf0e10cSrcweir aStrikeoutChar, 144cdf0e10cSrcweir getFontAttribute(), 145cdf0e10cSrcweir getLocale()))); 146cdf0e10cSrcweir } 147cdf0e10cSrcweir else 148cdf0e10cSrcweir { 149cdf0e10cSrcweir // strikeout with geometry 150cdf0e10cSrcweir rTarget.push_back(Primitive2DReference( 151cdf0e10cSrcweir new TextGeometryStrikeoutPrimitive2D( 152cdf0e10cSrcweir rDecTrans.getB2DHomMatrix(), 153cdf0e10cSrcweir fTextWidth, 154cdf0e10cSrcweir getFontColor(), 155cdf0e10cSrcweir aTextLayouter.getUnderlineHeight(), 156cdf0e10cSrcweir aTextLayouter.getStrikeoutOffset(), 157cdf0e10cSrcweir getTextStrikeout()))); 158cdf0e10cSrcweir } 159cdf0e10cSrcweir } 160cdf0e10cSrcweir } 161cdf0e10cSrcweir 162cdf0e10cSrcweir // TODO: Handle Font Emphasis Above/Below 163cdf0e10cSrcweir } 164cdf0e10cSrcweir create2DDecomposition(const geometry::ViewInformation2D &) const165*693be7f6SArmin Le Grand Primitive2DSequence TextDecoratedPortionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 166cdf0e10cSrcweir { 167*693be7f6SArmin Le Grand if(getWordLineMode()) 168cdf0e10cSrcweir { 169*693be7f6SArmin Le Grand // support for single word mode; split to single word primitives 170*693be7f6SArmin Le Grand // using TextBreakupHelper 171*693be7f6SArmin Le Grand const TextBreakupHelper aTextBreakupHelper(*this); 172*693be7f6SArmin Le Grand const Primitive2DSequence aBroken(aTextBreakupHelper.getResult(BreakupUnit_word)); 173cdf0e10cSrcweir 174*693be7f6SArmin Le Grand if(aBroken.hasElements()) 175cdf0e10cSrcweir { 176*693be7f6SArmin Le Grand // was indeed split to several words, use as result 177*693be7f6SArmin Le Grand return aBroken; 178*693be7f6SArmin Le Grand } 179*693be7f6SArmin Le Grand else 180*693be7f6SArmin Le Grand { 181*693be7f6SArmin Le Grand // no split, was already a single word. Continue to 182*693be7f6SArmin Le Grand // decompse local entity 183cdf0e10cSrcweir } 184cdf0e10cSrcweir } 185cdf0e10cSrcweir std::vector< Primitive2DReference > aNewPrimitives; 186cdf0e10cSrcweir basegfx::tools::B2DHomMatrixBufferedOnDemandDecompose aDecTrans(getTextTransform()); 187cdf0e10cSrcweir Primitive2DSequence aRetval; 188cdf0e10cSrcweir 189cdf0e10cSrcweir // create basic geometry such as SimpleTextPrimitive, Overline, Underline, 190cdf0e10cSrcweir // Strikeout, etc... 191*693be7f6SArmin Le Grand // prepare new font attributes WITHOUT outline 192*693be7f6SArmin Le Grand const attribute::FontAttribute aNewFontAttribute( 193*693be7f6SArmin Le Grand getFontAttribute().getFamilyName(), 194*693be7f6SArmin Le Grand getFontAttribute().getStyleName(), 195*693be7f6SArmin Le Grand getFontAttribute().getWeight(), 196*693be7f6SArmin Le Grand getFontAttribute().getSymbol(), 197*693be7f6SArmin Le Grand getFontAttribute().getVertical(), 198*693be7f6SArmin Le Grand getFontAttribute().getItalic(), 199*693be7f6SArmin Le Grand false, // no outline anymore, handled locally 200*693be7f6SArmin Le Grand getFontAttribute().getRTL(), 201*693be7f6SArmin Le Grand getFontAttribute().getBiDiStrong()); 202*693be7f6SArmin Le Grand 203*693be7f6SArmin Le Grand // handle as one word 204*693be7f6SArmin Le Grand impCreateGeometryContent(aNewPrimitives, aDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttribute); 205cdf0e10cSrcweir 206cdf0e10cSrcweir // convert to Primitive2DSequence 207cdf0e10cSrcweir const sal_uInt32 nMemberCount(aNewPrimitives.size()); 208cdf0e10cSrcweir 209cdf0e10cSrcweir if(nMemberCount) 210cdf0e10cSrcweir { 211cdf0e10cSrcweir aRetval.realloc(nMemberCount); 212cdf0e10cSrcweir 213cdf0e10cSrcweir for(sal_uInt32 a(0); a < nMemberCount; a++) 214cdf0e10cSrcweir { 215cdf0e10cSrcweir aRetval[a] = aNewPrimitives[a]; 216cdf0e10cSrcweir } 217cdf0e10cSrcweir } 218cdf0e10cSrcweir 219cdf0e10cSrcweir // Handle Shadow, Outline and TextRelief 220cdf0e10cSrcweir if(aRetval.hasElements()) 221cdf0e10cSrcweir { 222cdf0e10cSrcweir // outline AND shadow depend on NO TextRelief (see dialog) 223cdf0e10cSrcweir const bool bHasTextRelief(TEXT_RELIEF_NONE != getTextRelief()); 224cdf0e10cSrcweir const bool bHasShadow(!bHasTextRelief && getShadow()); 225cdf0e10cSrcweir const bool bHasOutline(!bHasTextRelief && getFontAttribute().getOutline()); 226cdf0e10cSrcweir 227cdf0e10cSrcweir if(bHasShadow || bHasTextRelief || bHasOutline) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir Primitive2DReference aShadow; 230cdf0e10cSrcweir 231cdf0e10cSrcweir if(bHasShadow) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir // create shadow with current content (in aRetval). Text shadow 234cdf0e10cSrcweir // is constant, relative to font size, rotated with the text and has a 235cdf0e10cSrcweir // constant color. 236cdf0e10cSrcweir // shadow parameter values 237cdf0e10cSrcweir static double fFactor(1.0 / 24.0); 238cdf0e10cSrcweir const double fTextShadowOffset(aDecTrans.getScale().getY() * fFactor); 239cdf0e10cSrcweir static basegfx::BColor aShadowColor(0.3, 0.3, 0.3); 240cdf0e10cSrcweir 241cdf0e10cSrcweir // preapare shadow transform matrix 242cdf0e10cSrcweir const basegfx::B2DHomMatrix aShadowTransform(basegfx::tools::createTranslateB2DHomMatrix( 243cdf0e10cSrcweir fTextShadowOffset, fTextShadowOffset)); 244cdf0e10cSrcweir 245cdf0e10cSrcweir // create shadow primitive 246cdf0e10cSrcweir aShadow = Primitive2DReference(new ShadowPrimitive2D( 247cdf0e10cSrcweir aShadowTransform, 248cdf0e10cSrcweir aShadowColor, 249cdf0e10cSrcweir aRetval)); 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir if(bHasTextRelief) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir // create emboss using an own helper primitive since this will 255cdf0e10cSrcweir // be view-dependent 256cdf0e10cSrcweir const basegfx::BColor aBBlack(0.0, 0.0, 0.0); 257cdf0e10cSrcweir const bool bDefaultTextColor(aBBlack == getFontColor()); 258cdf0e10cSrcweir TextEffectStyle2D aTextEffectStyle2D(TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED); 259cdf0e10cSrcweir 260cdf0e10cSrcweir if(bDefaultTextColor) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir if(TEXT_RELIEF_ENGRAVED == getTextRelief()) 263cdf0e10cSrcweir { 264cdf0e10cSrcweir aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT; 265cdf0e10cSrcweir } 266cdf0e10cSrcweir else 267cdf0e10cSrcweir { 268cdf0e10cSrcweir aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT; 269cdf0e10cSrcweir } 270cdf0e10cSrcweir } 271cdf0e10cSrcweir else 272cdf0e10cSrcweir { 273cdf0e10cSrcweir if(TEXT_RELIEF_ENGRAVED == getTextRelief()) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED; 276cdf0e10cSrcweir } 277cdf0e10cSrcweir else 278cdf0e10cSrcweir { 279cdf0e10cSrcweir aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED; 280cdf0e10cSrcweir } 281cdf0e10cSrcweir } 282cdf0e10cSrcweir 283cdf0e10cSrcweir Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D( 284cdf0e10cSrcweir aRetval, 285cdf0e10cSrcweir aDecTrans.getTranslate(), 286cdf0e10cSrcweir aDecTrans.getRotate(), 287cdf0e10cSrcweir aTextEffectStyle2D)); 288cdf0e10cSrcweir aRetval = Primitive2DSequence(&aNewTextEffect, 1); 289cdf0e10cSrcweir } 290cdf0e10cSrcweir else if(bHasOutline) 291cdf0e10cSrcweir { 292cdf0e10cSrcweir // create outline using an own helper primitive since this will 293cdf0e10cSrcweir // be view-dependent 294cdf0e10cSrcweir Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D( 295cdf0e10cSrcweir aRetval, 296cdf0e10cSrcweir aDecTrans.getTranslate(), 297cdf0e10cSrcweir aDecTrans.getRotate(), 298cdf0e10cSrcweir TEXTEFFECTSTYLE2D_OUTLINE)); 299cdf0e10cSrcweir aRetval = Primitive2DSequence(&aNewTextEffect, 1); 300cdf0e10cSrcweir } 301cdf0e10cSrcweir 302cdf0e10cSrcweir if(aShadow.is()) 303cdf0e10cSrcweir { 304cdf0e10cSrcweir // put shadow in front if there is one to paint timely before 305cdf0e10cSrcweir // but placed behind content 306cdf0e10cSrcweir const Primitive2DSequence aContent(aRetval); 307cdf0e10cSrcweir aRetval = Primitive2DSequence(&aShadow, 1); 308cdf0e10cSrcweir appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aContent); 309cdf0e10cSrcweir } 310cdf0e10cSrcweir } 311cdf0e10cSrcweir } 312cdf0e10cSrcweir 313cdf0e10cSrcweir return aRetval; 314cdf0e10cSrcweir } 315cdf0e10cSrcweir TextDecoratedPortionPrimitive2D(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,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)316cdf0e10cSrcweir TextDecoratedPortionPrimitive2D::TextDecoratedPortionPrimitive2D( 317cdf0e10cSrcweir 318cdf0e10cSrcweir // TextSimplePortionPrimitive2D parameters 319cdf0e10cSrcweir const basegfx::B2DHomMatrix& rNewTransform, 320cdf0e10cSrcweir const String& rText, 321cdf0e10cSrcweir xub_StrLen aTextPosition, 322cdf0e10cSrcweir xub_StrLen aTextLength, 323cdf0e10cSrcweir const ::std::vector< double >& rDXArray, 324cdf0e10cSrcweir const attribute::FontAttribute& rFontAttribute, 325cdf0e10cSrcweir const ::com::sun::star::lang::Locale& rLocale, 326cdf0e10cSrcweir const basegfx::BColor& rFontColor, 327cdf0e10cSrcweir 328cdf0e10cSrcweir // local parameters 329cdf0e10cSrcweir const basegfx::BColor& rOverlineColor, 330cdf0e10cSrcweir const basegfx::BColor& rTextlineColor, 331cdf0e10cSrcweir TextLine eFontOverline, 332cdf0e10cSrcweir TextLine eFontUnderline, 333cdf0e10cSrcweir bool bUnderlineAbove, 334cdf0e10cSrcweir TextStrikeout eTextStrikeout, 335cdf0e10cSrcweir bool bWordLineMode, 336cdf0e10cSrcweir TextEmphasisMark eTextEmphasisMark, 337cdf0e10cSrcweir bool bEmphasisMarkAbove, 338cdf0e10cSrcweir bool bEmphasisMarkBelow, 339cdf0e10cSrcweir TextRelief eTextRelief, 340cdf0e10cSrcweir bool bShadow) 341cdf0e10cSrcweir : TextSimplePortionPrimitive2D(rNewTransform, rText, aTextPosition, aTextLength, rDXArray, rFontAttribute, rLocale, rFontColor), 342cdf0e10cSrcweir maOverlineColor(rOverlineColor), 343cdf0e10cSrcweir maTextlineColor(rTextlineColor), 344cdf0e10cSrcweir meFontOverline(eFontOverline), 345cdf0e10cSrcweir meFontUnderline(eFontUnderline), 346cdf0e10cSrcweir meTextStrikeout(eTextStrikeout), 347cdf0e10cSrcweir meTextEmphasisMark(eTextEmphasisMark), 348cdf0e10cSrcweir meTextRelief(eTextRelief), 349cdf0e10cSrcweir mbUnderlineAbove(bUnderlineAbove), 350cdf0e10cSrcweir mbWordLineMode(bWordLineMode), 351cdf0e10cSrcweir mbEmphasisMarkAbove(bEmphasisMarkAbove), 352cdf0e10cSrcweir mbEmphasisMarkBelow(bEmphasisMarkBelow), 353cdf0e10cSrcweir mbShadow(bShadow) 354cdf0e10cSrcweir { 355cdf0e10cSrcweir } 356cdf0e10cSrcweir decoratedIsNeeded() const357*693be7f6SArmin Le Grand bool TextDecoratedPortionPrimitive2D::decoratedIsNeeded() const 358*693be7f6SArmin Le Grand { 359*693be7f6SArmin Le Grand return (TEXT_LINE_NONE != getFontOverline() 360*693be7f6SArmin Le Grand || TEXT_LINE_NONE != getFontUnderline() 361*693be7f6SArmin Le Grand || TEXT_STRIKEOUT_NONE != getTextStrikeout() 362*693be7f6SArmin Le Grand || TEXT_EMPHASISMARK_NONE != getTextEmphasisMark() 363*693be7f6SArmin Le Grand || TEXT_RELIEF_NONE != getTextRelief() 364*693be7f6SArmin Le Grand || getShadow()); 365*693be7f6SArmin Le Grand } 366*693be7f6SArmin Le Grand operator ==(const BasePrimitive2D & rPrimitive) const367cdf0e10cSrcweir bool TextDecoratedPortionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 368cdf0e10cSrcweir { 369cdf0e10cSrcweir if(TextSimplePortionPrimitive2D::operator==(rPrimitive)) 370cdf0e10cSrcweir { 371cdf0e10cSrcweir const TextDecoratedPortionPrimitive2D& rCompare = (TextDecoratedPortionPrimitive2D&)rPrimitive; 372cdf0e10cSrcweir 373cdf0e10cSrcweir return (getOverlineColor() == rCompare.getOverlineColor() 374cdf0e10cSrcweir && getTextlineColor() == rCompare.getTextlineColor() 375cdf0e10cSrcweir && getFontOverline() == rCompare.getFontOverline() 376cdf0e10cSrcweir && getFontUnderline() == rCompare.getFontUnderline() 377cdf0e10cSrcweir && getTextStrikeout() == rCompare.getTextStrikeout() 378cdf0e10cSrcweir && getTextEmphasisMark() == rCompare.getTextEmphasisMark() 379cdf0e10cSrcweir && getTextRelief() == rCompare.getTextRelief() 380cdf0e10cSrcweir && getUnderlineAbove() == rCompare.getUnderlineAbove() 381cdf0e10cSrcweir && getWordLineMode() == rCompare.getWordLineMode() 382cdf0e10cSrcweir && getEmphasisMarkAbove() == rCompare.getEmphasisMarkAbove() 383cdf0e10cSrcweir && getEmphasisMarkBelow() == rCompare.getEmphasisMarkBelow() 384cdf0e10cSrcweir && getShadow() == rCompare.getShadow()); 385cdf0e10cSrcweir } 386cdf0e10cSrcweir 387cdf0e10cSrcweir return false; 388cdf0e10cSrcweir } 389cdf0e10cSrcweir 390cdf0e10cSrcweir // #i96475# 391cdf0e10cSrcweir // Added missing implementation. Decorations may (will) stick out of the text's 392cdf0e10cSrcweir // inking area, so add them if needed getB2DRange(const geometry::ViewInformation2D & rViewInformation) const393cdf0e10cSrcweir basegfx::B2DRange TextDecoratedPortionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 394cdf0e10cSrcweir { 395*693be7f6SArmin Le Grand if(decoratedIsNeeded()) 396cdf0e10cSrcweir { 397cdf0e10cSrcweir // decoration is used, fallback to BufferedDecompositionPrimitive2D::getB2DRange which uses 398cdf0e10cSrcweir // the own local decomposition for computation and thus creates all necessary 399cdf0e10cSrcweir // geometric objects 400cdf0e10cSrcweir return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); 401cdf0e10cSrcweir } 402cdf0e10cSrcweir else 403cdf0e10cSrcweir { 404cdf0e10cSrcweir // no relevant decoration used, fallback to TextSimplePortionPrimitive2D::getB2DRange 405cdf0e10cSrcweir return TextSimplePortionPrimitive2D::getB2DRange(rViewInformation); 406cdf0e10cSrcweir } 407cdf0e10cSrcweir } 408cdf0e10cSrcweir 409cdf0e10cSrcweir // provide unique ID 410cdf0e10cSrcweir ImplPrimitrive2DIDBlock(TextDecoratedPortionPrimitive2D, PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D) 411cdf0e10cSrcweir 412cdf0e10cSrcweir } // end of namespace primitive2d 413cdf0e10cSrcweir } // end of namespace drawinglayer 414cdf0e10cSrcweir 415cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 416cdf0e10cSrcweir // eof 417