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

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

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

Powered by Google App Engine
This is Rietveld 408576698