LibreOffice Module vcl (master)  1
CairoCommon.hxx
Go to the documentation of this file.
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 #pragma once
21 
22 #include <sal/config.h>
23 #include <config_features.h>
24 
25 #include <cairo.h>
26 
27 #include <vcl/dllapi.h>
28 #include <vcl/region.hxx>
29 #include <vcl/salgtype.hxx>
30 #include <vcl/BitmapBuffer.hxx>
31 
32 #include <com/sun/star/drawing/LineCap.hpp>
33 
40 
41 #include <unordered_map>
42 
43 //Using formats that match cairo's formats. For android we patch cairo,
44 //which is internal in that case, to swap the rgb components so that
45 //cairo then matches the OpenGL GL_RGBA format so we can use it there
46 //where we don't have GL_BGRA support.
47 // SVP_24BIT_FORMAT is used to store 24-bit images in 3-byte pixels to conserve memory.
48 #if defined(ANDROID) && !HAVE_FEATURE_ANDROID_LOK
49 #define SVP_24BIT_FORMAT (ScanlineFormat::N24BitTcRgb | ScanlineFormat::TopDown)
50 #define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcRgba | ScanlineFormat::TopDown)
51 #define SVP_CAIRO_BLUE 1
52 #define SVP_CAIRO_GREEN 2
53 #define SVP_CAIRO_RED 0
54 #define SVP_CAIRO_ALPHA 3
55 #elif defined OSL_BIGENDIAN
56 #define SVP_24BIT_FORMAT (ScanlineFormat::N24BitTcRgb | ScanlineFormat::TopDown)
57 #define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcArgb | ScanlineFormat::TopDown)
58 #define SVP_CAIRO_BLUE 3
59 #define SVP_CAIRO_GREEN 2
60 #define SVP_CAIRO_RED 1
61 #define SVP_CAIRO_ALPHA 0
62 #else
63 #define SVP_24BIT_FORMAT (ScanlineFormat::N24BitTcBgr | ScanlineFormat::TopDown)
64 #define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcBgra | ScanlineFormat::TopDown)
65 #define SVP_CAIRO_BLUE 0
66 #define SVP_CAIRO_GREEN 1
67 #define SVP_CAIRO_RED 2
68 #define SVP_CAIRO_ALPHA 3
69 #endif
70 
71 typedef struct _cairo cairo_t;
72 typedef struct _cairo_surface cairo_surface_t;
73 typedef struct _cairo_user_data_key cairo_user_data_key_t;
74 
76  double y_scale);
78  double* y_scale);
79 
85 
87 {
88 private:
89  // the path data itself
90  cairo_path_t* mpCairoPath;
91 
92  // all other values the path data is based on and
93  // need to be compared with to check for data validity
94  bool mbNoJoin;
96  std::vector<double> maStroke;
97 
98 public:
100  size_t nSizeMeasure, cairo_t* cr, bool bNoJoin, bool bAntiAlias,
101  const std::vector<double>* pStroke); // MM01
102  virtual ~SystemDependentData_CairoPath() override;
103 
104  // read access
105  cairo_path_t* getCairoPath() { return mpCairoPath; }
106  bool getNoJoin() const { return mbNoJoin; }
107  bool getAntiAlias() const { return mbAntiAlias; }
108  const std::vector<double>& getStroke() const { return maStroke; }
109 
110  virtual sal_Int64 estimateUsageInBytes() const override;
111 };
112 
113 VCL_DLLPUBLIC size_t AddPolygonToPath(cairo_t* cr, const basegfx::B2DPolygon& rPolygon,
114  const basegfx::B2DHomMatrix& rObjectToDevice, bool bPixelSnap,
115  bool bPixelSnapHairline);
116 
118  const basegfx::B2DHomMatrix& rObjectToDevice,
119  basegfx::B2DHomMatrix& rObjectToDeviceInv,
120  sal_uInt32 nIndex);
121 
122 VCL_DLLPUBLIC void add_polygon_path(cairo_t* cr, const basegfx::B2DPolyPolygon& rPolyPolygon,
123  const basegfx::B2DHomMatrix& rObjectToDevice, bool bPixelSnap);
124 
125 VCL_DLLPUBLIC cairo_format_t getCairoFormat(const BitmapBuffer& rBuffer);
126 
127 VCL_DLLPUBLIC std::unique_ptr<BitmapBuffer>
129 
131 
132 enum class PaintMode
133 {
134  Over,
135  Xor
136 };
137 
138 typedef void (*damageHandler)(void* handle, sal_Int32 nExtentsX, sal_Int32 nExtentsY,
139  sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight);
140 
142 {
143  void* handle;
145 };
146 
148 {
155  double m_fScale;
156 
158  : m_pSurface(nullptr)
159  , m_aLineColor(Color(0x00, 0x00, 0x00))
160  , m_aFillColor(Color(0xFF, 0xFF, 0XFF))
161  , m_ePaintMode(PaintMode::Over)
162  , m_fScale(1.0)
163  {
164  }
165 
166  static cairo_user_data_key_t* getDamageKey();
167 
168  cairo_surface_t* getSurface() const { return m_pSurface; }
169 
170  cairo_t* getCairoContext(bool bXorModeAllowed, bool bAntiAlias) const;
171  void releaseCairoContext(cairo_t* cr, bool bXorModeAllowed,
172  const basegfx::B2DRange& rExtents) const;
173  cairo_t* createTmpCompatibleCairoContext() const;
174 
175  void applyColor(cairo_t* cr, Color rColor, double fTransparency = 0.0);
176  void clipRegion(cairo_t* cr);
177  static void clipRegion(cairo_t* cr, const vcl::Region& rClipRegion);
178 
179  // need this static version of ::drawPolyLine for usage from
180  // vcl/unx/generic/gdi/salgdi.cxx. It gets wrapped by
181  // ::drawPolyLine with some added parameters (see there)
182  static bool drawPolyLine(cairo_t* cr, basegfx::B2DRange* pExtents, const Color& rLineColor,
183  bool bAntiAlias, const basegfx::B2DHomMatrix& rObjectToDevice,
184  const basegfx::B2DPolygon& rPolyLine, double fTransparency,
185  double fLineWidth, const std::vector<double>* pStroke,
186  basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap,
187  double fMiterMinimumAngle, bool bPixelSnapHairline);
188 
189  void copyWithOperator(const SalTwoRect& rTR, cairo_surface_t* source, cairo_operator_t eOp,
190  bool bAntiAlias);
191 
192  void copySource(const SalTwoRect& rTR, cairo_surface_t* source, bool bAntiAlias);
193 
194  static basegfx::B2DRange renderSource(cairo_t* cr, const SalTwoRect& rTR,
195  cairo_surface_t* source);
196 
197  void copyBitsCairo(const SalTwoRect& rTR, cairo_surface_t* pSourceSurface, bool bAntiAlias);
198 
199  void invert(const basegfx::B2DPolygon& rPoly, SalInvert nFlags, bool bAntiAlias);
200 
201  static cairo_surface_t* createCairoSurface(const BitmapBuffer* pBuffer);
202 };
203 
205 {
206 private:
208  std::unordered_map<sal_uInt64, cairo_surface_t*> maDownscaled;
209 
210  SurfaceHelper(const SurfaceHelper&) = delete;
211  SurfaceHelper& operator=(const SurfaceHelper&) = delete;
212 
213  cairo_surface_t* implCreateOrReuseDownscale(unsigned long nTargetWidth,
214  unsigned long nTargetHeight);
215 
216 protected:
218  void implSetSurface(cairo_surface_t* pNew) { pSurface = pNew; }
219 
220  bool isTrivial() const;
221 
222 public:
223  explicit SurfaceHelper();
224  ~SurfaceHelper();
225 
226  cairo_surface_t* getSurface(unsigned long nTargetWidth = 0,
227  unsigned long nTargetHeight = 0) const;
228 };
229 
230 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
cairo_surface_t * getSurface() const
void implSetSurface(cairo_surface_t *pNew)
bool isTrivial() const
PaintMode m_ePaintMode
struct _cairo cairo_t
Definition: CairoCommon.hxx:71
VCL_DLLPUBLIC basegfx::B2DPoint impPixelSnap(const basegfx::B2DPolygon &rPolygon, const basegfx::B2DHomMatrix &rObjectToDevice, basegfx::B2DHomMatrix &rObjectToDeviceInv, sal_uInt32 nIndex)
basegfx::B2IVector m_aFrameSize
VCL_DLLPUBLIC cairo_format_t getCairoFormat(const BitmapBuffer &rBuffer)
cairo_surface_t * getSurface(unsigned long nTargetWidth=0, unsigned long nTargetHeight=0) const
#define VCL_DLLPUBLIC
Definition: dllapi.h:29
double m_fScale
vcl::Region m_aClipRegion
cairo_surface_t * pSurface
std::unordered_map< sal_uInt64, cairo_surface_t * > maDownscaled
Color m_aFillColor
cairo_surface_t * implGetSurface() const
VCL_DLLPUBLIC basegfx::B2DRange getClipBox(cairo_t *cr)
cairo_surface_t * m_pSurface
const std::vector< double > & getStroke() const
PaintMode
void(* damageHandler)(void *handle, sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight)
VCL_DLLPUBLIC basegfx::B2DRange getClippedStrokeDamage(cairo_t *cr)
damageHandler damaged
SalInvert
Definition: salgtype.hxx:74
std::vector< double > maStroke
Definition: CairoCommon.hxx:96
virtual sal_Int64 estimateUsageInBytes() const override
VCL_DLLPUBLIC void dl_cairo_surface_get_device_scale(cairo_surface_t *surface, double *x_scale, double *y_scale)
VCL_DLLPUBLIC size_t AddPolygonToPath(cairo_t *cr, const basegfx::B2DPolygon &rPolygon, const basegfx::B2DHomMatrix &rObjectToDevice, bool bPixelSnap, bool bPixelSnapHairline)
VCL_DLLPUBLIC void Toggle1BitTransparency(const BitmapBuffer &rBuf)
SystemDependentData_CairoPath(basegfx::SystemDependentDataManager &rSystemDependentDataManager, size_t nSizeMeasure, cairo_t *cr, bool bNoJoin, bool bAntiAlias, const std::vector< double > *pStroke)
VCL_DLLPUBLIC std::unique_ptr< BitmapBuffer > FastConvert24BitRgbTo32BitCairo(const BitmapBuffer *pSrc)
VCL_DLLPUBLIC basegfx::B2DRange getStrokeDamage(cairo_t *cr)
VCL_DLLPUBLIC void add_polygon_path(cairo_t *cr, const basegfx::B2DPolyPolygon &rPolyPolygon, const basegfx::B2DHomMatrix &rObjectToDevice, bool bPixelSnap)
Color m_aLineColor
struct _cairo_user_data_key cairo_user_data_key_t
Definition: CairoCommon.hxx:73
VCL_DLLPUBLIC basegfx::B2DRange getClippedFillDamage(cairo_t *cr)
struct _cairo_surface cairo_surface_t
Definition: CairoCommon.hxx:72
VCL_DLLPUBLIC basegfx::B2DRange getFillDamage(cairo_t *cr)
VCL_DLLPUBLIC void dl_cairo_surface_set_device_scale(cairo_surface_t *surface, double x_scale, double y_scale)
SurfaceHelper & operator=(const SurfaceHelper &)=delete
cairo_surface_t * implCreateOrReuseDownscale(unsigned long nTargetWidth, unsigned long nTargetHeight)
virtual ~SystemDependentData_CairoPath() override
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo