fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / drawinglayer / source / processor2d / vclhelperbitmaprender.cxx
blob37ee61df9be315f9599808f7cce4bb6c656c6d97
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 #include <vclhelperbitmaprender.hxx>
21 #include <svtools/grfmgr.hxx>
22 #include <basegfx/vector/b2dvector.hxx>
23 #include <basegfx/matrix/b2dhommatrix.hxx>
24 #include <basegfx/range/b2drange.hxx>
25 #include <vcl/outdev.hxx>
26 #include <vclhelperbitmaptransform.hxx>
27 #include <basegfx/matrix/b2dhommatrixtools.hxx>
29 //////////////////////////////////////////////////////////////////////////////
30 // support for different kinds of bitmap rendering using vcl
32 namespace drawinglayer
34 void RenderBitmapPrimitive2D_GraphicManager(
35 OutputDevice& rOutDev,
36 const BitmapEx& rBitmapEx,
37 const basegfx::B2DHomMatrix& rTransform)
39 // prepare attributes
40 GraphicAttr aAttributes;
42 // decompose matrix to check for shear, rotate and mirroring
43 basegfx::B2DVector aScale, aTranslate;
44 double fRotate, fShearX;
45 rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
47 // mirror flags
48 const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
49 const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
50 aAttributes.SetMirrorFlags((bMirrorX ? BMP_MIRROR_HORZ : 0)|(bMirrorY ? BMP_MIRROR_VERT : 0));
52 // rotation
53 if(!basegfx::fTools::equalZero(fRotate))
55 double fRotation(fmod(3600.0 - (fRotate * (10.0 / F_PI180)), 3600.0));
56 aAttributes.SetRotation((sal_uInt16)(fRotation));
59 // prepare Bitmap
60 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
62 if(basegfx::fTools::equalZero(fRotate))
64 aOutlineRange.transform(rTransform);
66 else
68 // if rotated, create the unrotated output rectangle for the GraphicManager paint
69 // #118824# Caution! When mirrored, adapt transformation accordingly
70 const basegfx::B2DHomMatrix aSimpleObjectMatrix(
71 basegfx::tools::createScaleTranslateB2DHomMatrix(
72 fabs(aScale.getX()),
73 fabs(aScale.getY()),
74 bMirrorX ? aTranslate.getX() - fabs(aScale.getX()): aTranslate.getX(),
75 bMirrorY ? aTranslate.getY() - fabs(aScale.getY()): aTranslate.getY()));
77 aOutlineRange.transform(aSimpleObjectMatrix);
80 // prepare dest coordinates
81 const Point aPoint(
82 basegfx::fround(aOutlineRange.getMinX()),
83 basegfx::fround(aOutlineRange.getMinY()));
84 const Size aSize(
85 basegfx::fround(aOutlineRange.getWidth()),
86 basegfx::fround(aOutlineRange.getHeight()));
88 // paint it using GraphicManager
89 Graphic aGraphic(rBitmapEx);
90 GraphicObject aGraphicObject(aGraphic);
91 aGraphicObject.Draw(&rOutDev, aPoint, aSize, &aAttributes);
94 void RenderBitmapPrimitive2D_BitmapEx(
95 OutputDevice& rOutDev,
96 const BitmapEx& rBitmapEx,
97 const basegfx::B2DHomMatrix& rTransform)
99 // only translate and scale, use vcl's DrawBitmapEx().
100 BitmapEx aContent(rBitmapEx);
102 // prepare dest coor. Necessary to expand since vcl's DrawBitmapEx draws one pix less
103 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
104 aOutlineRange.transform(rTransform);
105 // prepare dest coordinates
106 const Point aPoint(
107 basegfx::fround(aOutlineRange.getMinX()),
108 basegfx::fround(aOutlineRange.getMinY()));
109 const Size aSize(
110 basegfx::fround(aOutlineRange.getWidth()),
111 basegfx::fround(aOutlineRange.getHeight()));
113 // decompose matrix to check for shear, rotate and mirroring
114 basegfx::B2DVector aScale, aTranslate;
115 double fRotate, fShearX;
116 rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
118 // Check mirroring.
119 sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE);
121 if(basegfx::fTools::less(aScale.getX(), 0.0))
123 nMirrorFlags |= BMP_MIRROR_HORZ;
126 if(basegfx::fTools::less(aScale.getY(), 0.0))
128 nMirrorFlags |= BMP_MIRROR_VERT;
131 if(BMP_MIRROR_NONE != nMirrorFlags)
133 aContent.Mirror(nMirrorFlags);
136 // draw bitmap
137 rOutDev.DrawBitmapEx(aPoint, aSize, aContent);
140 void RenderBitmapPrimitive2D_self(
141 OutputDevice& rOutDev,
142 const BitmapEx& rBitmapEx,
143 const basegfx::B2DHomMatrix& rTransform)
145 // process self with free transformation (containing shear and rotate). Get dest rect in pixels.
146 basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
147 aOutlineRange.transform(rTransform);
148 const Rectangle aDestRectLogic(
149 basegfx::fround(aOutlineRange.getMinX()),
150 basegfx::fround(aOutlineRange.getMinY()),
151 basegfx::fround(aOutlineRange.getMaxX()),
152 basegfx::fround(aOutlineRange.getMaxY()));
153 const Rectangle aDestRectPixel(rOutDev.LogicToPixel(aDestRectLogic));
155 // #i96708# check if Metafile is recorded
156 const GDIMetaFile* pMetaFile = rOutDev.GetConnectMetaFile();
157 const bool bRecordToMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
159 // intersect with output pixel size, but only
160 // when not recording to metafile
161 const Rectangle aOutputRectPixel(Point(), rOutDev.GetOutputSizePixel());
162 Rectangle aCroppedRectPixel(bRecordToMetaFile ? aDestRectPixel : aDestRectPixel.GetIntersection(aOutputRectPixel));
164 if(!aCroppedRectPixel.IsEmpty())
166 // as maximum for destination, orientate at aOutputRectPixel, but
167 // take a rotation of 45 degrees (sqrt(2)) as maximum expansion into account
168 const Size aSourceSizePixel(rBitmapEx.GetSizePixel());
169 const double fMaximumArea(
170 (double)aOutputRectPixel.getWidth() *
171 (double)aOutputRectPixel.getHeight() *
172 1.4142136); // 1.4142136 taken as sqrt(2.0)
174 // test if discrete view size (pixel) maybe too big and limit it
175 const double fArea(aCroppedRectPixel.getWidth() * aCroppedRectPixel.getHeight());
176 const bool bNeedToReduce(fArea > fMaximumArea);
177 double fReduceFactor(1.0);
178 const Size aDestSizePixel(aCroppedRectPixel.GetSize());
180 if(bNeedToReduce)
182 fReduceFactor = sqrt(fMaximumArea / fArea);
183 aCroppedRectPixel.setWidth(basegfx::fround(aCroppedRectPixel.getWidth() * fReduceFactor));
184 aCroppedRectPixel.setHeight(basegfx::fround(aCroppedRectPixel.getHeight() * fReduceFactor));
187 // build transform from pixel in aDestination to pixel in rBitmapEx
188 // from relative in aCroppedRectPixel to relative in aDestRectPixel
189 // No need to take bNeedToReduce into account, TopLeft is unchanged
190 basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
191 aCroppedRectPixel.Left() - aDestRectPixel.Left(),
192 aCroppedRectPixel.Top() - aDestRectPixel.Top()));
194 // from relative in aDestRectPixel to absolute Logic. Here it
195 // is essential to adapt to reduce factor (if used)
196 double fAdaptedDRPWidth((double)aDestRectPixel.getWidth());
197 double fAdaptedDRPHeight((double)aDestRectPixel.getHeight());
199 if(bNeedToReduce)
201 fAdaptedDRPWidth *= fReduceFactor;
202 fAdaptedDRPHeight *= fReduceFactor;
205 aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
206 aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight,
207 aDestRectLogic.Left(), aDestRectLogic.Top())
208 * aTransform;
210 // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y)
211 basegfx::B2DHomMatrix aInvBitmapTransform(rTransform);
212 aInvBitmapTransform.invert();
213 aTransform = aInvBitmapTransform * aTransform;
215 // from unit object coordinates to rBitmapEx pixel coordintes
216 aTransform.scale(aSourceSizePixel.getWidth() - 1L, aSourceSizePixel.getHeight() - 1L);
218 // create bitmap using source, destination and linear back-transformation
219 BitmapEx aDestination = impTransformBitmapEx(rBitmapEx, aCroppedRectPixel, aTransform);
221 // paint
222 if(bNeedToReduce)
224 // paint in target size
225 if(bRecordToMetaFile)
227 rOutDev.DrawBitmapEx(
228 rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
229 rOutDev.PixelToLogic(aDestSizePixel),
230 aDestination);
232 else
234 const bool bWasEnabled(rOutDev.IsMapModeEnabled());
235 rOutDev.EnableMapMode(false);
237 rOutDev.DrawBitmapEx(
238 aCroppedRectPixel.TopLeft(),
239 aDestSizePixel,
240 aDestination);
242 rOutDev.EnableMapMode(bWasEnabled);
245 else
247 if(bRecordToMetaFile)
249 rOutDev.DrawBitmapEx(
250 rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()),
251 aDestination);
253 else
255 const bool bWasEnabled(rOutDev.IsMapModeEnabled());
256 rOutDev.EnableMapMode(false);
258 rOutDev.DrawBitmapEx(
259 aCroppedRectPixel.TopLeft(),
260 aDestination);
262 rOutDev.EnableMapMode(bWasEnabled);
267 } // end of namespace drawinglayer
269 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */