1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_drawinglayer.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/textlineprimitive2d.hxx>
28*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
29*b1cdbd2cSJim Jagielski #include <drawinglayer/attribute/strokeattribute.hxx>
30*b1cdbd2cSJim Jagielski #include <drawinglayer/attribute/lineattribute.hxx>
31*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrixtools.hxx>
32*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
33*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski //////////////////////////////////////////////////////////////////////////////
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski namespace drawinglayer
38*b1cdbd2cSJim Jagielski {
39*b1cdbd2cSJim Jagielski 	namespace primitive2d
40*b1cdbd2cSJim Jagielski 	{
create2DDecomposition(const geometry::ViewInformation2D &) const41*b1cdbd2cSJim Jagielski 		Primitive2DSequence TextLinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
42*b1cdbd2cSJim Jagielski         {
43*b1cdbd2cSJim Jagielski             Primitive2DSequence xRetval;
44*b1cdbd2cSJim Jagielski 
45*b1cdbd2cSJim Jagielski             if(TEXT_LINE_NONE != getTextLine())
46*b1cdbd2cSJim Jagielski             {
47*b1cdbd2cSJim Jagielski                 bool bDoubleLine(false);
48*b1cdbd2cSJim Jagielski                 bool bWaveLine(false);
49*b1cdbd2cSJim Jagielski                 bool bBoldLine(false);
50*b1cdbd2cSJim Jagielski                 const int* pDotDashArray(0);
51*b1cdbd2cSJim Jagielski                 basegfx::B2DLineJoin eLineJoin(basegfx::B2DLINEJOIN_NONE);
52*b1cdbd2cSJim Jagielski                 double fOffset(getOffset());
53*b1cdbd2cSJim Jagielski                 double fHeight(getHeight());
54*b1cdbd2cSJim Jagielski 
55*b1cdbd2cSJim Jagielski                 static const int aDottedArray[]     = { 1, 1, 0};               // DOTTED LINE
56*b1cdbd2cSJim Jagielski                 static const int aDotDashArray[]    = { 1, 1, 4, 1, 0};         // DASHDOT
57*b1cdbd2cSJim Jagielski                 static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0};   // DASHDOTDOT
58*b1cdbd2cSJim Jagielski                 static const int aDashedArray[]     = { 5, 2, 0};               // DASHED LINE
59*b1cdbd2cSJim Jagielski                 static const int aLongDashArray[]   = { 7, 2, 0};               // LONGDASH
60*b1cdbd2cSJim Jagielski 
61*b1cdbd2cSJim Jagielski 				// get decomposition
62*b1cdbd2cSJim Jagielski 				basegfx::B2DVector aScale, aTranslate;
63*b1cdbd2cSJim Jagielski 				double fRotate, fShearX;
64*b1cdbd2cSJim Jagielski 				getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski                 switch(getTextLine())
67*b1cdbd2cSJim Jagielski                 {
68*b1cdbd2cSJim Jagielski                     default: // case TEXT_LINE_SINGLE:
69*b1cdbd2cSJim Jagielski                     {
70*b1cdbd2cSJim Jagielski                         break;
71*b1cdbd2cSJim Jagielski                     }
72*b1cdbd2cSJim Jagielski                     case TEXT_LINE_DOUBLE:
73*b1cdbd2cSJim Jagielski                     {
74*b1cdbd2cSJim Jagielski                         bDoubleLine = true;
75*b1cdbd2cSJim Jagielski                         break;
76*b1cdbd2cSJim Jagielski                     }
77*b1cdbd2cSJim Jagielski                     case TEXT_LINE_DOTTED:
78*b1cdbd2cSJim Jagielski                     {
79*b1cdbd2cSJim Jagielski                         pDotDashArray = aDottedArray;
80*b1cdbd2cSJim Jagielski                         break;
81*b1cdbd2cSJim Jagielski                     }
82*b1cdbd2cSJim Jagielski                     case TEXT_LINE_DASH:
83*b1cdbd2cSJim Jagielski                     {
84*b1cdbd2cSJim Jagielski                         pDotDashArray = aDashedArray;
85*b1cdbd2cSJim Jagielski                         break;
86*b1cdbd2cSJim Jagielski                     }
87*b1cdbd2cSJim Jagielski                     case TEXT_LINE_LONGDASH:
88*b1cdbd2cSJim Jagielski                     {
89*b1cdbd2cSJim Jagielski                         pDotDashArray = aLongDashArray;
90*b1cdbd2cSJim Jagielski                         break;
91*b1cdbd2cSJim Jagielski                     }
92*b1cdbd2cSJim Jagielski                     case TEXT_LINE_DASHDOT:
93*b1cdbd2cSJim Jagielski                     {
94*b1cdbd2cSJim Jagielski                         pDotDashArray = aDotDashArray;
95*b1cdbd2cSJim Jagielski                         break;
96*b1cdbd2cSJim Jagielski                     }
97*b1cdbd2cSJim Jagielski                     case TEXT_LINE_DASHDOTDOT:
98*b1cdbd2cSJim Jagielski                     {
99*b1cdbd2cSJim Jagielski                         pDotDashArray = aDashDotDotArray;
100*b1cdbd2cSJim Jagielski                         break;
101*b1cdbd2cSJim Jagielski                     }
102*b1cdbd2cSJim Jagielski                     case TEXT_LINE_SMALLWAVE:
103*b1cdbd2cSJim Jagielski                     {
104*b1cdbd2cSJim Jagielski                         bWaveLine = true;
105*b1cdbd2cSJim Jagielski                         break;
106*b1cdbd2cSJim Jagielski                     }
107*b1cdbd2cSJim Jagielski                     case TEXT_LINE_WAVE:
108*b1cdbd2cSJim Jagielski                     {
109*b1cdbd2cSJim Jagielski                         bWaveLine = true;
110*b1cdbd2cSJim Jagielski                         break;
111*b1cdbd2cSJim Jagielski                     }
112*b1cdbd2cSJim Jagielski                     case TEXT_LINE_DOUBLEWAVE:
113*b1cdbd2cSJim Jagielski                     {
114*b1cdbd2cSJim Jagielski                         bDoubleLine = true;
115*b1cdbd2cSJim Jagielski                         bWaveLine = true;
116*b1cdbd2cSJim Jagielski                         break;
117*b1cdbd2cSJim Jagielski                     }
118*b1cdbd2cSJim Jagielski                     case TEXT_LINE_BOLD:
119*b1cdbd2cSJim Jagielski                     {
120*b1cdbd2cSJim Jagielski                         bBoldLine = true;
121*b1cdbd2cSJim Jagielski                         break;
122*b1cdbd2cSJim Jagielski                     }
123*b1cdbd2cSJim Jagielski                     case TEXT_LINE_BOLDDOTTED:
124*b1cdbd2cSJim Jagielski                     {
125*b1cdbd2cSJim Jagielski                         bBoldLine = true;
126*b1cdbd2cSJim Jagielski                         pDotDashArray = aDottedArray;
127*b1cdbd2cSJim Jagielski                         break;
128*b1cdbd2cSJim Jagielski                     }
129*b1cdbd2cSJim Jagielski                     case TEXT_LINE_BOLDDASH:
130*b1cdbd2cSJim Jagielski                     {
131*b1cdbd2cSJim Jagielski                         bBoldLine = true;
132*b1cdbd2cSJim Jagielski                         pDotDashArray = aDashedArray;
133*b1cdbd2cSJim Jagielski                         break;
134*b1cdbd2cSJim Jagielski                     }
135*b1cdbd2cSJim Jagielski                     case TEXT_LINE_BOLDLONGDASH:
136*b1cdbd2cSJim Jagielski                     {
137*b1cdbd2cSJim Jagielski                         bBoldLine = true;
138*b1cdbd2cSJim Jagielski                         pDotDashArray = aLongDashArray;
139*b1cdbd2cSJim Jagielski                         break;
140*b1cdbd2cSJim Jagielski                     }
141*b1cdbd2cSJim Jagielski                     case TEXT_LINE_BOLDDASHDOT:
142*b1cdbd2cSJim Jagielski                     {
143*b1cdbd2cSJim Jagielski                         bBoldLine = true;
144*b1cdbd2cSJim Jagielski                         pDotDashArray = aDotDashArray;
145*b1cdbd2cSJim Jagielski                         break;
146*b1cdbd2cSJim Jagielski                     }
147*b1cdbd2cSJim Jagielski                     case TEXT_LINE_BOLDDASHDOTDOT:
148*b1cdbd2cSJim Jagielski                     {
149*b1cdbd2cSJim Jagielski                         bBoldLine = true;
150*b1cdbd2cSJim Jagielski                         pDotDashArray = aDashDotDotArray;
151*b1cdbd2cSJim Jagielski                         break;
152*b1cdbd2cSJim Jagielski                     }
153*b1cdbd2cSJim Jagielski                     case TEXT_LINE_BOLDWAVE:
154*b1cdbd2cSJim Jagielski                     {
155*b1cdbd2cSJim Jagielski                         bWaveLine = true;
156*b1cdbd2cSJim Jagielski                         bBoldLine = true;
157*b1cdbd2cSJim Jagielski                         break;
158*b1cdbd2cSJim Jagielski                     }
159*b1cdbd2cSJim Jagielski                 }
160*b1cdbd2cSJim Jagielski 
161*b1cdbd2cSJim Jagielski                 if(bBoldLine)
162*b1cdbd2cSJim Jagielski                 {
163*b1cdbd2cSJim Jagielski                     fHeight *= 2.0;
164*b1cdbd2cSJim Jagielski                 }
165*b1cdbd2cSJim Jagielski 
166*b1cdbd2cSJim Jagielski                 if(bDoubleLine)
167*b1cdbd2cSJim Jagielski                 {
168*b1cdbd2cSJim Jagielski                     fOffset -= 0.50 * fHeight;
169*b1cdbd2cSJim Jagielski                     fHeight *= 0.64;
170*b1cdbd2cSJim Jagielski                 }
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski                 if(bWaveLine)
173*b1cdbd2cSJim Jagielski                 {
174*b1cdbd2cSJim Jagielski                     eLineJoin = basegfx::B2DLINEJOIN_ROUND;
175*b1cdbd2cSJim Jagielski                     fHeight *= 0.25;
176*b1cdbd2cSJim Jagielski                 }
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski                 // prepare Line and Stroke Attributes
179*b1cdbd2cSJim Jagielski                 const attribute::LineAttribute aLineAttribute(getLineColor(), fHeight, eLineJoin);
180*b1cdbd2cSJim Jagielski                 attribute::StrokeAttribute aStrokeAttribute;
181*b1cdbd2cSJim Jagielski 
182*b1cdbd2cSJim Jagielski                 if(pDotDashArray)
183*b1cdbd2cSJim Jagielski                 {
184*b1cdbd2cSJim Jagielski                     ::std::vector< double > aDoubleArray;
185*b1cdbd2cSJim Jagielski 
186*b1cdbd2cSJim Jagielski                     for(const int* p = pDotDashArray; *p; ++p)
187*b1cdbd2cSJim Jagielski                     {
188*b1cdbd2cSJim Jagielski                         aDoubleArray.push_back((double)(*p) * fHeight);
189*b1cdbd2cSJim Jagielski                     }
190*b1cdbd2cSJim Jagielski 
191*b1cdbd2cSJim Jagielski                     aStrokeAttribute = attribute::StrokeAttribute(aDoubleArray);
192*b1cdbd2cSJim Jagielski                 }
193*b1cdbd2cSJim Jagielski 
194*b1cdbd2cSJim Jagielski                 // create base polygon and new primitive
195*b1cdbd2cSJim Jagielski                 basegfx::B2DPolygon aLine;
196*b1cdbd2cSJim Jagielski                 Primitive2DReference aNewPrimitive;
197*b1cdbd2cSJim Jagielski 
198*b1cdbd2cSJim Jagielski                 aLine.append(basegfx::B2DPoint(0.0, fOffset));
199*b1cdbd2cSJim Jagielski                 aLine.append(basegfx::B2DPoint(getWidth(), fOffset));
200*b1cdbd2cSJim Jagielski 
201*b1cdbd2cSJim Jagielski                 const basegfx::B2DHomMatrix aUnscaledTransform(
202*b1cdbd2cSJim Jagielski                     basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
203*b1cdbd2cSJim Jagielski     					fShearX, fRotate, aTranslate));
204*b1cdbd2cSJim Jagielski 
205*b1cdbd2cSJim Jagielski                 aLine.transform(aUnscaledTransform);
206*b1cdbd2cSJim Jagielski 
207*b1cdbd2cSJim Jagielski                 if(bWaveLine)
208*b1cdbd2cSJim Jagielski                 {
209*b1cdbd2cSJim Jagielski                     double fWaveWidth(10.6 * fHeight);
210*b1cdbd2cSJim Jagielski 
211*b1cdbd2cSJim Jagielski                     if(TEXT_LINE_SMALLWAVE == getTextLine())
212*b1cdbd2cSJim Jagielski                     {
213*b1cdbd2cSJim Jagielski                         fWaveWidth *= 0.7;
214*b1cdbd2cSJim Jagielski                     }
215*b1cdbd2cSJim Jagielski                     else if(TEXT_LINE_WAVE == getTextLine())
216*b1cdbd2cSJim Jagielski                     {
217*b1cdbd2cSJim Jagielski                         // extra multiply to get the same WaveWidth as with the bold version
218*b1cdbd2cSJim Jagielski                         fWaveWidth *= 2.0;
219*b1cdbd2cSJim Jagielski                     }
220*b1cdbd2cSJim Jagielski 
221*b1cdbd2cSJim Jagielski                     aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, fWaveWidth * 0.5));
222*b1cdbd2cSJim Jagielski                 }
223*b1cdbd2cSJim Jagielski                 else
224*b1cdbd2cSJim Jagielski                 {
225*b1cdbd2cSJim Jagielski                     aNewPrimitive = Primitive2DReference(new PolygonStrokePrimitive2D(aLine, aLineAttribute, aStrokeAttribute));
226*b1cdbd2cSJim Jagielski                 }
227*b1cdbd2cSJim Jagielski 
228*b1cdbd2cSJim Jagielski                 // add primitive
229*b1cdbd2cSJim Jagielski                 appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, aNewPrimitive);
230*b1cdbd2cSJim Jagielski 
231*b1cdbd2cSJim Jagielski                 if(bDoubleLine)
232*b1cdbd2cSJim Jagielski                 {
233*b1cdbd2cSJim Jagielski                     // double line, create 2nd primitive with offset using TransformPrimitive based on
234*b1cdbd2cSJim Jagielski                     // already created NewPrimitive
235*b1cdbd2cSJim Jagielski                     double fLineDist(2.3 * fHeight);
236*b1cdbd2cSJim Jagielski 
237*b1cdbd2cSJim Jagielski                     if(bWaveLine)
238*b1cdbd2cSJim Jagielski                     {
239*b1cdbd2cSJim Jagielski                         fLineDist = 6.3 * fHeight;
240*b1cdbd2cSJim Jagielski                     }
241*b1cdbd2cSJim Jagielski 
242*b1cdbd2cSJim Jagielski                     // move base point of text to 0.0 and de-rotate
243*b1cdbd2cSJim Jagielski                     basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
244*b1cdbd2cSJim Jagielski                         -aTranslate.getX(), -aTranslate.getY()));
245*b1cdbd2cSJim Jagielski                     aTransform.rotate(-fRotate);
246*b1cdbd2cSJim Jagielski 
247*b1cdbd2cSJim Jagielski                     // translate in Y by offset
248*b1cdbd2cSJim Jagielski                     aTransform.translate(0.0, fLineDist);
249*b1cdbd2cSJim Jagielski 
250*b1cdbd2cSJim Jagielski                     // move back and rotate
251*b1cdbd2cSJim Jagielski                     aTransform.rotate(fRotate);
252*b1cdbd2cSJim Jagielski                     aTransform.translate(aTranslate.getX(), aTranslate.getY());
253*b1cdbd2cSJim Jagielski 
254*b1cdbd2cSJim Jagielski                     // add transform primitive
255*b1cdbd2cSJim Jagielski                     const Primitive2DSequence aContent(&aNewPrimitive, 1);
256*b1cdbd2cSJim Jagielski                     appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
257*b1cdbd2cSJim Jagielski                         Primitive2DReference(new TransformPrimitive2D(aTransform, aContent)));
258*b1cdbd2cSJim Jagielski                 }
259*b1cdbd2cSJim Jagielski             }
260*b1cdbd2cSJim Jagielski 
261*b1cdbd2cSJim Jagielski             return xRetval;
262*b1cdbd2cSJim Jagielski         }
263*b1cdbd2cSJim Jagielski 
TextLinePrimitive2D(const basegfx::B2DHomMatrix & rObjectTransformation,double fWidth,double fOffset,double fHeight,TextLine eTextLine,const basegfx::BColor & rLineColor)264*b1cdbd2cSJim Jagielski         TextLinePrimitive2D::TextLinePrimitive2D(
265*b1cdbd2cSJim Jagielski             const basegfx::B2DHomMatrix& rObjectTransformation,
266*b1cdbd2cSJim Jagielski             double fWidth,
267*b1cdbd2cSJim Jagielski             double fOffset,
268*b1cdbd2cSJim Jagielski             double fHeight,
269*b1cdbd2cSJim Jagielski             TextLine eTextLine,
270*b1cdbd2cSJim Jagielski             const basegfx::BColor& rLineColor)
271*b1cdbd2cSJim Jagielski         :   BufferedDecompositionPrimitive2D(),
272*b1cdbd2cSJim Jagielski             maObjectTransformation(rObjectTransformation),
273*b1cdbd2cSJim Jagielski             mfWidth(fWidth),
274*b1cdbd2cSJim Jagielski             mfOffset(fOffset),
275*b1cdbd2cSJim Jagielski             mfHeight(fHeight),
276*b1cdbd2cSJim Jagielski             meTextLine(eTextLine),
277*b1cdbd2cSJim Jagielski             maLineColor(rLineColor)
278*b1cdbd2cSJim Jagielski         {
279*b1cdbd2cSJim Jagielski         }
280*b1cdbd2cSJim Jagielski 
operator ==(const BasePrimitive2D & rPrimitive) const281*b1cdbd2cSJim Jagielski 		bool TextLinePrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
282*b1cdbd2cSJim Jagielski         {
283*b1cdbd2cSJim Jagielski 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
284*b1cdbd2cSJim Jagielski 			{
285*b1cdbd2cSJim Jagielski 				const TextLinePrimitive2D& rCompare = (TextLinePrimitive2D&)rPrimitive;
286*b1cdbd2cSJim Jagielski 
287*b1cdbd2cSJim Jagielski 				return (getObjectTransformation() == rCompare.getObjectTransformation()
288*b1cdbd2cSJim Jagielski                     && getWidth() == rCompare.getWidth()
289*b1cdbd2cSJim Jagielski                     && getOffset() == rCompare.getOffset()
290*b1cdbd2cSJim Jagielski                     && getHeight() == rCompare.getHeight()
291*b1cdbd2cSJim Jagielski                     && getTextLine() == rCompare.getTextLine()
292*b1cdbd2cSJim Jagielski                     && getLineColor() == rCompare.getLineColor());
293*b1cdbd2cSJim Jagielski 			}
294*b1cdbd2cSJim Jagielski 
295*b1cdbd2cSJim Jagielski 			return false;
296*b1cdbd2cSJim Jagielski         }
297*b1cdbd2cSJim Jagielski 
298*b1cdbd2cSJim Jagielski 		// provide unique ID
299*b1cdbd2cSJim Jagielski 		ImplPrimitrive2DIDBlock(TextLinePrimitive2D, PRIMITIVE2D_ID_TEXTLINEPRIMITIVE2D)
300*b1cdbd2cSJim Jagielski 
301*b1cdbd2cSJim Jagielski     } // end of namespace primitive2d
302*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer
303*b1cdbd2cSJim Jagielski 
304*b1cdbd2cSJim Jagielski //////////////////////////////////////////////////////////////////////////////
305*b1cdbd2cSJim Jagielski // eof
306