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