Branch libreoffice-5-0-4
[LibreOffice.git] / cppcanvas / source / inc / implrenderer.hxx
blobb4b2b28c3903d766cd61d5c3ce9e77aae605ac80
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_CPPCANVAS_SOURCE_INC_IMPLRENDERER_HXX
21 #define INCLUDED_CPPCANVAS_SOURCE_INC_IMPLRENDERER_HXX
23 #include <sal/types.h>
25 #include <boost/shared_ptr.hpp>
26 #include <cppcanvas/renderer.hxx>
27 #include <cppcanvas/canvas.hxx>
29 #include <canvasgraphichelper.hxx>
30 #include <action.hxx>
31 #include <outdevstate.hxx>
33 #include <vector>
34 #include <map>
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;
45 namespace basegfx {
46 class B2DPolyPolygon;
47 class B2DPolygon;
50 namespace cppcanvas
53 namespace internal
55 struct OutDevState;
56 struct ActionFactoryParameters;
57 struct XForm;
59 struct EMFPObject
61 virtual ~EMFPObject() {}
64 // state stack of OutputDevice, to correctly handle
65 // push/pop actions
66 class VectorOfOutDevStates
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;
78 // EMF+
79 // TODO: replace?
80 struct XForm
82 float eM11;
83 float eM12;
84 float eM21;
85 float eM22;
86 float eDx;
87 float eDy;
88 XForm()
90 SetIdentity ();
93 void SetIdentity ()
95 eM11 = eM22 = 1.0f;
96 eDx = eDy = eM12 = eM21 = 0.0f;
99 void Set (float m11, float m12, float dx, float m21, float m22, float dy)
101 eM11 = m11;
102 eM12 = m12;
103 eDx = dx;
104 eM21 = m21;
105 eM22 = m22;
106 eDy = dy;
109 void Set (const XForm& f)
111 eM11 = f.eM11;
112 eM12 = f.eM12;
113 eM21 = f.eM21;
114 eM22 = f.eM22;
115 eDx = f.eDx;
116 eDy = f.eDy;
119 void Multiply (float m11, float m12, float dx, float m21, float m22, float dy)
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;
129 void Multiply (const XForm& f)
131 eM11 = eM11*f.eM11 + eM12*f.eM21;
132 eM12 = eM11*f.eM12 + eM12*f.eM22;
133 eM21 = eM21*f.eM11 + eM22*f.eM21;
134 eM22 = eM21*f.eM12 + eM22*f.eM22;
135 eDx *= eDx*f.eM11 + eDy*f.eM21 + f.eDx;
136 eDy *= eDx*f.eM12 + eDy*f.eM22 + f.eDy;
139 #ifdef OSL_BIGENDIAN
140 // little endian <-> big endian switch
141 static float GetSwapFloat( SvStream& rSt )
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;
151 #endif
153 friend SvStream& ReadXForm( SvStream& rIn, XForm& rXForm )
155 if ( sizeof( float ) != 4 )
157 OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
158 rXForm = XForm();
160 else
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 rIn.ReadFloat( rXForm.eM11 ).ReadFloat( rXForm.eM12 ).ReadFloat( rXForm.eM21 ).ReadFloat( rXForm.eM22 )
171 .ReadFloat( rXForm.eDx ).ReadFloat( rXForm.eDy );
172 #endif
174 return rIn;
178 // EMF+
179 typedef struct {
180 XForm aWorldTransform;
181 OutDevState aDevState;
182 } EmfPlusGraphicState;
184 typedef ::std::map<int,EmfPlusGraphicState> GraphicStateMap;
186 class ImplRenderer : public virtual Renderer, protected CanvasGraphicHelper
188 public:
189 ImplRenderer( const CanvasSharedPtr& rCanvas,
190 const GDIMetaFile& rMtf,
191 const Parameters& rParms );
193 virtual ~ImplRenderer();
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;
202 // element of the Renderer's action vector. Need to be
203 // public, since some functors need it, too.
204 struct MtfAction
206 MtfAction( const ActionSharedPtr& rAction,
207 sal_Int32 nOrigIndex ) :
208 mpAction( rAction ),
209 mnOrigIndex( nOrigIndex )
213 ActionSharedPtr mpAction;
214 sal_Int32 mnOrigIndex;
217 // prefetched and prepared canvas actions
218 // (externally not visible)
219 typedef ::std::vector< MtfAction > ActionVector;
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);
230 private:
231 ImplRenderer(const ImplRenderer&) SAL_DELETED_FUNCTION;
232 ImplRenderer& operator=( const ImplRenderer& ) SAL_DELETED_FUNCTION;
234 static void updateClipping( const ::basegfx::B2DPolyPolygon& rClipPoly,
235 const ActionFactoryParameters& rParms,
236 bool bIntersect );
238 static void updateClipping( const ::Rectangle& rClipRect,
239 const ActionFactoryParameters& rParms,
240 bool bIntersect );
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 );
257 static bool isActionContained( GDIMetaFile& rMtf,
258 const char* pCommentString,
259 MetaActionType nType );
261 void createGradientAction( const ::tools::PolyPolygon& rPoly,
262 const ::Gradient& rGradient,
263 const ActionFactoryParameters& rParms,
264 bool bIsPolygonRectangle,
265 bool bSubsettableActions );
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 );
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;
280 void processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, bool bUseWholeStream = false);
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 );
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);
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);
296 ActionVector maActions;
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;
326 /// Common parameters when creating actions
327 struct ActionFactoryParameters
329 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 mrCurrActionIndex(io_rCurrActionIndex)
341 VectorOfOutDevStates& mrStates;
342 const CanvasSharedPtr& mrCanvas;
343 ::VirtualDevice& mrVDev;
344 const Renderer::Parameters& mrParms;
345 sal_Int32& mrCurrActionIndex;
350 #endif // INCLUDED_CPPCANVAS_SOURCE_INC_IMPLRENDERER_HXX
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */