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