Update ooo320-m1
[ooovba.git] / drawinglayer / source / processor2d / vclhelperbitmaptransform.cxx
blobd5f3388de5ef8cf4ecc4ebe8fbbc8dc950bf49e2
1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: vclhelperbitmaptransform.cxx,v $
7 * $Revision: 1.4 $
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 <vclhelperbitmaptransform.hxx>
40 #include <vcl/bmpacc.hxx>
41 #include <basegfx/point/b2dpoint.hxx>
42 #include <basegfx/color/bcolormodifier.hxx>
44 //////////////////////////////////////////////////////////////////////////////
45 // support for rendering Bitmap and BitmapEx contents
47 namespace drawinglayer
49 namespace
51 void impSmoothPoint(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead)
53 double fDeltaX(rSource.getX() - nIntX);
54 double fDeltaY(rSource.getY() - nIntY);
55 sal_Int32 nIndX(0L);
56 sal_Int32 nIndY(0L);
58 if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width())
60 nIndX++;
62 else if(fDeltaX < 0.0 && nIntX >= 1L)
64 fDeltaX = -fDeltaX;
65 nIndX--;
68 if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height())
70 nIndY++;
72 else if(fDeltaY < 0.0 && nIntY >= 1L)
74 fDeltaY = -fDeltaY;
75 nIndY--;
78 if(nIndX || nIndY)
80 const double fColorToReal(1.0 / 255.0);
81 double fR(rValue.GetRed() * fColorToReal);
82 double fG(rValue.GetGreen() * fColorToReal);
83 double fB(rValue.GetBlue() * fColorToReal);
84 double fRBottom(0.0), fGBottom(0.0), fBBottom(0.0);
86 if(nIndX)
88 const double fMulA(fDeltaX * fColorToReal);
89 double fMulB(1.0 - fDeltaX);
90 const BitmapColor aTopPartner(rRead.GetColor(nIntY, nIntX + nIndX));
92 fR = (fR * fMulB) + (aTopPartner.GetRed() * fMulA);
93 fG = (fG * fMulB) + (aTopPartner.GetGreen() * fMulA);
94 fB = (fB * fMulB) + (aTopPartner.GetBlue() * fMulA);
96 if(nIndY)
98 fMulB *= fColorToReal;
99 const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX));
100 const BitmapColor aBottomPartner(rRead.GetColor(nIntY + nIndY, nIntX + nIndX));
102 fRBottom = (aBottom.GetRed() * fMulB) + (aBottomPartner.GetRed() * fMulA);
103 fGBottom = (aBottom.GetGreen() * fMulB) + (aBottomPartner.GetGreen() * fMulA);
104 fBBottom = (aBottom.GetBlue() * fMulB) + (aBottomPartner.GetBlue() * fMulA);
108 if(nIndY)
110 if(!nIndX)
112 const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX));
114 fRBottom = aBottom.GetRed() * fColorToReal;
115 fGBottom = aBottom.GetGreen() * fColorToReal;
116 fBBottom = aBottom.GetBlue() * fColorToReal;
119 const double fMulB(1.0 - fDeltaY);
121 fR = (fR * fMulB) + (fRBottom * fDeltaY);
122 fG = (fG * fMulB) + (fGBottom * fDeltaY);
123 fB = (fB * fMulB) + (fBBottom * fDeltaY);
126 rValue.SetRed((sal_uInt8)(fR * 255.0));
127 rValue.SetGreen((sal_uInt8)(fG * 255.0));
128 rValue.SetBlue((sal_uInt8)(fB * 255.0));
132 void impSmoothIndex(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead)
134 double fDeltaX(rSource.getX() - nIntX);
135 double fDeltaY(rSource.getY() - nIntY);
136 sal_Int32 nIndX(0L);
137 sal_Int32 nIndY(0L);
139 if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width())
141 nIndX++;
143 else if(fDeltaX < 0.0 && nIntX >= 1L)
145 fDeltaX = -fDeltaX;
146 nIndX--;
149 if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height())
151 nIndY++;
153 else if(fDeltaY < 0.0 && nIntY >= 1L)
155 fDeltaY = -fDeltaY;
156 nIndY--;
159 if(nIndX || nIndY)
161 const double fColorToReal(1.0 / 255.0);
162 double fVal(rValue.GetIndex() * fColorToReal);
163 double fValBottom(0.0);
165 if(nIndX)
167 const double fMulA(fDeltaX * fColorToReal);
168 double fMulB(1.0 - fDeltaX);
169 const BitmapColor aTopPartner(rRead.GetPixel(nIntY, nIntX + nIndX));
171 fVal = (fVal * fMulB) + (aTopPartner.GetIndex() * fMulA);
173 if(nIndY)
175 fMulB *= fColorToReal;
176 const BitmapColor aBottom(rRead.GetPixel(nIntY + nIndY, nIntX));
177 const BitmapColor aBottomPartner(rRead.GetPixel(nIntY + nIndY, nIntX + nIndX));
179 fValBottom = (aBottom.GetIndex() * fMulB) + (aBottomPartner.GetIndex() * fMulA);
183 if(nIndY)
185 if(!nIndX)
187 const BitmapColor aBottom(rRead.GetPixel(nIntY + nIndY, nIntX));
189 fValBottom = aBottom.GetIndex() * fColorToReal;
192 const double fMulB(1.0 - fDeltaY);
194 fVal = (fVal * fMulB) + (fValBottom * fDeltaY);
197 rValue.SetIndex((sal_uInt8)(fVal * 255.0));
201 void impTransformBitmap(const Bitmap& rSource, Bitmap& rDestination, const basegfx::B2DHomMatrix& rTransform, bool bSmooth)
203 BitmapWriteAccess* pWrite = rDestination.AcquireWriteAccess();
205 if(pWrite)
207 const Size aContentSizePixel(rSource.GetSizePixel());
208 BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess();
210 if(pRead)
212 const Size aDestinationSizePixel(rDestination.GetSizePixel());
213 bool bWorkWithIndex(rDestination.GetBitCount() <= 8);
214 BitmapColor aOutside(pRead->GetBestMatchingColor(BitmapColor(0xff, 0xff, 0xff)));
216 for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++)
218 for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++)
220 const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y));
221 const sal_Int32 nIntX(basegfx::fround(aSourceCoor.getX()));
223 if(nIntX >= 0L && nIntX < aContentSizePixel.getWidth())
225 const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY()));
227 if(nIntY >= 0L && nIntY < aContentSizePixel.getHeight())
229 if(bWorkWithIndex)
231 BitmapColor aValue(pRead->GetPixel(nIntY, nIntX));
233 if(bSmooth)
235 impSmoothIndex(aValue, aSourceCoor, nIntX, nIntY, *pRead);
238 pWrite->SetPixel(y, x, aValue);
240 else
242 BitmapColor aValue(pRead->GetColor(nIntY, nIntX));
244 if(bSmooth)
246 impSmoothPoint(aValue, aSourceCoor, nIntX, nIntY, *pRead);
249 pWrite->SetPixel(y, x, aValue.IsIndex() ? aValue : pWrite->GetBestMatchingColor(aValue));
252 continue;
256 // here are outside pixels. Complete mask
257 if(bWorkWithIndex)
259 pWrite->SetPixel(y, x, aOutside);
264 delete pRead;
267 delete pWrite;
271 Bitmap impCreateEmptyBitmapWithPattern(const Bitmap& rSource, const Size& aTargetSizePixel)
273 Bitmap aRetval;
274 BitmapReadAccess* pReadAccess = (const_cast< Bitmap& >(rSource)).AcquireReadAccess();
276 if(pReadAccess)
278 if(rSource.GetBitCount() <= 8)
280 BitmapPalette aPalette(pReadAccess->GetPalette());
281 aRetval = Bitmap(aTargetSizePixel, rSource.GetBitCount(), &aPalette);
283 else
285 aRetval = Bitmap(aTargetSizePixel, rSource.GetBitCount());
288 delete pReadAccess;
291 return aRetval;
293 } // end of anonymous namespace
294 } // end of namespace drawinglayer
296 namespace drawinglayer
298 BitmapEx impTransformBitmapEx(
299 const BitmapEx& rSource,
300 const Rectangle& rCroppedRectPixel,
301 const basegfx::B2DHomMatrix& rTransform)
303 // force destination to 24 bit, we want to smooth output
304 const Size aDestinationSize(rCroppedRectPixel.GetSize());
305 Bitmap aDestination(impCreateEmptyBitmapWithPattern(rSource.GetBitmap(), aDestinationSize));
306 static bool bDoSmoothAtAll(true);
307 impTransformBitmap(rSource.GetBitmap(), aDestination, rTransform, bDoSmoothAtAll);
309 // create mask
310 if(rSource.IsTransparent())
312 if(rSource.IsAlpha())
314 Bitmap aAlpha(impCreateEmptyBitmapWithPattern(rSource.GetAlpha().GetBitmap(), aDestinationSize));
315 impTransformBitmap(rSource.GetAlpha().GetBitmap(), aAlpha, rTransform, bDoSmoothAtAll);
316 return BitmapEx(aDestination, AlphaMask(aAlpha));
318 else
320 Bitmap aMask(impCreateEmptyBitmapWithPattern(rSource.GetMask(), aDestinationSize));
321 impTransformBitmap(rSource.GetMask(), aMask, rTransform, false);
322 return BitmapEx(aDestination, aMask);
326 return BitmapEx(aDestination);
329 BitmapEx impModifyBitmapEx(
330 const basegfx::BColorModifierStack& rBColorModifierStack,
331 const BitmapEx& rSource)
333 Bitmap aChangedBitmap(rSource.GetBitmap());
334 bool bDone(false);
336 for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; )
338 const basegfx::BColorModifier& rModifier = rBColorModifierStack.getBColorModifier(--a);
340 switch(rModifier.getMode())
342 case basegfx::BCOLORMODIFYMODE_REPLACE :
344 // complete replace
345 if(rSource.IsTransparent())
347 // clear bitmap with dest color
348 if(aChangedBitmap.GetBitCount() <= 8)
350 // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given
351 // erase color is determined and used -> this may be different from what is
352 // wanted here. Better create a new bitmap with the needed color explicitely
353 BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess();
354 OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?");
356 if(pReadAccess)
358 BitmapPalette aNewPalette(pReadAccess->GetPalette());
359 aNewPalette[0] = BitmapColor(Color(rModifier.getBColor()));
360 aChangedBitmap = Bitmap(
361 aChangedBitmap.GetSizePixel(),
362 aChangedBitmap.GetBitCount(),
363 &aNewPalette);
364 delete pReadAccess;
367 else
369 aChangedBitmap.Erase(Color(rModifier.getBColor()));
372 else
374 // erase bitmap, caller will know to paint direct
375 aChangedBitmap.SetEmpty();
378 bDone = true;
379 break;
382 default : // BCOLORMODIFYMODE_INTERPOLATE, BCOLORMODIFYMODE_GRAY, BCOLORMODIFYMODE_BLACKANDWHITE
384 BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess();
386 if(pContent)
388 const double fConvertColor(1.0 / 255.0);
390 for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++)
392 for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++)
394 const BitmapColor aBMCol(pContent->GetColor(y, x));
395 const basegfx::BColor aBSource(
396 (double)aBMCol.GetRed() * fConvertColor,
397 (double)aBMCol.GetGreen() * fConvertColor,
398 (double)aBMCol.GetBlue() * fConvertColor);
399 const basegfx::BColor aBDest(rModifier.getModifiedColor(aBSource));
401 pContent->SetPixel(y, x, BitmapColor(Color(aBDest)));
405 delete pContent;
408 break;
413 if(aChangedBitmap.IsEmpty())
415 return BitmapEx();
417 else
419 if(rSource.IsTransparent())
421 if(rSource.IsAlpha())
423 return BitmapEx(aChangedBitmap, rSource.GetAlpha());
425 else
427 return BitmapEx(aChangedBitmap, rSource.GetMask());
430 else
432 return BitmapEx(aChangedBitmap);
436 } // end of namespace drawinglayer
438 //////////////////////////////////////////////////////////////////////////////
439 // eof