1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #ifndef INCLUDED_VCL_BITMAPEX_HXX
21 #define INCLUDED_VCL_BITMAPEX_HXX
22 
23 #include <vcl/dllapi.h>
24 #include <vcl/alpha.hxx>
25 #include <vcl/Scanline.hxx>
26 #include <tools/color.hxx>
27 #include <tools/degree.hxx>
28 #include <tools/solar.h>
29 
30 #include <sal/types.h>
31 
32 namespace com::sun::star::rendering {
33     class XBitmapCanvas;
34 }
35 namespace com::sun::star::uno { template <class interface_type> class Reference; }
36 namespace basegfx { class BColorModifierStack; }
37 
38 class SAL_WARN_UNUSED VCL_DLLPUBLIC BitmapEx
39 {
40 public:
41 
42                         BitmapEx();
43     explicit            BitmapEx( const OUString& rIconName );
44                         BitmapEx( const BitmapEx& rBitmapEx );
45                         BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize );
46                         BitmapEx(Size aSize, vcl::PixelFormat ePixelFormat);
47     explicit            BitmapEx( const Bitmap& rBmp );
48                         BitmapEx( const Bitmap& rBmp, const Bitmap& rMask );
49                         BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask );
50                         BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor );
51 
52     BitmapEx&           operator=( const BitmapEx& rBitmapEx );
operator =(const Bitmap & rBitmap)53     BitmapEx&           operator=( const Bitmap& rBitmap ) { return operator=(BitmapEx(rBitmap)); }
54     bool                operator==( const BitmapEx& rBitmapEx ) const;
operator !=(const BitmapEx & rBitmapEx) const55     bool                operator!=( const BitmapEx& rBitmapEx ) const { return !(*this==rBitmapEx); }
56 
57     bool                IsEmpty() const;
58     void                SetEmpty();
59     void                Clear();
60 
61     void                Draw( OutputDevice* pOutDev,
62                               const Point& rDestPt ) const;
63     void                Draw( OutputDevice* pOutDev,
64                               const Point& rDestPt, const Size& rDestSize ) const;
65 
66     Bitmap              GetBitmap( Color aTransparentReplaceColor ) const;
67     /// Gives direct access to the contained bitmap.
68     const Bitmap&       GetBitmap() const;
69 
70     bool                IsAlpha() const;
71     AlphaMask           GetAlpha() const;
72 
GetSizePixel() const73     const Size&         GetSizePixel() const { return maBitmapSize; }
74     void                SetSizePixel(const Size& rNewSize);
75 
GetPrefSize() const76     const Size&         GetPrefSize() const { return maBitmap.GetPrefSize(); }
SetPrefSize(const Size & rPrefSize)77     void                SetPrefSize( const Size& rPrefSize ) { maBitmap.SetPrefSize( rPrefSize ); }
78 
GetPrefMapMode() const79     const MapMode&      GetPrefMapMode() const { return maBitmap.GetPrefMapMode(); }
SetPrefMapMode(const MapMode & rPrefMapMode)80     void                SetPrefMapMode( const MapMode& rPrefMapMode ) { maBitmap.SetPrefMapMode( rPrefMapMode ); }
81 
getPixelFormat() const82     vcl::PixelFormat getPixelFormat() const
83     {
84         return maBitmap.getPixelFormat();
85     }
86 
87     sal_Int64           GetSizeBytes() const;
88     BitmapChecksum      GetChecksum() const;
89 
90     /** Convert bitmap format
91 
92         @param eConversion
93         The format this bitmap should be converted to.
94 
95         @return true, if the conversion was completed successfully.
96      */
97     bool                Convert( BmpConversion eConversion );
98 
99     /** Crop the bitmap
100 
101         @param rRectPixel
102         A rectangle specifying the crop amounts on all four sides of
103         the bitmap. If the upper left corner of the bitmap is assigned
104         (0,0), then this method cuts out the given rectangle from the
105         bitmap. Note that the rectangle is clipped to the bitmap's
106         dimension, i.e. negative left,top rectangle coordinates or
107         exceeding width or height is ignored.
108 
109         @return true, if cropping was performed successfully. If
110         nothing had to be cropped, because e.g. the crop rectangle
111         included the bitmap, false is returned, too!
112      */
113     bool                Crop( const tools::Rectangle& rRectPixel );
114 
115     /** Expand the bitmap by pixel padding
116 
117         @param nDX
118         Number of pixel to pad at the right border of the bitmap
119 
120         @param nDY
121         Number of scanlines to pad at the bottom border of the bitmap
122 
123         @param bExpandTransparent
124         Whether to expand the transparency color or not.
125      */
126     void                Expand(
127                             sal_Int32 nDX, sal_Int32 nDY,
128                             bool bExpandTransparent = false );
129 
130     /** Copy a rectangular area from another bitmap
131 
132         @param rRectDst
133         Destination rectangle in this bitmap. This is clipped to the
134         bitmap dimensions.
135 
136         @param rRectSrc
137         Source rectangle in pBmpSrc. This is clipped to the source
138         bitmap dimensions. Note further that no scaling takes place
139         during this copy operation, i.e. only the minimum of source
140         and destination rectangle's width and height are used.
141 
142         @param pBmpExSrc
143         The source bitmap to copy from. If this argument is NULL, or
144         equal to the object this method is called on, copying takes
145         place within the same bitmap.
146 
147         @return true, if the operation completed successfully. false
148         is not only returned when the operation failed, but also if
149         nothing had to be done, e.g. because one of the rectangles are
150         empty.
151      */
152     bool                CopyPixel(
153                             const tools::Rectangle& rRectDst,
154                             const tools::Rectangle& rRectSrc,
155                             const BitmapEx* pBmpExSrc );
156 
157     /** Fill the entire bitmap with the given color
158 
159         @param rFillColor
160         Color value to use for filling. Set the transparency part of
161         the color to fill the mask.
162 
163         @return true, if the operation was completed successfully.
164      */
165     bool                Erase( const Color& rFillColor );
166 
167     /** Perform the Invert operation on every pixel
168 
169         @return true, if the operation was completed successfully.
170      */
171     bool                Invert();
172 
173     /** Mirror the bitmap
174 
175         @param nMirrorFlags
176         About which axis (horizontal, vertical, or both) to mirror
177 
178         @return true, if the operation was completed successfully.
179      */
180     bool                Mirror( BmpMirrorFlags nMirrorFlags );
181 
182     /** Scale the bitmap
183 
184         @param rNewSize
185         The resulting size of the scaled bitmap
186 
187         @param nScaleFlag
188         The algorithm to be used for scaling
189 
190         @return true, if the operation was completed successfully.
191      */
192     bool                Scale(
193                             const Size& rNewSize,
194                             BmpScaleFlag nScaleFlag = BmpScaleFlag::Default );
195 
196     /** Scale the bitmap
197 
198         @param rScaleX
199         The scale factor in x direction.
200 
201         @param rScaleY
202         The scale factor in y direction.
203 
204         @param nScaleFlag
205         The algorithm to be used for scaling
206 
207         @return true, if the operation was completed successfully.
208      */
209     bool                Scale(
210                             const double& rScaleX,
211                             const double& rScaleY,
212                             BmpScaleFlag nScaleFlag = BmpScaleFlag::Default );
213 
214     /** Rotate bitmap by the specified angle
215 
216         @param nAngle10
217         The rotation angle in tenth of a degree. The bitmap is always rotated around its center.
218 
219         @param rFillColor
220         The color to use for filling blank areas. During rotation, the
221         bitmap is enlarged such that the whole rotation result fits
222         in. The empty spaces around that rotated original bitmap are
223         then filled with this color.
224 
225         @return true, if the operation was completed successfully.
226      */
227     bool                Rotate(
228                             Degree10 nAngle10,
229                             const Color& rFillColor );
230 
231     /** Replace all pixel having the search color with the specified color
232 
233         @param rSearchColor
234         Color specifying which pixel should be replaced
235 
236         @param rReplaceColor
237         Color to be placed in all changed pixel
238      */
239     void                Replace(
240                             const Color& rSearchColor,
241                             const Color& rReplaceColor );
242 
243     /** Replace all pixel having the search color with the specified color
244 
245         @param rSearchColor
246         Color specifying which pixel should be replaced
247 
248         @param rReplaceColor
249         Color to be placed in all changed pixel
250 
251         @param nTolerance
252         Tolerance value. Specifies the maximal difference between
253         rSearchColor and the individual pixel values, such that the
254         corresponding pixel is still regarded a match.
255      */
256     void                Replace(
257                             const Color& rSearchColor,
258                             const Color& rReplaceColor,
259                             sal_uInt8 nTolerance );
260 
261     /** Replace all pixel having one the search colors with the corresponding replace color
262 
263         @param pSearchColors
264         Array of colors specifying which pixel should be replaced
265 
266         @param pReplaceColors
267         Array of colors to be placed in all changed pixel
268 
269         @param nColorCount
270         Size of the aforementioned color arrays
271 
272         @param pTols
273         Tolerance value. Specifies the maximal difference between
274         pSearchColor colors and the individual pixel values, such that
275         the corresponding pixel is still regarded a match.
276      */
277     void                Replace(
278                             const Color* pSearchColors,
279                             const Color* pReplaceColors,
280                             size_t nColorCount );
281 
282     /** Replace all pixel having one the search colors with the corresponding replace color
283 
284         @param pSearchColors
285         Array of colors specifying which pixel should be replaced
286 
287         @param rReplaceColors
288         Array of colors to be placed in all changed pixel
289 
290         @param nColorCount
291         Size of the aforementioned color arrays
292 
293         @param pTols
294         Tolerance value. Specifies the maximal difference between
295         pSearchColor colors and the individual pixel values, such that
296         the corresponding pixel is still regarded a match.
297 
298         @return true, if the operation was completed successfully.
299      */
300     void                Replace(
301                             const Color* pSearchColors,
302                             const Color* pReplaceColors,
303                             size_t nColorCount,
304                             sal_uInt8 const * pTols );
305 
306     /** Replace transparency with given color.
307      */
308     void                ReplaceTransparency( const Color& rColor );
309 
310     /** Get contours in image */
311     tools::Polygon      GetContour( bool bContourEdgeDetect, const tools::Rectangle* pWorkRect );
312 
313     /** Change various global color characteristics
314 
315         @param nLuminancePercent
316         Percent of luminance change, valid range [-100,100]. Values outside this range are clipped to the valid range.
317 
318         @param nContrastPercent
319         Percent of contrast change, valid range [-100,100]. Values outside this range are clipped to the valid range.
320 
321         @param nChannelRPercent
322         Percent of red channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
323 
324         @param nChannelGPercent
325         Percent of green channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
326 
327         @param nChannelBPercent
328         Percent of blue channel change, valid range [-100,100]. Values outside this range are clipped to the valid range.
329 
330         @param fGamma
331         Exponent of the gamma function applied to the bitmap. The
332         value 1.0 results in no change, the valid range is
333         (0.0,10.0]. Values outside this range are regarded as 1.0.
334 
335         @param bInvert
336         If true, invert the channel values with the logical 'not' operator
337 
338         @param msoBrightness
339         Use the same formula for brightness as used by MSOffice.
340 
341         @return true, if the operation was completed successfully.
342      */
343     bool                Adjust(
344                             short nLuminancePercent,
345                             short nContrastPercent,
346                             short nChannelRPercent,
347                             short nChannelGPercent,
348                             short nChannelBPercent,
349                             double fGamma = 1.0,
350                             bool bInvert = false,
351                             bool msoBrightness = false );
352 
353     /** Get alpha at given position
354 
355         @param nX
356         integer X-Position in Bitmap
357 
358         @param nY
359         integer Y-Position in Bitmap
360 
361         @return alpha value in the range of [0 .. 255] where
362                 0 is fully transparent, 255 is not transparent
363      */
364     sal_uInt8           GetAlpha(
365                             sal_Int32 nX,
366                             sal_Int32 nY) const;
367 
368     /** Get pixel color (including alpha) at given position
369 
370         @param nX
371         integer X-Position in Bitmap
372 
373         @param nY
374         integer Y-Position in Bitmap
375      */
376     ::Color             GetPixelColor(
377                             sal_Int32 nX,
378                             sal_Int32 nY) const;
379 
380     /** Create transformed Bitmap
381 
382         @param fWidth
383         The target width in pixels
384 
385         @param fHeight
386         The target height in pixels
387 
388         @param rTransformation
389         The back transformation for each pixel in (0 .. fWidth),(0 .. fHeight) to
390         local pixel coordinates
391     */
392     [[nodiscard]]
393     BitmapEx            TransformBitmapEx(
394                             double fWidth,
395                             double fHeight,
396                             const basegfx::B2DHomMatrix& rTransformation) const;
397 
398     /** Create transformed Bitmap
399 
400         @param rTransformation
401         The transformation from unit coordinates to the unit range
402 
403         @param rVisibleRange
404         The relative visible range in unit coordinates, relative to (0,0,1,1) which
405         defines the whole target area
406 
407         @param fMaximumArea
408         A limitation for the maximum size of pixels to use for the result
409 
410         The target size of the result bitmap is defined by transforming the given
411         rTargetRange with the given rTransformation; the area of the result is
412         linearly scaled to not exceed the given fMaximumArea
413 
414         @return The transformed bitmap
415     */
416     [[nodiscard]]
417     BitmapEx            getTransformed(
418                             const basegfx::B2DHomMatrix& rTransformation,
419                             const basegfx::B2DRange& rVisibleRange,
420                             double fMaximumArea) const;
421 
422     /** Create ColorStack-modified version of this BitmapEx
423 
424         @param rBColorModifierStack
425         A ColrModifierStack which defines how each pixel has to be modified
426     */
427     [[nodiscard]]
428     BitmapEx            ModifyBitmapEx( const basegfx::BColorModifierStack& rBColorModifierStack) const;
429 
430     [[nodiscard]]
431     static BitmapEx     AutoScaleBitmap( BitmapEx const & aBitmap, const tools::Long aStandardSize );
432 
433     /// populate from a canvas implementation
434     bool                Create(
435                             const css::uno::Reference< css::rendering::XBitmapCanvas > &xBitmapCanvas,
436                             const Size &rSize );
437 
438     void                setAlphaFrom( sal_uInt8 cIndexFrom, sal_Int8 nAlphaTo );
439 
440     void                AdjustTransparency( sal_uInt8 cTrans );
441 
442     void                CombineMaskOr(Color maskColor, sal_uInt8 nTol);
443 
444     /**
445      * Retrieves the color model data we need for the XImageConsumer stuff.
446      */
447     void                GetColorModel(css::uno::Sequence< sal_Int32 >& rRGBPalette,
448                             sal_uInt32& rnRedMask, sal_uInt32& rnGreenMask, sal_uInt32& rnBlueMask, sal_uInt32& rnAlphaMask, sal_uInt32& rnTransparencyIndex,
449                             sal_uInt32& rnWidth, sal_uInt32& rnHeight, sal_uInt8& rnBitCount);
450 
ImplGetBitmapSalBitmap() const451     SAL_DLLPRIVATE std::shared_ptr<SalBitmap> const & ImplGetBitmapSalBitmap() const { return maBitmap.ImplGetSalBitmap(); }
452 
453 
454 private:
455     friend class ImpGraphic;
456     friend class OutputDevice;
457     friend bool VCL_DLLPUBLIC WriteDIBBitmapEx(const BitmapEx& rSource, SvStream& rOStm);
458     friend bool VCL_DLLPUBLIC ReadRawDIB(BitmapEx& rTarget, const unsigned char* pBuf,
459                                     const ScanlineFormat nFormat,
460                                     const int nHeight,
461                                     const int nStride);
462 
463     void  loadFromIconTheme( const OUString& rIconName );
464 
465     Bitmap              maBitmap;
466     Bitmap              maAlphaMask;
467     Size                maBitmapSize;
468 };
469 
470 
471 /** Create a blend frame as BitmapEx
472 
473     @param nAlpha
474     The blend value defines how strong the frame will be blended with the
475     existing content, 255 == full coverage, 0 == no frame will be drawn
476 
477     @param aColorTopLeft, aColorBottomRight
478     The colors defining the frame. These colors are linearly interpolated from
479     aColorTopLeft and aColorBottomRight using the width and height of the area
480 
481     @param rSize
482     The size of the frame in pixels
483     */
484 BitmapEx VCL_DLLPUBLIC createBlendFrame(
485     const Size& rSize,
486     sal_uInt8 nAlpha,
487     Color aColorTopLeft,
488     Color aColorBottomRight);
489 
490 
491 /** Create a blend frame as BitmapEx
492 
493     @param nAlpha
494     The blend value defines how strong the frame will be blended with the
495     existing content, 255 == full coverage, 0 == no frame will be drawn
496 
497     @param aColorTopLeft, aColorBottomRight, aColorTopRight, aColorBottomLeft
498     The colors defining the frame.
499 
500     @param rSize
501     The size of the frame in pixels
502     */
503 BitmapEx createBlendFrame(
504     const Size& rSize,
505     sal_uInt8 nAlpha,
506     Color aColorTopLeft,
507     Color aColorTopRight,
508     Color aColorBottomRight,
509     Color aColorBottomLeft);
510 
511 #endif // INCLUDED_VCL_BITMAPEX_HXX
512 
513 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
514