1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_drawinglayer.hxx"
26 
27 #include <drawinglayer/processor2d/textaspolygonextractor2d.hxx>
28 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
29 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
30 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
31 #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
32 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
33 
34 //////////////////////////////////////////////////////////////////////////////
35 
36 namespace drawinglayer
37 {
38 	namespace processor2d
39 	{
40 		void TextAsPolygonExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
41 		{
42 			switch(rCandidate.getPrimitive2DID())
43 			{
44 				case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D :
45 				{
46 					// TextDecoratedPortionPrimitive2D can produce the following primitives
47 					// when being decomposed:
48 					//
49 					// - TextSimplePortionPrimitive2D
50 					// - PolygonWavePrimitive2D
51 					//		- PolygonStrokePrimitive2D
52 					// - PolygonStrokePrimitive2D
53 					//		- PolyPolygonColorPrimitive2D
54 					//		- PolyPolygonHairlinePrimitive2D
55 					//			- PolygonHairlinePrimitive2D
56 					// - ShadowPrimitive2D
57 					//		- ModifiedColorPrimitive2D
58 					//		- TransformPrimitive2D
59 					// - TextEffectPrimitive2D
60 					//		- ModifiedColorPrimitive2D
61 					//		- TransformPrimitive2D
62 					//		- GroupPrimitive2D
63 
64 					// encapsulate with flag and use decomposition
65 					mnInText++;
66 					process(rCandidate.get2DDecomposition(getViewInformation2D()));
67 					mnInText--;
68 
69 					break;
70 				}
71 				case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
72 				{
73 					// TextSimplePortionPrimitive2D can produce the following primitives
74 					// when being decomposed:
75 					//
76 					// - PolyPolygonColorPrimitive2D
77 					// - TextEffectPrimitive2D
78 					//		- ModifiedColorPrimitive2D
79 					//		- TransformPrimitive2D
80 					//		- GroupPrimitive2D
81 
82 					// encapsulate with flag and use decomposition
83 					mnInText++;
84 					process(rCandidate.get2DDecomposition(getViewInformation2D()));
85 					mnInText--;
86 
87 					break;
88 				}
89 
90 				// as can be seen from the TextSimplePortionPrimitive2D and the
91 				// TextDecoratedPortionPrimitive2D, inside of the mnInText marks
92 				// the following primitives can occurr containing geometry data
93 				// from text decomposition:
94 				//
95 				// - PolyPolygonColorPrimitive2D
96 				// - PolygonHairlinePrimitive2D
97 				// - PolyPolygonHairlinePrimitive2D (for convenience)
98 				//
99 				case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
100 				{
101 					if(mnInText)
102 					{
103 						const primitive2d::PolyPolygonColorPrimitive2D& rPoPoCoCandidate(static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate));
104 						basegfx::B2DPolyPolygon aPolyPolygon(rPoPoCoCandidate.getB2DPolyPolygon());
105 
106 						if(aPolyPolygon.count())
107 						{
108 							// transform the PolyPolygon
109 							aPolyPolygon.transform(getViewInformation2D().getObjectToViewTransformation());
110 
111 							// get evtl. corrected color
112 							const basegfx::BColor aColor(maBColorModifierStack.getModifiedColor(rPoPoCoCandidate.getBColor()));
113 
114 							// add to result vector
115 							maTarget.push_back(TextAsPolygonDataNode(aPolyPolygon, aColor, true));
116 						}
117 					}
118 
119 					break;
120 				}
121 				case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
122 				{
123 					if(mnInText)
124 					{
125 						const primitive2d::PolygonHairlinePrimitive2D& rPoHaCandidate(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate));
126 						basegfx::B2DPolygon aPolygon(rPoHaCandidate.getB2DPolygon());
127 
128 						if(aPolygon.count())
129 						{
130 							// transform the Polygon
131 							aPolygon.transform(getViewInformation2D().getObjectToViewTransformation());
132 
133 							// get evtl. corrected color
134 							const basegfx::BColor aColor(maBColorModifierStack.getModifiedColor(rPoHaCandidate.getBColor()));
135 
136 							// add to result vector
137 							maTarget.push_back(TextAsPolygonDataNode(basegfx::B2DPolyPolygon(aPolygon), aColor, false));
138 						}
139 					}
140 
141 					break;
142 				}
143 				case PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D :
144 				{
145 					if(mnInText)
146 					{
147 						const primitive2d::PolyPolygonHairlinePrimitive2D& rPoPoHaCandidate(static_cast< const primitive2d::PolyPolygonHairlinePrimitive2D& >(rCandidate));
148 						basegfx::B2DPolyPolygon aPolyPolygon(rPoPoHaCandidate.getB2DPolyPolygon());
149 
150 						if(aPolyPolygon.count())
151 						{
152 							// transform the Polygon
153 							aPolyPolygon.transform(getViewInformation2D().getObjectToViewTransformation());
154 
155 							// get evtl. corrected color
156 							const basegfx::BColor aColor(maBColorModifierStack.getModifiedColor(rPoPoHaCandidate.getBColor()));
157 
158 							// add to result vector
159 							maTarget.push_back(TextAsPolygonDataNode(aPolyPolygon, aColor, false));
160 						}
161 					}
162 
163 					break;
164 				}
165 
166 				// usage of color modification stack is needed
167 				case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D :
168 				{
169 					const primitive2d::ModifiedColorPrimitive2D& rModifiedColorCandidate(static_cast< const primitive2d::ModifiedColorPrimitive2D& >(rCandidate));
170 
171 					if(rModifiedColorCandidate.getChildren().hasElements())
172 					{
173 						maBColorModifierStack.push(rModifiedColorCandidate.getColorModifier());
174 						process(rModifiedColorCandidate.getChildren());
175 						maBColorModifierStack.pop();
176 					}
177 
178 					break;
179 				}
180 
181 				// usage of transformation stack is needed
182 				case PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D :
183 				{
184 					// remember current transformation and ViewInformation
185 					const primitive2d::TransformPrimitive2D& rTransformCandidate(static_cast< const primitive2d::TransformPrimitive2D& >(rCandidate));
186 					const geometry::ViewInformation2D aLastViewInformation2D(getViewInformation2D());
187 
188 					// create new transformations for CurrentTransformation and for local ViewInformation2D
189 					const geometry::ViewInformation2D aViewInformation2D(
190 						getViewInformation2D().getObjectTransformation() * rTransformCandidate.getTransformation(),
191 						getViewInformation2D().getViewTransformation(),
192 						getViewInformation2D().getViewport(),
193 						getViewInformation2D().getVisualizedPage(),
194 						getViewInformation2D().getViewTime(),
195 						getViewInformation2D().getExtendedInformationSequence());
196 					updateViewInformation(aViewInformation2D);
197 
198 					// proccess content
199 					process(rTransformCandidate.getChildren());
200 
201 					// restore transformations
202 					updateViewInformation(aLastViewInformation2D);
203 
204 					break;
205 				}
206 
207 				// ignorable primitives
208 				case PRIMITIVE2D_ID_SCENEPRIMITIVE2D :
209                 case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
210 				case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
211 				case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
212 				case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
213 				case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
214 				case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
215                 {
216 					break;
217 				}
218 
219 				default :
220 				{
221 					// process recursively
222 					process(rCandidate.get2DDecomposition(getViewInformation2D()));
223 					break;
224 				}
225 			}
226 		}
227 
228 		TextAsPolygonExtractor2D::TextAsPolygonExtractor2D(const geometry::ViewInformation2D& rViewInformation)
229 		:	BaseProcessor2D(rViewInformation),
230 			maTarget(),
231 			maBColorModifierStack(),
232 			mnInText(0)
233 		{
234 		}
235 
236 		TextAsPolygonExtractor2D::~TextAsPolygonExtractor2D()
237 		{
238 		}
239 	} // end of namespace processor2d
240 } // end of namespace drawinglayer
241 
242 //////////////////////////////////////////////////////////////////////////////
243 // eof
244