1*464702f4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*464702f4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*464702f4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*464702f4SAndrew Rist  * distributed with this work for additional information
6*464702f4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*464702f4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*464702f4SAndrew Rist  * "License"); you may not use this file except in compliance
9*464702f4SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*464702f4SAndrew Rist  *
11*464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*464702f4SAndrew Rist  *
13*464702f4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*464702f4SAndrew Rist  * software distributed under the License is distributed on an
15*464702f4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*464702f4SAndrew Rist  * KIND, either express or implied.  See the License for the
17*464702f4SAndrew Rist  * specific language governing permissions and limitations
18*464702f4SAndrew Rist  * under the License.
19*464702f4SAndrew Rist  *
20*464702f4SAndrew Rist  *************************************************************/
21*464702f4SAndrew Rist 
22*464702f4SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx>
28cdf0e10cSrcweir #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
29cdf0e10cSrcweir #include <drawinglayer/primitive2d/textprimitive2d.hxx>
30cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
31cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
32cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
33cdf0e10cSrcweir #include <drawinglayer/attribute/lineattribute.hxx>
34cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
35cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
38cdf0e10cSrcweir 
39cdf0e10cSrcweir namespace drawinglayer
40cdf0e10cSrcweir {
41cdf0e10cSrcweir 	namespace primitive2d
42cdf0e10cSrcweir     {
BaseTextStrikeoutPrimitive2D(const basegfx::B2DHomMatrix & rObjectTransformation,double fWidth,const basegfx::BColor & rFontColor)43cdf0e10cSrcweir         BaseTextStrikeoutPrimitive2D::BaseTextStrikeoutPrimitive2D(
44cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectTransformation,
45cdf0e10cSrcweir             double fWidth,
46cdf0e10cSrcweir             const basegfx::BColor& rFontColor)
47cdf0e10cSrcweir         :   BufferedDecompositionPrimitive2D(),
48cdf0e10cSrcweir             maObjectTransformation(rObjectTransformation),
49cdf0e10cSrcweir             mfWidth(fWidth),
50cdf0e10cSrcweir             maFontColor(rFontColor)
51cdf0e10cSrcweir         {
52cdf0e10cSrcweir         }
53cdf0e10cSrcweir 
operator ==(const BasePrimitive2D & rPrimitive) const54cdf0e10cSrcweir         bool BaseTextStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
55cdf0e10cSrcweir         {
56cdf0e10cSrcweir 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
57cdf0e10cSrcweir 			{
58cdf0e10cSrcweir 				const BaseTextStrikeoutPrimitive2D& rCompare = (BaseTextStrikeoutPrimitive2D&)rPrimitive;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 				return (getObjectTransformation() == rCompare.getObjectTransformation()
61cdf0e10cSrcweir                     && getWidth() == rCompare.getWidth()
62cdf0e10cSrcweir                     && getFontColor() == rCompare.getFontColor());
63cdf0e10cSrcweir 			}
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 			return false;
66cdf0e10cSrcweir         }
67cdf0e10cSrcweir     } // end of namespace primitive2d
68cdf0e10cSrcweir } // end of namespace drawinglayer
69cdf0e10cSrcweir 
70cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
71cdf0e10cSrcweir 
72cdf0e10cSrcweir namespace drawinglayer
73cdf0e10cSrcweir {
74cdf0e10cSrcweir 	namespace primitive2d
75cdf0e10cSrcweir 	{
create2DDecomposition(const geometry::ViewInformation2D &) const76cdf0e10cSrcweir         Primitive2DSequence TextCharacterStrikeoutPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
77cdf0e10cSrcweir         {
78cdf0e10cSrcweir             // strikeout with character
79cdf0e10cSrcweir             const String aSingleCharString(getStrikeoutChar());
80cdf0e10cSrcweir 			basegfx::B2DVector aScale, aTranslate;
81cdf0e10cSrcweir 			double fRotate, fShearX;
82cdf0e10cSrcweir 
83cdf0e10cSrcweir             // get decomposition
84cdf0e10cSrcweir 			getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
85cdf0e10cSrcweir 
86cdf0e10cSrcweir 			// prepare TextLayouter
87cdf0e10cSrcweir 		    TextLayouterDevice aTextLayouter;
88cdf0e10cSrcweir 
89cdf0e10cSrcweir             aTextLayouter.setFontAttribute(
90cdf0e10cSrcweir                 getFontAttribute(),
91cdf0e10cSrcweir                 aScale.getX(),
92cdf0e10cSrcweir                 aScale.getY(),
93cdf0e10cSrcweir                 getLocale());
94cdf0e10cSrcweir 
95cdf0e10cSrcweir             const double fStrikeCharWidth(aTextLayouter.getTextWidth(aSingleCharString, 0, 1));
96cdf0e10cSrcweir             const double fStrikeCharCount(fabs(getWidth()/fStrikeCharWidth));
97cdf0e10cSrcweir             const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.5));
98cdf0e10cSrcweir 			std::vector<double> aDXArray(nStrikeCharCount);
99cdf0e10cSrcweir             String aStrikeoutString;
100cdf0e10cSrcweir 
101cdf0e10cSrcweir             for(sal_uInt32 a(0); a < nStrikeCharCount; a++)
102cdf0e10cSrcweir             {
103cdf0e10cSrcweir 	            aStrikeoutString += aSingleCharString;
104cdf0e10cSrcweir 	            aDXArray[a] = (a + 1) * fStrikeCharWidth;
105cdf0e10cSrcweir             }
106cdf0e10cSrcweir 
107cdf0e10cSrcweir             Primitive2DReference xReference(
108cdf0e10cSrcweir                 new TextSimplePortionPrimitive2D(
109cdf0e10cSrcweir                     getObjectTransformation(),
110cdf0e10cSrcweir                     aStrikeoutString,
111cdf0e10cSrcweir 			        0,
112cdf0e10cSrcweir 			        aStrikeoutString.Len(),
113cdf0e10cSrcweir                     aDXArray,
114cdf0e10cSrcweir                     getFontAttribute(),
115cdf0e10cSrcweir                     getLocale(),
116cdf0e10cSrcweir                     getFontColor()));
117cdf0e10cSrcweir 
118cdf0e10cSrcweir             return Primitive2DSequence(&xReference, 1);
119cdf0e10cSrcweir         }
120cdf0e10cSrcweir 
TextCharacterStrikeoutPrimitive2D(const basegfx::B2DHomMatrix & rObjectTransformation,double fWidth,const basegfx::BColor & rFontColor,sal_Unicode aStrikeoutChar,const attribute::FontAttribute & rFontAttribute,const::com::sun::star::lang::Locale & rLocale)121cdf0e10cSrcweir         TextCharacterStrikeoutPrimitive2D::TextCharacterStrikeoutPrimitive2D(
122cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectTransformation,
123cdf0e10cSrcweir             double fWidth,
124cdf0e10cSrcweir             const basegfx::BColor& rFontColor,
125cdf0e10cSrcweir             sal_Unicode aStrikeoutChar,
126cdf0e10cSrcweir             const attribute::FontAttribute& rFontAttribute,
127cdf0e10cSrcweir             const ::com::sun::star::lang::Locale& rLocale)
128cdf0e10cSrcweir         :   BaseTextStrikeoutPrimitive2D(rObjectTransformation, fWidth, rFontColor),
129cdf0e10cSrcweir             maStrikeoutChar(aStrikeoutChar),
130cdf0e10cSrcweir             maFontAttribute(rFontAttribute),
131cdf0e10cSrcweir             maLocale(rLocale)
132cdf0e10cSrcweir         {
133cdf0e10cSrcweir         }
134cdf0e10cSrcweir 
operator ==(const BasePrimitive2D & rPrimitive) const135cdf0e10cSrcweir         bool TextCharacterStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
136cdf0e10cSrcweir         {
137cdf0e10cSrcweir 			if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive))
138cdf0e10cSrcweir 			{
139cdf0e10cSrcweir 				const TextCharacterStrikeoutPrimitive2D& rCompare = (TextCharacterStrikeoutPrimitive2D&)rPrimitive;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 				return (getStrikeoutChar() == rCompare.getStrikeoutChar()
142cdf0e10cSrcweir                     && getFontAttribute() == rCompare.getFontAttribute()
143cdf0e10cSrcweir                     && LocalesAreEqual(getLocale(), rCompare.getLocale()));
144cdf0e10cSrcweir 			}
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 			return false;
147cdf0e10cSrcweir         }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 		// provide unique ID
150cdf0e10cSrcweir 		ImplPrimitrive2DIDBlock(TextCharacterStrikeoutPrimitive2D, PRIMITIVE2D_ID_TEXTCHARACTERSTRIKEOUTPRIMITIVE2D)
151cdf0e10cSrcweir 
152cdf0e10cSrcweir     } // end of namespace primitive2d
153cdf0e10cSrcweir } // end of namespace drawinglayer
154cdf0e10cSrcweir 
155cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
156cdf0e10cSrcweir 
157cdf0e10cSrcweir namespace drawinglayer
158cdf0e10cSrcweir {
159cdf0e10cSrcweir 	namespace primitive2d
160cdf0e10cSrcweir 	{
create2DDecomposition(const geometry::ViewInformation2D &) const161cdf0e10cSrcweir         Primitive2DSequence TextGeometryStrikeoutPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
162cdf0e10cSrcweir         {
163cdf0e10cSrcweir             OSL_ENSURE(TEXT_STRIKEOUT_SLASH != getTextStrikeout() && TEXT_STRIKEOUT_X != getTextStrikeout(),
164cdf0e10cSrcweir                 "Wrong TEXT_STRIKEOUT type; a TextCharacterStrikeoutPrimitive2D should be used (!)");
165cdf0e10cSrcweir 
166cdf0e10cSrcweir             // strikeout with geometry
167cdf0e10cSrcweir             double fStrikeoutHeight(getHeight());
168cdf0e10cSrcweir             double fStrikeoutOffset(getOffset());
169cdf0e10cSrcweir             bool bDoubleLine(false);
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 			// get decomposition
172cdf0e10cSrcweir 			basegfx::B2DVector aScale, aTranslate;
173cdf0e10cSrcweir 			double fRotate, fShearX;
174cdf0e10cSrcweir 			getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
175cdf0e10cSrcweir 
176cdf0e10cSrcweir             // set line attribute
177cdf0e10cSrcweir             switch(getTextStrikeout())
178cdf0e10cSrcweir             {
179cdf0e10cSrcweir                 default : // case primitive2d::TEXT_STRIKEOUT_SINGLE:
180cdf0e10cSrcweir                 {
181cdf0e10cSrcweir 		            break;
182cdf0e10cSrcweir                 }
183cdf0e10cSrcweir 	            case primitive2d::TEXT_STRIKEOUT_DOUBLE:
184cdf0e10cSrcweir                 {
185cdf0e10cSrcweir 		            bDoubleLine = true;
186cdf0e10cSrcweir 		            break;
187cdf0e10cSrcweir                 }
188cdf0e10cSrcweir 	            case primitive2d::TEXT_STRIKEOUT_BOLD:
189cdf0e10cSrcweir                 {
190cdf0e10cSrcweir 		            fStrikeoutHeight *= 2.0;
191cdf0e10cSrcweir 		            break;
192cdf0e10cSrcweir                 }
193cdf0e10cSrcweir             }
194cdf0e10cSrcweir 
195cdf0e10cSrcweir             if(bDoubleLine)
196cdf0e10cSrcweir             {
197cdf0e10cSrcweir 	            fStrikeoutOffset -= 0.50 * fStrikeoutHeight;
198cdf0e10cSrcweir 	            fStrikeoutHeight *= 0.64;
199cdf0e10cSrcweir             }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 		    // create base polygon and new primitive
202cdf0e10cSrcweir             basegfx::B2DPolygon aStrikeoutLine;
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 		    aStrikeoutLine.append(basegfx::B2DPoint(0.0, -fStrikeoutOffset));
205cdf0e10cSrcweir 	        aStrikeoutLine.append(basegfx::B2DPoint(getWidth(), -fStrikeoutOffset));
206cdf0e10cSrcweir 
207cdf0e10cSrcweir             const basegfx::B2DHomMatrix aUnscaledTransform(
208cdf0e10cSrcweir                 basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
209cdf0e10cSrcweir 					fShearX, fRotate, aTranslate));
210cdf0e10cSrcweir 
211cdf0e10cSrcweir             aStrikeoutLine.transform(aUnscaledTransform);
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 			// add primitive
214cdf0e10cSrcweir 	        const attribute::LineAttribute aLineAttribute(getFontColor(), fStrikeoutHeight, basegfx::B2DLINEJOIN_NONE);
215cdf0e10cSrcweir             Primitive2DSequence xRetval(1);
216cdf0e10cSrcweir             xRetval[0] = Primitive2DReference(new PolygonStrokePrimitive2D(aStrikeoutLine, aLineAttribute));
217cdf0e10cSrcweir 
218cdf0e10cSrcweir             if(bDoubleLine)
219cdf0e10cSrcweir 		    {
220cdf0e10cSrcweir 			    // double line, create 2nd primitive with offset using TransformPrimitive based on
221cdf0e10cSrcweir 			    // already created NewPrimitive
222cdf0e10cSrcweir 		        const double fLineDist(2.0 * fStrikeoutHeight);
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 			    // move base point of text to 0.0 and de-rotate
225cdf0e10cSrcweir                 basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
226cdf0e10cSrcweir                     -aTranslate.getX(), -aTranslate.getY()));
227cdf0e10cSrcweir 			    aTransform.rotate(-fRotate);
228cdf0e10cSrcweir 
229cdf0e10cSrcweir 			    // translate in Y by offset
230cdf0e10cSrcweir 			    aTransform.translate(0.0, -fLineDist);
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 			    // move back and rotate
233cdf0e10cSrcweir 			    aTransform.rotate(fRotate);
234cdf0e10cSrcweir 			    aTransform.translate(aTranslate.getX(), aTranslate.getY());
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 			    // add transform primitive
237cdf0e10cSrcweir                 appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
238cdf0e10cSrcweir                     Primitive2DReference(
239cdf0e10cSrcweir                         new TransformPrimitive2D(
240cdf0e10cSrcweir                             aTransform,
241cdf0e10cSrcweir                             xRetval)));
242cdf0e10cSrcweir 		    }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir             return xRetval;
245cdf0e10cSrcweir         }
246cdf0e10cSrcweir 
TextGeometryStrikeoutPrimitive2D(const basegfx::B2DHomMatrix & rObjectTransformation,double fWidth,const basegfx::BColor & rFontColor,double fHeight,double fOffset,TextStrikeout eTextStrikeout)247cdf0e10cSrcweir         TextGeometryStrikeoutPrimitive2D::TextGeometryStrikeoutPrimitive2D(
248cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectTransformation,
249cdf0e10cSrcweir             double fWidth,
250cdf0e10cSrcweir             const basegfx::BColor& rFontColor,
251cdf0e10cSrcweir             double fHeight,
252cdf0e10cSrcweir             double fOffset,
253cdf0e10cSrcweir 		    TextStrikeout eTextStrikeout)
254cdf0e10cSrcweir         :   BaseTextStrikeoutPrimitive2D(rObjectTransformation, fWidth, rFontColor),
255cdf0e10cSrcweir             mfHeight(fHeight),
256cdf0e10cSrcweir             mfOffset(fOffset),
257cdf0e10cSrcweir             meTextStrikeout(eTextStrikeout)
258cdf0e10cSrcweir         {
259cdf0e10cSrcweir         }
260cdf0e10cSrcweir 
operator ==(const BasePrimitive2D & rPrimitive) const261cdf0e10cSrcweir 		bool TextGeometryStrikeoutPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
262cdf0e10cSrcweir         {
263cdf0e10cSrcweir 			if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive))
264cdf0e10cSrcweir 			{
265cdf0e10cSrcweir 				const TextGeometryStrikeoutPrimitive2D& rCompare = (TextGeometryStrikeoutPrimitive2D&)rPrimitive;
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 				return (getHeight() == rCompare.getHeight()
268cdf0e10cSrcweir                     && getOffset() == rCompare.getOffset()
269cdf0e10cSrcweir                     && getTextStrikeout() == rCompare.getTextStrikeout());
270cdf0e10cSrcweir 			}
271cdf0e10cSrcweir 
272cdf0e10cSrcweir 			return false;
273cdf0e10cSrcweir         }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 		// provide unique ID
276cdf0e10cSrcweir 		ImplPrimitrive2DIDBlock(TextGeometryStrikeoutPrimitive2D, PRIMITIVE2D_ID_TEXTGEOMETRYSTRIKEOUTPRIMITIVE2D)
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     } // end of namespace primitive2d
279cdf0e10cSrcweir } // end of namespace drawinglayer
280cdf0e10cSrcweir 
281cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
282cdf0e10cSrcweir // eof
283