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 #include "xfa/fxgraphics/include/cfx_graphics.h"
8 
9 #include <memory>
10 
11 #include "xfa/fxgraphics/cagg_graphics.h"
12 #include "xfa/fxgraphics/cfx_color.h"
13 #include "xfa/fxgraphics/cfx_path.h"
14 #include "xfa/fxgraphics/cfx_path_generator.h"
15 #include "xfa/fxgraphics/cfx_pattern.h"
16 #include "xfa/fxgraphics/cfx_shading.h"
17 
18 namespace {
19 
20 enum {
21   FX_CONTEXT_None = 0,
22   FX_CONTEXT_Device,
23 };
24 
25 #define FX_HATCHSTYLE_Total 53
26 
27 struct FX_HATCHDATA {
28   int32_t width;
29   int32_t height;
30   uint8_t maskBits[64];
31 };
32 
33 const FX_HATCHDATA hatchBitmapData[FX_HATCHSTYLE_Total] = {
34     {16,
35      16,
36      {
37          0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
40          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42          0x00, 0x00, 0x00, 0x00,
43      }},
44     {16,
45      16,
46      {
47          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
48          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
49          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
50          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
51          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
52          0x80, 0x80, 0x00, 0x00,
53      }},
54     {16,
55      16,
56      {
57          0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00,
58          0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,
59          0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
60          0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
61          0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
62          0x01, 0x01, 0x00, 0x00,
63      }},
64     {16,
65      16,
66      {
67          0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,
68          0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00,
69          0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
70          0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
71          0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
72          0x80, 0x80, 0x00, 0x00,
73      }},
74     {16,
75      16,
76      {
77          0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
78          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
79          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
80          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
81          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
82          0x80, 0x80, 0x00, 0x00,
83      }},
84     {16,
85      16,
86      {
87          0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00,
88          0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00,
89          0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,
90          0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
91          0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00,
92          0x81, 0x81, 0x00, 0x00,
93      }},
94     {16,
95      16,
96      {
97          0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98          0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
100          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101          0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102          0x00, 0x00, 0x00, 0x00,
103      }},
104     {16,
105      16,
106      {
107          0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
108          0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109          0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
110          0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111          0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
112          0x00, 0x00, 0x00, 0x00,
113      }},
114     {16,
115      16,
116      {
117          0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
118          0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119          0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
120          0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121          0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
122          0x00, 0x00, 0x00, 0x00,
123      }},
124     {16,
125      16,
126      {
127          0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
128          0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
129          0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
130          0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
131          0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
132          0x22, 0x22, 0x00, 0x00,
133      }},
134     {16,
135      16,
136      {
137          0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
138          0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
139          0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
140          0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
141          0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
142          0x11, 0x11, 0x00, 0x00,
143      }},
144     {16,
145      16,
146      {
147          0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
148          0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
149          0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
150          0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00,
151          0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
152          0x15, 0x15, 0x00, 0x00,
153      }},
154     {16,
155      16,
156      {
157          0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
158          0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
159          0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
160          0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
161          0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
162          0x55, 0x55, 0x00, 0x00,
163      }},
164     {16,
165      16,
166      {
167          0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00,
168          0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
169          0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00,
170          0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
171          0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00,
172          0x55, 0x55, 0x00, 0x00,
173      }},
174     {16,
175      16,
176      {
177          0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00,
178          0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00,
179          0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00,
180          0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00,
181          0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00,
182          0xdd, 0xdd, 0x00, 0x00,
183      }},
184     {16,
185      16,
186      {
187          0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00,
188          0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
189          0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00,
190          0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
191          0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00,
192          0xff, 0xff, 0x00, 0x00,
193      }},
194     {16,
195      16,
196      {
197          0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00,
198          0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
199          0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00,
200          0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
201          0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00,
202          0xff, 0xff, 0x00, 0x00,
203      }},
204     {16,
205      16,
206      {
207          0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
208          0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
209          0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
210          0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00,
211          0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
212          0x7f, 0x7f, 0x00, 0x00,
213      }},
214     {16,
215      16,
216      {
217          0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
218          0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
219          0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
220          0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
221          0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
222          0x11, 0x11, 0x00, 0x00,
223      }},
224     {16,
225      16,
226      {
227          0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
228          0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
229          0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
230          0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
231          0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
232          0x88, 0x88, 0x00, 0x00,
233      }},
234     {16,
235      16,
236      {
237          0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00,
238          0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00,
239          0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
240          0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,
241          0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00,
242          0x99, 0x99, 0x00, 0x00,
243      }},
244     {16,
245      16,
246      {
247          0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
248          0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00,
249          0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00,
250          0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,
251          0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
252          0x99, 0x99, 0x00, 0x00,
253      }},
254     {16,
255      16,
256      {
257          0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00,
258          0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00,
259          0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00,
260          0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00,
261          0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00,
262          0x83, 0x83, 0x00, 0x00,
263      }},
264     {16,
265      16,
266      {
267          0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00,
268          0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00,
269          0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00,
270          0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00,
271          0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00,
272          0xc1, 0xc1, 0x00, 0x00,
273      }},
274     {16,
275      16,
276      {
277          0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
278          0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
279          0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
280          0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
281          0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
282          0x88, 0x88, 0x00, 0x00,
283      }},
284     {16,
285      16,
286      {
287          0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288          0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
290          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291          0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292          0x00, 0x00, 0x00, 0x00,
293      }},
294     {16,
295      16,
296      {
297          0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
298          0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
299          0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
300          0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
301          0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
302          0x55, 0x55, 0x00, 0x00,
303      }},
304     {16,
305      16,
306      {
307          0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
308          0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309          0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
310          0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311          0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
312          0x00, 0x00, 0x00, 0x00,
313      }},
314     {16,
315      16,
316      {
317          0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
318          0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
319          0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
320          0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
321          0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,
322          0xcc, 0xcc, 0x00, 0x00,
323      }},
324     {16,
325      16,
326      {
327          0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328          0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
329          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
330          0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331          0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332          0x00, 0x00, 0x00, 0x00,
333      }},
334     {16,
335      16,
336      {
337          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
338          0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
339          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340          0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
341          0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342          0x00, 0x00, 0x00, 0x00,
343      }},
344     {16,
345      16,
346      {
347          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,
348          0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
349          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350          0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
351          0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352          0x00, 0x00, 0x00, 0x00,
353      }},
354     {16,
355      16,
356      {
357          0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358          0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,
360          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361          0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362          0x00, 0x00, 0x00, 0x00,
363      }},
364     {16,
365      16,
366      {
367          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
368          0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
369          0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
370          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
371          0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
372          0x08, 0x08, 0x00, 0x00,
373      }},
374     {16,
375      16,
376      {
377          0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
378          0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
379          0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
380          0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
381          0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00,
382          0x04, 0x04, 0x00, 0x00,
383      }},
384     {16,
385      16,
386      {
387          0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,
388          0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00,
389          0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00, 0xb1, 0xb1, 0x00, 0x00,
390          0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00,
391          0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00,
392          0x8d, 0x8d, 0x00, 0x00,
393      }},
394     {16,
395      16,
396      {
397          0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00,
398          0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00,
399          0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,
400          0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
401          0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00,
402          0x18, 0x18, 0x00, 0x00,
403      }},
404     {16,
405      16,
406      {
407          0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00,
408          0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
409          0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410          0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00,
411          0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00,
412          0xc0, 0xc0, 0x00, 0x00,
413      }},
414     {16,
415      16,
416      {
417          0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,
418          0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00,
419          0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
420          0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
421          0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00,
422          0x81, 0x81, 0x00, 0x00,
423      }},
424     {16,
425      16,
426      {
427          0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
428          0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
429          0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
430          0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
431          0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
432          0x08, 0x08, 0x00, 0x00,
433      }},
434     {16,
435      16,
436      {
437          0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
438          0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00,
439          0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
440          0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00,
441          0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
442          0x51, 0x51, 0x00, 0x00,
443      }},
444     {16,
445      16,
446      {
447          0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
448          0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,
449          0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
450          0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
451          0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,
452          0xf0, 0xf0, 0x00, 0x00,
453      }},
454     {16,
455      16,
456      {
457          0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
458          0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
459          0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460          0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
461          0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
462          0x80, 0x80, 0x00, 0x00,
463      }},
464     {16,
465      16,
466      {
467          0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
468          0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469          0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
470          0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471          0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
472          0x00, 0x00, 0x00, 0x00,
473      }},
474     {16,
475      16,
476      {
477          0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
478          0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479          0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
480          0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481          0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
482          0x00, 0x00, 0x00, 0x00,
483      }},
484     {16,
485      16,
486      {
487          0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00,
488          0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
489          0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,
490          0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00,
491          0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
492          0x01, 0x01, 0x00, 0x00,
493      }},
494     {16,
495      16,
496      {
497          0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
498          0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00,
499          0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
500          0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,
501          0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
502          0x99, 0x99, 0x00, 0x00,
503      }},
504     {16,
505      16,
506      {
507          0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00,
508          0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00,
509          0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00,
510          0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00,
511          0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00,
512          0xf8, 0xf8, 0x00, 0x00,
513      }},
514     {16,
515      16,
516      {
517          0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
518          0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
519          0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
520          0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
521          0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
522          0x88, 0x88, 0x00, 0x00,
523      }},
524     {16,
525      16,
526      {
527          0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00,
528          0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00,
529          0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,
530          0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,
531          0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00,
532          0x99, 0x99, 0x00, 0x00,
533      }},
534     {16,
535      16,
536      {
537          0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,
538          0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00,
539          0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,
540          0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,
541          0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00,
542          0x0f, 0x0f, 0x00, 0x00,
543      }},
544     {16,
545      16,
546      {
547          0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00,
548          0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
549          0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00,
550          0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
551          0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00,
552          0x01, 0x01, 0x00, 0x00,
553      }},
554     {16,
555      16,
556      {
557          0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00,
558          0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00,
559          0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
560          0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00,
561          0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
562          0x00, 0x00, 0x00, 0x00,
563      }},
564 };
565 
566 }  // namespace
567 
CFX_Graphics()568 CFX_Graphics::CFX_Graphics()
569     : m_type(FX_CONTEXT_None),
570       m_renderDevice(nullptr),
571       m_aggGraphics(nullptr) {}
572 
Create(CFX_RenderDevice * renderDevice,FX_BOOL isAntialiasing)573 FWL_Error CFX_Graphics::Create(CFX_RenderDevice* renderDevice,
574                                FX_BOOL isAntialiasing) {
575   if (!renderDevice)
576     return FWL_Error::ParameterInvalid;
577   if (m_type != FX_CONTEXT_None)
578     return FWL_Error::PropertyInvalid;
579 
580   m_type = FX_CONTEXT_Device;
581   m_info.isAntialiasing = isAntialiasing;
582   m_renderDevice = renderDevice;
583   if (m_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)
584     return FWL_Error::Succeeded;
585   return FWL_Error::Indefinite;
586 }
587 
Create(int32_t width,int32_t height,FXDIB_Format format,FX_BOOL isNative,FX_BOOL isAntialiasing)588 FWL_Error CFX_Graphics::Create(int32_t width,
589                                int32_t height,
590                                FXDIB_Format format,
591                                FX_BOOL isNative,
592                                FX_BOOL isAntialiasing) {
593   if (m_type != FX_CONTEXT_None)
594     return FWL_Error::PropertyInvalid;
595 
596   m_type = FX_CONTEXT_Device;
597   m_info.isAntialiasing = isAntialiasing;
598   m_aggGraphics = new CAGG_Graphics;
599   return m_aggGraphics->Create(this, width, height, format);
600 }
601 
~CFX_Graphics()602 CFX_Graphics::~CFX_Graphics() {
603   delete m_aggGraphics;
604 }
605 
GetDeviceCap(const int32_t capID,FX_DeviceCap & capVal)606 FWL_Error CFX_Graphics::GetDeviceCap(const int32_t capID,
607                                      FX_DeviceCap& capVal) {
608   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
609     capVal = m_renderDevice->GetDeviceCaps(capID);
610     return FWL_Error::Succeeded;
611   }
612   return FWL_Error::PropertyInvalid;
613 }
614 
IsPrinterDevice(FX_BOOL & isPrinter)615 FWL_Error CFX_Graphics::IsPrinterDevice(FX_BOOL& isPrinter) {
616   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
617     isPrinter = m_renderDevice->GetDeviceClass() == FXDC_PRINTER;
618     return FWL_Error::Succeeded;
619   }
620   return FWL_Error::PropertyInvalid;
621 }
622 
EnableAntialiasing(FX_BOOL isAntialiasing)623 FWL_Error CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing) {
624   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
625     m_info.isAntialiasing = isAntialiasing;
626     return FWL_Error::Succeeded;
627   }
628   return FWL_Error::PropertyInvalid;
629 }
630 
SaveGraphState()631 FWL_Error CFX_Graphics::SaveGraphState() {
632   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
633     m_renderDevice->SaveState();
634     m_infoStack.Add(new TInfo(m_info));
635     return FWL_Error::Succeeded;
636   }
637   return FWL_Error::PropertyInvalid;
638 }
639 
RestoreGraphState()640 FWL_Error CFX_Graphics::RestoreGraphState() {
641   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
642     m_renderDevice->RestoreState(false);
643     int32_t size = m_infoStack.GetSize();
644     if (size <= 0) {
645       return FWL_Error::IntermediateValueInvalid;
646     }
647     int32_t topIndex = size - 1;
648     std::unique_ptr<TInfo> info(m_infoStack.GetAt(topIndex));
649     if (!info)
650       return FWL_Error::IntermediateValueInvalid;
651     m_info = *info;
652     m_infoStack.RemoveAt(topIndex);
653     return FWL_Error::Succeeded;
654   }
655   return FWL_Error::PropertyInvalid;
656 }
657 
GetLineCap(CFX_GraphStateData::LineCap & lineCap) const658 FWL_Error CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap& lineCap) const {
659   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
660     lineCap = m_info.graphState.m_LineCap;
661     return FWL_Error::Succeeded;
662   }
663   return FWL_Error::PropertyInvalid;
664 }
665 
SetLineCap(CFX_GraphStateData::LineCap lineCap)666 FWL_Error CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) {
667   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
668     m_info.graphState.m_LineCap = lineCap;
669     return FWL_Error::Succeeded;
670   }
671   return FWL_Error::PropertyInvalid;
672 }
673 
GetDashCount(int32_t & dashCount) const674 FWL_Error CFX_Graphics::GetDashCount(int32_t& dashCount) const {
675   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
676     dashCount = m_info.graphState.m_DashCount;
677     return FWL_Error::Succeeded;
678   }
679   return FWL_Error::PropertyInvalid;
680 }
681 
GetLineDash(FX_FLOAT & dashPhase,FX_FLOAT * dashArray) const682 FWL_Error CFX_Graphics::GetLineDash(FX_FLOAT& dashPhase,
683                                     FX_FLOAT* dashArray) const {
684   if (!dashArray)
685     return FWL_Error::ParameterInvalid;
686   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
687     dashPhase = m_info.graphState.m_DashPhase;
688     FXSYS_memcpy(dashArray, m_info.graphState.m_DashArray,
689                  m_info.graphState.m_DashCount * sizeof(FX_FLOAT));
690     return FWL_Error::Succeeded;
691   }
692   return FWL_Error::PropertyInvalid;
693 }
694 
SetLineDash(FX_FLOAT dashPhase,FX_FLOAT * dashArray,int32_t dashCount)695 FWL_Error CFX_Graphics::SetLineDash(FX_FLOAT dashPhase,
696                                     FX_FLOAT* dashArray,
697                                     int32_t dashCount) {
698   if (dashCount > 0 && !dashArray)
699     return FWL_Error::ParameterInvalid;
700 
701   dashCount = dashCount < 0 ? 0 : dashCount;
702   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
703     FX_FLOAT scale = 1.0;
704     if (m_info.isActOnDash) {
705       scale = m_info.graphState.m_LineWidth;
706     }
707     m_info.graphState.m_DashPhase = dashPhase;
708     m_info.graphState.SetDashCount(dashCount);
709     for (int32_t i = 0; i < dashCount; i++) {
710       m_info.graphState.m_DashArray[i] = dashArray[i] * scale;
711     }
712     return FWL_Error::Succeeded;
713   }
714   return FWL_Error::PropertyInvalid;
715 }
716 
SetLineDash(FX_DashStyle dashStyle)717 FWL_Error CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) {
718   if (m_type == FX_CONTEXT_Device && m_renderDevice)
719     return RenderDeviceSetLineDash(dashStyle);
720   return FWL_Error::PropertyInvalid;
721 }
722 
GetLineJoin(CFX_GraphStateData::LineJoin & lineJoin) const723 FWL_Error CFX_Graphics::GetLineJoin(
724     CFX_GraphStateData::LineJoin& lineJoin) const {
725   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
726     lineJoin = m_info.graphState.m_LineJoin;
727     return FWL_Error::Succeeded;
728   }
729   return FWL_Error::PropertyInvalid;
730 }
731 
SetLineJoin(CFX_GraphStateData::LineJoin lineJoin)732 FWL_Error CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin) {
733   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
734     m_info.graphState.m_LineJoin = lineJoin;
735     return FWL_Error::Succeeded;
736   }
737   return FWL_Error::PropertyInvalid;
738 }
739 
GetMiterLimit(FX_FLOAT & miterLimit) const740 FWL_Error CFX_Graphics::GetMiterLimit(FX_FLOAT& miterLimit) const {
741   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
742     miterLimit = m_info.graphState.m_MiterLimit;
743     return FWL_Error::Succeeded;
744   }
745   return FWL_Error::PropertyInvalid;
746 }
747 
SetMiterLimit(FX_FLOAT miterLimit)748 FWL_Error CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit) {
749   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
750     m_info.graphState.m_MiterLimit = miterLimit;
751     return FWL_Error::Succeeded;
752   }
753   return FWL_Error::PropertyInvalid;
754 }
755 
GetLineWidth(FX_FLOAT & lineWidth) const756 FWL_Error CFX_Graphics::GetLineWidth(FX_FLOAT& lineWidth) const {
757   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
758     lineWidth = m_info.graphState.m_LineWidth;
759     return FWL_Error::Succeeded;
760   }
761   return FWL_Error::PropertyInvalid;
762 }
763 
SetLineWidth(FX_FLOAT lineWidth,FX_BOOL isActOnDash)764 FWL_Error CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash) {
765   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
766     m_info.graphState.m_LineWidth = lineWidth;
767     m_info.isActOnDash = isActOnDash;
768     return FWL_Error::Succeeded;
769   }
770   return FWL_Error::PropertyInvalid;
771 }
772 
GetStrokeAlignment(FX_StrokeAlignment & strokeAlignment) const773 FWL_Error CFX_Graphics::GetStrokeAlignment(
774     FX_StrokeAlignment& strokeAlignment) const {
775   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
776     strokeAlignment = m_info.strokeAlignment;
777     return FWL_Error::Succeeded;
778   }
779   return FWL_Error::PropertyInvalid;
780 }
781 
SetStrokeAlignment(FX_StrokeAlignment strokeAlignment)782 FWL_Error CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment) {
783   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
784     m_info.strokeAlignment = strokeAlignment;
785     return FWL_Error::Succeeded;
786   }
787   return FWL_Error::PropertyInvalid;
788 }
789 
SetStrokeColor(CFX_Color * color)790 FWL_Error CFX_Graphics::SetStrokeColor(CFX_Color* color) {
791   if (!color)
792     return FWL_Error::ParameterInvalid;
793   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
794     m_info.strokeColor = color;
795     return FWL_Error::Succeeded;
796   }
797   return FWL_Error::PropertyInvalid;
798 }
799 
SetFillColor(CFX_Color * color)800 FWL_Error CFX_Graphics::SetFillColor(CFX_Color* color) {
801   if (!color)
802     return FWL_Error::ParameterInvalid;
803   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
804     m_info.fillColor = color;
805     return FWL_Error::Succeeded;
806   }
807   return FWL_Error::PropertyInvalid;
808 }
809 
StrokePath(CFX_Path * path,CFX_Matrix * matrix)810 FWL_Error CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) {
811   if (!path)
812     return FWL_Error::ParameterInvalid;
813   if (m_type == FX_CONTEXT_Device && m_renderDevice)
814     return RenderDeviceStrokePath(path, matrix);
815   return FWL_Error::PropertyInvalid;
816 }
817 
FillPath(CFX_Path * path,FX_FillMode fillMode,CFX_Matrix * matrix)818 FWL_Error CFX_Graphics::FillPath(CFX_Path* path,
819                                  FX_FillMode fillMode,
820                                  CFX_Matrix* matrix) {
821   if (!path)
822     return FWL_Error::ParameterInvalid;
823   if (m_type == FX_CONTEXT_Device && m_renderDevice)
824     return RenderDeviceFillPath(path, fillMode, matrix);
825   return FWL_Error::PropertyInvalid;
826 }
827 
ClipPath(CFX_Path * path,FX_FillMode fillMode,CFX_Matrix * matrix)828 FWL_Error CFX_Graphics::ClipPath(CFX_Path* path,
829                                  FX_FillMode fillMode,
830                                  CFX_Matrix* matrix) {
831   if (!path)
832     return FWL_Error::ParameterInvalid;
833   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
834     FX_BOOL result =
835         m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode);
836     if (!result)
837       return FWL_Error::Indefinite;
838     return FWL_Error::Succeeded;
839   }
840   return FWL_Error::PropertyInvalid;
841 }
842 
DrawImage(CFX_DIBSource * source,const CFX_PointF & point,CFX_Matrix * matrix)843 FWL_Error CFX_Graphics::DrawImage(CFX_DIBSource* source,
844                                   const CFX_PointF& point,
845                                   CFX_Matrix* matrix) {
846   if (!source)
847     return FWL_Error::ParameterInvalid;
848   if (m_type == FX_CONTEXT_Device && m_renderDevice)
849     return RenderDeviceDrawImage(source, point, matrix);
850   return FWL_Error::PropertyInvalid;
851 }
852 
StretchImage(CFX_DIBSource * source,const CFX_RectF & rect,CFX_Matrix * matrix)853 FWL_Error CFX_Graphics::StretchImage(CFX_DIBSource* source,
854                                      const CFX_RectF& rect,
855                                      CFX_Matrix* matrix) {
856   if (!source)
857     return FWL_Error::ParameterInvalid;
858   if (m_type == FX_CONTEXT_Device && m_renderDevice)
859     return RenderDeviceStretchImage(source, rect, matrix);
860   return FWL_Error::PropertyInvalid;
861 }
862 
ConcatMatrix(const CFX_Matrix * matrix)863 FWL_Error CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) {
864   if (!matrix)
865     return FWL_Error::ParameterInvalid;
866   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
867     m_info.CTM.Concat(*matrix);
868     return FWL_Error::Succeeded;
869   }
870   return FWL_Error::PropertyInvalid;
871 }
872 
GetMatrix()873 CFX_Matrix* CFX_Graphics::GetMatrix() {
874   if (m_type == FX_CONTEXT_Device && m_renderDevice)
875     return &m_info.CTM;
876   return nullptr;
877 }
878 
GetClipRect(CFX_RectF & rect) const879 FWL_Error CFX_Graphics::GetClipRect(CFX_RectF& rect) const {
880   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
881     FX_RECT r = m_renderDevice->GetClipBox();
882     rect.left = (FX_FLOAT)r.left;
883     rect.top = (FX_FLOAT)r.top;
884     rect.width = (FX_FLOAT)r.Width();
885     rect.height = (FX_FLOAT)r.Height();
886     return FWL_Error::Succeeded;
887   }
888   return FWL_Error::PropertyInvalid;
889 }
890 
SetClipRect(const CFX_RectF & rect)891 FWL_Error CFX_Graphics::SetClipRect(const CFX_RectF& rect) {
892   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
893     if (!m_renderDevice->SetClip_Rect(
894             FX_RECT(FXSYS_round(rect.left), FXSYS_round(rect.top),
895                     FXSYS_round(rect.right()), FXSYS_round(rect.bottom())))) {
896       return FWL_Error::MethodNotSupported;
897     }
898     return FWL_Error::Succeeded;
899   }
900   return FWL_Error::PropertyInvalid;
901 }
902 
ClearClip()903 FWL_Error CFX_Graphics::ClearClip() {
904   if (m_type == FX_CONTEXT_Device && m_renderDevice)
905     return FWL_Error::Succeeded;
906   return FWL_Error::PropertyInvalid;
907 }
908 
SetFont(CFX_Font * font)909 FWL_Error CFX_Graphics::SetFont(CFX_Font* font) {
910   if (!font)
911     return FWL_Error::ParameterInvalid;
912   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
913     m_info.font = font;
914     return FWL_Error::Succeeded;
915   }
916   return FWL_Error::PropertyInvalid;
917 }
918 
SetFontSize(const FX_FLOAT size)919 FWL_Error CFX_Graphics::SetFontSize(const FX_FLOAT size) {
920   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
921     m_info.fontSize = size <= 0 ? 1.0f : size;
922     return FWL_Error::Succeeded;
923   }
924   return FWL_Error::PropertyInvalid;
925 }
926 
SetFontHScale(const FX_FLOAT scale)927 FWL_Error CFX_Graphics::SetFontHScale(const FX_FLOAT scale) {
928   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
929     m_info.fontHScale = scale <= 0 ? 1.0f : scale;
930     return FWL_Error::Succeeded;
931   }
932   return FWL_Error::PropertyInvalid;
933 }
934 
SetCharSpacing(const FX_FLOAT spacing)935 FWL_Error CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing) {
936   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
937     m_info.fontSpacing = spacing < 0 ? 0 : spacing;
938     return FWL_Error::Succeeded;
939   }
940   return FWL_Error::PropertyInvalid;
941 }
942 
SetTextDrawingMode(const int32_t mode)943 FWL_Error CFX_Graphics::SetTextDrawingMode(const int32_t mode) {
944   if (m_type == FX_CONTEXT_Device && m_renderDevice)
945     return FWL_Error::Succeeded;
946   return FWL_Error::PropertyInvalid;
947 }
948 
ShowText(const CFX_PointF & point,const CFX_WideString & text,CFX_Matrix * matrix)949 FWL_Error CFX_Graphics::ShowText(const CFX_PointF& point,
950                                  const CFX_WideString& text,
951                                  CFX_Matrix* matrix) {
952   if (m_type == FX_CONTEXT_Device && m_renderDevice)
953     return RenderDeviceShowText(point, text, matrix);
954   return FWL_Error::PropertyInvalid;
955 }
956 
CalcTextRect(CFX_RectF & rect,const CFX_WideString & text,FX_BOOL isMultiline,CFX_Matrix * matrix)957 FWL_Error CFX_Graphics::CalcTextRect(CFX_RectF& rect,
958                                      const CFX_WideString& text,
959                                      FX_BOOL isMultiline,
960                                      CFX_Matrix* matrix) {
961   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
962     int32_t length = text.GetLength();
963     uint32_t* charCodes = FX_Alloc(uint32_t, length);
964     FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
965     CalcTextInfo(text, charCodes, charPos, rect);
966     FX_Free(charPos);
967     FX_Free(charCodes);
968     return FWL_Error::Succeeded;
969   }
970   return FWL_Error::PropertyInvalid;
971 }
972 
Transfer(CFX_Graphics * graphics,const CFX_Matrix * matrix)973 FWL_Error CFX_Graphics::Transfer(CFX_Graphics* graphics,
974                                  const CFX_Matrix* matrix) {
975   if (!graphics || !graphics->m_renderDevice)
976     return FWL_Error::ParameterInvalid;
977   CFX_Matrix m;
978   m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
979         m_info.CTM.f);
980   if (matrix) {
981     m.Concat(*matrix);
982   }
983   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
984     CFX_DIBitmap* bitmap = graphics->m_renderDevice->GetBitmap();
985     FX_BOOL result = m_renderDevice->SetDIBits(bitmap, 0, 0);
986     if (!result)
987       return FWL_Error::MethodNotSupported;
988     return FWL_Error::Succeeded;
989   }
990   return FWL_Error::PropertyInvalid;
991 }
992 
Transfer(CFX_Graphics * graphics,FX_FLOAT srcLeft,FX_FLOAT srcTop,const CFX_RectF & dstRect,const CFX_Matrix * matrix)993 FWL_Error CFX_Graphics::Transfer(CFX_Graphics* graphics,
994                                  FX_FLOAT srcLeft,
995                                  FX_FLOAT srcTop,
996                                  const CFX_RectF& dstRect,
997                                  const CFX_Matrix* matrix) {
998   if (!graphics || !graphics->m_renderDevice)
999     return FWL_Error::ParameterInvalid;
1000   CFX_Matrix m;
1001   m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
1002         m_info.CTM.f);
1003   if (matrix) {
1004     m.Concat(*matrix);
1005   }
1006   if (m_type == FX_CONTEXT_Device && m_renderDevice) {
1007     CFX_DIBitmap bmp;
1008     FX_BOOL result =
1009         bmp.Create((int32_t)dstRect.width, (int32_t)dstRect.height,
1010                    graphics->m_renderDevice->GetBitmap()->GetFormat());
1011     if (!result)
1012       return FWL_Error::IntermediateValueInvalid;
1013     result = graphics->m_renderDevice->GetDIBits(&bmp, (int32_t)srcLeft,
1014                                                  (int32_t)srcTop);
1015     if (!result)
1016       return FWL_Error::MethodNotSupported;
1017     result = m_renderDevice->SetDIBits(&bmp, (int32_t)dstRect.left,
1018                                        (int32_t)dstRect.top);
1019     if (!result)
1020       return FWL_Error::MethodNotSupported;
1021     return FWL_Error::Succeeded;
1022   }
1023   return FWL_Error::PropertyInvalid;
1024 }
1025 
GetRenderDevice()1026 CFX_RenderDevice* CFX_Graphics::GetRenderDevice() {
1027   return m_renderDevice;
1028 }
1029 
InverseRect(const CFX_RectF & rect)1030 FWL_Error CFX_Graphics::InverseRect(const CFX_RectF& rect) {
1031   if (!m_renderDevice)
1032     return FWL_Error::PropertyInvalid;
1033   CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
1034   if (!bitmap)
1035     return FWL_Error::PropertyInvalid;
1036   CFX_RectF temp(rect);
1037   m_info.CTM.TransformRect(temp);
1038   CFX_RectF r;
1039   r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth());
1040   r.Intersect(temp);
1041   if (r.IsEmpty()) {
1042     return FWL_Error::ParameterInvalid;
1043   }
1044   FX_ARGB* pBuf =
1045       (FX_ARGB*)(bitmap->GetBuffer() + int32_t(r.top) * bitmap->GetPitch());
1046   int32_t bottom = (int32_t)r.bottom();
1047   int32_t right = (int32_t)r.right();
1048   for (int32_t i = (int32_t)r.top; i < bottom; i++) {
1049     FX_ARGB* pLine = pBuf + (int32_t)r.left;
1050     for (int32_t j = (int32_t)r.left; j < right; j++) {
1051       FX_ARGB c = *pLine;
1052       *pLine++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF));
1053     }
1054     pBuf = (FX_ARGB*)((uint8_t*)pBuf + bitmap->GetPitch());
1055   }
1056   return FWL_Error::Succeeded;
1057 }
1058 
XorDIBitmap(const CFX_DIBitmap * srcBitmap,const CFX_RectF & rect)1059 FWL_Error CFX_Graphics::XorDIBitmap(const CFX_DIBitmap* srcBitmap,
1060                                     const CFX_RectF& rect) {
1061   if (!m_renderDevice)
1062     return FWL_Error::PropertyInvalid;
1063   CFX_DIBitmap* dst = m_renderDevice->GetBitmap();
1064   if (!dst)
1065     return FWL_Error::PropertyInvalid;
1066   CFX_RectF temp(rect);
1067   m_info.CTM.TransformRect(temp);
1068   CFX_RectF r;
1069   r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
1070   r.Intersect(temp);
1071   if (r.IsEmpty()) {
1072     return FWL_Error::ParameterInvalid;
1073   }
1074   FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
1075                                 int32_t(r.top) * srcBitmap->GetPitch());
1076   FX_ARGB* pDstBuf =
1077       (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
1078   int32_t bottom = (int32_t)r.bottom();
1079   int32_t right = (int32_t)r.right();
1080   for (int32_t i = (int32_t)r.top; i < bottom; i++) {
1081     FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
1082     FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
1083     for (int32_t j = (int32_t)r.left; j < right; j++) {
1084       FX_ARGB c = *pDstLine;
1085       *pDstLine++ =
1086           ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF));
1087       pSrcLine++;
1088     }
1089     pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
1090     pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
1091   }
1092   return FWL_Error::Succeeded;
1093 }
1094 
EqvDIBitmap(const CFX_DIBitmap * srcBitmap,const CFX_RectF & rect)1095 FWL_Error CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap* srcBitmap,
1096                                     const CFX_RectF& rect) {
1097   if (!m_renderDevice)
1098     return FWL_Error::PropertyInvalid;
1099   CFX_DIBitmap* dst = m_renderDevice->GetBitmap();
1100   if (!dst)
1101     return FWL_Error::PropertyInvalid;
1102   CFX_RectF temp(rect);
1103   m_info.CTM.TransformRect(temp);
1104   CFX_RectF r;
1105   r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
1106   r.Intersect(temp);
1107   if (r.IsEmpty()) {
1108     return FWL_Error::ParameterInvalid;
1109   }
1110   FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
1111                                 int32_t(r.top) * srcBitmap->GetPitch());
1112   FX_ARGB* pDstBuf =
1113       (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
1114   int32_t bottom = (int32_t)r.bottom();
1115   int32_t right = (int32_t)r.right();
1116   for (int32_t i = (int32_t)r.top; i < bottom; i++) {
1117     FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
1118     FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
1119     for (int32_t j = (int32_t)r.left; j < right; j++) {
1120       FX_ARGB c = *pDstLine;
1121       *pDstLine++ =
1122           ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)));
1123       pSrcLine++;
1124     }
1125     pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
1126     pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
1127   }
1128   return FWL_Error::Succeeded;
1129 }
1130 
RenderDeviceSetLineDash(FX_DashStyle dashStyle)1131 FWL_Error CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) {
1132   switch (dashStyle) {
1133     case FX_DASHSTYLE_Solid: {
1134       m_info.graphState.SetDashCount(0);
1135       return FWL_Error::Succeeded;
1136     }
1137     case FX_DASHSTYLE_Dash: {
1138       FX_FLOAT dashArray[] = {3, 1};
1139       SetLineDash(0, dashArray, 2);
1140       return FWL_Error::Succeeded;
1141     }
1142     case FX_DASHSTYLE_Dot: {
1143       FX_FLOAT dashArray[] = {1, 1};
1144       SetLineDash(0, dashArray, 2);
1145       return FWL_Error::Succeeded;
1146     }
1147     case FX_DASHSTYLE_DashDot: {
1148       FX_FLOAT dashArray[] = {3, 1, 1, 1};
1149       SetLineDash(0, dashArray, 4);
1150       return FWL_Error::Succeeded;
1151     }
1152     case FX_DASHSTYLE_DashDotDot: {
1153       FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
1154       SetLineDash(0, dashArray, 6);
1155       return FWL_Error::Succeeded;
1156     }
1157     default:
1158       return FWL_Error::ParameterInvalid;
1159   }
1160 }
1161 
RenderDeviceStrokePath(CFX_Path * path,CFX_Matrix * matrix)1162 FWL_Error CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path,
1163                                                CFX_Matrix* matrix) {
1164   if (!m_info.strokeColor)
1165     return FWL_Error::PropertyInvalid;
1166   CFX_Matrix m;
1167   m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
1168         m_info.CTM.f);
1169   if (matrix) {
1170     m.Concat(*matrix);
1171   }
1172   switch (m_info.strokeColor->m_type) {
1173     case FX_COLOR_Solid: {
1174       FX_BOOL result =
1175           m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState,
1176                                    0x0, m_info.strokeColor->m_info.argb, 0);
1177       if (!result)
1178         return FWL_Error::Indefinite;
1179       return FWL_Error::Succeeded;
1180     }
1181     case FX_COLOR_Pattern:
1182       return StrokePathWithPattern(path, &m);
1183     case FX_COLOR_Shading:
1184       return StrokePathWithShading(path, &m);
1185     default:
1186       return FWL_Error::PropertyInvalid;
1187   }
1188 }
1189 
RenderDeviceFillPath(CFX_Path * path,FX_FillMode fillMode,CFX_Matrix * matrix)1190 FWL_Error CFX_Graphics::RenderDeviceFillPath(CFX_Path* path,
1191                                              FX_FillMode fillMode,
1192                                              CFX_Matrix* matrix) {
1193   if (!m_info.fillColor)
1194     return FWL_Error::PropertyInvalid;
1195   CFX_Matrix m;
1196   m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
1197         m_info.CTM.f);
1198   if (matrix) {
1199     m.Concat(*matrix);
1200   }
1201   switch (m_info.fillColor->m_type) {
1202     case FX_COLOR_Solid: {
1203       FX_BOOL result = m_renderDevice->DrawPath(
1204           path->GetPathData(), &m, &m_info.graphState,
1205           m_info.fillColor->m_info.argb, 0x0, fillMode);
1206       if (!result)
1207         return FWL_Error::Indefinite;
1208       return FWL_Error::Succeeded;
1209     }
1210     case FX_COLOR_Pattern:
1211       return FillPathWithPattern(path, fillMode, &m);
1212     case FX_COLOR_Shading:
1213       return FillPathWithShading(path, fillMode, &m);
1214     default:
1215       return FWL_Error::PropertyInvalid;
1216   }
1217 }
1218 
RenderDeviceDrawImage(CFX_DIBSource * source,const CFX_PointF & point,CFX_Matrix * matrix)1219 FWL_Error CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource* source,
1220                                               const CFX_PointF& point,
1221                                               CFX_Matrix* matrix) {
1222   CFX_Matrix m1;
1223   m1.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
1224          m_info.CTM.f);
1225   if (matrix) {
1226     m1.Concat(*matrix);
1227   }
1228   CFX_Matrix m2;
1229   m2.Set((FX_FLOAT)source->GetWidth(), 0.0, 0.0, (FX_FLOAT)source->GetHeight(),
1230          point.x, point.y);
1231   m2.Concat(m1);
1232   int32_t left, top;
1233   std::unique_ptr<CFX_DIBitmap> bmp1(source->FlipImage(FALSE, TRUE));
1234   std::unique_ptr<CFX_DIBitmap> bmp2(bmp1->TransformTo(&m2, left, top));
1235   CFX_RectF r;
1236   GetClipRect(r);
1237   CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
1238   CFX_DIBitmap bmp;
1239   if (bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb) &&
1240       m_renderDevice->GetDIBits(&bmp, 0, 0) &&
1241       bmp.TransferBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
1242                          FXSYS_round(r.Width()), FXSYS_round(r.Height()),
1243                          bmp2.get(), FXSYS_round(r.left - left),
1244                          FXSYS_round(r.top - top)) &&
1245       m_renderDevice->SetDIBits(&bmp, 0, 0)) {
1246     return FWL_Error::Succeeded;
1247   }
1248   return FWL_Error::Indefinite;
1249 }
1250 
RenderDeviceStretchImage(CFX_DIBSource * source,const CFX_RectF & rect,CFX_Matrix * matrix)1251 FWL_Error CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source,
1252                                                  const CFX_RectF& rect,
1253                                                  CFX_Matrix* matrix) {
1254   CFX_Matrix m1;
1255   m1.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
1256          m_info.CTM.f);
1257   if (matrix) {
1258     m1.Concat(*matrix);
1259   }
1260   std::unique_ptr<CFX_DIBitmap> bmp1(
1261       source->StretchTo((int32_t)rect.Width(), (int32_t)rect.Height()));
1262   CFX_Matrix m2;
1263   m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top);
1264   m2.Concat(m1);
1265   int32_t left, top;
1266   std::unique_ptr<CFX_DIBitmap> bmp2(bmp1->FlipImage(FALSE, TRUE));
1267   std::unique_ptr<CFX_DIBitmap> bmp3(bmp2->TransformTo(&m2, left, top));
1268   CFX_RectF r;
1269   GetClipRect(r);
1270   CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
1271   if (bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
1272                               FXSYS_round(r.Width()), FXSYS_round(r.Height()),
1273                               bmp3.get(), FXSYS_round(r.left - left),
1274                               FXSYS_round(r.top - top))) {
1275     return FWL_Error::Succeeded;
1276   }
1277   return FWL_Error::Indefinite;
1278 }
1279 
RenderDeviceShowText(const CFX_PointF & point,const CFX_WideString & text,CFX_Matrix * matrix)1280 FWL_Error CFX_Graphics::RenderDeviceShowText(const CFX_PointF& point,
1281                                              const CFX_WideString& text,
1282                                              CFX_Matrix* matrix) {
1283   int32_t length = text.GetLength();
1284   uint32_t* charCodes = FX_Alloc(uint32_t, length);
1285   FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
1286   CFX_RectF rect;
1287   rect.Set(point.x, point.y, 0, 0);
1288   CalcTextInfo(text, charCodes, charPos, rect);
1289   CFX_Matrix m;
1290   m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
1291         m_info.CTM.f);
1292   m.Translate(0, m_info.fontSize * m_info.fontHScale);
1293   if (matrix) {
1294     m.Concat(*matrix);
1295   }
1296   FX_BOOL result = m_renderDevice->DrawNormalText(
1297       length, charPos, m_info.font, CFX_GEModule::Get()->GetFontCache(),
1298       -m_info.fontSize * m_info.fontHScale, &m, m_info.fillColor->m_info.argb,
1299       FXTEXT_CLEARTYPE);
1300   if (!result)
1301     return FWL_Error::Indefinite;
1302   FX_Free(charPos);
1303   FX_Free(charCodes);
1304   return FWL_Error::Succeeded;
1305 }
1306 
StrokePathWithPattern(CFX_Path * path,CFX_Matrix * matrix)1307 FWL_Error CFX_Graphics::StrokePathWithPattern(CFX_Path* path,
1308                                               CFX_Matrix* matrix) {
1309   return FWL_Error::MethodNotSupported;
1310 }
1311 
StrokePathWithShading(CFX_Path * path,CFX_Matrix * matrix)1312 FWL_Error CFX_Graphics::StrokePathWithShading(CFX_Path* path,
1313                                               CFX_Matrix* matrix) {
1314   return FWL_Error::MethodNotSupported;
1315 }
1316 
FillPathWithPattern(CFX_Path * path,FX_FillMode fillMode,CFX_Matrix * matrix)1317 FWL_Error CFX_Graphics::FillPathWithPattern(CFX_Path* path,
1318                                             FX_FillMode fillMode,
1319                                             CFX_Matrix* matrix) {
1320   CFX_Pattern* pattern = m_info.fillColor->m_info.pattern;
1321   CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
1322   int32_t width = bitmap->GetWidth();
1323   int32_t height = bitmap->GetHeight();
1324   CFX_DIBitmap bmp;
1325   bmp.Create(width, height, FXDIB_Argb);
1326   m_renderDevice->GetDIBits(&bmp, 0, 0);
1327 
1328   FX_HatchStyle hatchStyle = m_info.fillColor->m_info.pattern->m_hatchStyle;
1329   if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
1330       hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
1331     return FWL_Error::IntermediateValueInvalid;
1332   }
1333   const FX_HATCHDATA& data = hatchBitmapData[hatchStyle];
1334   CFX_DIBitmap mask;
1335   mask.Create(data.width, data.height, FXDIB_1bppMask);
1336   FXSYS_memcpy(mask.GetBuffer(), data.maskBits, mask.GetPitch() * data.height);
1337   CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox();
1338   if (matrix) {
1339     rectf.Transform(matrix);
1340   }
1341   FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
1342                FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
1343   CFX_FxgeDevice device;
1344   device.Attach(&bmp, false, nullptr, false);
1345   device.FillRect(&rect, m_info.fillColor->m_info.pattern->m_backArgb);
1346   for (int32_t j = rect.bottom; j < rect.top; j += mask.GetHeight()) {
1347     for (int32_t i = rect.left; i < rect.right; i += mask.GetWidth()) {
1348       device.SetBitMask(&mask, i, j,
1349                         m_info.fillColor->m_info.pattern->m_foreArgb);
1350     }
1351   }
1352 
1353   m_renderDevice->SaveState();
1354   m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode);
1355   SetDIBitsWithMatrix(&bmp, &pattern->m_matrix);
1356   m_renderDevice->RestoreState(false);
1357   return FWL_Error::Succeeded;
1358 }
1359 
FillPathWithShading(CFX_Path * path,FX_FillMode fillMode,CFX_Matrix * matrix)1360 FWL_Error CFX_Graphics::FillPathWithShading(CFX_Path* path,
1361                                             FX_FillMode fillMode,
1362                                             CFX_Matrix* matrix) {
1363   CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
1364   int32_t width = bitmap->GetWidth();
1365   int32_t height = bitmap->GetHeight();
1366   FX_FLOAT start_x = m_info.fillColor->m_shading->m_beginPoint.x;
1367   FX_FLOAT start_y = m_info.fillColor->m_shading->m_beginPoint.y;
1368   FX_FLOAT end_x = m_info.fillColor->m_shading->m_endPoint.x;
1369   FX_FLOAT end_y = m_info.fillColor->m_shading->m_endPoint.y;
1370   CFX_DIBitmap bmp;
1371   bmp.Create(width, height, FXDIB_Argb);
1372   m_renderDevice->GetDIBits(&bmp, 0, 0);
1373   int32_t pitch = bmp.GetPitch();
1374   bool result = false;
1375   switch (m_info.fillColor->m_shading->m_type) {
1376     case FX_SHADING_Axial: {
1377       FX_FLOAT x_span = end_x - start_x;
1378       FX_FLOAT y_span = end_y - start_y;
1379       FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span);
1380       for (int32_t row = 0; row < height; row++) {
1381         uint32_t* dib_buf = (uint32_t*)(bmp.GetBuffer() + row * pitch);
1382         for (int32_t column = 0; column < width; column++) {
1383           FX_FLOAT x = (FX_FLOAT)(column);
1384           FX_FLOAT y = (FX_FLOAT)(row);
1385           FX_FLOAT scale =
1386               (((x - start_x) * x_span) + ((y - start_y) * y_span)) /
1387               axis_len_square;
1388           if (scale < 0) {
1389             if (!m_info.fillColor->m_shading->m_isExtendedBegin) {
1390               continue;
1391             }
1392             scale = 0;
1393           } else if (scale > 1.0f) {
1394             if (!m_info.fillColor->m_shading->m_isExtendedEnd) {
1395               continue;
1396             }
1397             scale = 1.0f;
1398           }
1399           int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1));
1400           dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index];
1401         }
1402       }
1403       result = true;
1404       break;
1405     }
1406     case FX_SHADING_Radial: {
1407       FX_FLOAT start_r = m_info.fillColor->m_shading->m_beginRadius;
1408       FX_FLOAT end_r = m_info.fillColor->m_shading->m_endRadius;
1409       FX_FLOAT a = ((start_x - end_x) * (start_x - end_x)) +
1410                    ((start_y - end_y) * (start_y - end_y)) -
1411                    ((start_r - end_r) * (start_r - end_r));
1412       for (int32_t row = 0; row < height; row++) {
1413         uint32_t* dib_buf = (uint32_t*)(bmp.GetBuffer() + row * pitch);
1414         for (int32_t column = 0; column < width; column++) {
1415           FX_FLOAT x = (FX_FLOAT)(column);
1416           FX_FLOAT y = (FX_FLOAT)(row);
1417           FX_FLOAT b = -2 * (((x - start_x) * (end_x - start_x)) +
1418                              ((y - start_y) * (end_y - start_y)) +
1419                              (start_r * (end_r - start_r)));
1420           FX_FLOAT c = ((x - start_x) * (x - start_x)) +
1421                        ((y - start_y) * (y - start_y)) - (start_r * start_r);
1422           FX_FLOAT s;
1423           if (a == 0) {
1424             s = -c / b;
1425           } else {
1426             FX_FLOAT b2_4ac = (b * b) - 4 * (a * c);
1427             if (b2_4ac < 0) {
1428               continue;
1429             }
1430             FX_FLOAT root = (FXSYS_sqrt(b2_4ac));
1431             FX_FLOAT s1, s2;
1432             if (a > 0) {
1433               s1 = (-b - root) / (2 * a);
1434               s2 = (-b + root) / (2 * a);
1435             } else {
1436               s2 = (-b - root) / (2 * a);
1437               s1 = (-b + root) / (2 * a);
1438             }
1439             if (s2 <= 1.0f || m_info.fillColor->m_shading->m_isExtendedEnd) {
1440               s = (s2);
1441             } else {
1442               s = (s1);
1443             }
1444             if ((start_r) + s * (end_r - start_r) < 0) {
1445               continue;
1446             }
1447           }
1448           if (s < 0) {
1449             if (!m_info.fillColor->m_shading->m_isExtendedBegin) {
1450               continue;
1451             }
1452             s = 0;
1453           }
1454           if (s > 1.0f) {
1455             if (!m_info.fillColor->m_shading->m_isExtendedEnd) {
1456               continue;
1457             }
1458             s = 1.0f;
1459           }
1460           int index = (int32_t)(s * (FX_SHADING_Steps - 1));
1461           dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index];
1462         }
1463       }
1464       result = true;
1465       break;
1466     }
1467     default: {
1468       result = false;
1469       break;
1470     }
1471   }
1472   if (result) {
1473     m_renderDevice->SaveState();
1474     m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode);
1475     SetDIBitsWithMatrix(&bmp, matrix);
1476     m_renderDevice->RestoreState(false);
1477   }
1478   return result ? FWL_Error::Succeeded : FWL_Error::PropertyInvalid;
1479 }
1480 
SetDIBitsWithMatrix(CFX_DIBSource * source,CFX_Matrix * matrix)1481 FWL_Error CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source,
1482                                             CFX_Matrix* matrix) {
1483   if (matrix->IsIdentity()) {
1484     m_renderDevice->SetDIBits(source, 0, 0);
1485   } else {
1486     CFX_Matrix m;
1487     m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0,
1488           0);
1489     m.Concat(*matrix);
1490     int32_t left, top;
1491     std::unique_ptr<CFX_DIBitmap> bmp1(source->FlipImage(FALSE, TRUE));
1492     std::unique_ptr<CFX_DIBitmap> bmp2(bmp1->TransformTo(&m, left, top));
1493     m_renderDevice->SetDIBits(bmp2.get(), left, top);
1494   }
1495   return FWL_Error::Succeeded;
1496 }
1497 
CalcTextInfo(const CFX_WideString & text,uint32_t * charCodes,FXTEXT_CHARPOS * charPos,CFX_RectF & rect)1498 FWL_Error CFX_Graphics::CalcTextInfo(const CFX_WideString& text,
1499                                      uint32_t* charCodes,
1500                                      FXTEXT_CHARPOS* charPos,
1501                                      CFX_RectF& rect) {
1502   std::unique_ptr<CFX_UnicodeEncoding> encoding(
1503       new CFX_UnicodeEncoding(m_info.font));
1504   int32_t length = text.GetLength();
1505   FX_FLOAT penX = (FX_FLOAT)rect.left;
1506   FX_FLOAT penY = (FX_FLOAT)rect.top;
1507   FX_FLOAT left = (FX_FLOAT)(0);
1508   FX_FLOAT top = (FX_FLOAT)(0);
1509   charCodes[0] = text.GetAt(0);
1510   charPos[0].m_OriginX = penX + left;
1511   charPos[0].m_OriginY = penY + top;
1512   charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]);
1513   charPos[0].m_FontCharWidth = FXSYS_round(
1514       m_info.font->GetGlyphWidth(charPos[0].m_GlyphIndex) * m_info.fontHScale);
1515   charPos[0].m_bGlyphAdjust = TRUE;
1516   charPos[0].m_AdjustMatrix[0] = -1;
1517   charPos[0].m_AdjustMatrix[1] = 0;
1518   charPos[0].m_AdjustMatrix[2] = 0;
1519   charPos[0].m_AdjustMatrix[3] = 1;
1520   penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * m_info.fontSize / 1000 +
1521           m_info.fontSpacing;
1522   for (int32_t i = 1; i < length; i++) {
1523     charCodes[i] = text.GetAt(i);
1524     charPos[i].m_OriginX = penX + left;
1525     charPos[i].m_OriginY = penY + top;
1526     charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]);
1527     charPos[i].m_FontCharWidth =
1528         FXSYS_round(m_info.font->GetGlyphWidth(charPos[i].m_GlyphIndex) *
1529                     m_info.fontHScale);
1530     charPos[i].m_bGlyphAdjust = TRUE;
1531     charPos[i].m_AdjustMatrix[0] = -1;
1532     charPos[i].m_AdjustMatrix[1] = 0;
1533     charPos[i].m_AdjustMatrix[2] = 0;
1534     charPos[i].m_AdjustMatrix[3] = 1;
1535     penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * m_info.fontSize / 1000 +
1536             m_info.fontSpacing;
1537   }
1538   rect.width = (FX_FLOAT)penX - rect.left;
1539   rect.height = rect.top + m_info.fontSize * m_info.fontHScale - rect.top;
1540   return FWL_Error::Succeeded;
1541 }
1542 
TInfo()1543 CFX_Graphics::TInfo::TInfo()
1544     : isAntialiasing(TRUE),
1545       strokeAlignment(FX_STROKEALIGNMENT_Center),
1546       isActOnDash(FALSE),
1547       strokeColor(nullptr),
1548       fillColor(nullptr),
1549       font(nullptr),
1550       fontSize(40.0),
1551       fontHScale(1.0),
1552       fontSpacing(0.0) {}
1553 
TInfo(const TInfo & info)1554 CFX_Graphics::TInfo::TInfo(const TInfo& info)
1555     : graphState(info.graphState),
1556       isAntialiasing(info.isAntialiasing),
1557       strokeAlignment(info.strokeAlignment),
1558       CTM(info.CTM),
1559       isActOnDash(info.isActOnDash),
1560       strokeColor(info.strokeColor),
1561       fillColor(info.fillColor),
1562       font(info.font),
1563       fontSize(info.fontSize),
1564       fontHScale(info.fontHScale),
1565       fontSpacing(info.fontSpacing) {}
1566 
operator =(const TInfo & other)1567 CFX_Graphics::TInfo& CFX_Graphics::TInfo::operator=(const TInfo& other) {
1568   graphState.Copy(other.graphState);
1569   isAntialiasing = other.isAntialiasing;
1570   strokeAlignment = other.strokeAlignment;
1571   CTM = other.CTM;
1572   isActOnDash = other.isActOnDash;
1573   strokeColor = other.strokeColor;
1574   fillColor = other.fillColor;
1575   font = other.font;
1576   fontSize = other.fontSize;
1577   fontHScale = other.fontHScale;
1578   fontSpacing = other.fontSpacing;
1579   return *this;
1580 }
1581