Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <vclhelperbitmaprender.hxx>
30 : : #include <svtools/grfmgr.hxx>
31 : : #include <basegfx/vector/b2dvector.hxx>
32 : : #include <basegfx/matrix/b2dhommatrix.hxx>
33 : : #include <basegfx/range/b2drange.hxx>
34 : : #include <vcl/outdev.hxx>
35 : : #include <vclhelperbitmaptransform.hxx>
36 : : #include <basegfx/matrix/b2dhommatrixtools.hxx>
37 : :
38 : : //////////////////////////////////////////////////////////////////////////////
39 : : // support for different kinds of bitmap rendering using vcl
40 : :
41 : : namespace drawinglayer
42 : : {
43 : 17557 : void RenderBitmapPrimitive2D_GraphicManager(
44 : : OutputDevice& rOutDev,
45 : : const BitmapEx& rBitmapEx,
46 : : const basegfx::B2DHomMatrix& rTransform)
47 : : {
48 : : // prepare attributes
49 [ + - ]: 17557 : GraphicAttr aAttributes;
50 : :
51 : : // decompose matrix to check for shear, rotate and mirroring
52 : 17557 : basegfx::B2DVector aScale, aTranslate;
53 : : double fRotate, fShearX;
54 [ + - ]: 17557 : rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
55 : :
56 : : // mirror flags
57 : : aAttributes.SetMirrorFlags(
58 : 17557 : (basegfx::fTools::less(aScale.getX(), 0.0) ? BMP_MIRROR_HORZ : 0)|
59 [ - + ][ - + ]: 17557 : (basegfx::fTools::less(aScale.getY(), 0.0) ? BMP_MIRROR_VERT : 0));
60 : :
61 : : // rotation
62 [ - + ]: 17557 : if(!basegfx::fTools::equalZero(fRotate))
63 : : {
64 : 0 : double fRotation(fmod(3600.0 - (fRotate * (10.0 / F_PI180)), 3600.0));
65 : 0 : aAttributes.SetRotation((sal_uInt16)(fRotation));
66 : : }
67 : :
68 : : // prepare Bitmap
69 [ + - ]: 17557 : basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
70 : :
71 [ + - ]: 17557 : if(basegfx::fTools::equalZero(fRotate))
72 : : {
73 [ + - ]: 17557 : aOutlineRange.transform(rTransform);
74 : : }
75 : : else
76 : : {
77 : : // if rotated, create the unrotated output rectangle for the GraphicManager paint
78 : : const basegfx::B2DHomMatrix aSimpleObjectMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
79 : 0 : fabs(aScale.getX()), fabs(aScale.getY()),
80 [ # # ]: 0 : aTranslate.getX(), aTranslate.getY()));
81 : :
82 [ # # ][ # # ]: 0 : aOutlineRange.transform(aSimpleObjectMatrix);
83 : : }
84 : :
85 : : // prepare dest coordinates
86 : : const Point aPoint(
87 : : basegfx::fround(aOutlineRange.getMinX()),
88 [ + - ][ + - ]: 17557 : basegfx::fround(aOutlineRange.getMinY()));
89 : : const Size aSize(
90 : : basegfx::fround(aOutlineRange.getWidth()),
91 [ + - ][ + - ]: 17557 : basegfx::fround(aOutlineRange.getHeight()));
92 : :
93 : : // paint it using GraphicManager
94 [ + - ]: 17557 : Graphic aGraphic(rBitmapEx);
95 [ + - ]: 17557 : GraphicObject aGraphicObject(aGraphic);
96 [ + - ][ + - ]: 17557 : aGraphicObject.Draw(&rOutDev, aPoint, aSize, &aAttributes);
[ + - ][ + - ]
97 : 17557 : }
98 : :
99 : 0 : void RenderBitmapPrimitive2D_BitmapEx(
100 : : OutputDevice& rOutDev,
101 : : const BitmapEx& rBitmapEx,
102 : : const basegfx::B2DHomMatrix& rTransform)
103 : : {
104 : : // only translate and scale, use vcl's DrawBitmapEx().
105 [ # # ]: 0 : BitmapEx aContent(rBitmapEx);
106 : :
107 : : // prepare dest coor. Necessary to expand since vcl's DrawBitmapEx draws one pix less
108 [ # # ]: 0 : basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
109 [ # # ]: 0 : aOutlineRange.transform(rTransform);
110 : : // prepare dest coordinates
111 : : const Point aPoint(
112 : : basegfx::fround(aOutlineRange.getMinX()),
113 [ # # ][ # # ]: 0 : basegfx::fround(aOutlineRange.getMinY()));
114 : : const Size aSize(
115 : : basegfx::fround(aOutlineRange.getWidth()),
116 [ # # ][ # # ]: 0 : basegfx::fround(aOutlineRange.getHeight()));
117 : :
118 : : // decompose matrix to check for shear, rotate and mirroring
119 : 0 : basegfx::B2DVector aScale, aTranslate;
120 : : double fRotate, fShearX;
121 [ # # ]: 0 : rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
122 : :
123 : : // Check mirroring.
124 : 0 : sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE);
125 : :
126 [ # # ]: 0 : if(basegfx::fTools::less(aScale.getX(), 0.0))
127 : : {
128 : 0 : nMirrorFlags |= BMP_MIRROR_HORZ;
129 : : }
130 : :
131 [ # # ]: 0 : if(basegfx::fTools::less(aScale.getY(), 0.0))
132 : : {
133 : 0 : nMirrorFlags |= BMP_MIRROR_VERT;
134 : : }
135 : :
136 [ # # ]: 0 : if(BMP_MIRROR_NONE != nMirrorFlags)
137 : : {
138 [ # # ]: 0 : aContent.Mirror(nMirrorFlags);
139 : : }
140 : :
141 : : // draw bitmap
142 [ # # ][ # # ]: 0 : rOutDev.DrawBitmapEx(aPoint, aSize, aContent);
143 : 0 : }
144 : :
145 : 0 : void RenderBitmapPrimitive2D_self(
146 : : OutputDevice& rOutDev,
147 : : const BitmapEx& rBitmapEx,
148 : : const basegfx::B2DHomMatrix& rTransform)
149 : : {
150 : : // process self with free transformation (containing shear and rotate). Get dest rect in pixels.
151 [ # # ]: 0 : basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
152 [ # # ]: 0 : aOutlineRange.transform(rTransform);
153 : : const Rectangle aDestRectLogic(
154 : : basegfx::fround(aOutlineRange.getMinX()),
155 : : basegfx::fround(aOutlineRange.getMinY()),
156 : : basegfx::fround(aOutlineRange.getMaxX()),
157 [ # # ][ # # ]: 0 : basegfx::fround(aOutlineRange.getMaxY()));
[ # # ][ # # ]
[ # # ]
158 [ # # ]: 0 : const Rectangle aDestRectPixel(rOutDev.LogicToPixel(aDestRectLogic));
159 : :
160 : : // #i96708# check if Metafile is recorded
161 : 0 : const GDIMetaFile* pMetaFile = rOutDev.GetConnectMetaFile();
162 [ # # ][ # # ]: 0 : const bool bRecordToMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
[ # # ]
163 : :
164 : : // intersect with output pixel size, but only
165 : : // when not recording to metafile
166 [ # # ]: 0 : const Rectangle aOutputRectPixel(Point(), rOutDev.GetOutputSizePixel());
167 [ # # ][ # # ]: 0 : Rectangle aCroppedRectPixel(bRecordToMetaFile ? aDestRectPixel : aDestRectPixel.GetIntersection(aOutputRectPixel));
168 : :
169 [ # # ][ # # ]: 0 : if(!aCroppedRectPixel.IsEmpty())
170 : : {
171 : : // as maximum for destination, orientate at aOutputRectPixel, but
172 : : // take a rotation of 45 degrees (sqrt(2)) as maximum expansion into account
173 : 0 : const Size aSourceSizePixel(rBitmapEx.GetSizePixel());
174 : : const double fMaximumArea(
175 : 0 : (double)aOutputRectPixel.getWidth() *
176 : 0 : (double)aOutputRectPixel.getHeight() *
177 : 0 : 1.4142136); // 1.4142136 taken as sqrt(2.0)
178 : :
179 : : // test if discrete view size (pixel) maybe too big and limit it
180 : 0 : const double fArea(aCroppedRectPixel.getWidth() * aCroppedRectPixel.getHeight());
181 : 0 : const bool bNeedToReduce(fArea > fMaximumArea);
182 : 0 : double fReduceFactor(1.0);
183 [ # # ]: 0 : const Size aDestSizePixel(aCroppedRectPixel.GetSize());
184 : :
185 [ # # ]: 0 : if(bNeedToReduce)
186 : : {
187 : 0 : fReduceFactor = sqrt(fMaximumArea / fArea);
188 : 0 : aCroppedRectPixel.setWidth(basegfx::fround(aCroppedRectPixel.getWidth() * fReduceFactor));
189 : 0 : aCroppedRectPixel.setHeight(basegfx::fround(aCroppedRectPixel.getHeight() * fReduceFactor));
190 : : }
191 : :
192 : : // build transform from pixel in aDestination to pixel in rBitmapEx
193 : : // from relative in aCroppedRectPixel to relative in aDestRectPixel
194 : : // No need to take bNeedToReduce into account, TopLeft is unchanged
195 : : basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
196 : 0 : aCroppedRectPixel.Left() - aDestRectPixel.Left(),
197 [ # # ]: 0 : aCroppedRectPixel.Top() - aDestRectPixel.Top()));
198 : :
199 : : // from relative in aDestRectPixel to absolute Logic. Here it
200 : : // is essential to adapt to reduce factor (if used)
201 : 0 : double fAdaptedDRPWidth((double)aDestRectPixel.getWidth());
202 : 0 : double fAdaptedDRPHeight((double)aDestRectPixel.getHeight());
203 : :
204 [ # # ]: 0 : if(bNeedToReduce)
205 : : {
206 : 0 : fAdaptedDRPWidth *= fReduceFactor;
207 : 0 : fAdaptedDRPHeight *= fReduceFactor;
208 : : }
209 : :
210 : : aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
211 : 0 : aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight,
212 : 0 : aDestRectLogic.Left(), aDestRectLogic.Top())
213 [ # # ][ # # ]: 0 : * aTransform;
[ # # ][ # # ]
[ # # ]
214 : :
215 : : // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y)
216 [ # # ]: 0 : basegfx::B2DHomMatrix aInvBitmapTransform(rTransform);
217 [ # # ]: 0 : aInvBitmapTransform.invert();
218 [ # # ][ # # ]: 0 : aTransform = aInvBitmapTransform * aTransform;
[ # # ]
219 : :
220 : : // from unit object coordinates to rBitmapEx pixel coordintes
221 [ # # ]: 0 : aTransform.scale(aSourceSizePixel.getWidth() - 1L, aSourceSizePixel.getHeight() - 1L);
222 : :
223 : : // create bitmap using source, destination and linear back-transformation
224 [ # # ]: 0 : BitmapEx aDestination = impTransformBitmapEx(rBitmapEx, aCroppedRectPixel, aTransform);
225 : :
226 : : // paint
227 [ # # ]: 0 : if(bNeedToReduce)
228 : : {
229 : : // paint in target size
230 [ # # ]: 0 : if(bRecordToMetaFile)
231 : : {
232 : : rOutDev.DrawBitmapEx(
233 : 0 : rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
234 : : rOutDev.PixelToLogic(aDestSizePixel),
235 [ # # # # ]: 0 : aDestination);
[ # # ]
236 : : }
237 : : else
238 : : {
239 : 0 : const bool bWasEnabled(rOutDev.IsMapModeEnabled());
240 [ # # ]: 0 : rOutDev.EnableMapMode(false);
241 : :
242 : : rOutDev.DrawBitmapEx(
243 : : aCroppedRectPixel.TopLeft(),
244 : : aDestSizePixel,
245 [ # # ]: 0 : aDestination);
246 : :
247 [ # # ]: 0 : rOutDev.EnableMapMode(bWasEnabled);
248 : : }
249 : : }
250 : : else
251 : : {
252 [ # # ]: 0 : if(bRecordToMetaFile)
253 : : {
254 : : rOutDev.DrawBitmapEx(
255 : 0 : rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
256 [ # # ][ # # ]: 0 : aDestination);
257 : : }
258 : : else
259 : : {
260 : 0 : const bool bWasEnabled(rOutDev.IsMapModeEnabled());
261 [ # # ]: 0 : rOutDev.EnableMapMode(false);
262 : :
263 : : rOutDev.DrawBitmapEx(
264 : : aCroppedRectPixel.TopLeft(),
265 [ # # ]: 0 : aDestination);
266 : :
267 [ # # ]: 0 : rOutDev.EnableMapMode(bWasEnabled);
268 : : }
269 [ # # ][ # # ]: 0 : }
[ # # ]
270 : : }
271 : 0 : }
272 : : } // end of namespace drawinglayer
273 : :
274 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|