1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef XFA_INCLUDE_FXGRAPHICS_FX_GRAPHICS_H_
8 #define XFA_INCLUDE_FXGRAPHICS_FX_GRAPHICS_H_
9 
10 #include "core/include/fpdfapi/fpdf_pageobj.h"
11 
12 typedef int FX_ERR;
13 #define FX_ERR_Succeeded 0
14 #define FX_ERR_Indefinite -1
15 #define FX_ERR_Parameter_Invalid -100
16 #define FX_ERR_Property_Invalid -200
17 #define FX_ERR_Intermediate_Value_Invalid -300
18 #define FX_ERR_Method_Not_Supported -400
19 #define FX_ERR_Out_Of_Memory -500
20 #define _FX_RETURN_IF_FAIL(arg) \
21   {                             \
22     if (!(arg))                 \
23       return;                   \
24   }
25 #define _FX_RETURN_VALUE_IF_FAIL(arg, val) \
26   {                                        \
27     if (!(arg))                            \
28       return val;                          \
29   }
30 #define _FX_GOTO_POSITION_IF_FAIL(arg, pos) \
31   {                                         \
32     if (!(arg))                             \
33       goto pos;                             \
34   }
35 #define _FX_ERR_CHECK_RETURN_IF_FAIL(arg) \
36   {                                       \
37     if ((arg) != FX_ERR_Succeeded)        \
38       return;                             \
39   }
40 #define _FX_ERR_CHECK_RETURN_VALUE_IF_FAIL(arg, val) \
41   {                                                  \
42     if ((arg) != FX_ERR_Succeeded)                   \
43       return val;                                    \
44   }
45 #define _FX_ERR_CHECK_GOTO_POSITION_IF_FAIL(arg, pos) \
46   {                                                   \
47     if ((arg) != FX_ERR_Succeeded)                    \
48       goto pos;                                       \
49   }
50 
51 #define FX_SHADING_Steps 256
52 typedef int32_t FX_DashStyle;
53 enum {
54   FX_DASHSTYLE_Solid = 0,
55   FX_DASHSTYLE_Dash = 1,
56   FX_DASHSTYLE_Dot = 2,
57   FX_DASHSTYLE_DashDot = 3,
58   FX_DASHSTYLE_DashDotDot = 4
59 };
60 typedef int32_t FX_StrokeAlignment;
61 enum {
62   FX_STROKEALIGNMENT_Center = 0,
63   FX_STROKEALIGNMENT_Inset = 1,
64   FX_STROKEALIGNMENT_Outset = 2,
65   FX_STROKEALIGNMENT_Left = 3,
66   FX_STROKEALIGNMENT_Right = 4
67 };
68 typedef int32_t FX_HatchStyle;
69 enum {
70   FX_HATCHSTYLE_Horizontal = 0,
71   FX_HATCHSTYLE_Vertical = 1,
72   FX_HATCHSTYLE_ForwardDiagonal = 2,
73   FX_HATCHSTYLE_BackwardDiagonal = 3,
74   FX_HATCHSTYLE_Cross = 4,
75   FX_HATCHSTYLE_DiagonalCross = 5,
76   FX_HATCHSTYLE_05Percent = 6,
77   FX_HATCHSTYLE_10Percent = 7,
78   FX_HATCHSTYLE_20Percent = 8,
79   FX_HATCHSTYLE_25Percent = 9,
80   FX_HATCHSTYLE_30Percent = 10,
81   FX_HATCHSTYLE_40Percent = 11,
82   FX_HATCHSTYLE_50Percent = 12,
83   FX_HATCHSTYLE_60Percent = 13,
84   FX_HATCHSTYLE_70Percent = 14,
85   FX_HATCHSTYLE_75Percent = 15,
86   FX_HATCHSTYLE_80Percent = 16,
87   FX_HATCHSTYLE_90Percent = 17,
88   FX_HATCHSTYLE_LightDownwardDiagonal = 18,
89   FX_HATCHSTYLE_LightUpwardDiagonal = 19,
90   FX_HATCHSTYLE_DarkDownwardDiagonal = 20,
91   FX_HATCHSTYLE_DarkUpwardDiagonal = 21,
92   FX_HATCHSTYLE_WideDownwardDiagonal = 22,
93   FX_HATCHSTYLE_WideUpwardDiagonal = 23,
94   FX_HATCHSTYLE_LightVertical = 24,
95   FX_HATCHSTYLE_LightHorizontal = 25,
96   FX_HATCHSTYLE_NarrowVertical = 26,
97   FX_HATCHSTYLE_NarrowHorizontal = 27,
98   FX_HATCHSTYLE_DarkVertical = 28,
99   FX_HATCHSTYLE_DarkHorizontal = 29,
100   FX_HATCHSTYLE_DashedDownwardDiagonal = 30,
101   FX_HATCHSTYLE_DashedUpwardDiagonal = 31,
102   FX_HATCHSTYLE_DashedHorizontal = 32,
103   FX_HATCHSTYLE_DashedVertical = 33,
104   FX_HATCHSTYLE_SmallConfetti = 34,
105   FX_HATCHSTYLE_LargeConfetti = 35,
106   FX_HATCHSTYLE_ZigZag = 36,
107   FX_HATCHSTYLE_Wave = 37,
108   FX_HATCHSTYLE_DiagonalBrick = 38,
109   FX_HATCHSTYLE_HorizontalBrick = 39,
110   FX_HATCHSTYLE_Weave = 40,
111   FX_HATCHSTYLE_Plaid = 41,
112   FX_HATCHSTYLE_Divot = 42,
113   FX_HATCHSTYLE_DottedGrid = 43,
114   FX_HATCHSTYLE_DottedDiamond = 44,
115   FX_HATCHSTYLE_Shingle = 45,
116   FX_HATCHSTYLE_Trellis = 46,
117   FX_HATCHSTYLE_Sphere = 47,
118   FX_HATCHSTYLE_SmallGrid = 48,
119   FX_HATCHSTYLE_SmallCheckerBoard = 49,
120   FX_HATCHSTYLE_LargeCheckerBoard = 50,
121   FX_HATCHSTYLE_OutlinedDiamond = 51,
122   FX_HATCHSTYLE_SolidDiamond = 52
123 };
124 typedef int32_t FX_DeviceCap;
125 typedef int32_t FX_FillMode;
126 class CFX_RenderDevice;
127 class CFX_GraphStateData;
128 class CFX_Matrix;
129 class CFX_DIBSource;
130 class CFX_DIBitmap;
131 class CFX_Font;
132 class CFX_WideString;
133 class IFX_FileRead;
134 class CFX_PathGenerator;
135 class CAGG_Graphics;
136 class CFX_Graphics;
137 class CFX_Color;
138 class CFX_Path;
139 class CFX_Pattern;
140 class CFX_Shading;
141 class CFX_Graphics {
142  public:
143   CFX_Graphics();
144 
145   FX_ERR Create(CFX_RenderDevice* renderDevice, FX_BOOL isAntialiasing = TRUE);
146 
147   FX_ERR Create(int32_t width,
148                 int32_t height,
149                 FXDIB_Format format,
150                 FX_BOOL isNative = TRUE,
151                 FX_BOOL isAntialiasing = TRUE);
152 
153   virtual ~CFX_Graphics();
154 
155   FX_ERR GetDeviceCap(const int32_t capID, FX_DeviceCap& capVal);
156   FX_ERR IsPrinterDevice(FX_BOOL& isPrinter);
157   FX_ERR EnableAntialiasing(FX_BOOL isAntialiasing);
158 
159   FX_ERR SaveGraphState();
160 
161   FX_ERR RestoreGraphState();
162 
163   FX_ERR GetLineCap(CFX_GraphStateData::LineCap& lineCap);
164 
165   FX_ERR SetLineCap(CFX_GraphStateData::LineCap lineCap);
166 
167   FX_ERR GetDashCount(int32_t& dashCount);
168 
169   FX_ERR GetLineDash(FX_FLOAT& dashPhase, FX_FLOAT* dashArray);
170 
171   FX_ERR SetLineDash(FX_FLOAT dashPhase,
172                      FX_FLOAT* dashArray,
173                      int32_t dashCount);
174 
175   FX_ERR SetLineDash(FX_DashStyle dashStyle);
176 
177   FX_ERR GetLineJoin(CFX_GraphStateData::LineJoin& lineJoin);
178 
179   FX_ERR SetLineJoin(CFX_GraphStateData::LineJoin lineJoin);
180 
181   FX_ERR GetMiterLimit(FX_FLOAT& miterLimit);
182 
183   FX_ERR SetMiterLimit(FX_FLOAT miterLimit);
184 
185   FX_ERR GetLineWidth(FX_FLOAT& lineWidth);
186 
187   FX_ERR SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash = FALSE);
188 
189   FX_ERR GetStrokeAlignment(FX_StrokeAlignment& strokeAlignment);
190 
191   FX_ERR SetStrokeAlignment(FX_StrokeAlignment strokeAlignment);
192 
193   FX_ERR SetStrokeColor(CFX_Color* color);
194 
195   FX_ERR SetFillColor(CFX_Color* color);
196 
197   FX_ERR StrokePath(CFX_Path* path, CFX_Matrix* matrix = NULL);
198 
199   FX_ERR FillPath(CFX_Path* path,
200                   FX_FillMode fillMode = FXFILL_WINDING,
201                   CFX_Matrix* matrix = NULL);
202 
203   FX_ERR ClipPath(CFX_Path* path,
204                   FX_FillMode fillMode = FXFILL_WINDING,
205                   CFX_Matrix* matrix = NULL);
206 
207   FX_ERR DrawImage(CFX_DIBSource* source,
208                    const CFX_PointF& point,
209                    CFX_Matrix* matrix = NULL);
210 
211   FX_ERR StretchImage(CFX_DIBSource* source,
212                       const CFX_RectF& rect,
213                       CFX_Matrix* matrix = NULL);
214 
215   FX_ERR ConcatMatrix(const CFX_Matrix* matrix);
216 
217   CFX_Matrix* GetMatrix();
218 
219   FX_ERR GetClipRect(CFX_RectF& rect);
220 
221   FX_ERR SetClipRect(const CFX_RectF& rect);
222 
223   FX_ERR ClearClip();
224 
225   FX_ERR SetFont(CFX_Font* font);
226 
227   FX_ERR SetFontSize(const FX_FLOAT size);
228 
229   FX_ERR SetFontHScale(const FX_FLOAT scale);
230 
231   FX_ERR SetCharSpacing(const FX_FLOAT spacing);
232 
233   FX_ERR SetTextDrawingMode(const int32_t mode);
234 
235   FX_ERR ShowText(const CFX_PointF& point,
236                   const CFX_WideString& text,
237                   CFX_Matrix* matrix = NULL);
238 
239   FX_ERR CalcTextRect(CFX_RectF& rect,
240                       const CFX_WideString& text,
241                       FX_BOOL isMultiline = FALSE,
242                       CFX_Matrix* matrix = NULL);
243 
244   FX_ERR Transfer(CFX_Graphics* graphics, const CFX_Matrix* matrix);
245   FX_ERR Transfer(CFX_Graphics* graphics,
246                   FX_FLOAT srcLeft,
247                   FX_FLOAT srcTop,
248                   const CFX_RectF& dstRect,
249                   const CFX_Matrix* matrix);
250 
251   CFX_RenderDevice* GetRenderDevice();
252 
253   FX_ERR InverseRect(const CFX_RectF& rect);
254   FX_ERR XorDIBitmap(const CFX_DIBitmap* srcBitmap, const CFX_RectF& rect);
255   FX_ERR EqvDIBitmap(const CFX_DIBitmap* srcBitmap, const CFX_RectF& rect);
256 
257  private:
258   FX_ERR RenderDeviceSetLineDash(FX_DashStyle dashStyle);
259 
260   FX_ERR RenderDeviceStrokePath(CFX_Path* path, CFX_Matrix* matrix);
261 
262   FX_ERR RenderDeviceFillPath(CFX_Path* path,
263                               FX_FillMode fillMode,
264                               CFX_Matrix* matrix);
265 
266   FX_ERR RenderDeviceDrawImage(CFX_DIBSource* source,
267                                const CFX_PointF& point,
268                                CFX_Matrix* matrix);
269 
270   FX_ERR RenderDeviceStretchImage(CFX_DIBSource* source,
271                                   const CFX_RectF& rect,
272                                   CFX_Matrix* matrix);
273 
274   FX_ERR RenderDeviceShowText(const CFX_PointF& point,
275                               const CFX_WideString& text,
276                               CFX_Matrix* matrix);
277 
278   FX_ERR StrokePathWithPattern(CFX_Path* path, CFX_Matrix* matrix);
279 
280   FX_ERR StrokePathWithShading(CFX_Path* path, CFX_Matrix* matrix);
281 
282   FX_ERR FillPathWithPattern(CFX_Path* path,
283                              FX_FillMode fillMode,
284                              CFX_Matrix* matrix);
285 
286   FX_ERR FillPathWithShading(CFX_Path* path,
287                              FX_FillMode fillMode,
288                              CFX_Matrix* matrix);
289   FX_ERR SetDIBitsWithMatrix(CFX_DIBSource* source, CFX_Matrix* matrix);
290   FX_ERR CalcTextInfo(const CFX_WideString& text,
291                       FX_DWORD* charCodes,
292                       FXTEXT_CHARPOS* charPos,
293                       CFX_RectF& rect);
294 
295  protected:
296   int32_t _type;
297 
298  private:
299   struct TInfo {
300     CFX_GraphStateData _graphState;
301     FX_BOOL _isAntialiasing;
302     FX_StrokeAlignment _strokeAlignment;
303     CFX_Matrix _CTM;
304     FX_BOOL _isActOnDash;
305     CFX_Color* _strokeColor;
306     CFX_Color* _fillColor;
307     CFX_Font* _font;
308     FX_FLOAT _fontSize;
309     FX_FLOAT _fontHScale;
310     FX_FLOAT _fontSpacing;
311   } _info;
312   CFX_RenderDevice* _renderDevice;
313   CFX_PtrArray _infoStack;
314   CAGG_Graphics* _aggGraphics;
315   friend class CAGG_Graphics;
316 };
317 class CFX_Path {
318  public:
319   CFX_Path();
320 
321   FX_ERR Create();
322 
323   virtual ~CFX_Path();
324 
325   FX_ERR MoveTo(FX_FLOAT x, FX_FLOAT y);
326 
327   FX_ERR LineTo(FX_FLOAT x, FX_FLOAT y);
328 
329   FX_ERR BezierTo(FX_FLOAT ctrlX1,
330                   FX_FLOAT ctrlY1,
331                   FX_FLOAT ctrlX2,
332                   FX_FLOAT ctrlY2,
333                   FX_FLOAT toX,
334                   FX_FLOAT toY);
335 
336   FX_ERR ArcTo(FX_FLOAT left,
337                FX_FLOAT top,
338                FX_FLOAT width,
339                FX_FLOAT height,
340                FX_FLOAT startAngle,
341                FX_FLOAT sweepAngle);
342 
343   FX_ERR Close();
344 
345   FX_ERR AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
346 
347   FX_ERR AddBezier(FX_FLOAT startX,
348                    FX_FLOAT startY,
349                    FX_FLOAT ctrlX1,
350                    FX_FLOAT ctrlY1,
351                    FX_FLOAT ctrlX2,
352                    FX_FLOAT ctrlY2,
353                    FX_FLOAT endX,
354                    FX_FLOAT endY);
355 
356   FX_ERR AddRectangle(FX_FLOAT left,
357                       FX_FLOAT top,
358                       FX_FLOAT width,
359                       FX_FLOAT height);
360 
361   FX_ERR AddEllipse(FX_FLOAT left,
362                     FX_FLOAT top,
363                     FX_FLOAT width,
364                     FX_FLOAT height);
365 
366   FX_ERR AddEllipse(const CFX_RectF& rect);
367 
368   FX_ERR AddArc(FX_FLOAT left,
369                 FX_FLOAT top,
370                 FX_FLOAT width,
371                 FX_FLOAT height,
372                 FX_FLOAT startAngle,
373                 FX_FLOAT sweepAngle);
374 
375   FX_ERR AddPie(FX_FLOAT left,
376                 FX_FLOAT top,
377                 FX_FLOAT width,
378                 FX_FLOAT height,
379                 FX_FLOAT startAngle,
380                 FX_FLOAT sweepAngle);
381 
382   FX_ERR AddSubpath(CFX_Path* path);
383 
384   FX_ERR Clear();
385 
386   FX_BOOL IsEmpty();
387 
388   CFX_PathData* GetPathData();
389 
390  private:
391   CFX_PathGenerator* _generator;
392 };
393 class CFX_Color {
394  public:
395   CFX_Color();
396 
397   CFX_Color(const FX_ARGB argb);
398 
399   CFX_Color(CFX_Pattern* pattern, const FX_ARGB argb = 0x0);
400 
401   CFX_Color(CFX_Shading* shading);
402 
403   virtual ~CFX_Color();
404 
405   FX_ERR Set(const FX_ARGB argb);
406 
407   FX_ERR Set(CFX_Pattern* pattern, const FX_ARGB argb = 0x0);
408 
409   FX_ERR Set(CFX_Shading* shading);
410 
411  private:
412   int32_t _type;
413   union {
414     struct {
415       FX_ARGB _argb;
416       CFX_Pattern* _pattern;
417     };
418     CFX_Shading* _shading;
419   };
420 
421   friend class CFX_Graphics;
422 };
423 class CFX_Pattern {
424  public:
425   CFX_Pattern();
426 
427   FX_ERR Create(CFX_DIBitmap* bitmap,
428                 const FX_FLOAT xStep,
429                 const FX_FLOAT yStep,
430                 CFX_Matrix* matrix = NULL);
431 
432   FX_ERR Create(FX_HatchStyle hatchStyle,
433                 const FX_ARGB foreArgb,
434                 const FX_ARGB backArgb,
435                 CFX_Matrix* matrix = NULL);
436 
437   virtual ~CFX_Pattern();
438 
439  private:
440   int32_t _type;
441   CFX_Matrix _matrix;
442   union {
443     struct {
444       CFX_RectF _rect;
445       FX_FLOAT _xStep;
446       FX_FLOAT _yStep;
447       FX_BOOL _isColored;
448     };
449     struct {
450       CFX_DIBitmap* _bitmap;
451       FX_FLOAT _x1Step;
452       FX_FLOAT _y1Step;
453     };
454     struct {
455       FX_HatchStyle _hatchStyle;
456       FX_ARGB _foreArgb;
457       FX_ARGB _backArgb;
458     };
459   };
460   friend class CFX_Graphics;
461 };
462 class CFX_Shading {
463  public:
464   CFX_Shading();
465 
466   FX_ERR CreateAxial(const CFX_PointF& beginPoint,
467                      const CFX_PointF& endPoint,
468                      FX_BOOL isExtendedBegin,
469                      FX_BOOL isExtendedEnd,
470                      const FX_ARGB beginArgb,
471                      const FX_ARGB endArgb);
472 
473   FX_ERR CreateRadial(const CFX_PointF& beginPoint,
474                       const CFX_PointF& endPoint,
475                       const FX_FLOAT beginRadius,
476                       const FX_FLOAT endRadius,
477                       FX_BOOL isExtendedBegin,
478                       FX_BOOL isExtendedEnd,
479                       const FX_ARGB beginArgb,
480                       const FX_ARGB endArgb);
481 
482   virtual ~CFX_Shading();
483 
484  private:
485   FX_ERR InitArgbArray();
486 
487  private:
488   int32_t _type;
489   CFX_PointF _beginPoint;
490   CFX_PointF _endPoint;
491   FX_FLOAT _beginRadius;
492   FX_FLOAT _endRadius;
493   FX_BOOL _isExtendedBegin;
494   FX_BOOL _isExtendedEnd;
495   FX_ARGB _beginArgb;
496   FX_ARGB _endArgb;
497   FX_ARGB _argbArray[FX_SHADING_Steps];
498   friend class CFX_Graphics;
499 };
500 
501 #endif  // XFA_INCLUDE_FXGRAPHICS_FX_GRAPHICS_H_
502