update dev300-m58
[ooovba.git] / drawinglayer / source / processor2d / vclhelperbitmaprender.cxx
blob75ec7e38981a259a50d5e96217b78dedd2499a7d
1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: vclhelperbitmaprender.cxx,v $
7 * $Revision: 1.3 $
9 * last change: $Author: aw $ $Date: 2008-05-27 14:11:21 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * MA 02111-1307 USA
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_drawinglayer.hxx"
39 #include <vclhelperbitmaprender.hxx>
40 #include <goodies/grfmgr.hxx>
41 #include <basegfx/vector/b2dvector.hxx>
42 #include <basegfx/matrix/b2dhommatrix.hxx>
43 #include <basegfx/range/b2drange.hxx>
44 #include <vcl/outdev.hxx>
45 #include <vclhelperbitmaptransform.hxx>
47 //////////////////////////////////////////////////////////////////////////////
48 // support for different kinds of bitmap rendering using vcl
50 namespace drawinglayer
52 void RenderBitmapPrimitive2D_GraphicManager(
53 OutputDevice& rOutDev,
54 const BitmapEx& rBitmapEx,
55 const basegfx::B2DHomMatrix& rTransform)
57 // prepare attributes
58 GraphicAttr aAttributes;
60 // decompose matrix to check for shear, rotate and mirroring
61 basegfx::B2DVector aScale, aTranslate;
62 double fRotate, fShearX;
63 rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
65 // mirror flags
66 aAttributes.SetMirrorFlags(
67 (basegfx::fTools::less(aScale.getX(), 0.0) ? BMP_MIRROR_HORZ : 0)|
68 (basegfx::fTools::less(aScale.getY(), 0.0) ? BMP_MIRROR_VERT : 0));
70 // rotation
71 if(!basegfx::fTools::equalZero(fRotate))
73 double fRotation(fmod(3600.0 - (fRotate * (10.0 / F_PI180)), 3600.0));
74 aAttributes.SetRotation((sal_uInt16)(fRotation));
77 // prepare Bitmap
78 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
80 if(basegfx::fTools::equalZero(fRotate))
82 aOutlineRange.transform(rTransform);
84 else
86 // if rotated, create the unrotated output rectangle for the GraphicManager paint
87 basegfx::B2DHomMatrix aSimpleObjectMatrix;
89 aSimpleObjectMatrix.scale(fabs(aScale.getX()), fabs(aScale.getY()));
90 aSimpleObjectMatrix.translate(aTranslate.getX(), aTranslate.getY());
92 aOutlineRange.transform(aSimpleObjectMatrix);
95 // prepare dest coor
96 const Rectangle aDestRectPixel(
97 basegfx::fround(aOutlineRange.getMinX()), basegfx::fround(aOutlineRange.getMinY()),
98 basegfx::fround(aOutlineRange.getMaxX()), basegfx::fround(aOutlineRange.getMaxY()));
100 // paint it using GraphicManager
101 Graphic aGraphic(rBitmapEx);
102 GraphicObject aGraphicObject(aGraphic);
103 aGraphicObject.Draw(&rOutDev, aDestRectPixel.TopLeft(), aDestRectPixel.GetSize(), &aAttributes);
106 void RenderBitmapPrimitive2D_BitmapEx(
107 OutputDevice& rOutDev,
108 const BitmapEx& rBitmapEx,
109 const basegfx::B2DHomMatrix& rTransform)
111 // only translate and scale, use vcl's DrawBitmapEx().
112 BitmapEx aContent(rBitmapEx);
114 // prepare dest coor. Necessary to expand since vcl's DrawBitmapEx draws one pix less
115 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
116 aOutlineRange.transform(rTransform);
117 const Rectangle aDestRectPixel(
118 basegfx::fround(aOutlineRange.getMinX()), basegfx::fround(aOutlineRange.getMinY()),
119 basegfx::fround(aOutlineRange.getMaxX()), basegfx::fround(aOutlineRange.getMaxY()));
121 // decompose matrix to check for shear, rotate and mirroring
122 basegfx::B2DVector aScale, aTranslate;
123 double fRotate, fShearX;
124 rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
126 // Check mirroring.
127 sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE);
129 if(basegfx::fTools::less(aScale.getX(), 0.0))
131 nMirrorFlags |= BMP_MIRROR_HORZ;
134 if(basegfx::fTools::less(aScale.getY(), 0.0))
136 nMirrorFlags |= BMP_MIRROR_VERT;
139 if(BMP_MIRROR_NONE != nMirrorFlags)
141 aContent.Mirror(nMirrorFlags);
144 // draw bitmap
145 rOutDev.DrawBitmapEx(aDestRectPixel.TopLeft(), aDestRectPixel.GetSize(), aContent);
148 void RenderBitmapPrimitive2D_self(
149 OutputDevice& rOutDev,
150 const BitmapEx& rBitmapEx,
151 const basegfx::B2DHomMatrix& rTransform)
153 // process self with free transformation (containing shear and rotate). Get dest rect in pixels.
154 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
155 aOutlineRange.transform(rTransform);
156 const Rectangle aDestRectLogic(
157 basegfx::fround(aOutlineRange.getMinX()), basegfx::fround(aOutlineRange.getMinY()),
158 basegfx::fround(aOutlineRange.getMaxX()), basegfx::fround(aOutlineRange.getMaxY()));
159 const Rectangle aDestRectPixel(rOutDev.LogicToPixel(aDestRectLogic));
161 // #i96708# check if Metafile is recorded
162 const GDIMetaFile* pMetaFile = rOutDev.GetConnectMetaFile();
163 const bool bRecordToMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
165 // intersect with output pixel size, but only
166 // when not recording to metafile
167 const Rectangle aOutputRectPixel(Point(), rOutDev.GetOutputSizePixel());
168 Rectangle aCroppedRectPixel(bRecordToMetaFile ? aDestRectPixel : aDestRectPixel.GetIntersection(aOutputRectPixel));
170 if(!aCroppedRectPixel.IsEmpty())
172 // as maximum for destination, orientate at SourceSizePixel, but
173 // take a rotation of 45 degrees (sqrt(2)) as maximum expansion into account
174 const Size aSourceSizePixel(rBitmapEx.GetSizePixel());
175 const double fMaximumArea(
176 (double)aSourceSizePixel.getWidth() *
177 (double)aSourceSizePixel.getHeight() *
178 1.4142136); // 1.4142136 taken as sqrt(2.0)
180 // test if discrete view size (pixel) maybe too big and limit it
181 const double fArea(aCroppedRectPixel.getWidth() * aCroppedRectPixel.getHeight());
182 const bool bNeedToReduce(fArea > fMaximumArea);
183 double fReduceFactor(1.0);
185 if(bNeedToReduce)
187 fReduceFactor = sqrt(fMaximumArea / fArea);
188 aCroppedRectPixel.setWidth(basegfx::fround(aCroppedRectPixel.getWidth() * fReduceFactor));
189 aCroppedRectPixel.setHeight(basegfx::fround(aCroppedRectPixel.getHeight() * fReduceFactor));
192 // build transform from pixel in aDestination to pixel in rBitmapEx
193 basegfx::B2DHomMatrix aTransform;
195 // from relative in aCroppedRectPixel to relative in aDestRectPixel
196 // No need to take bNeedToReduce into account, TopLeft is unchanged
197 aTransform.translate(aCroppedRectPixel.Left() - aDestRectPixel.Left(), aCroppedRectPixel.Top() - aDestRectPixel.Top());
199 // from relative in aDestRectPixel to absolute Logic. Here it
200 // is essential to adapt to reduce factor (if used)
201 double fAdaptedDRPWidth((double)aDestRectPixel.getWidth());
202 double fAdaptedDRPHeight((double)aDestRectPixel.getHeight());
204 if(bNeedToReduce)
206 fAdaptedDRPWidth *= fReduceFactor;
207 fAdaptedDRPHeight *= fReduceFactor;
210 aTransform.scale(aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight);
211 aTransform.translate(aDestRectLogic.Left(), aDestRectLogic.Top());
213 // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y)
214 basegfx::B2DHomMatrix aInvBitmapTransform(rTransform);
215 aInvBitmapTransform.invert();
216 aTransform = aInvBitmapTransform * aTransform;
218 // from unit object coordinates to rBitmapEx pixel coordintes
219 aTransform.scale(aSourceSizePixel.getWidth() - 1L, aSourceSizePixel.getHeight() - 1L);
221 // create bitmap using source, destination and linear back-transformation
222 BitmapEx aDestination = impTransformBitmapEx(rBitmapEx, aCroppedRectPixel, aTransform);
224 // paint
225 if(bNeedToReduce)
227 // paint in target size
228 const double fFactor(1.0 / fReduceFactor);
229 const Size aDestSizePixel(
230 basegfx::fround(aCroppedRectPixel.getWidth() * fFactor),
231 basegfx::fround(aCroppedRectPixel.getHeight() * fFactor));
233 if(bRecordToMetaFile)
235 rOutDev.DrawBitmapEx(
236 rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
237 rOutDev.PixelToLogic(aDestSizePixel),
238 aDestination);
240 else
242 const bool bWasEnabled(rOutDev.IsMapModeEnabled());
243 rOutDev.EnableMapMode(false);
245 rOutDev.DrawBitmapEx(
246 aCroppedRectPixel.TopLeft(),
247 aDestSizePixel,
248 aDestination);
250 rOutDev.EnableMapMode(bWasEnabled);
253 else
255 if(bRecordToMetaFile)
257 rOutDev.DrawBitmapEx(
258 rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
259 aDestination);
261 else
263 const bool bWasEnabled(rOutDev.IsMapModeEnabled());
264 rOutDev.EnableMapMode(false);
266 rOutDev.DrawBitmapEx(
267 aCroppedRectPixel.TopLeft(),
268 aDestination);
270 rOutDev.EnableMapMode(bWasEnabled);
275 } // end of namespace drawinglayer
277 //////////////////////////////////////////////////////////////////////////////
278 // eof