xref: /AOO41X/main/drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx>
32*cdf0e10cSrcweir #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
33*cdf0e10cSrcweir #include <drawinglayer/primitive2d/textprimitive2d.hxx>
34*cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
35*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
36*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
37*cdf0e10cSrcweir #include <drawinglayer/attribute/lineattribute.hxx>
38*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
39*cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir namespace drawinglayer
44*cdf0e10cSrcweir {
45*cdf0e10cSrcweir 	namespace primitive2d
46*cdf0e10cSrcweir     {
47*cdf0e10cSrcweir         BaseTextStrikeoutPrimitive2D::BaseTextStrikeoutPrimitive2D(
48*cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectTransformation,
49*cdf0e10cSrcweir             double fWidth,
50*cdf0e10cSrcweir             const basegfx::BColor& rFontColor)
51*cdf0e10cSrcweir         :   BufferedDecompositionPrimitive2D(),
52*cdf0e10cSrcweir             maObjectTransformation(rObjectTransformation),
53*cdf0e10cSrcweir             mfWidth(fWidth),
54*cdf0e10cSrcweir             maFontColor(rFontColor)
55*cdf0e10cSrcweir         {
56*cdf0e10cSrcweir         }
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir         bool BaseTextStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
59*cdf0e10cSrcweir         {
60*cdf0e10cSrcweir 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
61*cdf0e10cSrcweir 			{
62*cdf0e10cSrcweir 				const BaseTextStrikeoutPrimitive2D& rCompare = (BaseTextStrikeoutPrimitive2D&)rPrimitive;
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir 				return (getObjectTransformation() == rCompare.getObjectTransformation()
65*cdf0e10cSrcweir                     && getWidth() == rCompare.getWidth()
66*cdf0e10cSrcweir                     && getFontColor() == rCompare.getFontColor());
67*cdf0e10cSrcweir 			}
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir 			return false;
70*cdf0e10cSrcweir         }
71*cdf0e10cSrcweir     } // end of namespace primitive2d
72*cdf0e10cSrcweir } // end of namespace drawinglayer
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir namespace drawinglayer
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir 	namespace primitive2d
79*cdf0e10cSrcweir 	{
80*cdf0e10cSrcweir         Primitive2DSequence TextCharacterStrikeoutPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
81*cdf0e10cSrcweir         {
82*cdf0e10cSrcweir             // strikeout with character
83*cdf0e10cSrcweir             const String aSingleCharString(getStrikeoutChar());
84*cdf0e10cSrcweir 			basegfx::B2DVector aScale, aTranslate;
85*cdf0e10cSrcweir 			double fRotate, fShearX;
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir             // get decomposition
88*cdf0e10cSrcweir 			getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir 			// prepare TextLayouter
91*cdf0e10cSrcweir 		    TextLayouterDevice aTextLayouter;
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir             aTextLayouter.setFontAttribute(
94*cdf0e10cSrcweir                 getFontAttribute(),
95*cdf0e10cSrcweir                 aScale.getX(),
96*cdf0e10cSrcweir                 aScale.getY(),
97*cdf0e10cSrcweir                 getLocale());
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir             const double fStrikeCharWidth(aTextLayouter.getTextWidth(aSingleCharString, 0, 1));
100*cdf0e10cSrcweir             const double fStrikeCharCount(fabs(getWidth()/fStrikeCharWidth));
101*cdf0e10cSrcweir             const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.5));
102*cdf0e10cSrcweir 			std::vector<double> aDXArray(nStrikeCharCount);
103*cdf0e10cSrcweir             String aStrikeoutString;
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir             for(sal_uInt32 a(0); a < nStrikeCharCount; a++)
106*cdf0e10cSrcweir             {
107*cdf0e10cSrcweir 	            aStrikeoutString += aSingleCharString;
108*cdf0e10cSrcweir 	            aDXArray[a] = (a + 1) * fStrikeCharWidth;
109*cdf0e10cSrcweir             }
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir             Primitive2DReference xReference(
112*cdf0e10cSrcweir                 new TextSimplePortionPrimitive2D(
113*cdf0e10cSrcweir                     getObjectTransformation(),
114*cdf0e10cSrcweir                     aStrikeoutString,
115*cdf0e10cSrcweir 			        0,
116*cdf0e10cSrcweir 			        aStrikeoutString.Len(),
117*cdf0e10cSrcweir                     aDXArray,
118*cdf0e10cSrcweir                     getFontAttribute(),
119*cdf0e10cSrcweir                     getLocale(),
120*cdf0e10cSrcweir                     getFontColor()));
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir             return Primitive2DSequence(&xReference, 1);
123*cdf0e10cSrcweir         }
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir         TextCharacterStrikeoutPrimitive2D::TextCharacterStrikeoutPrimitive2D(
126*cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectTransformation,
127*cdf0e10cSrcweir             double fWidth,
128*cdf0e10cSrcweir             const basegfx::BColor& rFontColor,
129*cdf0e10cSrcweir             sal_Unicode aStrikeoutChar,
130*cdf0e10cSrcweir             const attribute::FontAttribute& rFontAttribute,
131*cdf0e10cSrcweir             const ::com::sun::star::lang::Locale& rLocale)
132*cdf0e10cSrcweir         :   BaseTextStrikeoutPrimitive2D(rObjectTransformation, fWidth, rFontColor),
133*cdf0e10cSrcweir             maStrikeoutChar(aStrikeoutChar),
134*cdf0e10cSrcweir             maFontAttribute(rFontAttribute),
135*cdf0e10cSrcweir             maLocale(rLocale)
136*cdf0e10cSrcweir         {
137*cdf0e10cSrcweir         }
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir         bool TextCharacterStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
140*cdf0e10cSrcweir         {
141*cdf0e10cSrcweir 			if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive))
142*cdf0e10cSrcweir 			{
143*cdf0e10cSrcweir 				const TextCharacterStrikeoutPrimitive2D& rCompare = (TextCharacterStrikeoutPrimitive2D&)rPrimitive;
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir 				return (getStrikeoutChar() == rCompare.getStrikeoutChar()
146*cdf0e10cSrcweir                     && getFontAttribute() == rCompare.getFontAttribute()
147*cdf0e10cSrcweir                     && LocalesAreEqual(getLocale(), rCompare.getLocale()));
148*cdf0e10cSrcweir 			}
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir 			return false;
151*cdf0e10cSrcweir         }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 		// provide unique ID
154*cdf0e10cSrcweir 		ImplPrimitrive2DIDBlock(TextCharacterStrikeoutPrimitive2D, PRIMITIVE2D_ID_TEXTCHARACTERSTRIKEOUTPRIMITIVE2D)
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir     } // end of namespace primitive2d
157*cdf0e10cSrcweir } // end of namespace drawinglayer
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir namespace drawinglayer
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir 	namespace primitive2d
164*cdf0e10cSrcweir 	{
165*cdf0e10cSrcweir         Primitive2DSequence TextGeometryStrikeoutPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
166*cdf0e10cSrcweir         {
167*cdf0e10cSrcweir             OSL_ENSURE(TEXT_STRIKEOUT_SLASH != getTextStrikeout() && TEXT_STRIKEOUT_X != getTextStrikeout(),
168*cdf0e10cSrcweir                 "Wrong TEXT_STRIKEOUT type; a TextCharacterStrikeoutPrimitive2D should be used (!)");
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir             // strikeout with geometry
171*cdf0e10cSrcweir             double fStrikeoutHeight(getHeight());
172*cdf0e10cSrcweir             double fStrikeoutOffset(getOffset());
173*cdf0e10cSrcweir             bool bDoubleLine(false);
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 			// get decomposition
176*cdf0e10cSrcweir 			basegfx::B2DVector aScale, aTranslate;
177*cdf0e10cSrcweir 			double fRotate, fShearX;
178*cdf0e10cSrcweir 			getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir             // set line attribute
181*cdf0e10cSrcweir             switch(getTextStrikeout())
182*cdf0e10cSrcweir             {
183*cdf0e10cSrcweir                 default : // case primitive2d::TEXT_STRIKEOUT_SINGLE:
184*cdf0e10cSrcweir                 {
185*cdf0e10cSrcweir 		            break;
186*cdf0e10cSrcweir                 }
187*cdf0e10cSrcweir 	            case primitive2d::TEXT_STRIKEOUT_DOUBLE:
188*cdf0e10cSrcweir                 {
189*cdf0e10cSrcweir 		            bDoubleLine = true;
190*cdf0e10cSrcweir 		            break;
191*cdf0e10cSrcweir                 }
192*cdf0e10cSrcweir 	            case primitive2d::TEXT_STRIKEOUT_BOLD:
193*cdf0e10cSrcweir                 {
194*cdf0e10cSrcweir 		            fStrikeoutHeight *= 2.0;
195*cdf0e10cSrcweir 		            break;
196*cdf0e10cSrcweir                 }
197*cdf0e10cSrcweir             }
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir             if(bDoubleLine)
200*cdf0e10cSrcweir             {
201*cdf0e10cSrcweir 	            fStrikeoutOffset -= 0.50 * fStrikeoutHeight;
202*cdf0e10cSrcweir 	            fStrikeoutHeight *= 0.64;
203*cdf0e10cSrcweir             }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 		    // create base polygon and new primitive
206*cdf0e10cSrcweir             basegfx::B2DPolygon aStrikeoutLine;
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 		    aStrikeoutLine.append(basegfx::B2DPoint(0.0, -fStrikeoutOffset));
209*cdf0e10cSrcweir 	        aStrikeoutLine.append(basegfx::B2DPoint(getWidth(), -fStrikeoutOffset));
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir             const basegfx::B2DHomMatrix aUnscaledTransform(
212*cdf0e10cSrcweir                 basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
213*cdf0e10cSrcweir 					fShearX, fRotate, aTranslate));
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir             aStrikeoutLine.transform(aUnscaledTransform);
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir 			// add primitive
218*cdf0e10cSrcweir 	        const attribute::LineAttribute aLineAttribute(getFontColor(), fStrikeoutHeight, basegfx::B2DLINEJOIN_NONE);
219*cdf0e10cSrcweir             Primitive2DSequence xRetval(1);
220*cdf0e10cSrcweir             xRetval[0] = Primitive2DReference(new PolygonStrokePrimitive2D(aStrikeoutLine, aLineAttribute));
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir             if(bDoubleLine)
223*cdf0e10cSrcweir 		    {
224*cdf0e10cSrcweir 			    // double line, create 2nd primitive with offset using TransformPrimitive based on
225*cdf0e10cSrcweir 			    // already created NewPrimitive
226*cdf0e10cSrcweir 		        const double fLineDist(2.0 * fStrikeoutHeight);
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir 			    // move base point of text to 0.0 and de-rotate
229*cdf0e10cSrcweir                 basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
230*cdf0e10cSrcweir                     -aTranslate.getX(), -aTranslate.getY()));
231*cdf0e10cSrcweir 			    aTransform.rotate(-fRotate);
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 			    // translate in Y by offset
234*cdf0e10cSrcweir 			    aTransform.translate(0.0, -fLineDist);
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir 			    // move back and rotate
237*cdf0e10cSrcweir 			    aTransform.rotate(fRotate);
238*cdf0e10cSrcweir 			    aTransform.translate(aTranslate.getX(), aTranslate.getY());
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir 			    // add transform primitive
241*cdf0e10cSrcweir                 appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
242*cdf0e10cSrcweir                     Primitive2DReference(
243*cdf0e10cSrcweir                         new TransformPrimitive2D(
244*cdf0e10cSrcweir                             aTransform,
245*cdf0e10cSrcweir                             xRetval)));
246*cdf0e10cSrcweir 		    }
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir             return xRetval;
249*cdf0e10cSrcweir         }
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir         TextGeometryStrikeoutPrimitive2D::TextGeometryStrikeoutPrimitive2D(
252*cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectTransformation,
253*cdf0e10cSrcweir             double fWidth,
254*cdf0e10cSrcweir             const basegfx::BColor& rFontColor,
255*cdf0e10cSrcweir             double fHeight,
256*cdf0e10cSrcweir             double fOffset,
257*cdf0e10cSrcweir 		    TextStrikeout eTextStrikeout)
258*cdf0e10cSrcweir         :   BaseTextStrikeoutPrimitive2D(rObjectTransformation, fWidth, rFontColor),
259*cdf0e10cSrcweir             mfHeight(fHeight),
260*cdf0e10cSrcweir             mfOffset(fOffset),
261*cdf0e10cSrcweir             meTextStrikeout(eTextStrikeout)
262*cdf0e10cSrcweir         {
263*cdf0e10cSrcweir         }
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir 		bool TextGeometryStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
266*cdf0e10cSrcweir         {
267*cdf0e10cSrcweir 			if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive))
268*cdf0e10cSrcweir 			{
269*cdf0e10cSrcweir 				const TextGeometryStrikeoutPrimitive2D& rCompare = (TextGeometryStrikeoutPrimitive2D&)rPrimitive;
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir 				return (getHeight() == rCompare.getHeight()
272*cdf0e10cSrcweir                     && getOffset() == rCompare.getOffset()
273*cdf0e10cSrcweir                     && getTextStrikeout() == rCompare.getTextStrikeout());
274*cdf0e10cSrcweir 			}
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir 			return false;
277*cdf0e10cSrcweir         }
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir 		// provide unique ID
280*cdf0e10cSrcweir 		ImplPrimitrive2DIDBlock(TextGeometryStrikeoutPrimitive2D, PRIMITIVE2D_ID_TEXTGEOMETRYSTRIKEOUTPRIMITIVE2D)
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir     } // end of namespace primitive2d
283*cdf0e10cSrcweir } // end of namespace drawinglayer
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
286*cdf0e10cSrcweir // eof
287