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 : // little endian <-> big endian switch
141 : static float GetSwapFloat( SvStream& rSt )
142 : {
143 : float fTmp;
144 : sal_Int8* pPtr = (sal_Int8*)&fTmp;
145 : rSt.ReadSChar( pPtr[3] );
146 : rSt.ReadSChar( pPtr[2] );
147 : rSt.ReadSChar( pPtr[1] );
148 : rSt.ReadSChar( pPtr[0] );
149 : return fTmp;
150 : }
151 : #endif
152 :
153 0 : friend SvStream& ReadXForm( SvStream& rIn, XForm& rXForm )
154 : {
155 : if ( sizeof( float ) != 4 )
156 : {
157 : OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
158 : rXForm = XForm();
159 : }
160 : else
161 : {
162 : #ifdef OSL_BIGENDIAN
163 : rXForm.eM11 = GetSwapFloat( rIn );
164 : rXForm.eM12 = GetSwapFloat( rIn );
165 : rXForm.eM21 = GetSwapFloat( rIn );
166 : rXForm.eM22 = GetSwapFloat( rIn );
167 : rXForm.eDx = GetSwapFloat( rIn );
168 : rXForm.eDy = GetSwapFloat( rIn );
169 : #else
170 0 : rIn.ReadFloat( rXForm.eM11 ).ReadFloat( rXForm.eM12 ).ReadFloat( rXForm.eM21 ).ReadFloat( rXForm.eM22 )
171 0 : .ReadFloat( rXForm.eDx ).ReadFloat( rXForm.eDy );
172 : #endif
173 : }
174 0 : return rIn;
175 : }
176 : };
177 :
178 : // EMF+
179 0 : typedef struct {
180 : XForm aWorldTransform;
181 : OutDevState aDevState;
182 0 : } EmfPlusGraphicState;
183 :
184 : typedef ::std::map<int,EmfPlusGraphicState> GraphicStateMap;
185 :
186 : class ImplRenderer : public virtual Renderer, protected CanvasGraphicHelper
187 : {
188 : public:
189 : ImplRenderer( const CanvasSharedPtr& rCanvas,
190 : const GDIMetaFile& rMtf,
191 : const Parameters& rParms );
192 :
193 : virtual ~ImplRenderer();
194 :
195 : virtual bool draw() const SAL_OVERRIDE;
196 : virtual bool drawSubset( sal_Int32 nStartIndex,
197 : sal_Int32 nEndIndex ) const SAL_OVERRIDE;
198 : virtual ::basegfx::B2DRange getSubsetArea( sal_Int32 nStartIndex,
199 : sal_Int32 nEndIndex ) const SAL_OVERRIDE;
200 :
201 :
202 : // element of the Renderer's action vector. Need to be
203 : // public, since some functors need it, too.
204 0 : struct MtfAction
205 : {
206 0 : MtfAction( const ActionSharedPtr& rAction,
207 : sal_Int32 nOrigIndex ) :
208 : mpAction( rAction ),
209 0 : mnOrigIndex( nOrigIndex )
210 : {
211 0 : }
212 :
213 : ActionSharedPtr mpAction;
214 : sal_Int32 mnOrigIndex;
215 : };
216 :
217 : // prefetched and prepared canvas actions
218 : // (externally not visible)
219 : typedef ::std::vector< MtfAction > ActionVector;
220 :
221 : /* EMF+ */
222 : void ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false);
223 : void ReadPoint (SvStream& s, float& x, float& y, sal_uInt32 flags);
224 : void MapToDevice (double &x, double &y);
225 : ::basegfx::B2DPoint Map (double ix, double iy);
226 : ::basegfx::B2DSize MapSize (double iwidth, double iheight);
227 : void GraphicStatePush (GraphicStateMap& map, sal_Int32 index, OutDevState& rState);
228 : void GraphicStatePop (GraphicStateMap& map, sal_Int32 index, OutDevState& rState);
229 :
230 : private:
231 : // default: disabled copy/assignment
232 : ImplRenderer(const ImplRenderer&);
233 : ImplRenderer& operator=( const ImplRenderer& );
234 :
235 : void updateClipping( const ::basegfx::B2DPolyPolygon& rClipPoly,
236 : const ActionFactoryParameters& rParms,
237 : bool bIntersect );
238 :
239 : void updateClipping( const ::Rectangle& rClipRect,
240 : const ActionFactoryParameters& rParms,
241 : bool bIntersect );
242 :
243 : ::com::sun::star::uno::Reference<
244 : ::com::sun::star::rendering::XCanvasFont > createFont( double& o_rFontRotation,
245 : const ::Font& rFont,
246 : const ActionFactoryParameters& rParms ) const;
247 : bool createActions( GDIMetaFile& rMtf,
248 : const ActionFactoryParameters& rParms,
249 : bool bSubsettableActions );
250 : bool createFillAndStroke( const ::basegfx::B2DPolyPolygon& rPolyPoly,
251 : const ActionFactoryParameters& rParms );
252 : bool createFillAndStroke( const ::basegfx::B2DPolygon& rPoly,
253 : const ActionFactoryParameters& rParms );
254 : void skipContent( GDIMetaFile& rMtf,
255 : const char* pCommentString,
256 : sal_Int32& io_rCurrActionIndex ) const;
257 :
258 : bool isActionContained( GDIMetaFile& rMtf,
259 : const char* pCommentString,
260 : sal_uInt16 nType ) const;
261 :
262 : void createGradientAction( const ::PolyPolygon& rPoly,
263 : const ::Gradient& rGradient,
264 : const ActionFactoryParameters& rParms,
265 : bool bIsPolygonRectangle,
266 : bool bSubsettableActions );
267 :
268 : void createTextAction( const ::Point& rStartPoint,
269 : const OUString& rString,
270 : int nIndex,
271 : int nLength,
272 : const sal_Int32* pCharWidths,
273 : const ActionFactoryParameters& rParms,
274 : bool bSubsettable );
275 :
276 : bool getSubsetIndices( sal_Int32& io_rStartIndex,
277 : sal_Int32& io_rEndIndex,
278 : ActionVector::const_iterator& o_rRangeBegin,
279 : ActionVector::const_iterator& o_rRangeEnd ) const;
280 :
281 : void processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, bool bUseWholeStream = false);
282 :
283 : /* EMF+ */
284 : void processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms, OutDevState& rState, const CanvasSharedPtr& rCanvas );
285 : double setFont( sal_uInt8 objectId, const ActionFactoryParameters& rParms, OutDevState& rState );
286 :
287 : /// Render LineCap, like the start or end arrow of a polygon.
288 : /// @return how much we should shorten the original polygon.
289 : double EMFPPlusDrawLineCap(const ::basegfx::B2DPolygon& rPolygon, double fPolyLength,
290 : const ::basegfx::B2DPolyPolygon& rLineCap, bool isFilled, bool bStart,
291 : const com::sun::star::rendering::StrokeAttributes& rAttributes,
292 : const ActionFactoryParameters& rParms, OutDevState& rState);
293 :
294 : void EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, sal_uInt32 penIndex);
295 : void EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor);
296 :
297 : ActionVector maActions;
298 :
299 : /* EMF+ */
300 : XForm aBaseTransform;
301 : XForm aWorldTransform;
302 : EMFPObject* aObjects [256];
303 : float fPageScale;
304 : sal_Int32 nOriginX;
305 : sal_Int32 nOriginY;
306 : sal_Int32 nHDPI;
307 : sal_Int32 nVDPI;
308 : /* EMF+ emf header info */
309 : sal_Int32 nFrameLeft;
310 : sal_Int32 nFrameTop;
311 : sal_Int32 nFrameRight;
312 : sal_Int32 nFrameBottom;
313 : sal_Int32 nPixX;
314 : sal_Int32 nPixY;
315 : sal_Int32 nMmX;
316 : sal_Int32 nMmY;
317 : /* multipart object data */
318 : bool mbMultipart;
319 : sal_uInt16 mMFlags;
320 : SvMemoryStream mMStream;
321 : /* emf+ graphic state stack */
322 : GraphicStateMap mGSStack;
323 : GraphicStateMap mGSContainerStack;
324 : };
325 :
326 :
327 : /// Common parameters when creating actions
328 : struct ActionFactoryParameters
329 : {
330 0 : ActionFactoryParameters( VectorOfOutDevStates& rStates,
331 : const CanvasSharedPtr& rCanvas,
332 : ::VirtualDevice& rVDev,
333 : const Renderer::Parameters& rParms,
334 : sal_Int32& io_rCurrActionIndex ) :
335 : mrStates(rStates),
336 : mrCanvas(rCanvas),
337 : mrVDev(rVDev),
338 : mrParms(rParms),
339 0 : mrCurrActionIndex(io_rCurrActionIndex)
340 0 : {}
341 :
342 : VectorOfOutDevStates& mrStates;
343 : const CanvasSharedPtr& mrCanvas;
344 : ::VirtualDevice& mrVDev;
345 : const Renderer::Parameters& mrParms;
346 : sal_Int32& mrCurrActionIndex;
347 : };
348 : }
349 : }
350 :
351 : #endif /* _CPPCANVAS_IMPLRENDERER_HXX */
352 :
353 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|