1 // Copyright 2014 PDFium Authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\r
8 #include "fx_path_generator.h"
\r
9 class CAGG_Graphics : public CFX_Object
\r
13 FX_ERR Create(CFX_Graphics * owner,
\r
16 FXDIB_Format format);
\r
17 virtual ~CAGG_Graphics();
\r
19 CFX_Graphics * _owner;
\r
21 CFX_Graphics::CFX_Graphics()
\r
23 _type = FX_CONTEXT_None;
\r
24 _info._graphState.SetDashCount(0);
\r
25 _info._isAntialiasing = TRUE;
\r
26 _info._strokeAlignment = FX_STROKEALIGNMENT_Center;
\r
28 _info._isActOnDash = FALSE;
\r
29 _info._strokeColor = NULL;
\r
30 _info._fillColor = NULL;
\r
32 _info._fontSize = 40.0;
\r
33 _info._fontHScale = 1.0;
\r
34 _info._fontSpacing = 0.0;
\r
35 _renderDevice = NULL;
\r
36 _aggGraphics = NULL;
\r
38 FX_ERR CFX_Graphics::Create(CFX_RenderDevice * renderDevice,
\r
39 FX_BOOL isAntialiasing )
\r
41 _FX_RETURN_VALUE_IF_FAIL(renderDevice, FX_ERR_Parameter_Invalid);
\r
42 if (_type != FX_CONTEXT_None) {
\r
43 return FX_ERR_Property_Invalid;
\r
45 _type = FX_CONTEXT_Device;
\r
46 _info._isAntialiasing = isAntialiasing;
\r
47 _renderDevice = renderDevice;
\r
48 if (_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP) {
\r
49 return FX_ERR_Succeeded;
\r
51 return FX_ERR_Indefinite;
\r
53 FX_ERR CFX_Graphics::Create(FX_INT32 width,
\r
55 FXDIB_Format format,
\r
57 FX_BOOL isAntialiasing )
\r
59 if (_type != FX_CONTEXT_None) {
\r
60 return FX_ERR_Property_Invalid;
\r
62 _type = FX_CONTEXT_Device;
\r
63 _info._isAntialiasing = isAntialiasing;
\r
65 _aggGraphics = FX_NEW CAGG_Graphics;
\r
66 return _aggGraphics->Create(this, width, height, format);
\r
69 CFX_Graphics::~CFX_Graphics()
\r
72 delete _aggGraphics;
\r
73 _aggGraphics = NULL;
\r
75 _renderDevice = NULL;
\r
76 _info._graphState.SetDashCount(0);
\r
77 _type = FX_CONTEXT_None;
\r
79 FX_ERR CFX_Graphics::GetDeviceCap(const FX_INT32 capID, FX_DeviceCap & capVal)
\r
82 case FX_CONTEXT_Device: {
\r
83 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
84 capVal = _renderDevice->GetDeviceCaps(capID);
\r
85 return FX_ERR_Succeeded;
\r
88 return FX_ERR_Property_Invalid;
\r
92 FX_ERR CFX_Graphics::IsPrinterDevice(FX_BOOL & isPrinter)
\r
95 case FX_CONTEXT_Device: {
\r
96 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
97 FX_INT32 deviceClass = _renderDevice->GetDeviceClass();
\r
98 if (deviceClass == FXDC_PRINTER) {
\r
103 return FX_ERR_Succeeded;
\r
106 return FX_ERR_Property_Invalid;
\r
110 FX_ERR CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing)
\r
113 case FX_CONTEXT_Device: {
\r
114 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
115 _info._isAntialiasing = isAntialiasing;
\r
116 return FX_ERR_Succeeded;
\r
119 return FX_ERR_Property_Invalid;
\r
123 FX_ERR CFX_Graphics::SaveGraphState()
\r
126 case FX_CONTEXT_Device: {
\r
127 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
128 _renderDevice->SaveState();
\r
129 TInfo * info = FX_NEW TInfo;
\r
130 info->_graphState.Copy(_info._graphState);
\r
131 info->_isAntialiasing = _info._isAntialiasing;
\r
132 info->_strokeAlignment = _info._strokeAlignment;
\r
133 info->_CTM = _info._CTM;
\r
134 info->_isActOnDash = _info._isActOnDash;
\r
135 info->_strokeColor = _info._strokeColor;
\r
136 info->_fillColor = _info._fillColor;
\r
137 info->_font = _info._font;
\r
138 info->_fontSize = _info._fontSize;
\r
139 info->_fontHScale = _info._fontHScale;
\r
140 info->_fontSpacing = _info._fontSpacing;
\r
141 _infoStack.Add(info);
\r
142 return FX_ERR_Succeeded;
\r
145 return FX_ERR_Property_Invalid;
\r
149 FX_ERR CFX_Graphics::RestoreGraphState()
\r
152 case FX_CONTEXT_Device: {
\r
153 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
154 _renderDevice->RestoreState();
\r
155 FX_INT32 size = _infoStack.GetSize();
\r
157 return FX_ERR_Intermediate_Value_Invalid;
\r
159 FX_INT32 topIndex = size - 1;
\r
160 TInfo * info = (TInfo *) _infoStack.GetAt(topIndex);
\r
161 _FX_RETURN_VALUE_IF_FAIL(info, FX_ERR_Intermediate_Value_Invalid);
\r
162 _info._graphState.Copy(info->_graphState);
\r
163 _info._isAntialiasing = info->_isAntialiasing;
\r
164 _info._strokeAlignment = info->_strokeAlignment;
\r
165 _info._CTM = info->_CTM;
\r
166 _info._isActOnDash = info->_isActOnDash;
\r
167 _info._strokeColor = info->_strokeColor;
\r
168 _info._fillColor = info->_fillColor;
\r
169 _info._font = info->_font;
\r
170 _info._fontSize = info->_fontSize;
\r
171 _info._fontHScale = info->_fontHScale;
\r
172 _info._fontSpacing = info->_fontSpacing;
\r
175 _infoStack.RemoveAt(topIndex);
\r
176 return FX_ERR_Succeeded;
\r
179 return FX_ERR_Property_Invalid;
\r
183 FX_ERR CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap & lineCap)
\r
186 case FX_CONTEXT_Device: {
\r
187 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
188 lineCap = _info._graphState.m_LineCap;
\r
189 return FX_ERR_Succeeded;
\r
192 return FX_ERR_Property_Invalid;
\r
196 FX_ERR CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap)
\r
199 case FX_CONTEXT_Device: {
\r
200 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
201 _info._graphState.m_LineCap = lineCap;
\r
202 return FX_ERR_Succeeded;
\r
205 return FX_ERR_Property_Invalid;
\r
209 FX_ERR CFX_Graphics::GetDashCount(FX_INT32 & dashCount)
\r
212 case FX_CONTEXT_Device: {
\r
213 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
214 dashCount = _info._graphState.m_DashCount;
\r
215 return FX_ERR_Succeeded;
\r
218 return FX_ERR_Property_Invalid;
\r
222 FX_ERR CFX_Graphics::GetLineDash(FX_FLOAT & dashPhase, FX_FLOAT * dashArray)
\r
224 _FX_RETURN_VALUE_IF_FAIL(dashArray, FX_ERR_Parameter_Invalid);
\r
226 case FX_CONTEXT_Device: {
\r
227 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
228 dashPhase = _info._graphState.m_DashPhase;
\r
229 FXSYS_memcpy(dashArray,
\r
230 _info._graphState.m_DashArray,
\r
231 _info._graphState.m_DashCount * sizeof (FX_FLOAT));
\r
232 return FX_ERR_Succeeded;
\r
235 return FX_ERR_Property_Invalid;
\r
239 FX_ERR CFX_Graphics::SetLineDash(FX_FLOAT dashPhase,
\r
240 FX_FLOAT * dashArray,
\r
241 FX_INT32 dashCount)
\r
243 if (dashCount > 0 && !dashArray) {
\r
244 return FX_ERR_Parameter_Invalid;
\r
246 dashCount = dashCount < 0 ? 0 : dashCount;
\r
248 case FX_CONTEXT_Device: {
\r
249 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
250 FX_FLOAT scale = 1.0;
\r
251 if (_info._isActOnDash) {
\r
252 scale = _info._graphState.m_LineWidth;
\r
254 _info._graphState.m_DashPhase = dashPhase;
\r
255 _info._graphState.SetDashCount(dashCount);
\r
256 for (FX_INT32 i = 0; i < dashCount; i++) {
\r
257 _info._graphState.m_DashArray[i] = dashArray[i] * scale;
\r
259 return FX_ERR_Succeeded;
\r
262 return FX_ERR_Property_Invalid;
\r
266 FX_ERR CFX_Graphics::SetLineDash(FX_DashStyle dashStyle)
\r
269 case FX_CONTEXT_Device: {
\r
270 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
271 return RenderDeviceSetLineDash(dashStyle);
\r
274 return FX_ERR_Property_Invalid;
\r
278 FX_ERR CFX_Graphics::GetLineJoin(CFX_GraphStateData::LineJoin & lineJoin)
\r
281 case FX_CONTEXT_Device: {
\r
282 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
283 lineJoin = _info._graphState.m_LineJoin;
\r
284 return FX_ERR_Succeeded;
\r
287 return FX_ERR_Property_Invalid;
\r
291 FX_ERR CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin)
\r
294 case FX_CONTEXT_Device: {
\r
295 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
296 _info._graphState.m_LineJoin = lineJoin;
\r
297 return FX_ERR_Succeeded;
\r
300 return FX_ERR_Property_Invalid;
\r
304 FX_ERR CFX_Graphics::GetMiterLimit(FX_FLOAT & miterLimit)
\r
307 case FX_CONTEXT_Device: {
\r
308 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
309 miterLimit = _info._graphState.m_MiterLimit;
\r
310 return FX_ERR_Succeeded;
\r
313 return FX_ERR_Property_Invalid;
\r
317 FX_ERR CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit)
\r
320 case FX_CONTEXT_Device: {
\r
321 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
322 _info._graphState.m_MiterLimit = miterLimit;
\r
323 return FX_ERR_Succeeded;
\r
326 return FX_ERR_Property_Invalid;
\r
330 FX_ERR CFX_Graphics::GetLineWidth(FX_FLOAT & lineWidth)
\r
333 case FX_CONTEXT_Device: {
\r
334 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
335 lineWidth = _info._graphState.m_LineWidth;
\r
336 return FX_ERR_Succeeded;
\r
339 return FX_ERR_Property_Invalid;
\r
343 FX_ERR CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash )
\r
346 case FX_CONTEXT_Device: {
\r
347 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
348 _info._graphState.m_LineWidth = lineWidth;
\r
349 _info._isActOnDash = isActOnDash;
\r
350 return FX_ERR_Succeeded;
\r
353 return FX_ERR_Property_Invalid;
\r
357 FX_ERR CFX_Graphics::GetStrokeAlignment(FX_StrokeAlignment & strokeAlignment)
\r
360 case FX_CONTEXT_Device: {
\r
361 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
362 strokeAlignment = _info._strokeAlignment;
\r
363 return FX_ERR_Succeeded;
\r
366 return FX_ERR_Property_Invalid;
\r
370 FX_ERR CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment)
\r
373 case FX_CONTEXT_Device: {
\r
374 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
375 _info._strokeAlignment = strokeAlignment;
\r
376 return FX_ERR_Succeeded;
\r
379 return FX_ERR_Property_Invalid;
\r
383 FX_ERR CFX_Graphics::SetStrokeColor(CFX_Color * color)
\r
385 _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
\r
387 case FX_CONTEXT_Device: {
\r
388 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
389 _info._strokeColor = color;
\r
390 return FX_ERR_Succeeded;
\r
393 return FX_ERR_Property_Invalid;
\r
397 FX_ERR CFX_Graphics::SetFillColor(CFX_Color * color)
\r
399 _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
\r
401 case FX_CONTEXT_Device: {
\r
402 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
403 _info._fillColor = color;
\r
404 return FX_ERR_Succeeded;
\r
407 return FX_ERR_Property_Invalid;
\r
411 FX_ERR CFX_Graphics::StrokePath(CFX_Path * path, CFX_Matrix * matrix )
\r
413 _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
\r
415 case FX_CONTEXT_Device: {
\r
416 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
417 return RenderDeviceStrokePath(path, matrix);
\r
420 return FX_ERR_Property_Invalid;
\r
424 FX_ERR CFX_Graphics::FillPath(CFX_Path * path,
\r
425 FX_FillMode fillMode ,
\r
426 CFX_Matrix * matrix )
\r
428 _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
\r
430 case FX_CONTEXT_Device: {
\r
431 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
432 return RenderDeviceFillPath(path, fillMode, matrix);
\r
435 return FX_ERR_Property_Invalid;
\r
439 FX_ERR CFX_Graphics::ClipPath(CFX_Path * path,
\r
440 FX_FillMode fillMode ,
\r
441 CFX_Matrix * matrix )
\r
443 _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
\r
445 case FX_CONTEXT_Device: {
\r
446 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
447 FX_BOOL result = _renderDevice->SetClip_PathFill(path->GetPathData(),
\r
448 (CFX_AffineMatrix *) matrix,
\r
450 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
\r
451 return FX_ERR_Succeeded;
\r
454 return FX_ERR_Property_Invalid;
\r
458 FX_ERR CFX_Graphics::DrawImage(CFX_DIBSource * source,
\r
459 const CFX_PointF & point,
\r
460 CFX_Matrix * matrix )
\r
462 _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
\r
464 case FX_CONTEXT_Device: {
\r
465 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
466 return RenderDeviceDrawImage(source, point, matrix);
\r
469 return FX_ERR_Property_Invalid;
\r
473 FX_ERR CFX_Graphics::StretchImage(CFX_DIBSource * source,
\r
474 const CFX_RectF & rect,
\r
475 CFX_Matrix * matrix )
\r
477 _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
\r
479 case FX_CONTEXT_Device: {
\r
480 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
481 return RenderDeviceStretchImage(source, rect, matrix);
\r
484 return FX_ERR_Property_Invalid;
\r
488 FX_ERR CFX_Graphics::ConcatMatrix(CFX_Matrix * matrix)
\r
490 _FX_RETURN_VALUE_IF_FAIL(matrix, FX_ERR_Parameter_Invalid);
\r
492 case FX_CONTEXT_Device: {
\r
493 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
494 _info._CTM.Concat(*matrix);
\r
495 return FX_ERR_Succeeded;
\r
498 return FX_ERR_Property_Invalid;
\r
502 CFX_Matrix * CFX_Graphics::GetMatrix()
\r
505 case FX_CONTEXT_Device: {
\r
506 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, NULL);
\r
507 return &_info._CTM;
\r
514 FX_ERR CFX_Graphics::GetClipRect(CFX_RectF & rect)
\r
517 case FX_CONTEXT_Device: {
\r
518 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
519 FX_RECT r = _renderDevice->GetClipBox();
\r
520 rect.left = (FX_FLOAT) r.left;
\r
521 rect.top = (FX_FLOAT) r.top;
\r
522 rect.width = (FX_FLOAT) r.Width();
\r
523 rect.height = (FX_FLOAT) r.Height();
\r
524 return FX_ERR_Succeeded;
\r
527 return FX_ERR_Property_Invalid;
\r
531 FX_ERR CFX_Graphics::SetClipRect(const CFX_RectF & rect)
\r
534 case FX_CONTEXT_Device: {
\r
535 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
536 FX_RECT r(FXSYS_round(rect.left),
\r
537 FXSYS_round(rect.top),
\r
538 FXSYS_round(rect.right()),
\r
539 FXSYS_round(rect.bottom()));
\r
540 FX_BOOL result = _renderDevice->SetClip_Rect(&r);
\r
541 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
\r
542 return FX_ERR_Succeeded;
\r
545 return FX_ERR_Property_Invalid;
\r
549 FX_ERR CFX_Graphics::ClearClip()
\r
552 case FX_CONTEXT_Device: {
\r
553 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
554 FX_BOOL result = FX_ERR_Succeeded;
\r
555 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
\r
556 return FX_ERR_Succeeded;
\r
559 return FX_ERR_Property_Invalid;
\r
563 FX_ERR CFX_Graphics::SetFont(CFX_Font * font)
\r
565 _FX_RETURN_VALUE_IF_FAIL(font, FX_ERR_Parameter_Invalid);
\r
567 case FX_CONTEXT_Device: {
\r
568 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
569 _info._font = font;
\r
570 return FX_ERR_Succeeded;
\r
573 return FX_ERR_Property_Invalid;
\r
577 FX_ERR CFX_Graphics::SetFontSize(const FX_FLOAT size)
\r
579 FX_FLOAT fontSize = size <= 0 ? 1.0f : size;
\r
581 case FX_CONTEXT_Device: {
\r
582 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
583 _info._fontSize = fontSize;
\r
584 return FX_ERR_Succeeded;
\r
587 return FX_ERR_Property_Invalid;
\r
591 FX_ERR CFX_Graphics::SetFontHScale(const FX_FLOAT scale)
\r
593 FX_FLOAT fontHScale = scale <= 0 ? 1.0f : scale;
\r
595 case FX_CONTEXT_Device: {
\r
596 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
597 _info._fontHScale = fontHScale;
\r
598 return FX_ERR_Succeeded;
\r
601 return FX_ERR_Property_Invalid;
\r
605 FX_ERR CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing)
\r
607 FX_FLOAT fontSpacing = spacing < 0 ? 0 : spacing;
\r
609 case FX_CONTEXT_Device: {
\r
610 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
611 _info._fontSpacing = fontSpacing;
\r
612 return FX_ERR_Succeeded;
\r
615 return FX_ERR_Property_Invalid;
\r
619 FX_ERR CFX_Graphics::SetTextDrawingMode(const FX_INT32 mode)
\r
622 case FX_CONTEXT_Device: {
\r
623 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
624 return FX_ERR_Succeeded;
\r
627 return FX_ERR_Property_Invalid;
\r
631 FX_ERR CFX_Graphics::ShowText(const CFX_PointF & point,
\r
632 const CFX_WideString & text,
\r
633 CFX_Matrix * matrix )
\r
636 case FX_CONTEXT_Device: {
\r
637 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
638 return RenderDeviceShowText(point, text, matrix);
\r
641 return FX_ERR_Property_Invalid;
\r
645 FX_ERR CFX_Graphics::CalcTextRect(CFX_RectF & rect,
\r
646 const CFX_WideString & text,
\r
647 FX_BOOL isMultiline ,
\r
648 CFX_Matrix * matrix )
\r
651 case FX_CONTEXT_Device: {
\r
652 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
653 FX_INT32 length = text.GetLength();
\r
654 FX_DWORD * charCodes = FX_Alloc(FX_DWORD, length);
\r
655 FXTEXT_CHARPOS * charPos = FX_Alloc(FXTEXT_CHARPOS,
\r
656 length * sizeof (FXTEXT_CHARPOS));
\r
657 CalcTextInfo(text, charCodes, charPos, rect);
\r
659 FX_Free(charCodes);
\r
660 return FX_ERR_Succeeded;
\r
663 return FX_ERR_Property_Invalid;
\r
667 FX_ERR CFX_Graphics::Transfer(CFX_Graphics * graphics, CFX_Matrix * matrix )
\r
669 _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
\r
671 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
\r
676 case FX_CONTEXT_Device: {
\r
677 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
679 _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
\r
680 FX_ERR_Parameter_Invalid);
\r
681 CFX_DIBitmap * bitmap = graphics->_renderDevice->GetBitmap();
\r
682 FX_BOOL result = _renderDevice->SetDIBits(bitmap, 0, 0);
\r
683 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
\r
687 return FX_ERR_Property_Invalid;
\r
691 FX_ERR CFX_Graphics::Transfer(CFX_Graphics * graphics,
\r
694 const CFX_RectF & dstRect,
\r
695 CFX_Matrix * matrix )
\r
697 _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
\r
699 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
\r
704 case FX_CONTEXT_Device: {
\r
705 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
707 _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
\r
708 FX_ERR_Parameter_Invalid);
\r
709 CFX_DIBitmap * bitmap = graphics->_renderDevice->GetBitmap();
\r
710 FX_BOOL result = FX_ERR_Indefinite;
\r
712 result = bmp.Create((FX_INT32) dstRect.width,
\r
713 (FX_INT32) dstRect.height,
\r
714 bitmap->GetFormat());
\r
715 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Intermediate_Value_Invalid);
\r
716 result = graphics->_renderDevice->GetDIBits(&bmp,
\r
717 (FX_INT32) srcLeft,
\r
718 (FX_INT32) srcTop);
\r
719 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
\r
720 result = _renderDevice->SetDIBits(&bmp,
\r
721 (FX_INT32) dstRect.left,
\r
722 (FX_INT32) dstRect.top);
\r
723 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
\r
724 return FX_ERR_Succeeded;
\r
728 return FX_ERR_Property_Invalid;
\r
732 CFX_RenderDevice * CFX_Graphics::GetRenderDevice()
\r
734 return _renderDevice;
\r
736 FX_ERR CFX_Graphics::InverseRect(const CFX_RectF & rect)
\r
738 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
739 CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
\r
740 _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Property_Invalid);
\r
741 CFX_RectF temp(rect);
\r
742 _info._CTM.TransformRect(temp);
\r
744 r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth());
\r
747 return FX_ERR_Parameter_Invalid;
\r
749 FX_ARGB* pBuf = (FX_ARGB*)(bitmap->GetBuffer() + FX_INT32(r.top) * bitmap->GetPitch());
\r
750 FX_INT32 bottom = (FX_INT32)r.bottom();
\r
751 FX_INT32 right = (FX_INT32)r.right();
\r
752 for (FX_INT32 i = (FX_INT32)r.top; i < bottom; i ++) {
\r
753 FX_ARGB* pLine = pBuf + (FX_INT32)r.left;
\r
754 for (FX_INT32 j = (FX_INT32)r.left; j < right; j ++) {
\r
755 FX_ARGB c = *pLine;
\r
756 *pLine ++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF));
\r
758 pBuf = (FX_ARGB*)((FX_LPBYTE)pBuf + bitmap->GetPitch());
\r
760 return FX_ERR_Succeeded;
\r
762 FX_ERR CFX_Graphics::XorDIBitmap(const CFX_DIBitmap * srcBitmap, const CFX_RectF & rect)
\r
764 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
765 CFX_DIBitmap * dst = _renderDevice->GetBitmap();
\r
766 _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
\r
767 CFX_RectF temp(rect);
\r
768 _info._CTM.TransformRect(temp);
\r
770 r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
\r
773 return FX_ERR_Parameter_Invalid;
\r
775 FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + FX_INT32(r.top) * srcBitmap->GetPitch());
\r
776 FX_ARGB* pDstBuf = (FX_ARGB*)(dst->GetBuffer() + FX_INT32(r.top) * dst->GetPitch());
\r
777 FX_INT32 bottom = (FX_INT32)r.bottom();
\r
778 FX_INT32 right = (FX_INT32)r.right();
\r
779 for (FX_INT32 i = (FX_INT32)r.top; i < bottom; i ++) {
\r
780 FX_ARGB* pSrcLine = pSrcBuf + (FX_INT32)r.left;
\r
781 FX_ARGB* pDstLine = pDstBuf + (FX_INT32)r.left;
\r
782 for (FX_INT32 j = (FX_INT32)r.left; j < right; j ++) {
\r
783 FX_ARGB c = *pDstLine;
\r
784 *pDstLine ++ = ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF));
\r
787 pSrcBuf = (FX_ARGB*)((FX_LPBYTE)pSrcBuf + srcBitmap->GetPitch());
\r
788 pDstBuf = (FX_ARGB*)((FX_LPBYTE)pDstBuf + dst->GetPitch());
\r
790 return FX_ERR_Succeeded;
\r
792 FX_ERR CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap * srcBitmap, const CFX_RectF & rect)
\r
794 _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
\r
795 CFX_DIBitmap * dst = _renderDevice->GetBitmap();
\r
796 _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
\r
797 CFX_RectF temp(rect);
\r
798 _info._CTM.TransformRect(temp);
\r
800 r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
\r
803 return FX_ERR_Parameter_Invalid;
\r
805 FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + FX_INT32(r.top) * srcBitmap->GetPitch());
\r
806 FX_ARGB* pDstBuf = (FX_ARGB*)(dst->GetBuffer() + FX_INT32(r.top) * dst->GetPitch());
\r
807 FX_INT32 bottom = (FX_INT32)r.bottom();
\r
808 FX_INT32 right = (FX_INT32)r.right();
\r
809 for (FX_INT32 i = (FX_INT32)r.top; i < bottom; i ++) {
\r
810 FX_ARGB* pSrcLine = pSrcBuf + (FX_INT32)r.left;
\r
811 FX_ARGB* pDstLine = pDstBuf + (FX_INT32)r.left;
\r
812 for (FX_INT32 j = (FX_INT32)r.left; j < right; j ++) {
\r
813 FX_ARGB c = *pDstLine;
\r
814 *pDstLine ++ = ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)));
\r
817 pSrcBuf = (FX_ARGB*)((FX_LPBYTE)pSrcBuf + srcBitmap->GetPitch());
\r
818 pDstBuf = (FX_ARGB*)((FX_LPBYTE)pDstBuf + dst->GetPitch());
\r
820 return FX_ERR_Succeeded;
\r
822 FX_ERR CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle)
\r
824 switch (dashStyle) {
\r
825 case FX_DASHSTYLE_Solid: {
\r
826 _info._graphState.SetDashCount(0);
\r
827 return FX_ERR_Succeeded;
\r
829 case FX_DASHSTYLE_Dash: {
\r
830 FX_FLOAT dashArray[] = {3, 1};
\r
831 SetLineDash(0, dashArray, 2);
\r
832 return FX_ERR_Succeeded;
\r
834 case FX_DASHSTYLE_Dot: {
\r
835 FX_FLOAT dashArray[] = {1, 1};
\r
836 SetLineDash(0, dashArray, 2);
\r
837 return FX_ERR_Succeeded;
\r
839 case FX_DASHSTYLE_DashDot: {
\r
840 FX_FLOAT dashArray[] = {3, 1, 1, 1};
\r
841 SetLineDash(0, dashArray, 4);
\r
842 return FX_ERR_Succeeded;
\r
844 case FX_DASHSTYLE_DashDotDot: {
\r
845 FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
\r
846 SetLineDash(0, dashArray, 6);
\r
847 return FX_ERR_Succeeded;
\r
850 return FX_ERR_Parameter_Invalid;
\r
854 FX_ERR CFX_Graphics::RenderDeviceStrokePath(CFX_Path * path, CFX_Matrix * matrix)
\r
856 _FX_RETURN_VALUE_IF_FAIL(_info._strokeColor, FX_ERR_Property_Invalid);
\r
858 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
\r
862 switch (_info._strokeColor->_type) {
\r
863 case FX_COLOR_Solid: {
\r
864 FX_BOOL result = _renderDevice->DrawPath(path->GetPathData(),
\r
865 (CFX_AffineMatrix *) &m,
\r
866 &_info._graphState,
\r
868 _info._strokeColor->_argb,
\r
870 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
\r
871 return FX_ERR_Succeeded;
\r
873 case FX_COLOR_Pattern: {
\r
874 return StrokePathWithPattern(path, &m);
\r
876 case FX_COLOR_Shading: {
\r
877 return StrokePathWithShading(path, &m);
\r
880 return FX_ERR_Property_Invalid;
\r
884 FX_ERR CFX_Graphics::RenderDeviceFillPath(CFX_Path * path,
\r
885 FX_FillMode fillMode,
\r
886 CFX_Matrix * matrix)
\r
888 _FX_RETURN_VALUE_IF_FAIL(_info._fillColor, FX_ERR_Property_Invalid);
\r
890 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
\r
894 switch (_info._fillColor->_type) {
\r
895 case FX_COLOR_Solid: {
\r
896 FX_BOOL result = _renderDevice->DrawPath(path->GetPathData(),
\r
897 (CFX_AffineMatrix *) &m,
\r
898 &_info._graphState,
\r
899 _info._fillColor->_argb,
\r
902 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
\r
903 return FX_ERR_Succeeded;
\r
905 case FX_COLOR_Pattern: {
\r
907 return FillPathWithPattern(path, fillMode, &m);
\r
910 case FX_COLOR_Shading: {
\r
912 return FillPathWithShading(path, fillMode, &m);
\r
916 return FX_ERR_Property_Invalid;
\r
920 FX_ERR CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource * source,
\r
921 const CFX_PointF & point,
\r
922 CFX_Matrix * matrix)
\r
925 m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
\r
927 m1.Concat(*matrix);
\r
930 m2.Set((FX_FLOAT) source->GetWidth(),
\r
933 (FX_FLOAT) source->GetHeight(),
\r
937 FX_INT32 left, top;
\r
938 CFX_DIBitmap * bmp1 = source->FlipImage(FALSE, TRUE);
\r
939 CFX_DIBitmap * bmp2 = bmp1->TransformTo((CFX_AffineMatrix *) &m2, left, top);
\r
942 FX_ERR result = FX_ERR_Indefinite;
\r
944 CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
\r
946 bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb);
\r
947 _renderDevice->GetDIBits(&bmp, 0, 0);
\r
948 bmp.TransferBitmap(FXSYS_round(r.left),
\r
949 FXSYS_round(r.top),
\r
950 FXSYS_round(r.Width()),
\r
951 FXSYS_round(r.Height()),
\r
953 FXSYS_round(r.left - left),
\r
954 FXSYS_round(r.top - top));
\r
955 _renderDevice->SetDIBits(&bmp, 0, 0);
\r
956 result = FX_ERR_Succeeded;
\r
968 FX_ERR CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource * source,
\r
969 const CFX_RectF & rect,
\r
970 CFX_Matrix * matrix)
\r
973 m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
\r
975 m1.Concat(*matrix);
\r
977 CFX_DIBitmap * bmp1 = source->StretchTo((FX_INT32) rect.Width(),
\r
978 (FX_INT32) rect.Height());
\r
980 m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top);
\r
982 FX_INT32 left, top;
\r
983 CFX_DIBitmap * bmp2 = bmp1->FlipImage(FALSE, TRUE);
\r
984 CFX_DIBitmap * bmp3 = bmp2->TransformTo((CFX_AffineMatrix *) &m2, left, top);
\r
987 FX_ERR result = FX_ERR_Indefinite;
\r
989 CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
\r
990 bitmap->CompositeBitmap(FXSYS_round(r.left),
\r
991 FXSYS_round(r.top),
\r
992 FXSYS_round(r.Width()),
\r
993 FXSYS_round(r.Height()),
\r
995 FXSYS_round(r.left - left),
\r
996 FXSYS_round(r.top - top));
\r
997 result = FX_ERR_Succeeded;
\r
1013 FX_ERR CFX_Graphics::RenderDeviceShowText(const CFX_PointF & point,
\r
1014 const CFX_WideString & text,
\r
1015 CFX_Matrix * matrix)
\r
1017 FX_INT32 length = text.GetLength();
\r
1018 FX_DWORD * charCodes = FX_Alloc(FX_DWORD, length);
\r
1019 FXTEXT_CHARPOS * charPos = FX_Alloc(FXTEXT_CHARPOS,
\r
1020 length * sizeof (FXTEXT_CHARPOS));
\r
1022 rect.Set(point.x, point.y, 0, 0);
\r
1023 CalcTextInfo(text, charCodes, charPos, rect);
\r
1025 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
\r
1026 m.Translate(0, _info._fontSize * _info._fontHScale);
\r
1028 m.Concat(*matrix);
\r
1030 FX_BOOL result = _renderDevice->DrawNormalText(length,
\r
1033 CFX_GEModule::Get()->GetFontCache(),
\r
1034 -_info._fontSize * _info._fontHScale,
\r
1035 (CFX_AffineMatrix *) &m,
\r
1036 _info._fillColor->_argb,
\r
1037 FXTEXT_CLEARTYPE);
\r
1038 _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
\r
1040 FX_Free(charCodes);
\r
1041 return FX_ERR_Succeeded;
\r
1043 FX_ERR CFX_Graphics::StrokePathWithPattern(CFX_Path * path, CFX_Matrix * matrix)
\r
1045 return FX_ERR_Method_Not_Supported;
\r
1047 FX_ERR CFX_Graphics::StrokePathWithShading(CFX_Path * path, CFX_Matrix * matrix)
\r
1049 return FX_ERR_Method_Not_Supported;
\r
1051 FX_ERR CFX_Graphics::FillPathWithPattern(CFX_Path * path,
\r
1052 FX_FillMode fillMode,
\r
1053 CFX_Matrix * matrix)
\r
1055 CFX_Pattern * pattern = _info._fillColor->_pattern;
\r
1056 CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
\r
1057 FX_INT32 width = bitmap->GetWidth();
\r
1058 FX_INT32 height = bitmap->GetHeight();
\r
1060 bmp.Create(width, height, FXDIB_Argb);
\r
1061 _renderDevice->GetDIBits(&bmp, 0, 0);
\r
1062 switch (pattern->_type) {
\r
1063 case FX_PATTERN_Bitmap: {
\r
1064 FX_INT32 xStep = FXSYS_round(pattern->_x1Step);
\r
1065 FX_INT32 yStep = FXSYS_round(pattern->_y1Step);
\r
1066 FX_INT32 xCount = width / xStep + 1;
\r
1067 FX_INT32 yCount = height / yStep + 1;
\r
1068 for (FX_INT32 i = 0; i <= yCount; i++) {
\r
1069 for (FX_INT32 j = 0; j <= xCount; j++) {
\r
1070 bmp.TransferBitmap(j * xStep,
\r
1081 case FX_PATTERN_Hatch: {
\r
1082 FX_HatchStyle hatchStyle = _info._fillColor->_pattern->_hatchStyle;
\r
1083 if (hatchStyle < FX_HATCHSTYLE_Horizontal || hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
\r
1084 return FX_ERR_Intermediate_Value_Invalid;
\r
1086 const FX_HATCHDATA & data = hatchBitmapData[hatchStyle];
\r
1087 CFX_DIBitmap mask;
\r
1088 mask.Create(data.width, data.height, FXDIB_1bppMask);
\r
1089 FXSYS_memcpy(mask.GetBuffer(), data.maskBits, mask.GetPitch() * data.height);
\r
1090 CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox();
\r
1092 rectf.Transform((const CFX_AffineMatrix *) matrix);
\r
1094 FX_RECT rect(FXSYS_round(rectf.left),
\r
1095 FXSYS_round(rectf.top),
\r
1096 FXSYS_round(rectf.right),
\r
1097 FXSYS_round(rectf.bottom));
\r
1098 CFX_FxgeDevice device;
\r
1099 device.Attach(&bmp);
\r
1100 device.FillRect(&rect, _info._fillColor->_pattern->_backArgb);
\r
1101 for (FX_INT32 j = rect.bottom; j < rect.top; j += mask.GetHeight()) {
\r
1102 for (FX_INT32 i = rect.left; i < rect.right; i += mask.GetWidth()) {
\r
1103 device.SetBitMask(&mask, i, j, _info._fillColor->_pattern->_foreArgb);
\r
1109 _renderDevice->SaveState();
\r
1110 _renderDevice->SetClip_PathFill(path->GetPathData(),
\r
1111 (CFX_AffineMatrix *) matrix,
\r
1113 SetDIBitsWithMatrix(&bmp, &pattern->_matrix);
\r
1114 _renderDevice->RestoreState();
\r
1115 return FX_ERR_Succeeded;
\r
1117 FX_ERR CFX_Graphics::FillPathWithShading(CFX_Path * path,
\r
1118 FX_FillMode fillMode,
\r
1119 CFX_Matrix * matrix)
\r
1121 CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
\r
1122 FX_INT32 width = bitmap->GetWidth();
\r
1123 FX_INT32 height = bitmap->GetHeight();
\r
1124 FX_FLOAT start_x = _info._fillColor->_shading->_beginPoint.x;
\r
1125 FX_FLOAT start_y = _info._fillColor->_shading->_beginPoint.y;
\r
1126 FX_FLOAT end_x = _info._fillColor->_shading->_endPoint.x;
\r
1127 FX_FLOAT end_y = _info._fillColor->_shading->_endPoint.y;
\r
1129 bmp.Create(width, height, FXDIB_Argb);
\r
1130 _renderDevice->GetDIBits(&bmp, 0, 0);
\r
1131 FX_INT32 pitch = bmp.GetPitch();
\r
1132 FX_BOOL result = FALSE;
\r
1133 switch (_info._fillColor->_shading->_type) {
\r
1134 case FX_SHADING_Axial: {
\r
1135 FX_FLOAT x_span = end_x - start_x;
\r
1136 FX_FLOAT y_span = end_y - start_y;
\r
1137 FX_FLOAT axis_len_square = FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span);
\r
1138 for (FX_INT32 row = 0; row < height; row++) {
\r
1139 FX_DWORD * dib_buf = (FX_DWORD *) (bmp.GetBuffer() + row * pitch);
\r
1140 for (FX_INT32 column = 0; column < width; column++) {
\r
1141 FX_FLOAT x = (FX_FLOAT)(column);
\r
1142 FX_FLOAT y = (FX_FLOAT)(row);
\r
1143 FX_FLOAT scale = FXSYS_Div(FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span),
\r
1146 if (!_info._fillColor->_shading->_isExtendedBegin) {
\r
1150 } else if (scale > 1.0f) {
\r
1151 if (!_info._fillColor->_shading->_isExtendedEnd) {
\r
1156 FX_INT32 index = (FX_INT32)(scale * (FX_SHADING_Steps - 1));
\r
1157 dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
\r
1163 case FX_SHADING_Radial: {
\r
1164 FX_FLOAT start_r = _info._fillColor->_shading->_beginRadius;
\r
1165 FX_FLOAT end_r = _info._fillColor->_shading->_endRadius;
\r
1166 FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) + FXSYS_Mul(start_y - end_y, start_y - end_y) - FXSYS_Mul(start_r - end_r, start_r - end_r);
\r
1167 for (FX_INT32 row = 0; row < height; row++) {
\r
1168 FX_DWORD * dib_buf = (FX_DWORD *) (bmp.GetBuffer() + row * pitch);
\r
1169 for (FX_INT32 column = 0; column < width; column++) {
\r
1170 FX_FLOAT x = (FX_FLOAT)(column);
\r
1171 FX_FLOAT y = (FX_FLOAT)(row);
\r
1172 FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) + FXSYS_Mul(y - start_y, end_y - start_y) +
\r
1173 FXSYS_Mul(start_r, end_r - start_r));
\r
1174 FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) + FXSYS_Mul(y - start_y, y - start_y) -
\r
1175 FXSYS_Mul(start_r, start_r);
\r
1178 s = (FXSYS_Div(-c, b));
\r
1180 FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
\r
1184 FX_FLOAT root = (FXSYS_sqrt(b2_4ac));
\r
1187 s1 = FXSYS_Div(-b - root, 2 * a);
\r
1188 s2 = FXSYS_Div(-b + root, 2 * a);
\r
1190 s2 = FXSYS_Div(-b - root, 2 * a);
\r
1191 s1 = FXSYS_Div(-b + root, 2 * a);
\r
1193 if (s2 <= 1.0f || _info._fillColor->_shading->_isExtendedEnd) {
\r
1198 if ((start_r) + s * (end_r - start_r) < 0) {
\r
1203 if (!_info._fillColor->_shading->_isExtendedBegin) {
\r
1209 if (!_info._fillColor->_shading->_isExtendedEnd) {
\r
1214 int index = (FX_INT32)(s * (FX_SHADING_Steps - 1));
\r
1215 dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
\r
1226 _renderDevice->SaveState();
\r
1227 _renderDevice->SetClip_PathFill(path->GetPathData(),
\r
1228 (CFX_AffineMatrix *) matrix,
\r
1230 SetDIBitsWithMatrix(&bmp, matrix);
\r
1231 _renderDevice->RestoreState();
\r
1235 FX_ERR CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource * source, CFX_Matrix * matrix)
\r
1237 if (matrix->IsIdentity()) {
\r
1238 _renderDevice->SetDIBits(source, 0, 0);
\r
1241 m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0, 0);
\r
1242 m.Concat(*matrix);
\r
1243 FX_INT32 left, top;
\r
1244 CFX_DIBitmap * bmp1 = source->FlipImage(FALSE, TRUE);
\r
1245 CFX_DIBitmap * bmp2 = bmp1->TransformTo((CFX_AffineMatrix *) &m, left, top);
\r
1246 _renderDevice->SetDIBits(bmp2, left, top);
\r
1256 return FX_ERR_Succeeded;
\r
1258 FX_ERR CFX_Graphics::CalcTextInfo(const CFX_WideString & text, FX_DWORD * charCodes, FXTEXT_CHARPOS * charPos, CFX_RectF & rect)
\r
1260 IFX_FontEncoding * encoding = FXGE_CreateUnicodeEncoding(_info._font);
\r
1261 FX_INT32 length = text.GetLength();
\r
1262 FX_FLOAT penX = (FX_FLOAT) rect.left;
\r
1263 FX_FLOAT penY = (FX_FLOAT) rect.top;
\r
1264 FX_FLOAT left = (FX_FLOAT)(0);
\r
1265 FX_FLOAT top = (FX_FLOAT)(0);
\r
1266 charCodes[0] = text.GetAt(0);
\r
1267 charPos[0].m_OriginX = penX + left;
\r
1268 charPos[0].m_OriginY = penY + top;
\r
1269 charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]);
\r
1270 charPos[0].m_FontCharWidth = FXSYS_round(_info._font->GetGlyphWidth(charPos[0].m_GlyphIndex) * _info._fontHScale);
\r
1271 charPos[0].m_bGlyphAdjust = TRUE;
\r
1272 charPos[0].m_AdjustMatrix[0] = -1;
\r
1273 charPos[0].m_AdjustMatrix[1] = 0;
\r
1274 charPos[0].m_AdjustMatrix[2] = 0;
\r
1275 charPos[0].m_AdjustMatrix[3] = 1;
\r
1276 penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * _info._fontSize / 1000 + _info._fontSpacing;
\r
1277 for (FX_INT32 i = 1; i < length; i++) {
\r
1278 charCodes[i] = text.GetAt(i);
\r
1279 charPos[i].m_OriginX = penX + left;
\r
1280 charPos[i].m_OriginY = penY + top;
\r
1281 charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]);
\r
1282 charPos[i].m_FontCharWidth = FXSYS_round(_info._font->GetGlyphWidth(charPos[i].m_GlyphIndex) * _info._fontHScale);
\r
1283 charPos[i].m_bGlyphAdjust = TRUE;
\r
1284 charPos[i].m_AdjustMatrix[0] = -1;
\r
1285 charPos[i].m_AdjustMatrix[1] = 0;
\r
1286 charPos[i].m_AdjustMatrix[2] = 0;
\r
1287 charPos[i].m_AdjustMatrix[3] = 1;
\r
1288 penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * _info._fontSize / 1000 + _info._fontSpacing;
\r
1290 rect.width = (FX_FLOAT) penX - rect.left;
\r
1291 rect.height = rect.top + _info._fontSize * _info._fontHScale - rect.top;
\r
1294 return FX_ERR_Succeeded;
\r
1296 CAGG_Graphics::CAGG_Graphics()
\r
1300 FX_ERR CAGG_Graphics::Create(CFX_Graphics * owner,
\r
1303 FXDIB_Format format)
\r
1305 if (owner->_renderDevice) {
\r
1306 return FX_ERR_Parameter_Invalid;
\r
1309 return FX_ERR_Property_Invalid;
\r
1311 CFX_FxgeDevice * device = FX_NEW CFX_FxgeDevice;
\r
1312 device->Create(width, height, format);
\r
1314 _owner->_renderDevice = device;
\r
1315 _owner->_renderDevice->GetBitmap()->Clear(0xFFFFFFFF);
\r
1316 return FX_ERR_Succeeded;
\r
1318 CAGG_Graphics::~CAGG_Graphics()
\r
1320 if (_owner->_renderDevice) {
\r
1321 delete (CFX_FxgeDevice *) _owner->_renderDevice;
\r
1325 CFX_Path::CFX_Path()
\r
1327 _generator = NULL;
\r
1329 FX_ERR CFX_Path::Create()
\r
1332 return FX_ERR_Property_Invalid;
\r
1334 _generator = FX_NEW CFX_PathGenerator;
\r
1335 _generator->Create();
\r
1336 return FX_ERR_Succeeded;
\r
1338 CFX_Path::~CFX_Path()
\r
1341 delete _generator;
\r
1342 _generator = NULL;
\r
1345 FX_ERR CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y)
\r
1347 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1348 _generator->MoveTo(x, y);
\r
1349 return FX_ERR_Succeeded;
\r
1351 FX_ERR CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y)
\r
1353 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1354 _generator->LineTo(x, y);
\r
1355 return FX_ERR_Succeeded;
\r
1357 FX_ERR CFX_Path::BezierTo(FX_FLOAT ctrlX1,
\r
1364 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1365 _generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY);
\r
1366 return FX_ERR_Succeeded;
\r
1368 FX_ERR CFX_Path::ArcTo(FX_FLOAT left,
\r
1372 FX_FLOAT startAngle,
\r
1373 FX_FLOAT sweepAngle)
\r
1375 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1376 _generator->ArcTo(left + width / 2,
\r
1382 return FX_ERR_Succeeded;
\r
1384 FX_ERR CFX_Path::Close()
\r
1386 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1387 _generator->Close();
\r
1388 return FX_ERR_Succeeded;
\r
1390 FX_ERR CFX_Path::AddLine(FX_FLOAT x1,
\r
1395 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1396 _generator->AddLine(x1, y1, x2, y2);
\r
1397 return FX_ERR_Succeeded;
\r
1399 FX_ERR CFX_Path::AddBezier(FX_FLOAT startX,
\r
1408 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1409 _generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);
\r
1410 return FX_ERR_Succeeded;
\r
1412 FX_ERR CFX_Path::AddRectangle(FX_FLOAT left,
\r
1417 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1418 _generator->AddRectangle(left, top, left + width, top + height);
\r
1419 return FX_ERR_Succeeded;
\r
1421 FX_ERR CFX_Path::AddEllipse(FX_FLOAT left,
\r
1426 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1427 _generator->AddEllipse(left + width / 2, top + height / 2, width / 2, height / 2);
\r
1428 return FX_ERR_Succeeded;
\r
1430 FX_ERR CFX_Path::AddEllipse(const CFX_RectF & rect)
\r
1432 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1433 _generator->AddEllipse(rect.left + rect.Width() / 2,
\r
1434 rect.top + rect.Height() / 2,
\r
1436 rect.Height() / 2);
\r
1437 return FX_ERR_Succeeded;
\r
1439 FX_ERR CFX_Path::AddArc(FX_FLOAT left,
\r
1443 FX_FLOAT startAngle,
\r
1444 FX_FLOAT sweepAngle)
\r
1446 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1447 _generator->AddArc(left + width / 2,
\r
1453 return FX_ERR_Succeeded;
\r
1455 FX_ERR CFX_Path::AddPie(FX_FLOAT left,
\r
1459 FX_FLOAT startAngle,
\r
1460 FX_FLOAT sweepAngle)
\r
1462 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1463 _generator->AddPie(left + width / 2,
\r
1469 return FX_ERR_Succeeded;
\r
1471 FX_ERR CFX_Path::AddSubpath(CFX_Path * path)
\r
1473 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1474 _generator->AddPathData(path->GetPathData());
\r
1475 return FX_ERR_Succeeded;
\r
1477 FX_ERR CFX_Path::Clear()
\r
1479 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1480 _generator->GetPathData()->SetPointCount(0);
\r
1481 return FX_ERR_Succeeded;
\r
1483 FX_BOOL CFX_Path::IsEmpty()
\r
1485 _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
\r
1486 if (_generator->GetPathData()->GetPointCount() == 0) {
\r
1491 CFX_PathData * CFX_Path::GetPathData()
\r
1493 _FX_RETURN_VALUE_IF_FAIL(_generator, NULL);
\r
1494 return _generator->GetPathData();
\r
1496 CFX_Color::CFX_Color()
\r
1498 _type = FX_COLOR_None;
\r
1500 CFX_Color::CFX_Color(const FX_ARGB argb)
\r
1502 _type = FX_COLOR_None;
\r
1505 CFX_Color::CFX_Color(CFX_Pattern * pattern, const FX_ARGB argb )
\r
1507 _type = FX_COLOR_None;
\r
1508 Set(pattern, argb);
\r
1510 CFX_Color::CFX_Color(CFX_Shading * shading)
\r
1512 _type = FX_COLOR_None;
\r
1515 CFX_Color::~CFX_Color()
\r
1517 _type = FX_COLOR_None;
\r
1519 FX_ERR CFX_Color::Set(const FX_ARGB argb)
\r
1521 _type = FX_COLOR_Solid;
\r
1524 return FX_ERR_Succeeded;
\r
1526 FX_ERR CFX_Color::Set(CFX_Pattern * pattern, const FX_ARGB argb )
\r
1528 _FX_RETURN_VALUE_IF_FAIL(pattern, FX_ERR_Parameter_Invalid);
\r
1529 _type = FX_COLOR_Pattern;
\r
1531 _pattern = pattern;
\r
1532 return FX_ERR_Succeeded;
\r
1534 FX_ERR CFX_Color::Set(CFX_Shading * shading)
\r
1536 _FX_RETURN_VALUE_IF_FAIL(shading, FX_ERR_Parameter_Invalid);
\r
1537 _type = FX_COLOR_Shading;
\r
1538 _shading = shading;
\r
1539 return FX_ERR_Succeeded;
\r
1541 CFX_Pattern::CFX_Pattern()
\r
1543 _type = FX_PATTERN_None;
\r
1546 FX_ERR CFX_Pattern::Create(CFX_DIBitmap * bitmap,
\r
1547 const FX_FLOAT xStep,
\r
1548 const FX_FLOAT yStep,
\r
1549 CFX_Matrix * matrix )
\r
1551 _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Parameter_Invalid);
\r
1552 if (_type != FX_PATTERN_None) {
\r
1553 return FX_ERR_Property_Invalid;
\r
1555 _type = FX_PATTERN_Bitmap;
\r
1560 _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
\r
1562 return FX_ERR_Succeeded;
\r
1564 FX_ERR CFX_Pattern::Create(FX_HatchStyle hatchStyle,
\r
1565 const FX_ARGB foreArgb,
\r
1566 const FX_ARGB backArgb,
\r
1567 CFX_Matrix * matrix )
\r
1569 if (hatchStyle < FX_HATCHSTYLE_Horizontal
\r
1570 || hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
\r
1571 return FX_ERR_Parameter_Invalid;
\r
1573 if (_type != FX_PATTERN_None) {
\r
1574 return FX_ERR_Property_Invalid;
\r
1576 _type = FX_PATTERN_Hatch;
\r
1577 _hatchStyle = hatchStyle;
\r
1578 _foreArgb = foreArgb;
\r
1579 _backArgb = backArgb;
\r
1581 _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
\r
1583 return FX_ERR_Succeeded;
\r
1585 CFX_Pattern::~CFX_Pattern()
\r
1587 _type = FX_PATTERN_None;
\r
1589 CFX_Shading::CFX_Shading()
\r
1591 _type = FX_SHADING_None;
\r
1593 FX_ERR CFX_Shading::CreateAxial(const CFX_PointF & beginPoint,
\r
1594 const CFX_PointF & endPoint,
\r
1595 FX_BOOL isExtendedBegin,
\r
1596 FX_BOOL isExtendedEnd,
\r
1597 const FX_ARGB beginArgb,
\r
1598 const FX_ARGB endArgb)
\r
1600 if (_type != FX_SHADING_None) {
\r
1601 return FX_ERR_Property_Invalid;
\r
1603 _type = FX_SHADING_Axial;
\r
1604 _beginPoint = beginPoint;
\r
1605 _endPoint = endPoint;
\r
1606 _isExtendedBegin = isExtendedBegin;
\r
1607 _isExtendedEnd = isExtendedEnd;
\r
1608 _beginArgb = beginArgb;
\r
1609 _endArgb = endArgb;
\r
1610 return InitArgbArray();
\r
1612 FX_ERR CFX_Shading::CreateRadial(const CFX_PointF & beginPoint,
\r
1613 const CFX_PointF & endPoint,
\r
1614 const FX_FLOAT beginRadius,
\r
1615 const FX_FLOAT endRadius,
\r
1616 FX_BOOL isExtendedBegin,
\r
1617 FX_BOOL isExtendedEnd,
\r
1618 const FX_ARGB beginArgb,
\r
1619 const FX_ARGB endArgb)
\r
1621 if (_type != FX_SHADING_None) {
\r
1622 return FX_ERR_Property_Invalid;
\r
1624 _type = FX_SHADING_Radial;
\r
1625 _beginPoint = beginPoint;
\r
1626 _endPoint = endPoint;
\r
1627 _beginRadius = beginRadius;
\r
1628 _endRadius = endRadius;
\r
1629 _isExtendedBegin = isExtendedBegin;
\r
1630 _isExtendedEnd = isExtendedEnd;
\r
1631 _beginArgb = beginArgb;
\r
1632 _endArgb = endArgb;
\r
1633 return InitArgbArray();
\r
1635 CFX_Shading::~CFX_Shading()
\r
1637 _type = FX_SHADING_None;
\r
1639 FX_ERR CFX_Shading::InitArgbArray()
\r
1641 FX_INT32 a1, r1, g1, b1;
\r
1642 ArgbDecode(_beginArgb, a1, r1, g1, b1);
\r
1643 FX_INT32 a2, r2, g2, b2;
\r
1644 ArgbDecode(_endArgb, a2, r2, g2, b2);
\r
1645 FX_FLOAT f = (FX_FLOAT) (FX_SHADING_Steps - 1);
\r
1646 FX_FLOAT aScale = (FX_FLOAT) (1.0 * (a2 - a1) / f);
\r
1647 FX_FLOAT rScale = (FX_FLOAT) (1.0 * (r2 - r1) / f);
\r
1648 FX_FLOAT gScale = (FX_FLOAT) (1.0 * (g2 - g1) / f);
\r
1649 FX_FLOAT bScale = (FX_FLOAT) (1.0 * (b2 - b1) / f);
\r
1650 FX_INT32 a3, r3, g3, b3;
\r
1651 for (FX_INT32 i = 0; i < FX_SHADING_Steps; i++) {
\r
1652 a3 = (FX_INT32) (i * aScale);
\r
1653 r3 = (FX_INT32) (i * rScale);
\r
1654 g3 = (FX_INT32) (i * gScale);
\r
1655 b3 = (FX_INT32) (i * bScale);
\r
1656 _argbArray[i] = FXARGB_TODIB(FXARGB_MAKE((a1 + a3),
\r
1661 return FX_ERR_Succeeded;
\r
1663 class CFX_Pause : public IFX_Pause
\r
1666 virtual FX_BOOL NeedToPauseNow()
\r