Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef _CPPCANVAS_IMPLRENDERER_HXX
21 : #define _CPPCANVAS_IMPLRENDERER_HXX
22 :
23 : #include <sal/types.h>
24 :
25 : #include <boost/shared_ptr.hpp>
26 : #include <cppcanvas/renderer.hxx>
27 : #include <cppcanvas/canvas.hxx>
28 :
29 : #include <canvasgraphichelper.hxx>
30 : #include <action.hxx>
31 : #include <outdevstate.hxx>
32 :
33 : #include <vector>
34 : #include <map>
35 :
36 : class GDIMetaFile;
37 : class VirtualDevice;
38 : class Gradient;
39 : class Rectangle;
40 : class Font;
41 : class PolyPolygon;
42 : class Point;
43 : class MetaCommentAction;
44 :
45 : namespace basegfx {
46 : class B2DPolyPolygon;
47 : class B2DPolygon;
48 : }
49 :
50 : namespace cppcanvas
51 : {
52 :
53 : namespace internal
54 : {
55 : struct OutDevState;
56 : struct ActionFactoryParameters;
57 : struct XForm;
58 :
59 0 : struct EMFPObject
60 : {
61 0 : virtual ~EMFPObject() {}
62 : };
63 :
64 : // state stack of OutputDevice, to correctly handle
65 : // push/pop actions
66 0 : class VectorOfOutDevStates
67 : {
68 : public:
69 : OutDevState& getState();
70 : const OutDevState& getState() const;
71 : void pushState(sal_uInt16 nFlags);
72 : void popState();
73 : void clearStateStack();
74 : private:
75 : ::std::vector< OutDevState > m_aStates;
76 : };
77 :
78 : // EMF+
79 : // TODO: replace?
80 : struct XForm
81 : {
82 : float eM11;
83 : float eM12;
84 : float eM21;
85 : float eM22;
86 : float eDx;
87 : float eDy;
88 0 : XForm()
89 : {
90 0 : SetIdentity ();
91 0 : };
92 :
93 0 : void SetIdentity ()
94 : {
95 0 : eM11 = eM22 = 1.0f;
96 0 : eDx = eDy = eM12 = eM21 = 0.0f;
97 0 : }
98 :
99 : void Set (float m11, float m12, float dx, float m21, float m22, float dy)
100 : {
101 : eM11 = m11;
102 : eM12 = m12;
103 : eDx = dx;
104 : eM21 = m21;
105 : eM22 = m22;
106 : eDy = dy;
107 : }
108 :
109 0 : void Set (XForm f)
110 : {
111 0 : eM11 = f.eM11;
112 0 : eM12 = f.eM12;
113 0 : eM21 = f.eM21;
114 0 : eM22 = f.eM22;
115 0 : eDx = f.eDx;
116 0 : eDy = f.eDy;
117 0 : }
118 :
119 : void Multiply (float m11, float m12, float dx, float m21, float m22, float dy)
120 : {
121 : eM11 = eM11*m11 + eM12*m21;
122 : eM12 = eM11*m12 + eM12*m22;
123 : eM21 = eM21*m11 + eM22*m21;
124 : eM22 = eM21*m12 + eM22*m22;
125 : eDx *= eDx*m11 + eDy*m21 + dx;
126 : eDy *= eDx*m12 + eDy*m22 + dy;
127 : }
128 :
129 0 : void Multiply (XForm f)
130 : {
131 0 : eM11 = eM11*f.eM11 + eM12*f.eM21;
132 0 : eM12 = eM11*f.eM12 + eM12*f.eM22;
133 0 : eM21 = eM21*f.eM11 + eM22*f.eM21;
134 0 : eM22 = eM21*f.eM12 + eM22*f.eM22;
135 0 : eDx *= eDx*f.eM11 + eDy*f.eM21 + f.eDx;
136 0 : eDy *= eDx*f.eM12 + eDy*f.eM22 + f.eDy;
137 0 : }
138 :
139 : #ifdef OSL_BIGENDIAN
140 : // currently unused
141 : static float GetSwapFloat( SvStream& rSt )
142 : {
143 : float fTmp;
144 : sal_Int8* pPtr = (sal_Int8*)&fTmp;
145 : rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch
146 : return fTmp;
147 : }
148 : #endif
149 :
150 0 : friend SvStream& operator>>( SvStream& rIn, XForm& rXForm )
151 : {
152 : if ( sizeof( float ) != 4 )
153 : {
154 : OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
155 : rXForm = XForm();
156 : }
157 : else
158 : {
159 : #ifdef OSL_BIGENDIAN
160 : rXForm.eM11 = GetSwapFloat( rIn );
161 : rXForm.eM12 = GetSwapFloat( rIn );
162 : rXForm.eM21 = GetSwapFloat( rIn );
163 : rXForm.eM22 = GetSwapFloat( rIn );
164 : rXForm.eDx = GetSwapFloat( rIn );
165 : rXForm.eDy = GetSwapFloat( rIn );
166 : #else
167 0 : rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22
168 0 : >> rXForm.eDx >> rXForm.eDy;
169 : #endif
170 : }
171 0 : return rIn;
172 : }
173 : };
174 :
175 : // EMF+
176 0 : typedef struct {
177 : XForm aWorldTransform;
178 : OutDevState aDevState;
179 0 : } EmfPlusGraphicState;
180 :
181 : typedef ::std::map<int,EmfPlusGraphicState> GraphicStateMap;
182 :
183 : class ImplRenderer : public virtual Renderer, protected CanvasGraphicHelper
184 : {
185 : public:
186 : ImplRenderer( const CanvasSharedPtr& rCanvas,
187 : const GDIMetaFile& rMtf,
188 : const Parameters& rParms );
189 :
190 : virtual ~ImplRenderer();
191 :
192 : virtual bool draw() const;
193 : virtual bool drawSubset( sal_Int32 nStartIndex,
194 : sal_Int32 nEndIndex ) const;
195 : virtual ::basegfx::B2DRange getSubsetArea( sal_Int32 nStartIndex,
196 : sal_Int32 nEndIndex ) const;
197 :
198 :
199 : // element of the Renderer's action vector. Need to be
200 : // public, since some functors need it, too.
201 0 : struct MtfAction
202 : {
203 0 : MtfAction( const ActionSharedPtr& rAction,
204 : sal_Int32 nOrigIndex ) :
205 : mpAction( rAction ),
206 0 : mnOrigIndex( nOrigIndex )
207 : {
208 0 : }
209 :
210 : ActionSharedPtr mpAction;
211 : sal_Int32 mnOrigIndex;
212 : };
213 :
214 : // prefetched and prepared canvas actions
215 : // (externally not visible)
216 : typedef ::std::vector< MtfAction > ActionVector;
217 :
218 : /* EMF+ */
219 : void ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false);
220 : void ReadPoint (SvStream& s, float& x, float& y, sal_uInt32 flags);
221 : void MapToDevice (double &x, double &y);
222 : ::basegfx::B2DPoint Map (double ix, double iy);
223 : ::basegfx::B2DSize MapSize (double iwidth, double iheight);
224 : void GraphicStatePush (GraphicStateMap& map, sal_Int32 index, OutDevState& rState);
225 : void GraphicStatePop (GraphicStateMap& map, sal_Int32 index, OutDevState& rState);
226 :
227 : private:
228 : // default: disabled copy/assignment
229 : ImplRenderer(const ImplRenderer&);
230 : ImplRenderer& operator=( const ImplRenderer& );
231 :
232 : void updateClipping( const ::basegfx::B2DPolyPolygon& rClipPoly,
233 : const ActionFactoryParameters& rParms,
234 : bool bIntersect );
235 :
236 : void updateClipping( const ::Rectangle& rClipRect,
237 : const ActionFactoryParameters& rParms,
238 : bool bIntersect );
239 :
240 : ::com::sun::star::uno::Reference<
241 : ::com::sun::star::rendering::XCanvasFont > createFont( double& o_rFontRotation,
242 : const ::Font& rFont,
243 : const ActionFactoryParameters& rParms ) const;
244 : bool createActions( GDIMetaFile& rMtf,
245 : const ActionFactoryParameters& rParms,
246 : bool bSubsettableActions );
247 : bool createFillAndStroke( const ::basegfx::B2DPolyPolygon& rPolyPoly,
248 : const ActionFactoryParameters& rParms );
249 : bool createFillAndStroke( const ::basegfx::B2DPolygon& rPoly,
250 : const ActionFactoryParameters& rParms );
251 : void skipContent( GDIMetaFile& rMtf,
252 : const char* pCommentString,
253 : sal_Int32& io_rCurrActionIndex ) const;
254 :
255 : bool isActionContained( GDIMetaFile& rMtf,
256 : const char* pCommentString,
257 : sal_uInt16 nType ) const;
258 :
259 : void createGradientAction( const ::PolyPolygon& rPoly,
260 : const ::Gradient& rGradient,
261 : const ActionFactoryParameters& rParms,
262 : bool bIsPolygonRectangle,
263 : bool bSubsettableActions );
264 :
265 : void createTextAction( const ::Point& rStartPoint,
266 : const String rString,
267 : int nIndex,
268 : int nLength,
269 : const sal_Int32* pCharWidths,
270 : const ActionFactoryParameters& rParms,
271 : bool bSubsettable );
272 :
273 : bool getSubsetIndices( sal_Int32& io_rStartIndex,
274 : sal_Int32& io_rEndIndex,
275 : ActionVector::const_iterator& o_rRangeBegin,
276 : ActionVector::const_iterator& o_rRangeEnd ) const;
277 :
278 : void processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, sal_Bool bUseWholeStream = sal_False);
279 :
280 : /* EMF+ */
281 : void processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms, OutDevState& rState, const CanvasSharedPtr& rCanvas );
282 : double setFont( sal_uInt8 objectId, const ActionFactoryParameters& rParms, OutDevState& rState );
283 : void EMFPPlusDrawPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, sal_uInt32 penIndex);
284 : void EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor);
285 :
286 : ActionVector maActions;
287 :
288 : /* EMF+ */
289 : XForm aWorldTransform;
290 : EMFPObject* aObjects [256];
291 : float fPageScale;
292 : sal_Int32 nOriginX;
293 : sal_Int32 nOriginY;
294 : sal_Int32 nHDPI;
295 : sal_Int32 nVDPI;
296 : /* EMF+ emf header info */
297 : sal_Int32 nBoundsLeft;
298 : sal_Int32 nBoundsTop;
299 : sal_Int32 nBoundsRight;
300 : sal_Int32 nBoundsBottom;
301 : sal_Int32 nFrameLeft;
302 : sal_Int32 nFrameTop;
303 : sal_Int32 nFrameRight;
304 : sal_Int32 nFrameBottom;
305 : sal_Int32 nPixX;
306 : sal_Int32 nPixY;
307 : sal_Int32 nMmX;
308 : sal_Int32 nMmY;
309 : /* multipart object data */
310 : bool mbMultipart;
311 : sal_uInt16 mMFlags;
312 : SvMemoryStream mMStream;
313 : /* emf+ graphic state stack */
314 : GraphicStateMap mGSStack;
315 : GraphicStateMap mGSContainerStack;
316 : };
317 :
318 :
319 : /// Common parameters when creating actions
320 : struct ActionFactoryParameters
321 : {
322 0 : ActionFactoryParameters( VectorOfOutDevStates& rStates,
323 : const CanvasSharedPtr& rCanvas,
324 : ::VirtualDevice& rVDev,
325 : const Renderer::Parameters& rParms,
326 : sal_Int32& io_rCurrActionIndex ) :
327 : mrStates(rStates),
328 : mrCanvas(rCanvas),
329 : mrVDev(rVDev),
330 : mrParms(rParms),
331 0 : mrCurrActionIndex(io_rCurrActionIndex)
332 0 : {}
333 :
334 : VectorOfOutDevStates& mrStates;
335 : const CanvasSharedPtr& mrCanvas;
336 : ::VirtualDevice& mrVDev;
337 : const Renderer::Parameters& mrParms;
338 : sal_Int32& mrCurrActionIndex;
339 : };
340 : }
341 : }
342 :
343 : #endif /* _CPPCANVAS_IMPLRENDERER_HXX */
344 :
345 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|