Index: xfa/src/fxgraphics/src/fx_graphics.cpp |
diff --git a/xfa/src/fxgraphics/src/fx_graphics.cpp b/xfa/src/fxgraphics/src/fx_graphics.cpp |
index 69069817aa02de5aa944778da1d1129752dfed79..fae8aab006e03f77c5365376da5cc5c7656e730a 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; } |
+}; |