summaryrefslogtreecommitdiff
path: root/xfa/src/fxgraphics/src/fx_graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/src/fxgraphics/src/fx_graphics.cpp')
-rw-r--r--xfa/src/fxgraphics/src/fx_graphics.cpp2920
1 files changed, 1460 insertions, 1460 deletions
diff --git a/xfa/src/fxgraphics/src/fx_graphics.cpp b/xfa/src/fxgraphics/src/fx_graphics.cpp
index 69069817aa..fae8aab006 100644
--- a/xfa/src/fxgraphics/src/fx_graphics.cpp
+++ b/xfa/src/fxgraphics/src/fx_graphics.cpp
@@ -1,1460 +1,1460 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <memory>
-
-#include "fx_path_generator.h"
-#include "pre.h"
-
-class CAGG_Graphics {
- public:
- CAGG_Graphics();
- FX_ERR Create(CFX_Graphics* owner,
- int32_t width,
- int32_t height,
- FXDIB_Format format);
- virtual ~CAGG_Graphics();
-
- private:
- CFX_Graphics* _owner;
-};
-CFX_Graphics::CFX_Graphics() {
- _type = FX_CONTEXT_None;
- _info._graphState.SetDashCount(0);
- _info._isAntialiasing = TRUE;
- _info._strokeAlignment = FX_STROKEALIGNMENT_Center;
- _info._CTM.SetIdentity();
- _info._isActOnDash = FALSE;
- _info._strokeColor = NULL;
- _info._fillColor = NULL;
- _info._font = NULL;
- _info._fontSize = 40.0;
- _info._fontHScale = 1.0;
- _info._fontSpacing = 0.0;
- _renderDevice = NULL;
- _aggGraphics = NULL;
-}
-FX_ERR CFX_Graphics::Create(CFX_RenderDevice* renderDevice,
- FX_BOOL isAntialiasing) {
- _FX_RETURN_VALUE_IF_FAIL(renderDevice, FX_ERR_Parameter_Invalid);
- if (_type != FX_CONTEXT_None) {
- return FX_ERR_Property_Invalid;
- }
- _type = FX_CONTEXT_Device;
- _info._isAntialiasing = isAntialiasing;
- _renderDevice = renderDevice;
- if (_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP) {
- return FX_ERR_Succeeded;
- }
- return FX_ERR_Indefinite;
-}
-FX_ERR CFX_Graphics::Create(int32_t width,
- int32_t height,
- FXDIB_Format format,
- FX_BOOL isNative,
- FX_BOOL isAntialiasing) {
- if (_type != FX_CONTEXT_None) {
- return FX_ERR_Property_Invalid;
- }
- _type = FX_CONTEXT_Device;
- _info._isAntialiasing = isAntialiasing;
- {
- _aggGraphics = new CAGG_Graphics;
- return _aggGraphics->Create(this, width, height, format);
- }
-}
-CFX_Graphics::~CFX_Graphics() {
- if (_aggGraphics) {
- delete _aggGraphics;
- _aggGraphics = NULL;
- }
- _renderDevice = NULL;
- _info._graphState.SetDashCount(0);
- _type = FX_CONTEXT_None;
-}
-FX_ERR CFX_Graphics::GetDeviceCap(const int32_t capID, FX_DeviceCap& capVal) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- capVal = _renderDevice->GetDeviceCaps(capID);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::IsPrinterDevice(FX_BOOL& isPrinter) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- int32_t deviceClass = _renderDevice->GetDeviceClass();
- if (deviceClass == FXDC_PRINTER) {
- isPrinter = TRUE;
- } else {
- isPrinter = FALSE;
- }
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._isAntialiasing = isAntialiasing;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SaveGraphState() {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _renderDevice->SaveState();
- TInfo* info = new TInfo;
- info->_graphState.Copy(_info._graphState);
- info->_isAntialiasing = _info._isAntialiasing;
- info->_strokeAlignment = _info._strokeAlignment;
- info->_CTM = _info._CTM;
- info->_isActOnDash = _info._isActOnDash;
- info->_strokeColor = _info._strokeColor;
- info->_fillColor = _info._fillColor;
- info->_font = _info._font;
- info->_fontSize = _info._fontSize;
- info->_fontHScale = _info._fontHScale;
- info->_fontSpacing = _info._fontSpacing;
- _infoStack.Add(info);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::RestoreGraphState() {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _renderDevice->RestoreState();
- int32_t size = _infoStack.GetSize();
- if (size <= 0) {
- return FX_ERR_Intermediate_Value_Invalid;
- }
- int32_t topIndex = size - 1;
- TInfo* info = (TInfo*)_infoStack.GetAt(topIndex);
- _FX_RETURN_VALUE_IF_FAIL(info, FX_ERR_Intermediate_Value_Invalid);
- _info._graphState.Copy(info->_graphState);
- _info._isAntialiasing = info->_isAntialiasing;
- _info._strokeAlignment = info->_strokeAlignment;
- _info._CTM = info->_CTM;
- _info._isActOnDash = info->_isActOnDash;
- _info._strokeColor = info->_strokeColor;
- _info._fillColor = info->_fillColor;
- _info._font = info->_font;
- _info._fontSize = info->_fontSize;
- _info._fontHScale = info->_fontHScale;
- _info._fontSpacing = info->_fontSpacing;
- delete info;
- info = NULL;
- _infoStack.RemoveAt(topIndex);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap& lineCap) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- lineCap = _info._graphState.m_LineCap;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._graphState.m_LineCap = lineCap;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::GetDashCount(int32_t& dashCount) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- dashCount = _info._graphState.m_DashCount;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::GetLineDash(FX_FLOAT& dashPhase, FX_FLOAT* dashArray) {
- _FX_RETURN_VALUE_IF_FAIL(dashArray, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- dashPhase = _info._graphState.m_DashPhase;
- FXSYS_memcpy(dashArray, _info._graphState.m_DashArray,
- _info._graphState.m_DashCount * sizeof(FX_FLOAT));
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetLineDash(FX_FLOAT dashPhase,
- FX_FLOAT* dashArray,
- int32_t dashCount) {
- if (dashCount > 0 && !dashArray) {
- return FX_ERR_Parameter_Invalid;
- }
- dashCount = dashCount < 0 ? 0 : dashCount;
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- FX_FLOAT scale = 1.0;
- if (_info._isActOnDash) {
- scale = _info._graphState.m_LineWidth;
- }
- _info._graphState.m_DashPhase = dashPhase;
- _info._graphState.SetDashCount(dashCount);
- for (int32_t i = 0; i < dashCount; i++) {
- _info._graphState.m_DashArray[i] = dashArray[i] * scale;
- }
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- return RenderDeviceSetLineDash(dashStyle);
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::GetLineJoin(CFX_GraphStateData::LineJoin& lineJoin) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- lineJoin = _info._graphState.m_LineJoin;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._graphState.m_LineJoin = lineJoin;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::GetMiterLimit(FX_FLOAT& miterLimit) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- miterLimit = _info._graphState.m_MiterLimit;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._graphState.m_MiterLimit = miterLimit;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::GetLineWidth(FX_FLOAT& lineWidth) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- lineWidth = _info._graphState.m_LineWidth;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._graphState.m_LineWidth = lineWidth;
- _info._isActOnDash = isActOnDash;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::GetStrokeAlignment(FX_StrokeAlignment& strokeAlignment) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- strokeAlignment = _info._strokeAlignment;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._strokeAlignment = strokeAlignment;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetStrokeColor(CFX_Color* color) {
- _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._strokeColor = color;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetFillColor(CFX_Color* color) {
- _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._fillColor = color;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- return RenderDeviceStrokePath(path, matrix);
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::FillPath(CFX_Path* path,
- FX_FillMode fillMode,
- CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- return RenderDeviceFillPath(path, fillMode, matrix);
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::ClipPath(CFX_Path* path,
- FX_FillMode fillMode,
- CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- FX_BOOL result = _renderDevice->SetClip_PathFill(
- path->GetPathData(), (CFX_Matrix*)matrix, fillMode);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::DrawImage(CFX_DIBSource* source,
- const CFX_PointF& point,
- CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- return RenderDeviceDrawImage(source, point, matrix);
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::StretchImage(CFX_DIBSource* source,
- const CFX_RectF& rect,
- CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- return RenderDeviceStretchImage(source, rect, matrix);
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(matrix, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._CTM.Concat(*matrix);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-CFX_Matrix* CFX_Graphics::GetMatrix() {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, NULL);
- return &_info._CTM;
- }
- default: { return NULL; }
- }
-}
-FX_ERR CFX_Graphics::GetClipRect(CFX_RectF& rect) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- FX_RECT r = _renderDevice->GetClipBox();
- rect.left = (FX_FLOAT)r.left;
- rect.top = (FX_FLOAT)r.top;
- rect.width = (FX_FLOAT)r.Width();
- rect.height = (FX_FLOAT)r.Height();
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetClipRect(const CFX_RectF& rect) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- FX_RECT r(FXSYS_round(rect.left), FXSYS_round(rect.top),
- FXSYS_round(rect.right()), FXSYS_round(rect.bottom()));
- FX_BOOL result = _renderDevice->SetClip_Rect(&r);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::ClearClip() {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- FX_BOOL result = FX_ERR_Succeeded;
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetFont(CFX_Font* font) {
- _FX_RETURN_VALUE_IF_FAIL(font, FX_ERR_Parameter_Invalid);
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._font = font;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetFontSize(const FX_FLOAT size) {
- FX_FLOAT fontSize = size <= 0 ? 1.0f : size;
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._fontSize = fontSize;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetFontHScale(const FX_FLOAT scale) {
- FX_FLOAT fontHScale = scale <= 0 ? 1.0f : scale;
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._fontHScale = fontHScale;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing) {
- FX_FLOAT fontSpacing = spacing < 0 ? 0 : spacing;
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- _info._fontSpacing = fontSpacing;
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::SetTextDrawingMode(const int32_t mode) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::ShowText(const CFX_PointF& point,
- const CFX_WideString& text,
- CFX_Matrix* matrix) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- return RenderDeviceShowText(point, text, matrix);
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::CalcTextRect(CFX_RectF& rect,
- const CFX_WideString& text,
- FX_BOOL isMultiline,
- CFX_Matrix* matrix) {
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- int32_t length = text.GetLength();
- FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
- FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
- CalcTextInfo(text, charCodes, charPos, rect);
- FX_Free(charPos);
- FX_Free(charCodes);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
- const CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
- CFX_Matrix m;
- m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
- _info._CTM.f);
- if (matrix) {
- m.Concat(*matrix);
- }
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- {
- _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
- FX_ERR_Parameter_Invalid);
- CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap();
- FX_BOOL result = _renderDevice->SetDIBits(bitmap, 0, 0);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
- }
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
- FX_FLOAT srcLeft,
- FX_FLOAT srcTop,
- const CFX_RectF& dstRect,
- const CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
- CFX_Matrix m;
- m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
- _info._CTM.f);
- if (matrix) {
- m.Concat(*matrix);
- }
- switch (_type) {
- case FX_CONTEXT_Device: {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- {
- _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
- FX_ERR_Parameter_Invalid);
- CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap();
- FX_BOOL result = FX_ERR_Indefinite;
- CFX_DIBitmap bmp;
- result = bmp.Create((int32_t)dstRect.width, (int32_t)dstRect.height,
- bitmap->GetFormat());
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Intermediate_Value_Invalid);
- result = graphics->_renderDevice->GetDIBits(&bmp, (int32_t)srcLeft,
- (int32_t)srcTop);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
- result = _renderDevice->SetDIBits(&bmp, (int32_t)dstRect.left,
- (int32_t)dstRect.top);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
- return FX_ERR_Succeeded;
- }
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-CFX_RenderDevice* CFX_Graphics::GetRenderDevice() {
- return _renderDevice;
-}
-FX_ERR CFX_Graphics::InverseRect(const CFX_RectF& rect) {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
- _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Property_Invalid);
- CFX_RectF temp(rect);
- _info._CTM.TransformRect(temp);
- CFX_RectF r;
- r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth());
- r.Intersect(temp);
- if (r.IsEmpty()) {
- return FX_ERR_Parameter_Invalid;
- }
- FX_ARGB* pBuf =
- (FX_ARGB*)(bitmap->GetBuffer() + int32_t(r.top) * bitmap->GetPitch());
- int32_t bottom = (int32_t)r.bottom();
- int32_t right = (int32_t)r.right();
- for (int32_t i = (int32_t)r.top; i < bottom; i++) {
- FX_ARGB* pLine = pBuf + (int32_t)r.left;
- for (int32_t j = (int32_t)r.left; j < right; j++) {
- FX_ARGB c = *pLine;
- *pLine++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF));
- }
- pBuf = (FX_ARGB*)((uint8_t*)pBuf + bitmap->GetPitch());
- }
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Graphics::XorDIBitmap(const CFX_DIBitmap* srcBitmap,
- const CFX_RectF& rect) {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- CFX_DIBitmap* dst = _renderDevice->GetBitmap();
- _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
- CFX_RectF temp(rect);
- _info._CTM.TransformRect(temp);
- CFX_RectF r;
- r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
- r.Intersect(temp);
- if (r.IsEmpty()) {
- return FX_ERR_Parameter_Invalid;
- }
- FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
- int32_t(r.top) * srcBitmap->GetPitch());
- FX_ARGB* pDstBuf =
- (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
- int32_t bottom = (int32_t)r.bottom();
- int32_t right = (int32_t)r.right();
- for (int32_t i = (int32_t)r.top; i < bottom; i++) {
- FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
- FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
- for (int32_t j = (int32_t)r.left; j < right; j++) {
- FX_ARGB c = *pDstLine;
- *pDstLine++ =
- ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF));
- pSrcLine++;
- }
- pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
- pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
- }
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap* srcBitmap,
- const CFX_RectF& rect) {
- _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
- CFX_DIBitmap* dst = _renderDevice->GetBitmap();
- _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
- CFX_RectF temp(rect);
- _info._CTM.TransformRect(temp);
- CFX_RectF r;
- r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
- r.Intersect(temp);
- if (r.IsEmpty()) {
- return FX_ERR_Parameter_Invalid;
- }
- FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
- int32_t(r.top) * srcBitmap->GetPitch());
- FX_ARGB* pDstBuf =
- (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
- int32_t bottom = (int32_t)r.bottom();
- int32_t right = (int32_t)r.right();
- for (int32_t i = (int32_t)r.top; i < bottom; i++) {
- FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
- FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
- for (int32_t j = (int32_t)r.left; j < right; j++) {
- FX_ARGB c = *pDstLine;
- *pDstLine++ =
- ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)));
- pSrcLine++;
- }
- pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
- pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
- }
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) {
- switch (dashStyle) {
- case FX_DASHSTYLE_Solid: {
- _info._graphState.SetDashCount(0);
- return FX_ERR_Succeeded;
- }
- case FX_DASHSTYLE_Dash: {
- FX_FLOAT dashArray[] = {3, 1};
- SetLineDash(0, dashArray, 2);
- return FX_ERR_Succeeded;
- }
- case FX_DASHSTYLE_Dot: {
- FX_FLOAT dashArray[] = {1, 1};
- SetLineDash(0, dashArray, 2);
- return FX_ERR_Succeeded;
- }
- case FX_DASHSTYLE_DashDot: {
- FX_FLOAT dashArray[] = {3, 1, 1, 1};
- SetLineDash(0, dashArray, 4);
- return FX_ERR_Succeeded;
- }
- case FX_DASHSTYLE_DashDotDot: {
- FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
- SetLineDash(0, dashArray, 6);
- return FX_ERR_Succeeded;
- }
- default: { return FX_ERR_Parameter_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path,
- CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(_info._strokeColor, FX_ERR_Property_Invalid);
- CFX_Matrix m;
- m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
- _info._CTM.f);
- if (matrix) {
- m.Concat(*matrix);
- }
- switch (_info._strokeColor->_type) {
- case FX_COLOR_Solid: {
- FX_BOOL result = _renderDevice->DrawPath(
- path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState, 0x0,
- _info._strokeColor->_argb, 0);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
- return FX_ERR_Succeeded;
- }
- case FX_COLOR_Pattern: {
- return StrokePathWithPattern(path, &m);
- }
- case FX_COLOR_Shading: {
- return StrokePathWithShading(path, &m);
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::RenderDeviceFillPath(CFX_Path* path,
- FX_FillMode fillMode,
- CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(_info._fillColor, FX_ERR_Property_Invalid);
- CFX_Matrix m;
- m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
- _info._CTM.f);
- if (matrix) {
- m.Concat(*matrix);
- }
- switch (_info._fillColor->_type) {
- case FX_COLOR_Solid: {
- FX_BOOL result = _renderDevice->DrawPath(
- path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState,
- _info._fillColor->_argb, 0x0, fillMode);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
- return FX_ERR_Succeeded;
- }
- case FX_COLOR_Pattern: {
- { return FillPathWithPattern(path, fillMode, &m); }
- }
- case FX_COLOR_Shading: {
- { return FillPathWithShading(path, fillMode, &m); }
- }
- default: { return FX_ERR_Property_Invalid; }
- }
-}
-FX_ERR CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource* source,
- const CFX_PointF& point,
- CFX_Matrix* matrix) {
- CFX_Matrix m1;
- m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
- _info._CTM.f);
- if (matrix) {
- m1.Concat(*matrix);
- }
- CFX_Matrix m2;
- m2.Set((FX_FLOAT)source->GetWidth(), 0.0, 0.0, (FX_FLOAT)source->GetHeight(),
- point.x, point.y);
- m2.Concat(m1);
- int32_t left, top;
- CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE);
- CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m2, left, top);
- CFX_RectF r;
- GetClipRect(r);
- FX_ERR result = FX_ERR_Indefinite;
- {
- CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
- CFX_DIBitmap bmp;
- bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb);
- _renderDevice->GetDIBits(&bmp, 0, 0);
- bmp.TransferBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
- FXSYS_round(r.Width()), FXSYS_round(r.Height()), bmp2,
- FXSYS_round(r.left - left), FXSYS_round(r.top - top));
- _renderDevice->SetDIBits(&bmp, 0, 0);
- result = FX_ERR_Succeeded;
- }
- if (bmp2) {
- delete bmp2;
- bmp2 = NULL;
- }
- if (bmp1) {
- delete bmp1;
- bmp1 = NULL;
- }
- return result;
-}
-FX_ERR CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source,
- const CFX_RectF& rect,
- CFX_Matrix* matrix) {
- CFX_Matrix m1;
- m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
- _info._CTM.f);
- if (matrix) {
- m1.Concat(*matrix);
- }
- CFX_DIBitmap* bmp1 =
- source->StretchTo((int32_t)rect.Width(), (int32_t)rect.Height());
- CFX_Matrix m2;
- m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top);
- m2.Concat(m1);
- int32_t left, top;
- CFX_DIBitmap* bmp2 = bmp1->FlipImage(FALSE, TRUE);
- CFX_DIBitmap* bmp3 = bmp2->TransformTo((CFX_Matrix*)&m2, left, top);
- CFX_RectF r;
- GetClipRect(r);
- FX_ERR result = FX_ERR_Indefinite;
- {
- CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
- bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
- FXSYS_round(r.Width()), FXSYS_round(r.Height()),
- bmp3, FXSYS_round(r.left - left),
- FXSYS_round(r.top - top));
- result = FX_ERR_Succeeded;
- }
- if (bmp3) {
- delete bmp3;
- bmp3 = NULL;
- }
- if (bmp2) {
- delete bmp2;
- bmp2 = NULL;
- }
- if (bmp1) {
- delete bmp1;
- bmp1 = NULL;
- }
- return result;
-}
-FX_ERR CFX_Graphics::RenderDeviceShowText(const CFX_PointF& point,
- const CFX_WideString& text,
- CFX_Matrix* matrix) {
- int32_t length = text.GetLength();
- FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
- FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
- CFX_RectF rect;
- rect.Set(point.x, point.y, 0, 0);
- CalcTextInfo(text, charCodes, charPos, rect);
- CFX_Matrix m;
- m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
- _info._CTM.f);
- m.Translate(0, _info._fontSize * _info._fontHScale);
- if (matrix) {
- m.Concat(*matrix);
- }
- FX_BOOL result = _renderDevice->DrawNormalText(
- length, charPos, _info._font, CFX_GEModule::Get()->GetFontCache(),
- -_info._fontSize * _info._fontHScale, (CFX_Matrix*)&m,
- _info._fillColor->_argb, FXTEXT_CLEARTYPE);
- _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
- FX_Free(charPos);
- FX_Free(charCodes);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Graphics::StrokePathWithPattern(CFX_Path* path, CFX_Matrix* matrix) {
- return FX_ERR_Method_Not_Supported;
-}
-FX_ERR CFX_Graphics::StrokePathWithShading(CFX_Path* path, CFX_Matrix* matrix) {
- return FX_ERR_Method_Not_Supported;
-}
-FX_ERR CFX_Graphics::FillPathWithPattern(CFX_Path* path,
- FX_FillMode fillMode,
- CFX_Matrix* matrix) {
- CFX_Pattern* pattern = _info._fillColor->_pattern;
- CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
- int32_t width = bitmap->GetWidth();
- int32_t height = bitmap->GetHeight();
- CFX_DIBitmap bmp;
- bmp.Create(width, height, FXDIB_Argb);
- _renderDevice->GetDIBits(&bmp, 0, 0);
- switch (pattern->_type) {
- case FX_PATTERN_Bitmap: {
- int32_t xStep = FXSYS_round(pattern->_x1Step);
- int32_t yStep = FXSYS_round(pattern->_y1Step);
- int32_t xCount = width / xStep + 1;
- int32_t yCount = height / yStep + 1;
- for (int32_t i = 0; i <= yCount; i++) {
- for (int32_t j = 0; j <= xCount; j++) {
- bmp.TransferBitmap(j * xStep, i * yStep, xStep, yStep,
- pattern->_bitmap, 0, 0);
- }
- }
- break;
- }
- case FX_PATTERN_Hatch: {
- FX_HatchStyle hatchStyle = _info._fillColor->_pattern->_hatchStyle;
- if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
- hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
- return FX_ERR_Intermediate_Value_Invalid;
- }
- const FX_HATCHDATA& data = hatchBitmapData[hatchStyle];
- CFX_DIBitmap mask;
- mask.Create(data.width, data.height, FXDIB_1bppMask);
- FXSYS_memcpy(mask.GetBuffer(), data.maskBits,
- mask.GetPitch() * data.height);
- CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox();
- if (matrix) {
- rectf.Transform((const CFX_Matrix*)matrix);
- }
- FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
- FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
- CFX_FxgeDevice device;
- device.Attach(&bmp);
- device.FillRect(&rect, _info._fillColor->_pattern->_backArgb);
- for (int32_t j = rect.bottom; j < rect.top; j += mask.GetHeight()) {
- for (int32_t i = rect.left; i < rect.right; i += mask.GetWidth()) {
- device.SetBitMask(&mask, i, j, _info._fillColor->_pattern->_foreArgb);
- }
- }
- break;
- }
- }
- _renderDevice->SaveState();
- _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
- fillMode);
- SetDIBitsWithMatrix(&bmp, &pattern->_matrix);
- _renderDevice->RestoreState();
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Graphics::FillPathWithShading(CFX_Path* path,
- FX_FillMode fillMode,
- CFX_Matrix* matrix) {
- CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
- int32_t width = bitmap->GetWidth();
- int32_t height = bitmap->GetHeight();
- FX_FLOAT start_x = _info._fillColor->_shading->_beginPoint.x;
- FX_FLOAT start_y = _info._fillColor->_shading->_beginPoint.y;
- FX_FLOAT end_x = _info._fillColor->_shading->_endPoint.x;
- FX_FLOAT end_y = _info._fillColor->_shading->_endPoint.y;
- CFX_DIBitmap bmp;
- bmp.Create(width, height, FXDIB_Argb);
- _renderDevice->GetDIBits(&bmp, 0, 0);
- int32_t pitch = bmp.GetPitch();
- FX_BOOL result = FALSE;
- switch (_info._fillColor->_shading->_type) {
- case FX_SHADING_Axial: {
- FX_FLOAT x_span = end_x - start_x;
- FX_FLOAT y_span = end_y - start_y;
- FX_FLOAT axis_len_square =
- FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span);
- for (int32_t row = 0; row < height; row++) {
- FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
- for (int32_t column = 0; column < width; column++) {
- FX_FLOAT x = (FX_FLOAT)(column);
- FX_FLOAT y = (FX_FLOAT)(row);
- FX_FLOAT scale = FXSYS_Div(
- FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span),
- axis_len_square);
- if (scale < 0) {
- if (!_info._fillColor->_shading->_isExtendedBegin) {
- continue;
- }
- scale = 0;
- } else if (scale > 1.0f) {
- if (!_info._fillColor->_shading->_isExtendedEnd) {
- continue;
- }
- scale = 1.0f;
- }
- int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1));
- dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
- }
- }
- result = TRUE;
- break;
- }
- case FX_SHADING_Radial: {
- FX_FLOAT start_r = _info._fillColor->_shading->_beginRadius;
- FX_FLOAT end_r = _info._fillColor->_shading->_endRadius;
- 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);
- for (int32_t row = 0; row < height; row++) {
- FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
- for (int32_t column = 0; column < width; column++) {
- FX_FLOAT x = (FX_FLOAT)(column);
- FX_FLOAT y = (FX_FLOAT)(row);
- FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) +
- FXSYS_Mul(y - start_y, end_y - start_y) +
- FXSYS_Mul(start_r, end_r - start_r));
- FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) +
- FXSYS_Mul(y - start_y, y - start_y) -
- FXSYS_Mul(start_r, start_r);
- FX_FLOAT s;
- if (a == 0) {
- s = (FXSYS_Div(-c, b));
- } else {
- FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
- if (b2_4ac < 0) {
- continue;
- }
- FX_FLOAT root = (FXSYS_sqrt(b2_4ac));
- FX_FLOAT s1, s2;
- if (a > 0) {
- s1 = FXSYS_Div(-b - root, 2 * a);
- s2 = FXSYS_Div(-b + root, 2 * a);
- } else {
- s2 = FXSYS_Div(-b - root, 2 * a);
- s1 = FXSYS_Div(-b + root, 2 * a);
- }
- if (s2 <= 1.0f || _info._fillColor->_shading->_isExtendedEnd) {
- s = (s2);
- } else {
- s = (s1);
- }
- if ((start_r) + s * (end_r - start_r) < 0) {
- continue;
- }
- }
- if (s < 0) {
- if (!_info._fillColor->_shading->_isExtendedBegin) {
- continue;
- }
- s = 0;
- }
- if (s > 1.0f) {
- if (!_info._fillColor->_shading->_isExtendedEnd) {
- continue;
- }
- s = 1.0f;
- }
- int index = (int32_t)(s * (FX_SHADING_Steps - 1));
- dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
- }
- }
- result = TRUE;
- break;
- }
- default: { result = FALSE; }
- }
- if (result) {
- _renderDevice->SaveState();
- _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
- fillMode);
- SetDIBitsWithMatrix(&bmp, matrix);
- _renderDevice->RestoreState();
- }
- return result;
-}
-FX_ERR CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source,
- CFX_Matrix* matrix) {
- if (matrix->IsIdentity()) {
- _renderDevice->SetDIBits(source, 0, 0);
- } else {
- CFX_Matrix m;
- m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0,
- 0);
- m.Concat(*matrix);
- int32_t left, top;
- CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE);
- CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m, left, top);
- _renderDevice->SetDIBits(bmp2, left, top);
- if (bmp2) {
- delete bmp2;
- bmp2 = NULL;
- }
- if (bmp1) {
- delete bmp1;
- bmp1 = NULL;
- }
- }
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Graphics::CalcTextInfo(const CFX_WideString& text,
- FX_DWORD* charCodes,
- FXTEXT_CHARPOS* charPos,
- CFX_RectF& rect) {
- std::unique_ptr<CFX_UnicodeEncoding> encoding(
- new CFX_UnicodeEncoding(_info._font));
- int32_t length = text.GetLength();
- FX_FLOAT penX = (FX_FLOAT)rect.left;
- FX_FLOAT penY = (FX_FLOAT)rect.top;
- FX_FLOAT left = (FX_FLOAT)(0);
- FX_FLOAT top = (FX_FLOAT)(0);
- charCodes[0] = text.GetAt(0);
- charPos[0].m_OriginX = penX + left;
- charPos[0].m_OriginY = penY + top;
- charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]);
- charPos[0].m_FontCharWidth = FXSYS_round(
- _info._font->GetGlyphWidth(charPos[0].m_GlyphIndex) * _info._fontHScale);
- charPos[0].m_bGlyphAdjust = TRUE;
- charPos[0].m_AdjustMatrix[0] = -1;
- charPos[0].m_AdjustMatrix[1] = 0;
- charPos[0].m_AdjustMatrix[2] = 0;
- charPos[0].m_AdjustMatrix[3] = 1;
- penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * _info._fontSize / 1000 +
- _info._fontSpacing;
- for (int32_t i = 1; i < length; i++) {
- charCodes[i] = text.GetAt(i);
- charPos[i].m_OriginX = penX + left;
- charPos[i].m_OriginY = penY + top;
- charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]);
- charPos[i].m_FontCharWidth =
- FXSYS_round(_info._font->GetGlyphWidth(charPos[i].m_GlyphIndex) *
- _info._fontHScale);
- charPos[i].m_bGlyphAdjust = TRUE;
- charPos[i].m_AdjustMatrix[0] = -1;
- charPos[i].m_AdjustMatrix[1] = 0;
- charPos[i].m_AdjustMatrix[2] = 0;
- charPos[i].m_AdjustMatrix[3] = 1;
- penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * _info._fontSize / 1000 +
- _info._fontSpacing;
- }
- rect.width = (FX_FLOAT)penX - rect.left;
- rect.height = rect.top + _info._fontSize * _info._fontHScale - rect.top;
- return FX_ERR_Succeeded;
-}
-CAGG_Graphics::CAGG_Graphics() {
- _owner = NULL;
-}
-FX_ERR CAGG_Graphics::Create(CFX_Graphics* owner,
- int32_t width,
- int32_t height,
- FXDIB_Format format) {
- if (owner->_renderDevice) {
- return FX_ERR_Parameter_Invalid;
- }
- if (_owner) {
- return FX_ERR_Property_Invalid;
- }
- CFX_FxgeDevice* device = new CFX_FxgeDevice;
- device->Create(width, height, format);
- _owner = owner;
- _owner->_renderDevice = device;
- _owner->_renderDevice->GetBitmap()->Clear(0xFFFFFFFF);
- return FX_ERR_Succeeded;
-}
-CAGG_Graphics::~CAGG_Graphics() {
- if (_owner->_renderDevice) {
- delete (CFX_FxgeDevice*)_owner->_renderDevice;
- }
- _owner = NULL;
-}
-CFX_Path::CFX_Path() {
- _generator = NULL;
-}
-FX_ERR CFX_Path::Create() {
- if (_generator) {
- return FX_ERR_Property_Invalid;
- }
- _generator = new CFX_PathGenerator;
- _generator->Create();
- return FX_ERR_Succeeded;
-}
-CFX_Path::~CFX_Path() {
- if (_generator) {
- delete _generator;
- _generator = NULL;
- }
-}
-FX_ERR CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->MoveTo(x, y);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->LineTo(x, y);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::BezierTo(FX_FLOAT ctrlX1,
- FX_FLOAT ctrlY1,
- FX_FLOAT ctrlX2,
- FX_FLOAT ctrlY2,
- FX_FLOAT toX,
- FX_FLOAT toY) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::ArcTo(FX_FLOAT left,
- FX_FLOAT top,
- FX_FLOAT width,
- FX_FLOAT height,
- FX_FLOAT startAngle,
- FX_FLOAT sweepAngle) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->ArcTo(left + width / 2, top + height / 2, width / 2, height / 2,
- startAngle, sweepAngle);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::Close() {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->Close();
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddLine(x1, y1, x2, y2);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddBezier(FX_FLOAT startX,
- FX_FLOAT startY,
- FX_FLOAT ctrlX1,
- FX_FLOAT ctrlY1,
- FX_FLOAT ctrlX2,
- FX_FLOAT ctrlY2,
- FX_FLOAT endX,
- FX_FLOAT endY) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX,
- endY);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddRectangle(FX_FLOAT left,
- FX_FLOAT top,
- FX_FLOAT width,
- FX_FLOAT height) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddRectangle(left, top, left + width, top + height);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddEllipse(FX_FLOAT left,
- FX_FLOAT top,
- FX_FLOAT width,
- FX_FLOAT height) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddEllipse(left + width / 2, top + height / 2, width / 2,
- height / 2);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddEllipse(const CFX_RectF& rect) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddEllipse(rect.left + rect.Width() / 2,
- rect.top + rect.Height() / 2, rect.Width() / 2,
- rect.Height() / 2);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddArc(FX_FLOAT left,
- FX_FLOAT top,
- FX_FLOAT width,
- FX_FLOAT height,
- FX_FLOAT startAngle,
- FX_FLOAT sweepAngle) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddArc(left + width / 2, top + height / 2, width / 2, height / 2,
- startAngle, sweepAngle);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddPie(FX_FLOAT left,
- FX_FLOAT top,
- FX_FLOAT width,
- FX_FLOAT height,
- FX_FLOAT startAngle,
- FX_FLOAT sweepAngle) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddPie(left + width / 2, top + height / 2, width / 2, height / 2,
- startAngle, sweepAngle);
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::AddSubpath(CFX_Path* path) {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->AddPathData(path->GetPathData());
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Path::Clear() {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- _generator->GetPathData()->SetPointCount(0);
- return FX_ERR_Succeeded;
-}
-FX_BOOL CFX_Path::IsEmpty() {
- _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
- if (_generator->GetPathData()->GetPointCount() == 0) {
- return TRUE;
- }
- return FALSE;
-}
-CFX_PathData* CFX_Path::GetPathData() {
- _FX_RETURN_VALUE_IF_FAIL(_generator, NULL);
- return _generator->GetPathData();
-}
-CFX_Color::CFX_Color() {
- _type = FX_COLOR_None;
-}
-CFX_Color::CFX_Color(const FX_ARGB argb) {
- _type = FX_COLOR_None;
- Set(argb);
-}
-CFX_Color::CFX_Color(CFX_Pattern* pattern, const FX_ARGB argb) {
- _type = FX_COLOR_None;
- Set(pattern, argb);
-}
-CFX_Color::CFX_Color(CFX_Shading* shading) {
- _type = FX_COLOR_None;
- Set(shading);
-}
-CFX_Color::~CFX_Color() {
- _type = FX_COLOR_None;
-}
-FX_ERR CFX_Color::Set(const FX_ARGB argb) {
- _type = FX_COLOR_Solid;
- _argb = argb;
- _pattern = NULL;
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) {
- _FX_RETURN_VALUE_IF_FAIL(pattern, FX_ERR_Parameter_Invalid);
- _type = FX_COLOR_Pattern;
- _argb = argb;
- _pattern = pattern;
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Color::Set(CFX_Shading* shading) {
- _FX_RETURN_VALUE_IF_FAIL(shading, FX_ERR_Parameter_Invalid);
- _type = FX_COLOR_Shading;
- _shading = shading;
- return FX_ERR_Succeeded;
-}
-CFX_Pattern::CFX_Pattern() {
- _type = FX_PATTERN_None;
- _matrix.SetIdentity();
-}
-FX_ERR CFX_Pattern::Create(CFX_DIBitmap* bitmap,
- const FX_FLOAT xStep,
- const FX_FLOAT yStep,
- CFX_Matrix* matrix) {
- _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Parameter_Invalid);
- if (_type != FX_PATTERN_None) {
- return FX_ERR_Property_Invalid;
- }
- _type = FX_PATTERN_Bitmap;
- _bitmap = bitmap;
- _x1Step = xStep;
- _y1Step = yStep;
- if (matrix) {
- _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
- matrix->f);
- }
- return FX_ERR_Succeeded;
-}
-FX_ERR CFX_Pattern::Create(FX_HatchStyle hatchStyle,
- const FX_ARGB foreArgb,
- const FX_ARGB backArgb,
- CFX_Matrix* matrix) {
- if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
- hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
- return FX_ERR_Parameter_Invalid;
- }
- if (_type != FX_PATTERN_None) {
- return FX_ERR_Property_Invalid;
- }
- _type = FX_PATTERN_Hatch;
- _hatchStyle = hatchStyle;
- _foreArgb = foreArgb;
- _backArgb = backArgb;
- if (matrix) {
- _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
- matrix->f);
- }
- return FX_ERR_Succeeded;
-}
-CFX_Pattern::~CFX_Pattern() {
- _type = FX_PATTERN_None;
-}
-CFX_Shading::CFX_Shading() {
- _type = FX_SHADING_None;
-}
-FX_ERR CFX_Shading::CreateAxial(const CFX_PointF& beginPoint,
- const CFX_PointF& endPoint,
- FX_BOOL isExtendedBegin,
- FX_BOOL isExtendedEnd,
- const FX_ARGB beginArgb,
- const FX_ARGB endArgb) {
- if (_type != FX_SHADING_None) {
- return FX_ERR_Property_Invalid;
- }
- _type = FX_SHADING_Axial;
- _beginPoint = beginPoint;
- _endPoint = endPoint;
- _isExtendedBegin = isExtendedBegin;
- _isExtendedEnd = isExtendedEnd;
- _beginArgb = beginArgb;
- _endArgb = endArgb;
- return InitArgbArray();
-}
-FX_ERR CFX_Shading::CreateRadial(const CFX_PointF& beginPoint,
- const CFX_PointF& endPoint,
- const FX_FLOAT beginRadius,
- const FX_FLOAT endRadius,
- FX_BOOL isExtendedBegin,
- FX_BOOL isExtendedEnd,
- const FX_ARGB beginArgb,
- const FX_ARGB endArgb) {
- if (_type != FX_SHADING_None) {
- return FX_ERR_Property_Invalid;
- }
- _type = FX_SHADING_Radial;
- _beginPoint = beginPoint;
- _endPoint = endPoint;
- _beginRadius = beginRadius;
- _endRadius = endRadius;
- _isExtendedBegin = isExtendedBegin;
- _isExtendedEnd = isExtendedEnd;
- _beginArgb = beginArgb;
- _endArgb = endArgb;
- return InitArgbArray();
-}
-CFX_Shading::~CFX_Shading() {
- _type = FX_SHADING_None;
-}
-FX_ERR CFX_Shading::InitArgbArray() {
- int32_t a1, r1, g1, b1;
- ArgbDecode(_beginArgb, a1, r1, g1, b1);
- int32_t a2, r2, g2, b2;
- ArgbDecode(_endArgb, a2, r2, g2, b2);
- FX_FLOAT f = (FX_FLOAT)(FX_SHADING_Steps - 1);
- FX_FLOAT aScale = (FX_FLOAT)(1.0 * (a2 - a1) / f);
- FX_FLOAT rScale = (FX_FLOAT)(1.0 * (r2 - r1) / f);
- FX_FLOAT gScale = (FX_FLOAT)(1.0 * (g2 - g1) / f);
- FX_FLOAT bScale = (FX_FLOAT)(1.0 * (b2 - b1) / f);
- int32_t a3, r3, g3, b3;
- for (int32_t i = 0; i < FX_SHADING_Steps; i++) {
- a3 = (int32_t)(i * aScale);
- r3 = (int32_t)(i * rScale);
- g3 = (int32_t)(i * gScale);
- b3 = (int32_t)(i * bScale);
- _argbArray[i] =
- FXARGB_TODIB(FXARGB_MAKE((a1 + a3), (r1 + r3), (g1 + g3), (b1 + b3)));
- }
- return FX_ERR_Succeeded;
-}
-class CFX_Pause : public IFX_Pause {
- public:
- virtual FX_BOOL NeedToPauseNow() { return TRUE; }
-};
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <memory>
+
+#include "fx_path_generator.h"
+#include "pre.h"
+
+class CAGG_Graphics {
+ public:
+ CAGG_Graphics();
+ FX_ERR Create(CFX_Graphics* owner,
+ int32_t width,
+ int32_t height,
+ FXDIB_Format format);
+ virtual ~CAGG_Graphics();
+
+ private:
+ CFX_Graphics* _owner;
+};
+CFX_Graphics::CFX_Graphics() {
+ _type = FX_CONTEXT_None;
+ _info._graphState.SetDashCount(0);
+ _info._isAntialiasing = TRUE;
+ _info._strokeAlignment = FX_STROKEALIGNMENT_Center;
+ _info._CTM.SetIdentity();
+ _info._isActOnDash = FALSE;
+ _info._strokeColor = NULL;
+ _info._fillColor = NULL;
+ _info._font = NULL;
+ _info._fontSize = 40.0;
+ _info._fontHScale = 1.0;
+ _info._fontSpacing = 0.0;
+ _renderDevice = NULL;
+ _aggGraphics = NULL;
+}
+FX_ERR CFX_Graphics::Create(CFX_RenderDevice* renderDevice,
+ FX_BOOL isAntialiasing) {
+ _FX_RETURN_VALUE_IF_FAIL(renderDevice, FX_ERR_Parameter_Invalid);
+ if (_type != FX_CONTEXT_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_CONTEXT_Device;
+ _info._isAntialiasing = isAntialiasing;
+ _renderDevice = renderDevice;
+ if (_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP) {
+ return FX_ERR_Succeeded;
+ }
+ return FX_ERR_Indefinite;
+}
+FX_ERR CFX_Graphics::Create(int32_t width,
+ int32_t height,
+ FXDIB_Format format,
+ FX_BOOL isNative,
+ FX_BOOL isAntialiasing) {
+ if (_type != FX_CONTEXT_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_CONTEXT_Device;
+ _info._isAntialiasing = isAntialiasing;
+ {
+ _aggGraphics = new CAGG_Graphics;
+ return _aggGraphics->Create(this, width, height, format);
+ }
+}
+CFX_Graphics::~CFX_Graphics() {
+ if (_aggGraphics) {
+ delete _aggGraphics;
+ _aggGraphics = NULL;
+ }
+ _renderDevice = NULL;
+ _info._graphState.SetDashCount(0);
+ _type = FX_CONTEXT_None;
+}
+FX_ERR CFX_Graphics::GetDeviceCap(const int32_t capID, FX_DeviceCap& capVal) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ capVal = _renderDevice->GetDeviceCaps(capID);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::IsPrinterDevice(FX_BOOL& isPrinter) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ int32_t deviceClass = _renderDevice->GetDeviceClass();
+ if (deviceClass == FXDC_PRINTER) {
+ isPrinter = TRUE;
+ } else {
+ isPrinter = FALSE;
+ }
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._isAntialiasing = isAntialiasing;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SaveGraphState() {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _renderDevice->SaveState();
+ TInfo* info = new TInfo;
+ info->_graphState.Copy(_info._graphState);
+ info->_isAntialiasing = _info._isAntialiasing;
+ info->_strokeAlignment = _info._strokeAlignment;
+ info->_CTM = _info._CTM;
+ info->_isActOnDash = _info._isActOnDash;
+ info->_strokeColor = _info._strokeColor;
+ info->_fillColor = _info._fillColor;
+ info->_font = _info._font;
+ info->_fontSize = _info._fontSize;
+ info->_fontHScale = _info._fontHScale;
+ info->_fontSpacing = _info._fontSpacing;
+ _infoStack.Add(info);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::RestoreGraphState() {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _renderDevice->RestoreState();
+ int32_t size = _infoStack.GetSize();
+ if (size <= 0) {
+ return FX_ERR_Intermediate_Value_Invalid;
+ }
+ int32_t topIndex = size - 1;
+ TInfo* info = (TInfo*)_infoStack.GetAt(topIndex);
+ _FX_RETURN_VALUE_IF_FAIL(info, FX_ERR_Intermediate_Value_Invalid);
+ _info._graphState.Copy(info->_graphState);
+ _info._isAntialiasing = info->_isAntialiasing;
+ _info._strokeAlignment = info->_strokeAlignment;
+ _info._CTM = info->_CTM;
+ _info._isActOnDash = info->_isActOnDash;
+ _info._strokeColor = info->_strokeColor;
+ _info._fillColor = info->_fillColor;
+ _info._font = info->_font;
+ _info._fontSize = info->_fontSize;
+ _info._fontHScale = info->_fontHScale;
+ _info._fontSpacing = info->_fontSpacing;
+ delete info;
+ info = NULL;
+ _infoStack.RemoveAt(topIndex);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap& lineCap) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ lineCap = _info._graphState.m_LineCap;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_LineCap = lineCap;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::GetDashCount(int32_t& dashCount) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ dashCount = _info._graphState.m_DashCount;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::GetLineDash(FX_FLOAT& dashPhase, FX_FLOAT* dashArray) {
+ _FX_RETURN_VALUE_IF_FAIL(dashArray, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ dashPhase = _info._graphState.m_DashPhase;
+ FXSYS_memcpy(dashArray, _info._graphState.m_DashArray,
+ _info._graphState.m_DashCount * sizeof(FX_FLOAT));
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetLineDash(FX_FLOAT dashPhase,
+ FX_FLOAT* dashArray,
+ int32_t dashCount) {
+ if (dashCount > 0 && !dashArray) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ dashCount = dashCount < 0 ? 0 : dashCount;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_FLOAT scale = 1.0;
+ if (_info._isActOnDash) {
+ scale = _info._graphState.m_LineWidth;
+ }
+ _info._graphState.m_DashPhase = dashPhase;
+ _info._graphState.SetDashCount(dashCount);
+ for (int32_t i = 0; i < dashCount; i++) {
+ _info._graphState.m_DashArray[i] = dashArray[i] * scale;
+ }
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceSetLineDash(dashStyle);
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::GetLineJoin(CFX_GraphStateData::LineJoin& lineJoin) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ lineJoin = _info._graphState.m_LineJoin;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_LineJoin = lineJoin;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::GetMiterLimit(FX_FLOAT& miterLimit) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ miterLimit = _info._graphState.m_MiterLimit;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_MiterLimit = miterLimit;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::GetLineWidth(FX_FLOAT& lineWidth) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ lineWidth = _info._graphState.m_LineWidth;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_LineWidth = lineWidth;
+ _info._isActOnDash = isActOnDash;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::GetStrokeAlignment(FX_StrokeAlignment& strokeAlignment) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ strokeAlignment = _info._strokeAlignment;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._strokeAlignment = strokeAlignment;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetStrokeColor(CFX_Color* color) {
+ _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._strokeColor = color;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetFillColor(CFX_Color* color) {
+ _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fillColor = color;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceStrokePath(path, matrix);
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::FillPath(CFX_Path* path,
+ FX_FillMode fillMode,
+ CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceFillPath(path, fillMode, matrix);
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::ClipPath(CFX_Path* path,
+ FX_FillMode fillMode,
+ CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_BOOL result = _renderDevice->SetClip_PathFill(
+ path->GetPathData(), (CFX_Matrix*)matrix, fillMode);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::DrawImage(CFX_DIBSource* source,
+ const CFX_PointF& point,
+ CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceDrawImage(source, point, matrix);
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::StretchImage(CFX_DIBSource* source,
+ const CFX_RectF& rect,
+ CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceStretchImage(source, rect, matrix);
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(matrix, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._CTM.Concat(*matrix);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+CFX_Matrix* CFX_Graphics::GetMatrix() {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, NULL);
+ return &_info._CTM;
+ }
+ default: { return NULL; }
+ }
+}
+FX_ERR CFX_Graphics::GetClipRect(CFX_RectF& rect) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_RECT r = _renderDevice->GetClipBox();
+ rect.left = (FX_FLOAT)r.left;
+ rect.top = (FX_FLOAT)r.top;
+ rect.width = (FX_FLOAT)r.Width();
+ rect.height = (FX_FLOAT)r.Height();
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetClipRect(const CFX_RectF& rect) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_RECT r(FXSYS_round(rect.left), FXSYS_round(rect.top),
+ FXSYS_round(rect.right()), FXSYS_round(rect.bottom()));
+ FX_BOOL result = _renderDevice->SetClip_Rect(&r);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::ClearClip() {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_BOOL result = FX_ERR_Succeeded;
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetFont(CFX_Font* font) {
+ _FX_RETURN_VALUE_IF_FAIL(font, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._font = font;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetFontSize(const FX_FLOAT size) {
+ FX_FLOAT fontSize = size <= 0 ? 1.0f : size;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fontSize = fontSize;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetFontHScale(const FX_FLOAT scale) {
+ FX_FLOAT fontHScale = scale <= 0 ? 1.0f : scale;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fontHScale = fontHScale;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing) {
+ FX_FLOAT fontSpacing = spacing < 0 ? 0 : spacing;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fontSpacing = fontSpacing;
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::SetTextDrawingMode(const int32_t mode) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::ShowText(const CFX_PointF& point,
+ const CFX_WideString& text,
+ CFX_Matrix* matrix) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceShowText(point, text, matrix);
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::CalcTextRect(CFX_RectF& rect,
+ const CFX_WideString& text,
+ FX_BOOL isMultiline,
+ CFX_Matrix* matrix) {
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ int32_t length = text.GetLength();
+ FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
+ FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
+ CalcTextInfo(text, charCodes, charPos, rect);
+ FX_Free(charPos);
+ FX_Free(charCodes);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
+ const CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
+ _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ {
+ _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
+ FX_ERR_Parameter_Invalid);
+ CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap();
+ FX_BOOL result = _renderDevice->SetDIBits(bitmap, 0, 0);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ }
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
+ FX_FLOAT srcLeft,
+ FX_FLOAT srcTop,
+ const CFX_RectF& dstRect,
+ const CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
+ _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ {
+ _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
+ FX_ERR_Parameter_Invalid);
+ CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap();
+ FX_BOOL result = FX_ERR_Indefinite;
+ CFX_DIBitmap bmp;
+ result = bmp.Create((int32_t)dstRect.width, (int32_t)dstRect.height,
+ bitmap->GetFormat());
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Intermediate_Value_Invalid);
+ result = graphics->_renderDevice->GetDIBits(&bmp, (int32_t)srcLeft,
+ (int32_t)srcTop);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ result = _renderDevice->SetDIBits(&bmp, (int32_t)dstRect.left,
+ (int32_t)dstRect.top);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ return FX_ERR_Succeeded;
+ }
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+CFX_RenderDevice* CFX_Graphics::GetRenderDevice() {
+ return _renderDevice;
+}
+FX_ERR CFX_Graphics::InverseRect(const CFX_RectF& rect) {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
+ _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Property_Invalid);
+ CFX_RectF temp(rect);
+ _info._CTM.TransformRect(temp);
+ CFX_RectF r;
+ r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth());
+ r.Intersect(temp);
+ if (r.IsEmpty()) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ FX_ARGB* pBuf =
+ (FX_ARGB*)(bitmap->GetBuffer() + int32_t(r.top) * bitmap->GetPitch());
+ int32_t bottom = (int32_t)r.bottom();
+ int32_t right = (int32_t)r.right();
+ for (int32_t i = (int32_t)r.top; i < bottom; i++) {
+ FX_ARGB* pLine = pBuf + (int32_t)r.left;
+ for (int32_t j = (int32_t)r.left; j < right; j++) {
+ FX_ARGB c = *pLine;
+ *pLine++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF));
+ }
+ pBuf = (FX_ARGB*)((uint8_t*)pBuf + bitmap->GetPitch());
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::XorDIBitmap(const CFX_DIBitmap* srcBitmap,
+ const CFX_RectF& rect) {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ CFX_DIBitmap* dst = _renderDevice->GetBitmap();
+ _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
+ CFX_RectF temp(rect);
+ _info._CTM.TransformRect(temp);
+ CFX_RectF r;
+ r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
+ r.Intersect(temp);
+ if (r.IsEmpty()) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
+ int32_t(r.top) * srcBitmap->GetPitch());
+ FX_ARGB* pDstBuf =
+ (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
+ int32_t bottom = (int32_t)r.bottom();
+ int32_t right = (int32_t)r.right();
+ for (int32_t i = (int32_t)r.top; i < bottom; i++) {
+ FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
+ FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
+ for (int32_t j = (int32_t)r.left; j < right; j++) {
+ FX_ARGB c = *pDstLine;
+ *pDstLine++ =
+ ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF));
+ pSrcLine++;
+ }
+ pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
+ pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap* srcBitmap,
+ const CFX_RectF& rect) {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ CFX_DIBitmap* dst = _renderDevice->GetBitmap();
+ _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
+ CFX_RectF temp(rect);
+ _info._CTM.TransformRect(temp);
+ CFX_RectF r;
+ r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
+ r.Intersect(temp);
+ if (r.IsEmpty()) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
+ int32_t(r.top) * srcBitmap->GetPitch());
+ FX_ARGB* pDstBuf =
+ (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
+ int32_t bottom = (int32_t)r.bottom();
+ int32_t right = (int32_t)r.right();
+ for (int32_t i = (int32_t)r.top; i < bottom; i++) {
+ FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
+ FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
+ for (int32_t j = (int32_t)r.left; j < right; j++) {
+ FX_ARGB c = *pDstLine;
+ *pDstLine++ =
+ ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)));
+ pSrcLine++;
+ }
+ pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
+ pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) {
+ switch (dashStyle) {
+ case FX_DASHSTYLE_Solid: {
+ _info._graphState.SetDashCount(0);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_Dash: {
+ FX_FLOAT dashArray[] = {3, 1};
+ SetLineDash(0, dashArray, 2);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_Dot: {
+ FX_FLOAT dashArray[] = {1, 1};
+ SetLineDash(0, dashArray, 2);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_DashDot: {
+ FX_FLOAT dashArray[] = {3, 1, 1, 1};
+ SetLineDash(0, dashArray, 4);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_DashDotDot: {
+ FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
+ SetLineDash(0, dashArray, 6);
+ return FX_ERR_Succeeded;
+ }
+ default: { return FX_ERR_Parameter_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path,
+ CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(_info._strokeColor, FX_ERR_Property_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
+ _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_info._strokeColor->_type) {
+ case FX_COLOR_Solid: {
+ FX_BOOL result = _renderDevice->DrawPath(
+ path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState, 0x0,
+ _info._strokeColor->_argb, 0);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ return FX_ERR_Succeeded;
+ }
+ case FX_COLOR_Pattern: {
+ return StrokePathWithPattern(path, &m);
+ }
+ case FX_COLOR_Shading: {
+ return StrokePathWithShading(path, &m);
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::RenderDeviceFillPath(CFX_Path* path,
+ FX_FillMode fillMode,
+ CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(_info._fillColor, FX_ERR_Property_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
+ _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_info._fillColor->_type) {
+ case FX_COLOR_Solid: {
+ FX_BOOL result = _renderDevice->DrawPath(
+ path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState,
+ _info._fillColor->_argb, 0x0, fillMode);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ return FX_ERR_Succeeded;
+ }
+ case FX_COLOR_Pattern: {
+ { return FillPathWithPattern(path, fillMode, &m); }
+ }
+ case FX_COLOR_Shading: {
+ { return FillPathWithShading(path, fillMode, &m); }
+ }
+ default: { return FX_ERR_Property_Invalid; }
+ }
+}
+FX_ERR CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource* source,
+ const CFX_PointF& point,
+ CFX_Matrix* matrix) {
+ CFX_Matrix m1;
+ m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
+ _info._CTM.f);
+ if (matrix) {
+ m1.Concat(*matrix);
+ }
+ CFX_Matrix m2;
+ m2.Set((FX_FLOAT)source->GetWidth(), 0.0, 0.0, (FX_FLOAT)source->GetHeight(),
+ point.x, point.y);
+ m2.Concat(m1);
+ int32_t left, top;
+ CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE);
+ CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m2, left, top);
+ CFX_RectF r;
+ GetClipRect(r);
+ FX_ERR result = FX_ERR_Indefinite;
+ {
+ CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
+ CFX_DIBitmap bmp;
+ bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb);
+ _renderDevice->GetDIBits(&bmp, 0, 0);
+ bmp.TransferBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
+ FXSYS_round(r.Width()), FXSYS_round(r.Height()), bmp2,
+ FXSYS_round(r.left - left), FXSYS_round(r.top - top));
+ _renderDevice->SetDIBits(&bmp, 0, 0);
+ result = FX_ERR_Succeeded;
+ }
+ if (bmp2) {
+ delete bmp2;
+ bmp2 = NULL;
+ }
+ if (bmp1) {
+ delete bmp1;
+ bmp1 = NULL;
+ }
+ return result;
+}
+FX_ERR CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source,
+ const CFX_RectF& rect,
+ CFX_Matrix* matrix) {
+ CFX_Matrix m1;
+ m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
+ _info._CTM.f);
+ if (matrix) {
+ m1.Concat(*matrix);
+ }
+ CFX_DIBitmap* bmp1 =
+ source->StretchTo((int32_t)rect.Width(), (int32_t)rect.Height());
+ CFX_Matrix m2;
+ m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top);
+ m2.Concat(m1);
+ int32_t left, top;
+ CFX_DIBitmap* bmp2 = bmp1->FlipImage(FALSE, TRUE);
+ CFX_DIBitmap* bmp3 = bmp2->TransformTo((CFX_Matrix*)&m2, left, top);
+ CFX_RectF r;
+ GetClipRect(r);
+ FX_ERR result = FX_ERR_Indefinite;
+ {
+ CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
+ bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
+ FXSYS_round(r.Width()), FXSYS_round(r.Height()),
+ bmp3, FXSYS_round(r.left - left),
+ FXSYS_round(r.top - top));
+ result = FX_ERR_Succeeded;
+ }
+ if (bmp3) {
+ delete bmp3;
+ bmp3 = NULL;
+ }
+ if (bmp2) {
+ delete bmp2;
+ bmp2 = NULL;
+ }
+ if (bmp1) {
+ delete bmp1;
+ bmp1 = NULL;
+ }
+ return result;
+}
+FX_ERR CFX_Graphics::RenderDeviceShowText(const CFX_PointF& point,
+ const CFX_WideString& text,
+ CFX_Matrix* matrix) {
+ int32_t length = text.GetLength();
+ FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
+ FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
+ CFX_RectF rect;
+ rect.Set(point.x, point.y, 0, 0);
+ CalcTextInfo(text, charCodes, charPos, rect);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
+ _info._CTM.f);
+ m.Translate(0, _info._fontSize * _info._fontHScale);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ FX_BOOL result = _renderDevice->DrawNormalText(
+ length, charPos, _info._font, CFX_GEModule::Get()->GetFontCache(),
+ -_info._fontSize * _info._fontHScale, (CFX_Matrix*)&m,
+ _info._fillColor->_argb, FXTEXT_CLEARTYPE);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ FX_Free(charPos);
+ FX_Free(charCodes);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::StrokePathWithPattern(CFX_Path* path, CFX_Matrix* matrix) {
+ return FX_ERR_Method_Not_Supported;
+}
+FX_ERR CFX_Graphics::StrokePathWithShading(CFX_Path* path, CFX_Matrix* matrix) {
+ return FX_ERR_Method_Not_Supported;
+}
+FX_ERR CFX_Graphics::FillPathWithPattern(CFX_Path* path,
+ FX_FillMode fillMode,
+ CFX_Matrix* matrix) {
+ CFX_Pattern* pattern = _info._fillColor->_pattern;
+ CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
+ int32_t width = bitmap->GetWidth();
+ int32_t height = bitmap->GetHeight();
+ CFX_DIBitmap bmp;
+ bmp.Create(width, height, FXDIB_Argb);
+ _renderDevice->GetDIBits(&bmp, 0, 0);
+ switch (pattern->_type) {
+ case FX_PATTERN_Bitmap: {
+ int32_t xStep = FXSYS_round(pattern->_x1Step);
+ int32_t yStep = FXSYS_round(pattern->_y1Step);
+ int32_t xCount = width / xStep + 1;
+ int32_t yCount = height / yStep + 1;
+ for (int32_t i = 0; i <= yCount; i++) {
+ for (int32_t j = 0; j <= xCount; j++) {
+ bmp.TransferBitmap(j * xStep, i * yStep, xStep, yStep,
+ pattern->_bitmap, 0, 0);
+ }
+ }
+ break;
+ }
+ case FX_PATTERN_Hatch: {
+ FX_HatchStyle hatchStyle = _info._fillColor->_pattern->_hatchStyle;
+ if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
+ hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
+ return FX_ERR_Intermediate_Value_Invalid;
+ }
+ const FX_HATCHDATA& data = hatchBitmapData[hatchStyle];
+ CFX_DIBitmap mask;
+ mask.Create(data.width, data.height, FXDIB_1bppMask);
+ FXSYS_memcpy(mask.GetBuffer(), data.maskBits,
+ mask.GetPitch() * data.height);
+ CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox();
+ if (matrix) {
+ rectf.Transform((const CFX_Matrix*)matrix);
+ }
+ FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
+ FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
+ CFX_FxgeDevice device;
+ device.Attach(&bmp);
+ device.FillRect(&rect, _info._fillColor->_pattern->_backArgb);
+ for (int32_t j = rect.bottom; j < rect.top; j += mask.GetHeight()) {
+ for (int32_t i = rect.left; i < rect.right; i += mask.GetWidth()) {
+ device.SetBitMask(&mask, i, j, _info._fillColor->_pattern->_foreArgb);
+ }
+ }
+ break;
+ }
+ }
+ _renderDevice->SaveState();
+ _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
+ fillMode);
+ SetDIBitsWithMatrix(&bmp, &pattern->_matrix);
+ _renderDevice->RestoreState();
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::FillPathWithShading(CFX_Path* path,
+ FX_FillMode fillMode,
+ CFX_Matrix* matrix) {
+ CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
+ int32_t width = bitmap->GetWidth();
+ int32_t height = bitmap->GetHeight();
+ FX_FLOAT start_x = _info._fillColor->_shading->_beginPoint.x;
+ FX_FLOAT start_y = _info._fillColor->_shading->_beginPoint.y;
+ FX_FLOAT end_x = _info._fillColor->_shading->_endPoint.x;
+ FX_FLOAT end_y = _info._fillColor->_shading->_endPoint.y;
+ CFX_DIBitmap bmp;
+ bmp.Create(width, height, FXDIB_Argb);
+ _renderDevice->GetDIBits(&bmp, 0, 0);
+ int32_t pitch = bmp.GetPitch();
+ FX_BOOL result = FALSE;
+ switch (_info._fillColor->_shading->_type) {
+ case FX_SHADING_Axial: {
+ FX_FLOAT x_span = end_x - start_x;
+ FX_FLOAT y_span = end_y - start_y;
+ FX_FLOAT axis_len_square =
+ FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span);
+ for (int32_t row = 0; row < height; row++) {
+ FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
+ for (int32_t column = 0; column < width; column++) {
+ FX_FLOAT x = (FX_FLOAT)(column);
+ FX_FLOAT y = (FX_FLOAT)(row);
+ FX_FLOAT scale = FXSYS_Div(
+ FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span),
+ axis_len_square);
+ if (scale < 0) {
+ if (!_info._fillColor->_shading->_isExtendedBegin) {
+ continue;
+ }
+ scale = 0;
+ } else if (scale > 1.0f) {
+ if (!_info._fillColor->_shading->_isExtendedEnd) {
+ continue;
+ }
+ scale = 1.0f;
+ }
+ int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1));
+ dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
+ }
+ }
+ result = TRUE;
+ break;
+ }
+ case FX_SHADING_Radial: {
+ FX_FLOAT start_r = _info._fillColor->_shading->_beginRadius;
+ FX_FLOAT end_r = _info._fillColor->_shading->_endRadius;
+ 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);
+ for (int32_t row = 0; row < height; row++) {
+ FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
+ for (int32_t column = 0; column < width; column++) {
+ FX_FLOAT x = (FX_FLOAT)(column);
+ FX_FLOAT y = (FX_FLOAT)(row);
+ FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) +
+ FXSYS_Mul(y - start_y, end_y - start_y) +
+ FXSYS_Mul(start_r, end_r - start_r));
+ FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) +
+ FXSYS_Mul(y - start_y, y - start_y) -
+ FXSYS_Mul(start_r, start_r);
+ FX_FLOAT s;
+ if (a == 0) {
+ s = (FXSYS_Div(-c, b));
+ } else {
+ FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
+ if (b2_4ac < 0) {
+ continue;
+ }
+ FX_FLOAT root = (FXSYS_sqrt(b2_4ac));
+ FX_FLOAT s1, s2;
+ if (a > 0) {
+ s1 = FXSYS_Div(-b - root, 2 * a);
+ s2 = FXSYS_Div(-b + root, 2 * a);
+ } else {
+ s2 = FXSYS_Div(-b - root, 2 * a);
+ s1 = FXSYS_Div(-b + root, 2 * a);
+ }
+ if (s2 <= 1.0f || _info._fillColor->_shading->_isExtendedEnd) {
+ s = (s2);
+ } else {
+ s = (s1);
+ }
+ if ((start_r) + s * (end_r - start_r) < 0) {
+ continue;
+ }
+ }
+ if (s < 0) {
+ if (!_info._fillColor->_shading->_isExtendedBegin) {
+ continue;
+ }
+ s = 0;
+ }
+ if (s > 1.0f) {
+ if (!_info._fillColor->_shading->_isExtendedEnd) {
+ continue;
+ }
+ s = 1.0f;
+ }
+ int index = (int32_t)(s * (FX_SHADING_Steps - 1));
+ dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
+ }
+ }
+ result = TRUE;
+ break;
+ }
+ default: { result = FALSE; }
+ }
+ if (result) {
+ _renderDevice->SaveState();
+ _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
+ fillMode);
+ SetDIBitsWithMatrix(&bmp, matrix);
+ _renderDevice->RestoreState();
+ }
+ return result;
+}
+FX_ERR CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source,
+ CFX_Matrix* matrix) {
+ if (matrix->IsIdentity()) {
+ _renderDevice->SetDIBits(source, 0, 0);
+ } else {
+ CFX_Matrix m;
+ m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0,
+ 0);
+ m.Concat(*matrix);
+ int32_t left, top;
+ CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE);
+ CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m, left, top);
+ _renderDevice->SetDIBits(bmp2, left, top);
+ if (bmp2) {
+ delete bmp2;
+ bmp2 = NULL;
+ }
+ if (bmp1) {
+ delete bmp1;
+ bmp1 = NULL;
+ }
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::CalcTextInfo(const CFX_WideString& text,
+ FX_DWORD* charCodes,
+ FXTEXT_CHARPOS* charPos,
+ CFX_RectF& rect) {
+ std::unique_ptr<CFX_UnicodeEncoding> encoding(
+ new CFX_UnicodeEncoding(_info._font));
+ int32_t length = text.GetLength();
+ FX_FLOAT penX = (FX_FLOAT)rect.left;
+ FX_FLOAT penY = (FX_FLOAT)rect.top;
+ FX_FLOAT left = (FX_FLOAT)(0);
+ FX_FLOAT top = (FX_FLOAT)(0);
+ charCodes[0] = text.GetAt(0);
+ charPos[0].m_OriginX = penX + left;
+ charPos[0].m_OriginY = penY + top;
+ charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]);
+ charPos[0].m_FontCharWidth = FXSYS_round(
+ _info._font->GetGlyphWidth(charPos[0].m_GlyphIndex) * _info._fontHScale);
+ charPos[0].m_bGlyphAdjust = TRUE;
+ charPos[0].m_AdjustMatrix[0] = -1;
+ charPos[0].m_AdjustMatrix[1] = 0;
+ charPos[0].m_AdjustMatrix[2] = 0;
+ charPos[0].m_AdjustMatrix[3] = 1;
+ penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * _info._fontSize / 1000 +
+ _info._fontSpacing;
+ for (int32_t i = 1; i < length; i++) {
+ charCodes[i] = text.GetAt(i);
+ charPos[i].m_OriginX = penX + left;
+ charPos[i].m_OriginY = penY + top;
+ charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]);
+ charPos[i].m_FontCharWidth =
+ FXSYS_round(_info._font->GetGlyphWidth(charPos[i].m_GlyphIndex) *
+ _info._fontHScale);
+ charPos[i].m_bGlyphAdjust = TRUE;
+ charPos[i].m_AdjustMatrix[0] = -1;
+ charPos[i].m_AdjustMatrix[1] = 0;
+ charPos[i].m_AdjustMatrix[2] = 0;
+ charPos[i].m_AdjustMatrix[3] = 1;
+ penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * _info._fontSize / 1000 +
+ _info._fontSpacing;
+ }
+ rect.width = (FX_FLOAT)penX - rect.left;
+ rect.height = rect.top + _info._fontSize * _info._fontHScale - rect.top;
+ return FX_ERR_Succeeded;
+}
+CAGG_Graphics::CAGG_Graphics() {
+ _owner = NULL;
+}
+FX_ERR CAGG_Graphics::Create(CFX_Graphics* owner,
+ int32_t width,
+ int32_t height,
+ FXDIB_Format format) {
+ if (owner->_renderDevice) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ if (_owner) {
+ return FX_ERR_Property_Invalid;
+ }
+ CFX_FxgeDevice* device = new CFX_FxgeDevice;
+ device->Create(width, height, format);
+ _owner = owner;
+ _owner->_renderDevice = device;
+ _owner->_renderDevice->GetBitmap()->Clear(0xFFFFFFFF);
+ return FX_ERR_Succeeded;
+}
+CAGG_Graphics::~CAGG_Graphics() {
+ if (_owner->_renderDevice) {
+ delete (CFX_FxgeDevice*)_owner->_renderDevice;
+ }
+ _owner = NULL;
+}
+CFX_Path::CFX_Path() {
+ _generator = NULL;
+}
+FX_ERR CFX_Path::Create() {
+ if (_generator) {
+ return FX_ERR_Property_Invalid;
+ }
+ _generator = new CFX_PathGenerator;
+ _generator->Create();
+ return FX_ERR_Succeeded;
+}
+CFX_Path::~CFX_Path() {
+ if (_generator) {
+ delete _generator;
+ _generator = NULL;
+ }
+}
+FX_ERR CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->MoveTo(x, y);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->LineTo(x, y);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::BezierTo(FX_FLOAT ctrlX1,
+ FX_FLOAT ctrlY1,
+ FX_FLOAT ctrlX2,
+ FX_FLOAT ctrlY2,
+ FX_FLOAT toX,
+ FX_FLOAT toY) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::ArcTo(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->ArcTo(left + width / 2, top + height / 2, width / 2, height / 2,
+ startAngle, sweepAngle);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::Close() {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->Close();
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddLine(x1, y1, x2, y2);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddBezier(FX_FLOAT startX,
+ FX_FLOAT startY,
+ FX_FLOAT ctrlX1,
+ FX_FLOAT ctrlY1,
+ FX_FLOAT ctrlX2,
+ FX_FLOAT ctrlY2,
+ FX_FLOAT endX,
+ FX_FLOAT endY) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX,
+ endY);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddRectangle(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddRectangle(left, top, left + width, top + height);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddEllipse(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddEllipse(left + width / 2, top + height / 2, width / 2,
+ height / 2);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddEllipse(const CFX_RectF& rect) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddEllipse(rect.left + rect.Width() / 2,
+ rect.top + rect.Height() / 2, rect.Width() / 2,
+ rect.Height() / 2);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddArc(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddArc(left + width / 2, top + height / 2, width / 2, height / 2,
+ startAngle, sweepAngle);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddPie(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddPie(left + width / 2, top + height / 2, width / 2, height / 2,
+ startAngle, sweepAngle);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddSubpath(CFX_Path* path) {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddPathData(path->GetPathData());
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::Clear() {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->GetPathData()->SetPointCount(0);
+ return FX_ERR_Succeeded;
+}
+FX_BOOL CFX_Path::IsEmpty() {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ if (_generator->GetPathData()->GetPointCount() == 0) {
+ return TRUE;
+ }
+ return FALSE;
+}
+CFX_PathData* CFX_Path::GetPathData() {
+ _FX_RETURN_VALUE_IF_FAIL(_generator, NULL);
+ return _generator->GetPathData();
+}
+CFX_Color::CFX_Color() {
+ _type = FX_COLOR_None;
+}
+CFX_Color::CFX_Color(const FX_ARGB argb) {
+ _type = FX_COLOR_None;
+ Set(argb);
+}
+CFX_Color::CFX_Color(CFX_Pattern* pattern, const FX_ARGB argb) {
+ _type = FX_COLOR_None;
+ Set(pattern, argb);
+}
+CFX_Color::CFX_Color(CFX_Shading* shading) {
+ _type = FX_COLOR_None;
+ Set(shading);
+}
+CFX_Color::~CFX_Color() {
+ _type = FX_COLOR_None;
+}
+FX_ERR CFX_Color::Set(const FX_ARGB argb) {
+ _type = FX_COLOR_Solid;
+ _argb = argb;
+ _pattern = NULL;
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) {
+ _FX_RETURN_VALUE_IF_FAIL(pattern, FX_ERR_Parameter_Invalid);
+ _type = FX_COLOR_Pattern;
+ _argb = argb;
+ _pattern = pattern;
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Color::Set(CFX_Shading* shading) {
+ _FX_RETURN_VALUE_IF_FAIL(shading, FX_ERR_Parameter_Invalid);
+ _type = FX_COLOR_Shading;
+ _shading = shading;
+ return FX_ERR_Succeeded;
+}
+CFX_Pattern::CFX_Pattern() {
+ _type = FX_PATTERN_None;
+ _matrix.SetIdentity();
+}
+FX_ERR CFX_Pattern::Create(CFX_DIBitmap* bitmap,
+ const FX_FLOAT xStep,
+ const FX_FLOAT yStep,
+ CFX_Matrix* matrix) {
+ _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Parameter_Invalid);
+ if (_type != FX_PATTERN_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_PATTERN_Bitmap;
+ _bitmap = bitmap;
+ _x1Step = xStep;
+ _y1Step = yStep;
+ if (matrix) {
+ _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
+ matrix->f);
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Pattern::Create(FX_HatchStyle hatchStyle,
+ const FX_ARGB foreArgb,
+ const FX_ARGB backArgb,
+ CFX_Matrix* matrix) {
+ if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
+ hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ if (_type != FX_PATTERN_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_PATTERN_Hatch;
+ _hatchStyle = hatchStyle;
+ _foreArgb = foreArgb;
+ _backArgb = backArgb;
+ if (matrix) {
+ _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
+ matrix->f);
+ }
+ return FX_ERR_Succeeded;
+}
+CFX_Pattern::~CFX_Pattern() {
+ _type = FX_PATTERN_None;
+}
+CFX_Shading::CFX_Shading() {
+ _type = FX_SHADING_None;
+}
+FX_ERR CFX_Shading::CreateAxial(const CFX_PointF& beginPoint,
+ const CFX_PointF& endPoint,
+ FX_BOOL isExtendedBegin,
+ FX_BOOL isExtendedEnd,
+ const FX_ARGB beginArgb,
+ const FX_ARGB endArgb) {
+ if (_type != FX_SHADING_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_SHADING_Axial;
+ _beginPoint = beginPoint;
+ _endPoint = endPoint;
+ _isExtendedBegin = isExtendedBegin;
+ _isExtendedEnd = isExtendedEnd;
+ _beginArgb = beginArgb;
+ _endArgb = endArgb;
+ return InitArgbArray();
+}
+FX_ERR CFX_Shading::CreateRadial(const CFX_PointF& beginPoint,
+ const CFX_PointF& endPoint,
+ const FX_FLOAT beginRadius,
+ const FX_FLOAT endRadius,
+ FX_BOOL isExtendedBegin,
+ FX_BOOL isExtendedEnd,
+ const FX_ARGB beginArgb,
+ const FX_ARGB endArgb) {
+ if (_type != FX_SHADING_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_SHADING_Radial;
+ _beginPoint = beginPoint;
+ _endPoint = endPoint;
+ _beginRadius = beginRadius;
+ _endRadius = endRadius;
+ _isExtendedBegin = isExtendedBegin;
+ _isExtendedEnd = isExtendedEnd;
+ _beginArgb = beginArgb;
+ _endArgb = endArgb;
+ return InitArgbArray();
+}
+CFX_Shading::~CFX_Shading() {
+ _type = FX_SHADING_None;
+}
+FX_ERR CFX_Shading::InitArgbArray() {
+ int32_t a1, r1, g1, b1;
+ ArgbDecode(_beginArgb, a1, r1, g1, b1);
+ int32_t a2, r2, g2, b2;
+ ArgbDecode(_endArgb, a2, r2, g2, b2);
+ FX_FLOAT f = (FX_FLOAT)(FX_SHADING_Steps - 1);
+ FX_FLOAT aScale = (FX_FLOAT)(1.0 * (a2 - a1) / f);
+ FX_FLOAT rScale = (FX_FLOAT)(1.0 * (r2 - r1) / f);
+ FX_FLOAT gScale = (FX_FLOAT)(1.0 * (g2 - g1) / f);
+ FX_FLOAT bScale = (FX_FLOAT)(1.0 * (b2 - b1) / f);
+ int32_t a3, r3, g3, b3;
+ for (int32_t i = 0; i < FX_SHADING_Steps; i++) {
+ a3 = (int32_t)(i * aScale);
+ r3 = (int32_t)(i * rScale);
+ g3 = (int32_t)(i * gScale);
+ b3 = (int32_t)(i * bScale);
+ _argbArray[i] =
+ FXARGB_TODIB(FXARGB_MAKE((a1 + a3), (r1 + r3), (g1 + g3), (b1 + b3)));
+ }
+ return FX_ERR_Succeeded;
+}
+class CFX_Pause : public IFX_Pause {
+ public:
+ virtual FX_BOOL NeedToPauseNow() { return TRUE; }
+};