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 :
32 : #include <vector>
33 :
34 : class GDIMetaFile;
35 : class VirtualDevice;
36 : class Gradient;
37 : class Rectangle;
38 : class Font;
39 : class PolyPolygon;
40 : class Point;
41 : class MetaCommentAction;
42 :
43 : namespace basegfx {
44 : class B2DPolyPolygon;
45 : class B2DPolygon;
46 : }
47 :
48 : namespace cppcanvas
49 : {
50 :
51 : namespace internal
52 : {
53 : struct OutDevState;
54 : struct ActionFactoryParameters;
55 : struct EMFPObject;
56 : struct XForm;
57 :
58 : // state stack of OutputDevice, to correctly handle
59 : // push/pop actions
60 0 : class VectorOfOutDevStates
61 : {
62 : public:
63 : OutDevState& getState();
64 : const OutDevState& getState() const;
65 : void pushState(sal_uInt16 nFlags);
66 : void popState();
67 : void clearStateStack();
68 : private:
69 : ::std::vector< OutDevState > m_aStates;
70 : };
71 :
72 : // EMF+
73 : // TODO: replace?
74 : struct XForm
75 : {
76 : float eM11;
77 : float eM12;
78 : float eM21;
79 : float eM22;
80 : float eDx;
81 : float eDy;
82 0 : XForm()
83 : {
84 0 : SetIdentity ();
85 0 : };
86 :
87 0 : void SetIdentity ()
88 : {
89 0 : eM11 = eM22 = 1.0f;
90 0 : eDx = eDy = eM12 = eM21 = 0.0f;
91 0 : }
92 :
93 : void Set (float m11, float m12, float dx, float m21, float m22, float dy)
94 : {
95 : eM11 = m11;
96 : eM12 = m12;
97 : eDx = dx;
98 : eM21 = m21;
99 : eM22 = m22;
100 : eDy = dy;
101 : }
102 :
103 0 : void Set (XForm f)
104 : {
105 0 : eM11 = f.eM11;
106 0 : eM12 = f.eM12;
107 0 : eM21 = f.eM21;
108 0 : eM22 = f.eM22;
109 0 : eDx = f.eDx;
110 0 : eDy = f.eDy;
111 0 : }
112 :
113 : void Multiply (float m11, float m12, float dx, float m21, float m22, float dy)
114 : {
115 : eM11 = eM11*m11 + eM12*m21;
116 : eM12 = eM11*m12 + eM12*m22;
117 : eM21 = eM21*m11 + eM22*m21;
118 : eM22 = eM21*m12 + eM22*m22;
119 : eDx *= eDx*m11 + eDy*m21 + dx;
120 : eDy *= eDx*m12 + eDy*m22 + dy;
121 : }
122 :
123 0 : void Multiply (XForm f)
124 : {
125 0 : eM11 = eM11*f.eM11 + eM12*f.eM21;
126 0 : eM12 = eM11*f.eM12 + eM12*f.eM22;
127 0 : eM21 = eM21*f.eM11 + eM22*f.eM21;
128 0 : eM22 = eM21*f.eM12 + eM22*f.eM22;
129 0 : eDx *= eDx*f.eM11 + eDy*f.eM21 + f.eDx;
130 0 : eDy *= eDx*f.eM12 + eDy*f.eM22 + f.eDy;
131 0 : }
132 :
133 : #ifdef OSL_BIGENDIAN
134 : // currently unused
135 : static float GetSwapFloat( SvStream& rSt )
136 : {
137 : float fTmp;
138 : sal_Int8* pPtr = (sal_Int8*)&fTmp;
139 : rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch
140 : return fTmp;
141 : }
142 : #endif
143 :
144 0 : friend SvStream& operator>>( SvStream& rIn, XForm& rXForm )
145 : {
146 : if ( sizeof( float ) != 4 )
147 : {
148 : OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
149 : rXForm = XForm();
150 : }
151 : else
152 : {
153 : #ifdef OSL_BIGENDIAN
154 : rXForm.eM11 = GetSwapFloat( rIn );
155 : rXForm.eM12 = GetSwapFloat( rIn );
156 : rXForm.eM21 = GetSwapFloat( rIn );
157 : rXForm.eM22 = GetSwapFloat( rIn );
158 : rXForm.eDx = GetSwapFloat( rIn );
159 : rXForm.eDy = GetSwapFloat( rIn );
160 : #else
161 0 : rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22
162 0 : >> rXForm.eDx >> rXForm.eDy;
163 : #endif
164 : }
165 0 : return rIn;
166 : }
167 : };
168 :
169 : class ImplRenderer : public virtual Renderer, protected CanvasGraphicHelper
170 : {
171 : public:
172 : ImplRenderer( const CanvasSharedPtr& rCanvas,
173 : const GDIMetaFile& rMtf,
174 : const Parameters& rParms );
175 :
176 : virtual ~ImplRenderer();
177 :
178 : virtual bool draw() const;
179 : virtual bool drawSubset( sal_Int32 nStartIndex,
180 : sal_Int32 nEndIndex ) const;
181 : virtual ::basegfx::B2DRange getSubsetArea( sal_Int32 nStartIndex,
182 : sal_Int32 nEndIndex ) const;
183 :
184 :
185 : // element of the Renderer's action vector. Need to be
186 : // public, since some functors need it, too.
187 0 : struct MtfAction
188 : {
189 0 : MtfAction( const ActionSharedPtr& rAction,
190 : sal_Int32 nOrigIndex ) :
191 : mpAction( rAction ),
192 0 : mnOrigIndex( nOrigIndex )
193 : {
194 0 : }
195 :
196 : ActionSharedPtr mpAction;
197 : sal_Int32 mnOrigIndex;
198 : };
199 :
200 : // prefetched and prepared canvas actions
201 : // (externally not visible)
202 : typedef ::std::vector< MtfAction > ActionVector;
203 :
204 : /* EMF+ */
205 : void ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false);
206 : void ReadPoint (SvStream& s, float& x, float& y, sal_uInt32 flags);
207 : void MapToDevice (double &x, double &y);
208 : ::basegfx::B2DPoint Map (double ix, double iy);
209 : ::basegfx::B2DSize MapSize (double iwidth, double iheight);
210 :
211 : private:
212 : // default: disabled copy/assignment
213 : ImplRenderer(const ImplRenderer&);
214 : ImplRenderer& operator=( const ImplRenderer& );
215 :
216 : void updateClipping( const ::basegfx::B2DPolyPolygon& rClipPoly,
217 : const ActionFactoryParameters& rParms,
218 : bool bIntersect );
219 :
220 : void updateClipping( const ::Rectangle& rClipRect,
221 : const ActionFactoryParameters& rParms,
222 : bool bIntersect );
223 :
224 : ::com::sun::star::uno::Reference<
225 : ::com::sun::star::rendering::XCanvasFont > createFont( double& o_rFontRotation,
226 : const ::Font& rFont,
227 : const ActionFactoryParameters& rParms ) const;
228 : bool createActions( GDIMetaFile& rMtf,
229 : const ActionFactoryParameters& rParms,
230 : bool bSubsettableActions );
231 : bool createFillAndStroke( const ::basegfx::B2DPolyPolygon& rPolyPoly,
232 : const ActionFactoryParameters& rParms );
233 : bool createFillAndStroke( const ::basegfx::B2DPolygon& rPoly,
234 : const ActionFactoryParameters& rParms );
235 : void skipContent( GDIMetaFile& rMtf,
236 : const char* pCommentString,
237 : sal_Int32& io_rCurrActionIndex ) const;
238 :
239 : bool isActionContained( GDIMetaFile& rMtf,
240 : const char* pCommentString,
241 : sal_uInt16 nType ) const;
242 :
243 : void createGradientAction( const ::PolyPolygon& rPoly,
244 : const ::Gradient& rGradient,
245 : const ActionFactoryParameters& rParms,
246 : bool bIsPolygonRectangle,
247 : bool bSubsettableActions );
248 :
249 : void createTextAction( const ::Point& rStartPoint,
250 : const String rString,
251 : int nIndex,
252 : int nLength,
253 : const sal_Int32* pCharWidths,
254 : const ActionFactoryParameters& rParms,
255 : bool bSubsettable );
256 :
257 : bool getSubsetIndices( sal_Int32& io_rStartIndex,
258 : sal_Int32& io_rEndIndex,
259 : ActionVector::const_iterator& o_rRangeBegin,
260 : ActionVector::const_iterator& o_rRangeEnd ) const;
261 :
262 : void processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_Bool bUseWholeStream = sal_False);
263 :
264 : /* EMF+ */
265 : void processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms, OutDevState& rState, const CanvasSharedPtr& rCanvas );
266 : double setFont( sal_uInt8 objectId, const ActionFactoryParameters& rParms, OutDevState& rState );
267 : void EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor);
268 :
269 : ActionVector maActions;
270 :
271 : /* EMF+ */
272 : XForm aBaseTransform;
273 : XForm aWorldTransform;
274 : EMFPObject* aObjects [256];
275 : float fPageScale;
276 : sal_Int32 nOriginX;
277 : sal_Int32 nOriginY;
278 : sal_Int32 nHDPI;
279 : sal_Int32 nVDPI;
280 : ::PolyPolygon aClippingPolygon;
281 : /* EMF+ emf header info */
282 : sal_Int32 nFrameLeft;
283 : sal_Int32 nFrameTop;
284 : sal_Int32 nFrameRight;
285 : sal_Int32 nFrameBottom;
286 : sal_Int32 nPixX;
287 : sal_Int32 nPixY;
288 : sal_Int32 nMmX;
289 : sal_Int32 nMmY;
290 : /* multipart object data */
291 : bool mbMultipart;
292 : sal_uInt16 mMFlags;
293 : SvMemoryStream mMStream;
294 : };
295 :
296 :
297 : /// Common parameters when creating actions
298 : struct ActionFactoryParameters
299 : {
300 0 : ActionFactoryParameters( VectorOfOutDevStates& rStates,
301 : const CanvasSharedPtr& rCanvas,
302 : ::VirtualDevice& rVDev,
303 : const Renderer::Parameters& rParms,
304 : sal_Int32& io_rCurrActionIndex ) :
305 : mrStates(rStates),
306 : mrCanvas(rCanvas),
307 : mrVDev(rVDev),
308 : mrParms(rParms),
309 0 : mrCurrActionIndex(io_rCurrActionIndex)
310 0 : {}
311 :
312 : VectorOfOutDevStates& mrStates;
313 : const CanvasSharedPtr& mrCanvas;
314 : ::VirtualDevice& mrVDev;
315 : const Renderer::Parameters& mrParms;
316 : sal_Int32& mrCurrActionIndex;
317 : };
318 : }
319 : }
320 :
321 : #endif /* _CPPCANVAS_IMPLRENDERER_HXX */
322 :
323 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|