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 INCLUDED_CPPCANVAS_SOURCE_INC_IMPLRENDERER_HXX
21 : #define INCLUDED_CPPCANVAS_SOURCE_INC_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 : namespace vcl { class Font; }
41 : namespace tools { 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 18 : struct EMFPObject
60 : {
61 18 : virtual ~EMFPObject() {}
62 : };
63 :
64 : // state stack of OutputDevice, to correctly handle
65 : // push/pop actions
66 4 : class VectorOfOutDevStates
67 : {
68 : public:
69 : OutDevState& getState();
70 : const OutDevState& getState() const;
71 : void pushState(PushFlags 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 58 : XForm()
89 : {
90 58 : SetIdentity ();
91 58 : };
92 :
93 94 : void SetIdentity ()
94 : {
95 94 : eM11 = eM22 = 1.0f;
96 94 : eDx = eDy = eM12 = eM21 = 0.0f;
97 94 : }
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 46 : void Set (const XForm& f)
110 : {
111 46 : eM11 = f.eM11;
112 46 : eM12 = f.eM12;
113 46 : eM21 = f.eM21;
114 46 : eM22 = f.eM22;
115 46 : eDx = f.eDx;
116 46 : eDy = f.eDy;
117 46 : }
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 (const 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 48 : 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 48 : rIn.ReadFloat( rXForm.eM11 ).ReadFloat( rXForm.eM12 ).ReadFloat( rXForm.eM21 ).ReadFloat( rXForm.eM22 )
171 96 : .ReadFloat( rXForm.eDx ).ReadFloat( rXForm.eDy );
172 : #endif
173 : }
174 48 : 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 64 : struct MtfAction
205 : {
206 12 : MtfAction( const ActionSharedPtr& rAction,
207 : sal_Int32 nOrigIndex ) :
208 : mpAction( rAction ),
209 12 : mnOrigIndex( nOrigIndex )
210 : {
211 12 : }
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 : static void ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false);
223 : static 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 : ImplRenderer(const ImplRenderer&) SAL_DELETED_FUNCTION;
232 : ImplRenderer& operator=( const ImplRenderer& ) SAL_DELETED_FUNCTION;
233 :
234 : static void updateClipping( const ::basegfx::B2DPolyPolygon& rClipPoly,
235 : const ActionFactoryParameters& rParms,
236 : bool bIntersect );
237 :
238 : static void updateClipping( const ::Rectangle& rClipRect,
239 : const ActionFactoryParameters& rParms,
240 : bool bIntersect );
241 :
242 : static ::com::sun::star::uno::Reference<
243 : ::com::sun::star::rendering::XCanvasFont > createFont( double& o_rFontRotation,
244 : const vcl::Font& rFont,
245 : const ActionFactoryParameters& rParms );
246 : bool createActions( GDIMetaFile& rMtf,
247 : const ActionFactoryParameters& rParms,
248 : bool bSubsettableActions );
249 : bool createFillAndStroke( const ::basegfx::B2DPolyPolygon& rPolyPoly,
250 : const ActionFactoryParameters& rParms );
251 : bool createFillAndStroke( const ::basegfx::B2DPolygon& rPoly,
252 : const ActionFactoryParameters& rParms );
253 : static void skipContent( GDIMetaFile& rMtf,
254 : const char* pCommentString,
255 : sal_Int32& io_rCurrActionIndex );
256 :
257 : static bool isActionContained( GDIMetaFile& rMtf,
258 : const char* pCommentString,
259 : MetaActionType nType );
260 :
261 : void createGradientAction( const ::tools::PolyPolygon& rPoly,
262 : const ::Gradient& rGradient,
263 : const ActionFactoryParameters& rParms,
264 : bool bIsPolygonRectangle,
265 : bool bSubsettableActions );
266 :
267 : void createTextAction( const ::Point& rStartPoint,
268 : const OUString& rString,
269 : int nIndex,
270 : int nLength,
271 : const long* pCharWidths,
272 : const ActionFactoryParameters& rParms,
273 : bool bSubsettable );
274 :
275 : bool getSubsetIndices( sal_Int32& io_rStartIndex,
276 : sal_Int32& io_rEndIndex,
277 : ActionVector::const_iterator& o_rRangeBegin,
278 : ActionVector::const_iterator& o_rRangeEnd ) const;
279 :
280 : void processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, bool bUseWholeStream = false);
281 :
282 : /* EMF+ */
283 : void processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms, OutDevState& rState, const CanvasSharedPtr& rCanvas );
284 : double setFont( sal_uInt8 objectId, const ActionFactoryParameters& rParms, OutDevState& rState );
285 :
286 : /// Render LineCap, like the start or end arrow of a polygon.
287 : /// @return how much we should shorten the original polygon.
288 : double EMFPPlusDrawLineCap(const ::basegfx::B2DPolygon& rPolygon, double fPolyLength,
289 : const ::basegfx::B2DPolyPolygon& rLineCap, bool isFilled, bool bStart,
290 : const com::sun::star::rendering::StrokeAttributes& rAttributes,
291 : const ActionFactoryParameters& rParms, OutDevState& rState);
292 :
293 : void EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, sal_uInt32 penIndex);
294 : void EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor);
295 :
296 : ActionVector maActions;
297 :
298 : /* EMF+ */
299 : XForm aBaseTransform;
300 : XForm aWorldTransform;
301 : EMFPObject* aObjects [256];
302 : float fPageScale;
303 : sal_Int32 nOriginX;
304 : sal_Int32 nOriginY;
305 : sal_Int32 nHDPI;
306 : sal_Int32 nVDPI;
307 : /* EMF+ emf header info */
308 : sal_Int32 nFrameLeft;
309 : sal_Int32 nFrameTop;
310 : sal_Int32 nFrameRight;
311 : sal_Int32 nFrameBottom;
312 : sal_Int32 nPixX;
313 : sal_Int32 nPixY;
314 : sal_Int32 nMmX;
315 : sal_Int32 nMmY;
316 : /* multipart object data */
317 : bool mbMultipart;
318 : sal_uInt16 mMFlags;
319 : SvMemoryStream mMStream;
320 : /* emf+ graphic state stack */
321 : GraphicStateMap mGSStack;
322 : GraphicStateMap mGSContainerStack;
323 : };
324 :
325 :
326 : /// Common parameters when creating actions
327 : struct ActionFactoryParameters
328 : {
329 2 : ActionFactoryParameters( VectorOfOutDevStates& rStates,
330 : const CanvasSharedPtr& rCanvas,
331 : ::VirtualDevice& rVDev,
332 : const Renderer::Parameters& rParms,
333 : sal_Int32& io_rCurrActionIndex ) :
334 : mrStates(rStates),
335 : mrCanvas(rCanvas),
336 : mrVDev(rVDev),
337 : mrParms(rParms),
338 2 : mrCurrActionIndex(io_rCurrActionIndex)
339 2 : {}
340 :
341 : VectorOfOutDevStates& mrStates;
342 : const CanvasSharedPtr& mrCanvas;
343 : ::VirtualDevice& mrVDev;
344 : const Renderer::Parameters& mrParms;
345 : sal_Int32& mrCurrActionIndex;
346 : };
347 : }
348 : }
349 :
350 : #endif // INCLUDED_CPPCANVAS_SOURCE_INC_IMPLRENDERER_HXX
351 :
352 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|