Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: xfa/fxgraphics/fx_graphics.cpp

Issue 1810563002: Move xfa/include/fxgraphics/fx_graphics.h to xfa/fxgraphics. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/fxgraphics/cfx_shading.cpp ('k') | xfa/fxgraphics/fx_path_generator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/include/fxgraphics/fx_graphics.h"
8
9 #include <memory>
10
11 #include "xfa/fxgraphics/fx_path_generator.h"
12 #include "xfa/fxgraphics/pre.h"
13
14 CFX_Graphics::CFX_Graphics()
15 : m_renderDevice(nullptr), m_aggGraphics(nullptr) {}
16
17 FX_ERR CFX_Graphics::Create(CFX_RenderDevice* renderDevice,
18 FX_BOOL isAntialiasing) {
19 if (!renderDevice)
20 return FX_ERR_Parameter_Invalid;
21 if (m_type != FX_CONTEXT_None)
22 return FX_ERR_Property_Invalid;
23
24 m_type = FX_CONTEXT_Device;
25 m_info.isAntialiasing = isAntialiasing;
26 m_renderDevice = renderDevice;
27 if (m_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)
28 return FX_ERR_Succeeded;
29 return FX_ERR_Indefinite;
30 }
31
32 FX_ERR CFX_Graphics::Create(int32_t width,
33 int32_t height,
34 FXDIB_Format format,
35 FX_BOOL isNative,
36 FX_BOOL isAntialiasing) {
37 if (m_type != FX_CONTEXT_None)
38 return FX_ERR_Property_Invalid;
39
40 m_type = FX_CONTEXT_Device;
41 m_info.isAntialiasing = isAntialiasing;
42 m_aggGraphics = new CAGG_Graphics;
43 return m_aggGraphics->Create(this, width, height, format);
44 }
45
46 CFX_Graphics::~CFX_Graphics() {
47 delete m_aggGraphics;
48 }
49
50 FX_ERR CFX_Graphics::GetDeviceCap(const int32_t capID, FX_DeviceCap& capVal) {
51 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
52 capVal = m_renderDevice->GetDeviceCaps(capID);
53 return FX_ERR_Succeeded;
54 }
55 return FX_ERR_Property_Invalid;
56 }
57
58 FX_ERR CFX_Graphics::IsPrinterDevice(FX_BOOL& isPrinter) {
59 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
60 isPrinter = m_renderDevice->GetDeviceClass() == FXDC_PRINTER;
61 return FX_ERR_Succeeded;
62 }
63 return FX_ERR_Property_Invalid;
64 }
65
66 FX_ERR CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing) {
67 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
68 m_info.isAntialiasing = isAntialiasing;
69 return FX_ERR_Succeeded;
70 }
71 return FX_ERR_Property_Invalid;
72 }
73
74 FX_ERR CFX_Graphics::SaveGraphState() {
75 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
76 m_renderDevice->SaveState();
77 m_infoStack.Add(new TInfo(m_info));
78 return FX_ERR_Succeeded;
79 }
80 return FX_ERR_Property_Invalid;
81 }
82
83 FX_ERR CFX_Graphics::RestoreGraphState() {
84 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
85 m_renderDevice->RestoreState();
86 int32_t size = m_infoStack.GetSize();
87 if (size <= 0) {
88 return FX_ERR_Intermediate_Value_Invalid;
89 }
90 int32_t topIndex = size - 1;
91 std::unique_ptr<TInfo> info(
92 reinterpret_cast<TInfo*>(m_infoStack.GetAt(topIndex)));
93 if (!info)
94 return FX_ERR_Intermediate_Value_Invalid;
95 m_info = *info;
96 m_infoStack.RemoveAt(topIndex);
97 return FX_ERR_Succeeded;
98 }
99 return FX_ERR_Property_Invalid;
100 }
101
102 FX_ERR CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap& lineCap) const {
103 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
104 lineCap = m_info.graphState.m_LineCap;
105 return FX_ERR_Succeeded;
106 }
107 return FX_ERR_Property_Invalid;
108 }
109
110 FX_ERR CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) {
111 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
112 m_info.graphState.m_LineCap = lineCap;
113 return FX_ERR_Succeeded;
114 }
115 return FX_ERR_Property_Invalid;
116 }
117
118 FX_ERR CFX_Graphics::GetDashCount(int32_t& dashCount) const {
119 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
120 dashCount = m_info.graphState.m_DashCount;
121 return FX_ERR_Succeeded;
122 }
123 return FX_ERR_Property_Invalid;
124 }
125
126 FX_ERR CFX_Graphics::GetLineDash(FX_FLOAT& dashPhase,
127 FX_FLOAT* dashArray) const {
128 if (!dashArray)
129 return FX_ERR_Parameter_Invalid;
130 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
131 dashPhase = m_info.graphState.m_DashPhase;
132 FXSYS_memcpy(dashArray, m_info.graphState.m_DashArray,
133 m_info.graphState.m_DashCount * sizeof(FX_FLOAT));
134 return FX_ERR_Succeeded;
135 }
136 return FX_ERR_Property_Invalid;
137 }
138
139 FX_ERR CFX_Graphics::SetLineDash(FX_FLOAT dashPhase,
140 FX_FLOAT* dashArray,
141 int32_t dashCount) {
142 if (dashCount > 0 && !dashArray)
143 return FX_ERR_Parameter_Invalid;
144
145 dashCount = dashCount < 0 ? 0 : dashCount;
146 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
147 FX_FLOAT scale = 1.0;
148 if (m_info.isActOnDash) {
149 scale = m_info.graphState.m_LineWidth;
150 }
151 m_info.graphState.m_DashPhase = dashPhase;
152 m_info.graphState.SetDashCount(dashCount);
153 for (int32_t i = 0; i < dashCount; i++) {
154 m_info.graphState.m_DashArray[i] = dashArray[i] * scale;
155 }
156 return FX_ERR_Succeeded;
157 }
158 return FX_ERR_Property_Invalid;
159 }
160
161 FX_ERR CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) {
162 if (m_type == FX_CONTEXT_Device && m_renderDevice)
163 return RenderDeviceSetLineDash(dashStyle);
164 return FX_ERR_Property_Invalid;
165 }
166
167 FX_ERR CFX_Graphics::GetLineJoin(CFX_GraphStateData::LineJoin& lineJoin) const {
168 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
169 lineJoin = m_info.graphState.m_LineJoin;
170 return FX_ERR_Succeeded;
171 }
172 return FX_ERR_Property_Invalid;
173 }
174
175 FX_ERR CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin) {
176 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
177 m_info.graphState.m_LineJoin = lineJoin;
178 return FX_ERR_Succeeded;
179 }
180 return FX_ERR_Property_Invalid;
181 }
182
183 FX_ERR CFX_Graphics::GetMiterLimit(FX_FLOAT& miterLimit) const {
184 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
185 miterLimit = m_info.graphState.m_MiterLimit;
186 return FX_ERR_Succeeded;
187 }
188 return FX_ERR_Property_Invalid;
189 }
190
191 FX_ERR CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit) {
192 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
193 m_info.graphState.m_MiterLimit = miterLimit;
194 return FX_ERR_Succeeded;
195 }
196 return FX_ERR_Property_Invalid;
197 }
198
199 FX_ERR CFX_Graphics::GetLineWidth(FX_FLOAT& lineWidth) const {
200 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
201 lineWidth = m_info.graphState.m_LineWidth;
202 return FX_ERR_Succeeded;
203 }
204 return FX_ERR_Property_Invalid;
205 }
206
207 FX_ERR CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash) {
208 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
209 m_info.graphState.m_LineWidth = lineWidth;
210 m_info.isActOnDash = isActOnDash;
211 return FX_ERR_Succeeded;
212 }
213 return FX_ERR_Property_Invalid;
214 }
215
216 FX_ERR CFX_Graphics::GetStrokeAlignment(
217 FX_StrokeAlignment& strokeAlignment) const {
218 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
219 strokeAlignment = m_info.strokeAlignment;
220 return FX_ERR_Succeeded;
221 }
222 return FX_ERR_Property_Invalid;
223 }
224
225 FX_ERR CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment) {
226 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
227 m_info.strokeAlignment = strokeAlignment;
228 return FX_ERR_Succeeded;
229 }
230 return FX_ERR_Property_Invalid;
231 }
232
233 FX_ERR CFX_Graphics::SetStrokeColor(CFX_Color* color) {
234 if (!color)
235 return FX_ERR_Parameter_Invalid;
236 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
237 m_info.strokeColor = color;
238 return FX_ERR_Succeeded;
239 }
240 return FX_ERR_Property_Invalid;
241 }
242
243 FX_ERR CFX_Graphics::SetFillColor(CFX_Color* color) {
244 if (!color)
245 return FX_ERR_Parameter_Invalid;
246 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
247 m_info.fillColor = color;
248 return FX_ERR_Succeeded;
249 }
250 return FX_ERR_Property_Invalid;
251 }
252
253 FX_ERR CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) {
254 if (!path)
255 return FX_ERR_Parameter_Invalid;
256 if (m_type == FX_CONTEXT_Device && m_renderDevice)
257 return RenderDeviceStrokePath(path, matrix);
258 return FX_ERR_Property_Invalid;
259 }
260
261 FX_ERR CFX_Graphics::FillPath(CFX_Path* path,
262 FX_FillMode fillMode,
263 CFX_Matrix* matrix) {
264 if (!path)
265 return FX_ERR_Parameter_Invalid;
266 if (m_type == FX_CONTEXT_Device && m_renderDevice)
267 return RenderDeviceFillPath(path, fillMode, matrix);
268 return FX_ERR_Property_Invalid;
269 }
270
271 FX_ERR CFX_Graphics::ClipPath(CFX_Path* path,
272 FX_FillMode fillMode,
273 CFX_Matrix* matrix) {
274 if (!path)
275 return FX_ERR_Parameter_Invalid;
276 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
277 FX_BOOL result = m_renderDevice->SetClip_PathFill(
278 path->GetPathData(), (CFX_Matrix*)matrix, fillMode);
279 if (!result)
280 return FX_ERR_Indefinite;
281 return FX_ERR_Succeeded;
282 }
283 return FX_ERR_Property_Invalid;
284 }
285
286 FX_ERR CFX_Graphics::DrawImage(CFX_DIBSource* source,
287 const CFX_PointF& point,
288 CFX_Matrix* matrix) {
289 if (!source)
290 return FX_ERR_Parameter_Invalid;
291 if (m_type == FX_CONTEXT_Device && m_renderDevice)
292 return RenderDeviceDrawImage(source, point, matrix);
293 return FX_ERR_Property_Invalid;
294 }
295
296 FX_ERR CFX_Graphics::StretchImage(CFX_DIBSource* source,
297 const CFX_RectF& rect,
298 CFX_Matrix* matrix) {
299 if (!source)
300 return FX_ERR_Parameter_Invalid;
301 if (m_type == FX_CONTEXT_Device && m_renderDevice)
302 return RenderDeviceStretchImage(source, rect, matrix);
303 return FX_ERR_Property_Invalid;
304 }
305
306 FX_ERR CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) {
307 if (!matrix)
308 return FX_ERR_Parameter_Invalid;
309 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
310 m_info.CTM.Concat(*matrix);
311 return FX_ERR_Succeeded;
312 }
313 return FX_ERR_Property_Invalid;
314 }
315
316 CFX_Matrix* CFX_Graphics::GetMatrix() {
317 if (m_type == FX_CONTEXT_Device && m_renderDevice)
318 return &m_info.CTM;
319 return nullptr;
320 }
321
322 FX_ERR CFX_Graphics::GetClipRect(CFX_RectF& rect) const {
323 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
324 FX_RECT r = m_renderDevice->GetClipBox();
325 rect.left = (FX_FLOAT)r.left;
326 rect.top = (FX_FLOAT)r.top;
327 rect.width = (FX_FLOAT)r.Width();
328 rect.height = (FX_FLOAT)r.Height();
329 return FX_ERR_Succeeded;
330 }
331 return FX_ERR_Property_Invalid;
332 }
333
334 FX_ERR CFX_Graphics::SetClipRect(const CFX_RectF& rect) {
335 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
336 if (!m_renderDevice->SetClip_Rect(
337 FX_RECT(FXSYS_round(rect.left), FXSYS_round(rect.top),
338 FXSYS_round(rect.right()), FXSYS_round(rect.bottom())))) {
339 return FX_ERR_Method_Not_Supported;
340 }
341 return FX_ERR_Succeeded;
342 }
343 return FX_ERR_Property_Invalid;
344 }
345
346 FX_ERR CFX_Graphics::ClearClip() {
347 if (m_type == FX_CONTEXT_Device && m_renderDevice)
348 return FX_ERR_Succeeded;
349 return FX_ERR_Property_Invalid;
350 }
351
352 FX_ERR CFX_Graphics::SetFont(CFX_Font* font) {
353 if (!font)
354 return FX_ERR_Parameter_Invalid;
355 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
356 m_info.font = font;
357 return FX_ERR_Succeeded;
358 }
359 return FX_ERR_Property_Invalid;
360 }
361
362 FX_ERR CFX_Graphics::SetFontSize(const FX_FLOAT size) {
363 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
364 m_info.fontSize = size <= 0 ? 1.0f : size;
365 return FX_ERR_Succeeded;
366 }
367 return FX_ERR_Property_Invalid;
368 }
369
370 FX_ERR CFX_Graphics::SetFontHScale(const FX_FLOAT scale) {
371 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
372 m_info.fontHScale = scale <= 0 ? 1.0f : scale;
373 return FX_ERR_Succeeded;
374 }
375 return FX_ERR_Property_Invalid;
376 }
377
378 FX_ERR CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing) {
379 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
380 m_info.fontSpacing = spacing < 0 ? 0 : spacing;
381 return FX_ERR_Succeeded;
382 }
383 return FX_ERR_Property_Invalid;
384 }
385
386 FX_ERR CFX_Graphics::SetTextDrawingMode(const int32_t mode) {
387 if (m_type == FX_CONTEXT_Device && m_renderDevice)
388 return FX_ERR_Succeeded;
389 return FX_ERR_Property_Invalid;
390 }
391
392 FX_ERR CFX_Graphics::ShowText(const CFX_PointF& point,
393 const CFX_WideString& text,
394 CFX_Matrix* matrix) {
395 if (m_type == FX_CONTEXT_Device && m_renderDevice)
396 return RenderDeviceShowText(point, text, matrix);
397 return FX_ERR_Property_Invalid;
398 }
399
400 FX_ERR CFX_Graphics::CalcTextRect(CFX_RectF& rect,
401 const CFX_WideString& text,
402 FX_BOOL isMultiline,
403 CFX_Matrix* matrix) {
404 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
405 int32_t length = text.GetLength();
406 FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
407 FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
408 CalcTextInfo(text, charCodes, charPos, rect);
409 FX_Free(charPos);
410 FX_Free(charCodes);
411 return FX_ERR_Succeeded;
412 }
413 return FX_ERR_Property_Invalid;
414 }
415
416 FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
417 const CFX_Matrix* matrix) {
418 if (!graphics || !graphics->m_renderDevice)
419 return FX_ERR_Parameter_Invalid;
420 CFX_Matrix m;
421 m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
422 m_info.CTM.f);
423 if (matrix) {
424 m.Concat(*matrix);
425 }
426 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
427 CFX_DIBitmap* bitmap = graphics->m_renderDevice->GetBitmap();
428 FX_BOOL result = m_renderDevice->SetDIBits(bitmap, 0, 0);
429 if (!result)
430 return FX_ERR_Method_Not_Supported;
431 return FX_ERR_Succeeded;
432 }
433 return FX_ERR_Property_Invalid;
434 }
435
436 FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
437 FX_FLOAT srcLeft,
438 FX_FLOAT srcTop,
439 const CFX_RectF& dstRect,
440 const CFX_Matrix* matrix) {
441 if (!graphics || !graphics->m_renderDevice)
442 return FX_ERR_Parameter_Invalid;
443 CFX_Matrix m;
444 m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
445 m_info.CTM.f);
446 if (matrix) {
447 m.Concat(*matrix);
448 }
449 if (m_type == FX_CONTEXT_Device && m_renderDevice) {
450 CFX_DIBitmap bmp;
451 FX_BOOL result =
452 bmp.Create((int32_t)dstRect.width, (int32_t)dstRect.height,
453 graphics->m_renderDevice->GetBitmap()->GetFormat());
454 if (!result)
455 return FX_ERR_Intermediate_Value_Invalid;
456 result = graphics->m_renderDevice->GetDIBits(&bmp, (int32_t)srcLeft,
457 (int32_t)srcTop);
458 if (!result)
459 return FX_ERR_Method_Not_Supported;
460 result = m_renderDevice->SetDIBits(&bmp, (int32_t)dstRect.left,
461 (int32_t)dstRect.top);
462 if (!result)
463 return FX_ERR_Method_Not_Supported;
464 return FX_ERR_Succeeded;
465 }
466 return FX_ERR_Property_Invalid;
467 }
468
469 CFX_RenderDevice* CFX_Graphics::GetRenderDevice() {
470 return m_renderDevice;
471 }
472
473 FX_ERR CFX_Graphics::InverseRect(const CFX_RectF& rect) {
474 if (!m_renderDevice)
475 return FX_ERR_Property_Invalid;
476 CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
477 if (!bitmap)
478 return FX_ERR_Property_Invalid;
479 CFX_RectF temp(rect);
480 m_info.CTM.TransformRect(temp);
481 CFX_RectF r;
482 r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth());
483 r.Intersect(temp);
484 if (r.IsEmpty()) {
485 return FX_ERR_Parameter_Invalid;
486 }
487 FX_ARGB* pBuf =
488 (FX_ARGB*)(bitmap->GetBuffer() + int32_t(r.top) * bitmap->GetPitch());
489 int32_t bottom = (int32_t)r.bottom();
490 int32_t right = (int32_t)r.right();
491 for (int32_t i = (int32_t)r.top; i < bottom; i++) {
492 FX_ARGB* pLine = pBuf + (int32_t)r.left;
493 for (int32_t j = (int32_t)r.left; j < right; j++) {
494 FX_ARGB c = *pLine;
495 *pLine++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF));
496 }
497 pBuf = (FX_ARGB*)((uint8_t*)pBuf + bitmap->GetPitch());
498 }
499 return FX_ERR_Succeeded;
500 }
501
502 FX_ERR CFX_Graphics::XorDIBitmap(const CFX_DIBitmap* srcBitmap,
503 const CFX_RectF& rect) {
504 if (!m_renderDevice)
505 return FX_ERR_Property_Invalid;
506 CFX_DIBitmap* dst = m_renderDevice->GetBitmap();
507 if (!dst)
508 return FX_ERR_Property_Invalid;
509 CFX_RectF temp(rect);
510 m_info.CTM.TransformRect(temp);
511 CFX_RectF r;
512 r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
513 r.Intersect(temp);
514 if (r.IsEmpty()) {
515 return FX_ERR_Parameter_Invalid;
516 }
517 FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
518 int32_t(r.top) * srcBitmap->GetPitch());
519 FX_ARGB* pDstBuf =
520 (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
521 int32_t bottom = (int32_t)r.bottom();
522 int32_t right = (int32_t)r.right();
523 for (int32_t i = (int32_t)r.top; i < bottom; i++) {
524 FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
525 FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
526 for (int32_t j = (int32_t)r.left; j < right; j++) {
527 FX_ARGB c = *pDstLine;
528 *pDstLine++ =
529 ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF));
530 pSrcLine++;
531 }
532 pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
533 pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
534 }
535 return FX_ERR_Succeeded;
536 }
537
538 FX_ERR CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap* srcBitmap,
539 const CFX_RectF& rect) {
540 if (!m_renderDevice)
541 return FX_ERR_Property_Invalid;
542 CFX_DIBitmap* dst = m_renderDevice->GetBitmap();
543 if (!dst)
544 return FX_ERR_Property_Invalid;
545 CFX_RectF temp(rect);
546 m_info.CTM.TransformRect(temp);
547 CFX_RectF r;
548 r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
549 r.Intersect(temp);
550 if (r.IsEmpty()) {
551 return FX_ERR_Parameter_Invalid;
552 }
553 FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
554 int32_t(r.top) * srcBitmap->GetPitch());
555 FX_ARGB* pDstBuf =
556 (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
557 int32_t bottom = (int32_t)r.bottom();
558 int32_t right = (int32_t)r.right();
559 for (int32_t i = (int32_t)r.top; i < bottom; i++) {
560 FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
561 FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
562 for (int32_t j = (int32_t)r.left; j < right; j++) {
563 FX_ARGB c = *pDstLine;
564 *pDstLine++ =
565 ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)));
566 pSrcLine++;
567 }
568 pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
569 pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
570 }
571 return FX_ERR_Succeeded;
572 }
573
574 FX_ERR CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) {
575 switch (dashStyle) {
576 case FX_DASHSTYLE_Solid: {
577 m_info.graphState.SetDashCount(0);
578 return FX_ERR_Succeeded;
579 }
580 case FX_DASHSTYLE_Dash: {
581 FX_FLOAT dashArray[] = {3, 1};
582 SetLineDash(0, dashArray, 2);
583 return FX_ERR_Succeeded;
584 }
585 case FX_DASHSTYLE_Dot: {
586 FX_FLOAT dashArray[] = {1, 1};
587 SetLineDash(0, dashArray, 2);
588 return FX_ERR_Succeeded;
589 }
590 case FX_DASHSTYLE_DashDot: {
591 FX_FLOAT dashArray[] = {3, 1, 1, 1};
592 SetLineDash(0, dashArray, 4);
593 return FX_ERR_Succeeded;
594 }
595 case FX_DASHSTYLE_DashDotDot: {
596 FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
597 SetLineDash(0, dashArray, 6);
598 return FX_ERR_Succeeded;
599 }
600 default:
601 return FX_ERR_Parameter_Invalid;
602 }
603 }
604
605 FX_ERR CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path,
606 CFX_Matrix* matrix) {
607 if (!m_info.strokeColor)
608 return FX_ERR_Property_Invalid;
609 CFX_Matrix m;
610 m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
611 m_info.CTM.f);
612 if (matrix) {
613 m.Concat(*matrix);
614 }
615 switch (m_info.strokeColor->m_type) {
616 case FX_COLOR_Solid: {
617 FX_BOOL result = m_renderDevice->DrawPath(
618 path->GetPathData(), (CFX_Matrix*)&m, &m_info.graphState, 0x0,
619 m_info.strokeColor->m_info.argb, 0);
620 if (!result)
621 return FX_ERR_Indefinite;
622 return FX_ERR_Succeeded;
623 }
624 case FX_COLOR_Pattern:
625 return StrokePathWithPattern(path, &m);
626 case FX_COLOR_Shading:
627 return StrokePathWithShading(path, &m);
628 default:
629 return FX_ERR_Property_Invalid;
630 }
631 }
632
633 FX_ERR CFX_Graphics::RenderDeviceFillPath(CFX_Path* path,
634 FX_FillMode fillMode,
635 CFX_Matrix* matrix) {
636 if (!m_info.fillColor)
637 return FX_ERR_Property_Invalid;
638 CFX_Matrix m;
639 m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
640 m_info.CTM.f);
641 if (matrix) {
642 m.Concat(*matrix);
643 }
644 switch (m_info.fillColor->m_type) {
645 case FX_COLOR_Solid: {
646 FX_BOOL result = m_renderDevice->DrawPath(
647 path->GetPathData(), (CFX_Matrix*)&m, &m_info.graphState,
648 m_info.fillColor->m_info.argb, 0x0, fillMode);
649 if (!result)
650 return FX_ERR_Indefinite;
651 return FX_ERR_Succeeded;
652 }
653 case FX_COLOR_Pattern:
654 return FillPathWithPattern(path, fillMode, &m);
655 case FX_COLOR_Shading:
656 return FillPathWithShading(path, fillMode, &m);
657 default:
658 return FX_ERR_Property_Invalid;
659 }
660 }
661
662 FX_ERR CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource* source,
663 const CFX_PointF& point,
664 CFX_Matrix* matrix) {
665 CFX_Matrix m1;
666 m1.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
667 m_info.CTM.f);
668 if (matrix) {
669 m1.Concat(*matrix);
670 }
671 CFX_Matrix m2;
672 m2.Set((FX_FLOAT)source->GetWidth(), 0.0, 0.0, (FX_FLOAT)source->GetHeight(),
673 point.x, point.y);
674 m2.Concat(m1);
675 int32_t left, top;
676 std::unique_ptr<CFX_DIBitmap> bmp1(source->FlipImage(FALSE, TRUE));
677 std::unique_ptr<CFX_DIBitmap> bmp2(
678 bmp1->TransformTo((CFX_Matrix*)&m2, left, top));
679 CFX_RectF r;
680 GetClipRect(r);
681 CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
682 CFX_DIBitmap bmp;
683 if (bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb) &&
684 m_renderDevice->GetDIBits(&bmp, 0, 0) &&
685 bmp.TransferBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
686 FXSYS_round(r.Width()), FXSYS_round(r.Height()),
687 bmp2.get(), FXSYS_round(r.left - left),
688 FXSYS_round(r.top - top)) &&
689 m_renderDevice->SetDIBits(&bmp, 0, 0)) {
690 return FX_ERR_Succeeded;
691 }
692 return FX_ERR_Indefinite;
693 }
694
695 FX_ERR CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source,
696 const CFX_RectF& rect,
697 CFX_Matrix* matrix) {
698 CFX_Matrix m1;
699 m1.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
700 m_info.CTM.f);
701 if (matrix) {
702 m1.Concat(*matrix);
703 }
704 std::unique_ptr<CFX_DIBitmap> bmp1(
705 source->StretchTo((int32_t)rect.Width(), (int32_t)rect.Height()));
706 CFX_Matrix m2;
707 m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top);
708 m2.Concat(m1);
709 int32_t left, top;
710 std::unique_ptr<CFX_DIBitmap> bmp2(bmp1->FlipImage(FALSE, TRUE));
711 std::unique_ptr<CFX_DIBitmap> bmp3(
712 bmp2->TransformTo((CFX_Matrix*)&m2, left, top));
713 CFX_RectF r;
714 GetClipRect(r);
715 CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
716 if (bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
717 FXSYS_round(r.Width()), FXSYS_round(r.Height()),
718 bmp3.get(), FXSYS_round(r.left - left),
719 FXSYS_round(r.top - top))) {
720 return FX_ERR_Succeeded;
721 }
722 return FX_ERR_Indefinite;
723 }
724
725 FX_ERR CFX_Graphics::RenderDeviceShowText(const CFX_PointF& point,
726 const CFX_WideString& text,
727 CFX_Matrix* matrix) {
728 int32_t length = text.GetLength();
729 FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
730 FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
731 CFX_RectF rect;
732 rect.Set(point.x, point.y, 0, 0);
733 CalcTextInfo(text, charCodes, charPos, rect);
734 CFX_Matrix m;
735 m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e,
736 m_info.CTM.f);
737 m.Translate(0, m_info.fontSize * m_info.fontHScale);
738 if (matrix) {
739 m.Concat(*matrix);
740 }
741 FX_BOOL result = m_renderDevice->DrawNormalText(
742 length, charPos, m_info.font, CFX_GEModule::Get()->GetFontCache(),
743 -m_info.fontSize * m_info.fontHScale, (CFX_Matrix*)&m,
744 m_info.fillColor->m_info.argb, FXTEXT_CLEARTYPE);
745 if (!result)
746 return FX_ERR_Indefinite;
747 FX_Free(charPos);
748 FX_Free(charCodes);
749 return FX_ERR_Succeeded;
750 }
751
752 FX_ERR CFX_Graphics::StrokePathWithPattern(CFX_Path* path, CFX_Matrix* matrix) {
753 return FX_ERR_Method_Not_Supported;
754 }
755
756 FX_ERR CFX_Graphics::StrokePathWithShading(CFX_Path* path, CFX_Matrix* matrix) {
757 return FX_ERR_Method_Not_Supported;
758 }
759
760 FX_ERR CFX_Graphics::FillPathWithPattern(CFX_Path* path,
761 FX_FillMode fillMode,
762 CFX_Matrix* matrix) {
763 CFX_Pattern* pattern = m_info.fillColor->m_info.pattern;
764 CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
765 int32_t width = bitmap->GetWidth();
766 int32_t height = bitmap->GetHeight();
767 CFX_DIBitmap bmp;
768 bmp.Create(width, height, FXDIB_Argb);
769 m_renderDevice->GetDIBits(&bmp, 0, 0);
770 switch (pattern->m_type) {
771 case FX_PATTERN_Bitmap: {
772 int32_t xStep = FXSYS_round(pattern->m_bitmapInfo.x1Step);
773 int32_t yStep = FXSYS_round(pattern->m_bitmapInfo.y1Step);
774 int32_t xCount = width / xStep + 1;
775 int32_t yCount = height / yStep + 1;
776 for (int32_t i = 0; i <= yCount; i++) {
777 for (int32_t j = 0; j <= xCount; j++) {
778 bmp.TransferBitmap(j * xStep, i * yStep, xStep, yStep,
779 pattern->m_bitmapInfo.bitmap, 0, 0);
780 }
781 }
782 break;
783 }
784 case FX_PATTERN_Hatch: {
785 FX_HatchStyle hatchStyle =
786 m_info.fillColor->m_info.pattern->m_hatchInfo.hatchStyle;
787 if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
788 hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
789 return FX_ERR_Intermediate_Value_Invalid;
790 }
791 const FX_HATCHDATA& data = hatchBitmapData[hatchStyle];
792 CFX_DIBitmap mask;
793 mask.Create(data.width, data.height, FXDIB_1bppMask);
794 FXSYS_memcpy(mask.GetBuffer(), data.maskBits,
795 mask.GetPitch() * data.height);
796 CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox();
797 if (matrix) {
798 rectf.Transform((const CFX_Matrix*)matrix);
799 }
800 FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
801 FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
802 CFX_FxgeDevice device;
803 device.Attach(&bmp);
804 device.FillRect(&rect,
805 m_info.fillColor->m_info.pattern->m_hatchInfo.backArgb);
806 for (int32_t j = rect.bottom; j < rect.top; j += mask.GetHeight()) {
807 for (int32_t i = rect.left; i < rect.right; i += mask.GetWidth()) {
808 device.SetBitMask(
809 &mask, i, j,
810 m_info.fillColor->m_info.pattern->m_hatchInfo.foreArgb);
811 }
812 }
813 break;
814 }
815 }
816 m_renderDevice->SaveState();
817 m_renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
818 fillMode);
819 SetDIBitsWithMatrix(&bmp, &pattern->m_matrix);
820 m_renderDevice->RestoreState();
821 return FX_ERR_Succeeded;
822 }
823
824 FX_ERR CFX_Graphics::FillPathWithShading(CFX_Path* path,
825 FX_FillMode fillMode,
826 CFX_Matrix* matrix) {
827 CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap();
828 int32_t width = bitmap->GetWidth();
829 int32_t height = bitmap->GetHeight();
830 FX_FLOAT start_x = m_info.fillColor->m_shading->m_beginPoint.x;
831 FX_FLOAT start_y = m_info.fillColor->m_shading->m_beginPoint.y;
832 FX_FLOAT end_x = m_info.fillColor->m_shading->m_endPoint.x;
833 FX_FLOAT end_y = m_info.fillColor->m_shading->m_endPoint.y;
834 CFX_DIBitmap bmp;
835 bmp.Create(width, height, FXDIB_Argb);
836 m_renderDevice->GetDIBits(&bmp, 0, 0);
837 int32_t pitch = bmp.GetPitch();
838 FX_BOOL result = FALSE;
839 switch (m_info.fillColor->m_shading->m_type) {
840 case FX_SHADING_Axial: {
841 FX_FLOAT x_span = end_x - start_x;
842 FX_FLOAT y_span = end_y - start_y;
843 FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span);
844 for (int32_t row = 0; row < height; row++) {
845 FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
846 for (int32_t column = 0; column < width; column++) {
847 FX_FLOAT x = (FX_FLOAT)(column);
848 FX_FLOAT y = (FX_FLOAT)(row);
849 FX_FLOAT scale =
850 (((x - start_x) * x_span) + ((y - start_y) * y_span)) /
851 axis_len_square;
852 if (scale < 0) {
853 if (!m_info.fillColor->m_shading->m_isExtendedBegin) {
854 continue;
855 }
856 scale = 0;
857 } else if (scale > 1.0f) {
858 if (!m_info.fillColor->m_shading->m_isExtendedEnd) {
859 continue;
860 }
861 scale = 1.0f;
862 }
863 int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1));
864 dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index];
865 }
866 }
867 result = TRUE;
868 break;
869 }
870 case FX_SHADING_Radial: {
871 FX_FLOAT start_r = m_info.fillColor->m_shading->m_beginRadius;
872 FX_FLOAT end_r = m_info.fillColor->m_shading->m_endRadius;
873 FX_FLOAT a = ((start_x - end_x) * (start_x - end_x)) +
874 ((start_y - end_y) * (start_y - end_y)) -
875 ((start_r - end_r) * (start_r - end_r));
876 for (int32_t row = 0; row < height; row++) {
877 FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
878 for (int32_t column = 0; column < width; column++) {
879 FX_FLOAT x = (FX_FLOAT)(column);
880 FX_FLOAT y = (FX_FLOAT)(row);
881 FX_FLOAT b = -2 * (((x - start_x) * (end_x - start_x)) +
882 ((y - start_y) * (end_y - start_y)) +
883 (start_r * (end_r - start_r)));
884 FX_FLOAT c = ((x - start_x) * (x - start_x)) +
885 ((y - start_y) * (y - start_y)) - (start_r * start_r);
886 FX_FLOAT s;
887 if (a == 0) {
888 s = -c / b;
889 } else {
890 FX_FLOAT b2_4ac = (b * b) - 4 * (a * c);
891 if (b2_4ac < 0) {
892 continue;
893 }
894 FX_FLOAT root = (FXSYS_sqrt(b2_4ac));
895 FX_FLOAT s1, s2;
896 if (a > 0) {
897 s1 = (-b - root) / (2 * a);
898 s2 = (-b + root) / (2 * a);
899 } else {
900 s2 = (-b - root) / (2 * a);
901 s1 = (-b + root) / (2 * a);
902 }
903 if (s2 <= 1.0f || m_info.fillColor->m_shading->m_isExtendedEnd) {
904 s = (s2);
905 } else {
906 s = (s1);
907 }
908 if ((start_r) + s * (end_r - start_r) < 0) {
909 continue;
910 }
911 }
912 if (s < 0) {
913 if (!m_info.fillColor->m_shading->m_isExtendedBegin) {
914 continue;
915 }
916 s = 0;
917 }
918 if (s > 1.0f) {
919 if (!m_info.fillColor->m_shading->m_isExtendedEnd) {
920 continue;
921 }
922 s = 1.0f;
923 }
924 int index = (int32_t)(s * (FX_SHADING_Steps - 1));
925 dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index];
926 }
927 }
928 result = TRUE;
929 break;
930 }
931 default: { result = FALSE; }
932 }
933 if (result) {
934 m_renderDevice->SaveState();
935 m_renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
936 fillMode);
937 SetDIBitsWithMatrix(&bmp, matrix);
938 m_renderDevice->RestoreState();
939 }
940 return result;
941 }
942
943 FX_ERR CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source,
944 CFX_Matrix* matrix) {
945 if (matrix->IsIdentity()) {
946 m_renderDevice->SetDIBits(source, 0, 0);
947 } else {
948 CFX_Matrix m;
949 m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0,
950 0);
951 m.Concat(*matrix);
952 int32_t left, top;
953 std::unique_ptr<CFX_DIBitmap> bmp1(source->FlipImage(FALSE, TRUE));
954 std::unique_ptr<CFX_DIBitmap> bmp2(
955 bmp1->TransformTo((CFX_Matrix*)&m, left, top));
956 m_renderDevice->SetDIBits(bmp2.get(), left, top);
957 }
958 return FX_ERR_Succeeded;
959 }
960
961 FX_ERR CFX_Graphics::CalcTextInfo(const CFX_WideString& text,
962 FX_DWORD* charCodes,
963 FXTEXT_CHARPOS* charPos,
964 CFX_RectF& rect) {
965 std::unique_ptr<CFX_UnicodeEncoding> encoding(
966 new CFX_UnicodeEncoding(m_info.font));
967 int32_t length = text.GetLength();
968 FX_FLOAT penX = (FX_FLOAT)rect.left;
969 FX_FLOAT penY = (FX_FLOAT)rect.top;
970 FX_FLOAT left = (FX_FLOAT)(0);
971 FX_FLOAT top = (FX_FLOAT)(0);
972 charCodes[0] = text.GetAt(0);
973 charPos[0].m_OriginX = penX + left;
974 charPos[0].m_OriginY = penY + top;
975 charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]);
976 charPos[0].m_FontCharWidth = FXSYS_round(
977 m_info.font->GetGlyphWidth(charPos[0].m_GlyphIndex) * m_info.fontHScale);
978 charPos[0].m_bGlyphAdjust = TRUE;
979 charPos[0].m_AdjustMatrix[0] = -1;
980 charPos[0].m_AdjustMatrix[1] = 0;
981 charPos[0].m_AdjustMatrix[2] = 0;
982 charPos[0].m_AdjustMatrix[3] = 1;
983 penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * m_info.fontSize / 1000 +
984 m_info.fontSpacing;
985 for (int32_t i = 1; i < length; i++) {
986 charCodes[i] = text.GetAt(i);
987 charPos[i].m_OriginX = penX + left;
988 charPos[i].m_OriginY = penY + top;
989 charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]);
990 charPos[i].m_FontCharWidth =
991 FXSYS_round(m_info.font->GetGlyphWidth(charPos[i].m_GlyphIndex) *
992 m_info.fontHScale);
993 charPos[i].m_bGlyphAdjust = TRUE;
994 charPos[i].m_AdjustMatrix[0] = -1;
995 charPos[i].m_AdjustMatrix[1] = 0;
996 charPos[i].m_AdjustMatrix[2] = 0;
997 charPos[i].m_AdjustMatrix[3] = 1;
998 penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * m_info.fontSize / 1000 +
999 m_info.fontSpacing;
1000 }
1001 rect.width = (FX_FLOAT)penX - rect.left;
1002 rect.height = rect.top + m_info.fontSize * m_info.fontHScale - rect.top;
1003 return FX_ERR_Succeeded;
1004 }
1005
1006 CFX_Graphics::TInfo::TInfo(const TInfo& info)
1007 : graphState(info.graphState),
1008 isAntialiasing(info.isAntialiasing),
1009 strokeAlignment(info.strokeAlignment),
1010 CTM(info.CTM),
1011 isActOnDash(info.isActOnDash),
1012 strokeColor(info.strokeColor),
1013 fillColor(info.fillColor),
1014 font(info.font),
1015 fontSize(info.fontSize),
1016 fontHScale(info.fontHScale),
1017 fontSpacing(info.fontSpacing) {}
1018
1019 CFX_Graphics::TInfo& CFX_Graphics::TInfo::operator=(const TInfo& other) {
1020 graphState.Copy(other.graphState);
1021 isAntialiasing = other.isAntialiasing;
1022 strokeAlignment = other.strokeAlignment;
1023 CTM = other.CTM;
1024 isActOnDash = other.isActOnDash;
1025 strokeColor = other.strokeColor;
1026 fillColor = other.fillColor;
1027 font = other.font;
1028 fontSize = other.fontSize;
1029 fontHScale = other.fontHScale;
1030 fontSpacing = other.fontSpacing;
1031 return *this;
1032 }
1033
1034 CAGG_Graphics::CAGG_Graphics() {
1035 m_owner = nullptr;
1036 }
1037
1038 FX_ERR CAGG_Graphics::Create(CFX_Graphics* owner,
1039 int32_t width,
1040 int32_t height,
1041 FXDIB_Format format) {
1042 if (owner->m_renderDevice)
1043 return FX_ERR_Parameter_Invalid;
1044 if (m_owner)
1045 return FX_ERR_Property_Invalid;
1046
1047 CFX_FxgeDevice* device = new CFX_FxgeDevice;
1048 device->Create(width, height, format);
1049 m_owner = owner;
1050 m_owner->m_renderDevice = device;
1051 m_owner->m_renderDevice->GetBitmap()->Clear(0xFFFFFFFF);
1052 return FX_ERR_Succeeded;
1053 }
1054
1055 CAGG_Graphics::~CAGG_Graphics() {
1056 if (m_owner->m_renderDevice)
1057 delete (CFX_FxgeDevice*)m_owner->m_renderDevice;
1058 m_owner = nullptr;
1059 }
1060
1061 CFX_Path::CFX_Path() {
1062 m_generator = nullptr;
1063 }
1064
1065 FX_ERR CFX_Path::Create() {
1066 if (m_generator)
1067 return FX_ERR_Property_Invalid;
1068
1069 m_generator = new CFX_PathGenerator;
1070 m_generator->Create();
1071 return FX_ERR_Succeeded;
1072 }
1073
1074 CFX_Path::~CFX_Path() {
1075 delete m_generator;
1076 }
1077
1078 FX_ERR CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y) {
1079 if (!m_generator)
1080 return FX_ERR_Property_Invalid;
1081 m_generator->MoveTo(x, y);
1082 return FX_ERR_Succeeded;
1083 }
1084
1085 FX_ERR CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y) {
1086 if (!m_generator)
1087 return FX_ERR_Property_Invalid;
1088 m_generator->LineTo(x, y);
1089 return FX_ERR_Succeeded;
1090 }
1091
1092 FX_ERR CFX_Path::BezierTo(FX_FLOAT ctrlX1,
1093 FX_FLOAT ctrlY1,
1094 FX_FLOAT ctrlX2,
1095 FX_FLOAT ctrlY2,
1096 FX_FLOAT toX,
1097 FX_FLOAT toY) {
1098 if (!m_generator)
1099 return FX_ERR_Property_Invalid;
1100 m_generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY);
1101 return FX_ERR_Succeeded;
1102 }
1103
1104 FX_ERR CFX_Path::ArcTo(FX_FLOAT left,
1105 FX_FLOAT top,
1106 FX_FLOAT width,
1107 FX_FLOAT height,
1108 FX_FLOAT startAngle,
1109 FX_FLOAT sweepAngle) {
1110 if (!m_generator)
1111 return FX_ERR_Property_Invalid;
1112 m_generator->ArcTo(left + width / 2, top + height / 2, width / 2, height / 2,
1113 startAngle, sweepAngle);
1114 return FX_ERR_Succeeded;
1115 }
1116
1117 FX_ERR CFX_Path::Close() {
1118 if (!m_generator)
1119 return FX_ERR_Property_Invalid;
1120 m_generator->Close();
1121 return FX_ERR_Succeeded;
1122 }
1123
1124 FX_ERR CFX_Path::AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) {
1125 if (!m_generator)
1126 return FX_ERR_Property_Invalid;
1127 m_generator->AddLine(x1, y1, x2, y2);
1128 return FX_ERR_Succeeded;
1129 }
1130
1131 FX_ERR CFX_Path::AddBezier(FX_FLOAT startX,
1132 FX_FLOAT startY,
1133 FX_FLOAT ctrlX1,
1134 FX_FLOAT ctrlY1,
1135 FX_FLOAT ctrlX2,
1136 FX_FLOAT ctrlY2,
1137 FX_FLOAT endX,
1138 FX_FLOAT endY) {
1139 if (!m_generator)
1140 return FX_ERR_Property_Invalid;
1141 m_generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX,
1142 endY);
1143 return FX_ERR_Succeeded;
1144 }
1145
1146 FX_ERR CFX_Path::AddRectangle(FX_FLOAT left,
1147 FX_FLOAT top,
1148 FX_FLOAT width,
1149 FX_FLOAT height) {
1150 if (!m_generator)
1151 return FX_ERR_Property_Invalid;
1152 m_generator->AddRectangle(left, top, left + width, top + height);
1153 return FX_ERR_Succeeded;
1154 }
1155
1156 FX_ERR CFX_Path::AddEllipse(FX_FLOAT left,
1157 FX_FLOAT top,
1158 FX_FLOAT width,
1159 FX_FLOAT height) {
1160 if (!m_generator)
1161 return FX_ERR_Property_Invalid;
1162 m_generator->AddEllipse(left + width / 2, top + height / 2, width / 2,
1163 height / 2);
1164 return FX_ERR_Succeeded;
1165 }
1166
1167 FX_ERR CFX_Path::AddEllipse(const CFX_RectF& rect) {
1168 if (!m_generator)
1169 return FX_ERR_Property_Invalid;
1170 m_generator->AddEllipse(rect.left + rect.Width() / 2,
1171 rect.top + rect.Height() / 2, rect.Width() / 2,
1172 rect.Height() / 2);
1173 return FX_ERR_Succeeded;
1174 }
1175
1176 FX_ERR CFX_Path::AddArc(FX_FLOAT left,
1177 FX_FLOAT top,
1178 FX_FLOAT width,
1179 FX_FLOAT height,
1180 FX_FLOAT startAngle,
1181 FX_FLOAT sweepAngle) {
1182 if (!m_generator)
1183 return FX_ERR_Property_Invalid;
1184 m_generator->AddArc(left + width / 2, top + height / 2, width / 2, height / 2,
1185 startAngle, sweepAngle);
1186 return FX_ERR_Succeeded;
1187 }
1188
1189 FX_ERR CFX_Path::AddPie(FX_FLOAT left,
1190 FX_FLOAT top,
1191 FX_FLOAT width,
1192 FX_FLOAT height,
1193 FX_FLOAT startAngle,
1194 FX_FLOAT sweepAngle) {
1195 if (!m_generator)
1196 return FX_ERR_Property_Invalid;
1197 m_generator->AddPie(left + width / 2, top + height / 2, width / 2, height / 2,
1198 startAngle, sweepAngle);
1199 return FX_ERR_Succeeded;
1200 }
1201
1202 FX_ERR CFX_Path::AddSubpath(CFX_Path* path) {
1203 if (!m_generator)
1204 return FX_ERR_Property_Invalid;
1205 m_generator->AddPathData(path->GetPathData());
1206 return FX_ERR_Succeeded;
1207 }
1208
1209 FX_ERR CFX_Path::Clear() {
1210 if (!m_generator)
1211 return FX_ERR_Property_Invalid;
1212 m_generator->GetPathData()->SetPointCount(0);
1213 return FX_ERR_Succeeded;
1214 }
1215
1216 FX_BOOL CFX_Path::IsEmpty() {
1217 if (!m_generator)
1218 return FX_ERR_Property_Invalid;
1219 if (m_generator->GetPathData()->GetPointCount() == 0) {
1220 return TRUE;
1221 }
1222 return FALSE;
1223 }
1224
1225 CFX_PathData* CFX_Path::GetPathData() {
1226 if (!m_generator)
1227 return nullptr;
1228 return m_generator->GetPathData();
1229 }
1230
1231 CFX_Color::CFX_Color() : m_type(FX_COLOR_None) {}
1232
1233 CFX_Color::CFX_Color(const FX_ARGB argb) {
1234 Set(argb);
1235 }
1236
1237 CFX_Color::CFX_Color(CFX_Pattern* pattern, const FX_ARGB argb) {
1238 Set(pattern, argb);
1239 }
1240
1241 CFX_Color::CFX_Color(CFX_Shading* shading) {
1242 Set(shading);
1243 }
1244
1245 CFX_Color::~CFX_Color() {
1246 m_type = FX_COLOR_None;
1247 }
1248
1249 FX_ERR CFX_Color::Set(const FX_ARGB argb) {
1250 m_type = FX_COLOR_Solid;
1251 m_info.argb = argb;
1252 m_info.pattern = nullptr;
1253 return FX_ERR_Succeeded;
1254 }
1255
1256 FX_ERR CFX_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) {
1257 if (!pattern)
1258 return FX_ERR_Parameter_Invalid;
1259 m_type = FX_COLOR_Pattern;
1260 m_info.argb = argb;
1261 m_info.pattern = pattern;
1262 return FX_ERR_Succeeded;
1263 }
1264
1265 FX_ERR CFX_Color::Set(CFX_Shading* shading) {
1266 if (!shading)
1267 return FX_ERR_Parameter_Invalid;
1268 m_type = FX_COLOR_Shading;
1269 m_shading = shading;
1270 return FX_ERR_Succeeded;
1271 }
1272
1273 CFX_Pattern::CFX_Pattern() {
1274 m_type = FX_PATTERN_None;
1275 m_matrix.SetIdentity();
1276 }
1277
1278 FX_ERR CFX_Pattern::Create(CFX_DIBitmap* bitmap,
1279 const FX_FLOAT xStep,
1280 const FX_FLOAT yStep,
1281 CFX_Matrix* matrix) {
1282 if (!bitmap)
1283 return FX_ERR_Parameter_Invalid;
1284 if (m_type != FX_PATTERN_None) {
1285 return FX_ERR_Property_Invalid;
1286 }
1287 m_type = FX_PATTERN_Bitmap;
1288 m_bitmapInfo.bitmap = bitmap;
1289 m_bitmapInfo.x1Step = xStep;
1290 m_bitmapInfo.y1Step = yStep;
1291 if (matrix) {
1292 m_matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
1293 matrix->f);
1294 }
1295 return FX_ERR_Succeeded;
1296 }
1297
1298 FX_ERR CFX_Pattern::Create(FX_HatchStyle hatchStyle,
1299 const FX_ARGB foreArgb,
1300 const FX_ARGB backArgb,
1301 CFX_Matrix* matrix) {
1302 if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
1303 hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
1304 return FX_ERR_Parameter_Invalid;
1305 }
1306 if (m_type != FX_PATTERN_None) {
1307 return FX_ERR_Property_Invalid;
1308 }
1309 m_type = FX_PATTERN_Hatch;
1310 m_hatchInfo.hatchStyle = hatchStyle;
1311 m_hatchInfo.foreArgb = foreArgb;
1312 m_hatchInfo.backArgb = backArgb;
1313 if (matrix) {
1314 m_matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
1315 matrix->f);
1316 }
1317 return FX_ERR_Succeeded;
1318 }
1319
1320 CFX_Pattern::~CFX_Pattern() {
1321 m_type = FX_PATTERN_None;
1322 }
1323
1324 CFX_Shading::CFX_Shading() {
1325 m_type = FX_SHADING_None;
1326 }
1327
1328 FX_ERR CFX_Shading::CreateAxial(const CFX_PointF& beginPoint,
1329 const CFX_PointF& endPoint,
1330 FX_BOOL isExtendedBegin,
1331 FX_BOOL isExtendedEnd,
1332 const FX_ARGB beginArgb,
1333 const FX_ARGB endArgb) {
1334 if (m_type != FX_SHADING_None) {
1335 return FX_ERR_Property_Invalid;
1336 }
1337 m_type = FX_SHADING_Axial;
1338 m_beginPoint = beginPoint;
1339 m_endPoint = endPoint;
1340 m_isExtendedBegin = isExtendedBegin;
1341 m_isExtendedEnd = isExtendedEnd;
1342 m_beginArgb = beginArgb;
1343 m_endArgb = endArgb;
1344 return InitArgbArray();
1345 }
1346
1347 FX_ERR CFX_Shading::CreateRadial(const CFX_PointF& beginPoint,
1348 const CFX_PointF& endPoint,
1349 const FX_FLOAT beginRadius,
1350 const FX_FLOAT endRadius,
1351 FX_BOOL isExtendedBegin,
1352 FX_BOOL isExtendedEnd,
1353 const FX_ARGB beginArgb,
1354 const FX_ARGB endArgb) {
1355 if (m_type != FX_SHADING_None) {
1356 return FX_ERR_Property_Invalid;
1357 }
1358 m_type = FX_SHADING_Radial;
1359 m_beginPoint = beginPoint;
1360 m_endPoint = endPoint;
1361 m_beginRadius = beginRadius;
1362 m_endRadius = endRadius;
1363 m_isExtendedBegin = isExtendedBegin;
1364 m_isExtendedEnd = isExtendedEnd;
1365 m_beginArgb = beginArgb;
1366 m_endArgb = endArgb;
1367 return InitArgbArray();
1368 }
1369
1370 CFX_Shading::~CFX_Shading() {
1371 m_type = FX_SHADING_None;
1372 }
1373
1374 FX_ERR CFX_Shading::InitArgbArray() {
1375 int32_t a1, r1, g1, b1;
1376 ArgbDecode(m_beginArgb, a1, r1, g1, b1);
1377 int32_t a2, r2, g2, b2;
1378 ArgbDecode(m_endArgb, a2, r2, g2, b2);
1379 FX_FLOAT f = (FX_FLOAT)(FX_SHADING_Steps - 1);
1380 FX_FLOAT aScale = (FX_FLOAT)(1.0 * (a2 - a1) / f);
1381 FX_FLOAT rScale = (FX_FLOAT)(1.0 * (r2 - r1) / f);
1382 FX_FLOAT gScale = (FX_FLOAT)(1.0 * (g2 - g1) / f);
1383 FX_FLOAT bScale = (FX_FLOAT)(1.0 * (b2 - b1) / f);
1384 int32_t a3, r3, g3, b3;
1385 for (int32_t i = 0; i < FX_SHADING_Steps; i++) {
1386 a3 = (int32_t)(i * aScale);
1387 r3 = (int32_t)(i * rScale);
1388 g3 = (int32_t)(i * gScale);
1389 b3 = (int32_t)(i * bScale);
1390 m_argbArray[i] =
1391 FXARGB_TODIB(FXARGB_MAKE((a1 + a3), (r1 + r3), (g1 + g3), (b1 + b3)));
1392 }
1393 return FX_ERR_Succeeded;
1394 }
OLDNEW
« no previous file with comments | « xfa/fxgraphics/cfx_shading.cpp ('k') | xfa/fxgraphics/fx_path_generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698