From 2b918c8d05c922287efbc8858f029026cee31442 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Thu, 13 Jul 2017 14:47:10 -0400 Subject: Fixup naming of XFA graphics classes These files were originally renamed thinking they'd move with the colour class up to core/. It was decided that CPWL_Color was a better core colour class the the xfa colour so these are being renamed back to XFA based names to make it clear where they live. Change-Id: Ie89f2306be0609add29bd445e719567e7b439211 Reviewed-on: https://pdfium-review.googlesource.com/7754 Reviewed-by: Tom Sepez Commit-Queue: dsinclair --- xfa/fxgraphics/cfx_graphics.cpp | 535 -------------------------------------- xfa/fxgraphics/cfx_graphics.h | 111 -------- xfa/fxgraphics/cfx_path.cpp | 148 ----------- xfa/fxgraphics/cfx_path.h | 55 ---- xfa/fxgraphics/cfx_pattern.cpp | 20 -- xfa/fxgraphics/cfx_pattern.h | 36 --- xfa/fxgraphics/cfx_shading.cpp | 78 ------ xfa/fxgraphics/cfx_shading.h | 56 ---- xfa/fxgraphics/cxfa_color.cpp | 8 +- xfa/fxgraphics/cxfa_color.h | 20 +- xfa/fxgraphics/cxfa_graphics.cpp | 536 +++++++++++++++++++++++++++++++++++++++ xfa/fxgraphics/cxfa_graphics.h | 111 ++++++++ xfa/fxgraphics/cxfa_path.cpp | 148 +++++++++++ xfa/fxgraphics/cxfa_path.h | 55 ++++ xfa/fxgraphics/cxfa_pattern.cpp | 20 ++ xfa/fxgraphics/cxfa_pattern.h | 36 +++ xfa/fxgraphics/cxfa_shading.cpp | 78 ++++++ xfa/fxgraphics/cxfa_shading.h | 56 ++++ 18 files changed, 1054 insertions(+), 1053 deletions(-) delete mode 100644 xfa/fxgraphics/cfx_graphics.cpp delete mode 100644 xfa/fxgraphics/cfx_graphics.h delete mode 100644 xfa/fxgraphics/cfx_path.cpp delete mode 100644 xfa/fxgraphics/cfx_path.h delete mode 100644 xfa/fxgraphics/cfx_pattern.cpp delete mode 100644 xfa/fxgraphics/cfx_pattern.h delete mode 100644 xfa/fxgraphics/cfx_shading.cpp delete mode 100644 xfa/fxgraphics/cfx_shading.h create mode 100644 xfa/fxgraphics/cxfa_graphics.cpp create mode 100644 xfa/fxgraphics/cxfa_graphics.h create mode 100644 xfa/fxgraphics/cxfa_path.cpp create mode 100644 xfa/fxgraphics/cxfa_path.h create mode 100644 xfa/fxgraphics/cxfa_pattern.cpp create mode 100644 xfa/fxgraphics/cxfa_pattern.h create mode 100644 xfa/fxgraphics/cxfa_shading.cpp create mode 100644 xfa/fxgraphics/cxfa_shading.h (limited to 'xfa/fxgraphics') diff --git a/xfa/fxgraphics/cfx_graphics.cpp b/xfa/fxgraphics/cfx_graphics.cpp deleted file mode 100644 index 0865221aa9..0000000000 --- a/xfa/fxgraphics/cfx_graphics.cpp +++ /dev/null @@ -1,535 +0,0 @@ -// 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 "xfa/fxgraphics/cfx_graphics.h" - -#include - -#include "core/fxge/cfx_defaultrenderdevice.h" -#include "core/fxge/cfx_renderdevice.h" -#include "core/fxge/cfx_unicodeencoding.h" -#include "third_party/base/ptr_util.h" -#include "xfa/fxgraphics/cfx_path.h" -#include "xfa/fxgraphics/cfx_pattern.h" -#include "xfa/fxgraphics/cfx_shading.h" -#include "xfa/fxgraphics/cxfa_color.h" - -namespace { - -enum { - FX_CONTEXT_None = 0, - FX_CONTEXT_Device, -}; - -#define FX_HATCHSTYLE_Total 53 - -struct FX_HATCHDATA { - int32_t width; - int32_t height; - uint8_t maskBits[64]; -}; - -const FX_HATCHDATA hatchBitmapData[FX_HATCHSTYLE_Total] = { - {16, // Horizontal - 16, - { - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }}, - {16, // Vertical - 16, - { - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, - 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, - 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, - 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, - 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - }}, - {16, // ForwardDiagonal - 16, - { - 0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, - 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, - 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, - 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - }}, - {16, // BackwardDiagonal - 16, - { - 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, - 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, - 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - }}, - {16, // Cross - 16, - { - 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, - 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, - 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, - 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, - 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - }}, - {16, // DiagonalCross - 16, - { - 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, - 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, - 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, - 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, - }}, -}; - -} // namespace - -CFX_Graphics::CFX_Graphics(CFX_RenderDevice* renderDevice) - : m_type(FX_CONTEXT_None), m_renderDevice(renderDevice) { - if (!renderDevice) - return; - m_type = FX_CONTEXT_Device; -} - -CFX_Graphics::~CFX_Graphics() {} - -void CFX_Graphics::SaveGraphState() { - if (m_type != FX_CONTEXT_Device || !m_renderDevice) - return; - - m_renderDevice->SaveState(); - m_infoStack.push_back(pdfium::MakeUnique(m_info)); -} - -void CFX_Graphics::RestoreGraphState() { - if (m_type != FX_CONTEXT_Device || !m_renderDevice) - return; - - m_renderDevice->RestoreState(false); - if (m_infoStack.empty() || !m_infoStack.back()) - return; - - m_info = *m_infoStack.back(); - m_infoStack.pop_back(); - return; -} - -void CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.graphState.m_LineCap = lineCap; - } -} - -void CFX_Graphics::SetLineDash(float dashPhase, - float* dashArray, - int32_t dashCount) { - if (dashCount > 0 && !dashArray) - return; - - dashCount = dashCount < 0 ? 0 : dashCount; - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - float scale = 1.0; - if (m_info.isActOnDash) { - scale = m_info.graphState.m_LineWidth; - } - m_info.graphState.m_DashPhase = dashPhase; - m_info.graphState.SetDashCount(dashCount); - for (int32_t i = 0; i < dashCount; i++) { - m_info.graphState.m_DashArray[i] = dashArray[i] * scale; - } - } -} - -void CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) - RenderDeviceSetLineDash(dashStyle); -} - -void CFX_Graphics::SetLineWidth(float lineWidth, bool isActOnDash) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.graphState.m_LineWidth = lineWidth; - m_info.isActOnDash = isActOnDash; - } -} - -void CFX_Graphics::SetStrokeColor(CXFA_Color* color) { - if (!color) - return; - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.strokeColor = color; - } -} - -void CFX_Graphics::SetFillColor(CXFA_Color* color) { - if (!color) - return; - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.fillColor = color; - } -} - -void CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) { - if (!path) - return; - if (m_type == FX_CONTEXT_Device && m_renderDevice) - RenderDeviceStrokePath(path, matrix); -} - -void CFX_Graphics::FillPath(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { - if (!path) - return; - if (m_type == FX_CONTEXT_Device && m_renderDevice) - RenderDeviceFillPath(path, fillMode, matrix); -} - -void CFX_Graphics::StretchImage(const CFX_RetainPtr& source, - const CFX_RectF& rect, - CFX_Matrix* matrix) { - if (!source) - return; - if (m_type == FX_CONTEXT_Device && m_renderDevice) - RenderDeviceStretchImage(source, rect, matrix); -} - -void CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) { - if (!matrix) - return; - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.CTM.Concat(*matrix); - } -} - -CFX_Matrix* CFX_Graphics::GetMatrix() { - if (m_type == FX_CONTEXT_Device && m_renderDevice) - return &m_info.CTM; - return nullptr; -} - -CFX_RectF CFX_Graphics::GetClipRect() const { - if (m_type != FX_CONTEXT_Device || !m_renderDevice) - return CFX_RectF(); - - FX_RECT r = m_renderDevice->GetClipBox(); - return CFX_Rect(r.left, r.top, r.Width(), r.Height()).As(); -} - -void CFX_Graphics::SetClipRect(const CFX_RectF& rect) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_renderDevice->SetClip_Rect( - FX_RECT(FXSYS_round(rect.left), FXSYS_round(rect.top), - FXSYS_round(rect.right()), FXSYS_round(rect.bottom()))); - } -} - -CFX_RenderDevice* CFX_Graphics::GetRenderDevice() { - return m_renderDevice; -} - -void CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) { - switch (dashStyle) { - case FX_DASHSTYLE_Solid: { - m_info.graphState.SetDashCount(0); - return; - } - case FX_DASHSTYLE_Dash: { - float dashArray[] = {3, 1}; - SetLineDash(0, dashArray, 2); - return; - } - case FX_DASHSTYLE_Dot: { - float dashArray[] = {1, 1}; - SetLineDash(0, dashArray, 2); - return; - } - case FX_DASHSTYLE_DashDot: { - float dashArray[] = {3, 1, 1, 1}; - SetLineDash(0, dashArray, 4); - return; - } - case FX_DASHSTYLE_DashDotDot: { - float dashArray[] = {4, 1, 2, 1, 2, 1}; - SetLineDash(0, dashArray, 6); - return; - } - default: - return; - } -} - -void CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path, CFX_Matrix* matrix) { - if (!m_info.strokeColor) - return; - CFX_Matrix m(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, - m_info.CTM.e, m_info.CTM.f); - if (matrix) { - m.Concat(*matrix); - } - switch (m_info.strokeColor->m_type) { - case FX_COLOR_Solid: { - m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState, 0x0, - m_info.strokeColor->m_info.argb, 0); - return; - } - default: - return; - } -} - -void CFX_Graphics::RenderDeviceFillPath(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { - if (!m_info.fillColor) - return; - CFX_Matrix m(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, - m_info.CTM.e, m_info.CTM.f); - if (matrix) { - m.Concat(*matrix); - } - switch (m_info.fillColor->m_type) { - case FX_COLOR_Solid: { - m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState, - m_info.fillColor->m_info.argb, 0x0, fillMode); - return; - } - case FX_COLOR_Pattern: - FillPathWithPattern(path, fillMode, &m); - return; - case FX_COLOR_Shading: - FillPathWithShading(path, fillMode, &m); - return; - default: - return; - } -} - -void CFX_Graphics::RenderDeviceStretchImage( - const CFX_RetainPtr& source, - const CFX_RectF& rect, - CFX_Matrix* matrix) { - CFX_Matrix m1(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, - m_info.CTM.e, m_info.CTM.f); - if (matrix) { - m1.Concat(*matrix); - } - CFX_RetainPtr bmp1 = - source->StretchTo(static_cast(rect.Width()), - static_cast(rect.Height()), 0, nullptr); - CFX_Matrix m2(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top); - m2.Concat(m1); - - int32_t left; - int32_t top; - CFX_RetainPtr bmp2 = bmp1->FlipImage(false, true); - CFX_RetainPtr bmp3 = bmp2->TransformTo(&m2, &left, &top); - CFX_RectF r = GetClipRect(); - CFX_RetainPtr bitmap = m_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)); -} - -void CFX_Graphics::FillPathWithPattern(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { - CFX_Pattern* pattern = m_info.fillColor->m_info.pattern; - CFX_RetainPtr bitmap = m_renderDevice->GetBitmap(); - int32_t width = bitmap->GetWidth(); - int32_t height = bitmap->GetHeight(); - auto bmp = pdfium::MakeRetain(); - bmp->Create(width, height, FXDIB_Argb); - m_renderDevice->GetDIBits(bmp, 0, 0); - - FX_HatchStyle hatchStyle = m_info.fillColor->m_info.pattern->m_hatchStyle; - const FX_HATCHDATA& data = hatchBitmapData[static_cast(hatchStyle)]; - - auto mask = pdfium::MakeRetain(); - mask->Create(data.width, data.height, FXDIB_1bppMask); - memcpy(mask->GetBuffer(), data.maskBits, mask->GetPitch() * data.height); - CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox(); - if (matrix) - matrix->TransformRect(rectf); - - FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top), - FXSYS_round(rectf.right), FXSYS_round(rectf.bottom)); - CFX_DefaultRenderDevice device; - device.Attach(bmp, false, nullptr, false); - device.FillRect(&rect, m_info.fillColor->m_info.pattern->m_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, - m_info.fillColor->m_info.pattern->m_foreArgb); - } - } - CFX_RenderDevice::StateRestorer restorer(m_renderDevice); - m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); - SetDIBitsWithMatrix(bmp, &pattern->m_matrix); -} - -void CFX_Graphics::FillPathWithShading(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { - CFX_RetainPtr bitmap = m_renderDevice->GetBitmap(); - int32_t width = bitmap->GetWidth(); - int32_t height = bitmap->GetHeight(); - float start_x = m_info.fillColor->m_shading->m_beginPoint.x; - float start_y = m_info.fillColor->m_shading->m_beginPoint.y; - float end_x = m_info.fillColor->m_shading->m_endPoint.x; - float end_y = m_info.fillColor->m_shading->m_endPoint.y; - auto bmp = pdfium::MakeRetain(); - bmp->Create(width, height, FXDIB_Argb); - m_renderDevice->GetDIBits(bmp, 0, 0); - int32_t pitch = bmp->GetPitch(); - bool result = false; - switch (m_info.fillColor->m_shading->m_type) { - case FX_SHADING_Axial: { - float x_span = end_x - start_x; - float y_span = end_y - start_y; - float axis_len_square = (x_span * x_span) + (y_span * y_span); - for (int32_t row = 0; row < height; row++) { - uint32_t* dib_buf = (uint32_t*)(bmp->GetBuffer() + row * pitch); - for (int32_t column = 0; column < width; column++) { - float x = (float)(column); - float y = (float)(row); - float scale = (((x - start_x) * x_span) + ((y - start_y) * y_span)) / - axis_len_square; - if (scale < 0) { - if (!m_info.fillColor->m_shading->m_isExtendedBegin) { - continue; - } - scale = 0; - } else if (scale > 1.0f) { - if (!m_info.fillColor->m_shading->m_isExtendedEnd) { - continue; - } - scale = 1.0f; - } - int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1)); - dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index]; - } - } - result = true; - break; - } - case FX_SHADING_Radial: { - float start_r = m_info.fillColor->m_shading->m_beginRadius; - float end_r = m_info.fillColor->m_shading->m_endRadius; - float a = ((start_x - end_x) * (start_x - end_x)) + - ((start_y - end_y) * (start_y - end_y)) - - ((start_r - end_r) * (start_r - end_r)); - for (int32_t row = 0; row < height; row++) { - uint32_t* dib_buf = (uint32_t*)(bmp->GetBuffer() + row * pitch); - for (int32_t column = 0; column < width; column++) { - float x = (float)(column); - float y = (float)(row); - float b = -2 * (((x - start_x) * (end_x - start_x)) + - ((y - start_y) * (end_y - start_y)) + - (start_r * (end_r - start_r))); - float c = ((x - start_x) * (x - start_x)) + - ((y - start_y) * (y - start_y)) - (start_r * start_r); - float s; - if (a == 0) { - s = -c / b; - } else { - float b2_4ac = (b * b) - 4 * (a * c); - if (b2_4ac < 0) { - continue; - } - float root = (sqrt(b2_4ac)); - float s1, s2; - if (a > 0) { - s1 = (-b - root) / (2 * a); - s2 = (-b + root) / (2 * a); - } else { - s2 = (-b - root) / (2 * a); - s1 = (-b + root) / (2 * a); - } - if (s2 <= 1.0f || m_info.fillColor->m_shading->m_isExtendedEnd) { - s = (s2); - } else { - s = (s1); - } - if ((start_r) + s * (end_r - start_r) < 0) { - continue; - } - } - if (s < 0) { - if (!m_info.fillColor->m_shading->m_isExtendedBegin) { - continue; - } - s = 0; - } - if (s > 1.0f) { - if (!m_info.fillColor->m_shading->m_isExtendedEnd) { - continue; - } - s = 1.0f; - } - int index = (int32_t)(s * (FX_SHADING_Steps - 1)); - dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index]; - } - } - result = true; - break; - } - default: { - result = false; - break; - } - } - if (result) { - CFX_RenderDevice::StateRestorer restorer(m_renderDevice); - m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); - SetDIBitsWithMatrix(bmp, matrix); - } -} - -void CFX_Graphics::SetDIBitsWithMatrix( - const CFX_RetainPtr& source, - CFX_Matrix* matrix) { - if (matrix->IsIdentity()) { - m_renderDevice->SetDIBits(source, 0, 0); - } else { - CFX_Matrix m((float)source->GetWidth(), 0, 0, (float)source->GetHeight(), 0, - 0); - m.Concat(*matrix); - int32_t left; - int32_t top; - CFX_RetainPtr bmp1 = source->FlipImage(false, true); - CFX_RetainPtr bmp2 = bmp1->TransformTo(&m, &left, &top); - m_renderDevice->SetDIBits(bmp2, left, top); - } -} - -CFX_Graphics::TInfo::TInfo() - : isActOnDash(false), strokeColor(nullptr), fillColor(nullptr) {} - -CFX_Graphics::TInfo::TInfo(const TInfo& info) - : graphState(info.graphState), - CTM(info.CTM), - isActOnDash(info.isActOnDash), - strokeColor(info.strokeColor), - fillColor(info.fillColor) {} - -CFX_Graphics::TInfo& CFX_Graphics::TInfo::operator=(const TInfo& other) { - graphState.Copy(other.graphState); - CTM = other.CTM; - isActOnDash = other.isActOnDash; - strokeColor = other.strokeColor; - fillColor = other.fillColor; - return *this; -} diff --git a/xfa/fxgraphics/cfx_graphics.h b/xfa/fxgraphics/cfx_graphics.h deleted file mode 100644 index 0ce9bf4b32..0000000000 --- a/xfa/fxgraphics/cfx_graphics.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2016 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 - -#ifndef XFA_FXGRAPHICS_CFX_GRAPHICS_H_ -#define XFA_FXGRAPHICS_CFX_GRAPHICS_H_ - -#include -#include - -#include "core/fxcrt/fx_system.h" -#include "core/fxge/cfx_defaultrenderdevice.h" -#include "core/fxge/cfx_graphstatedata.h" -#include "core/fxge/cfx_renderdevice.h" -#include "core/fxge/fx_dib.h" -#include "core/fxge/fx_font.h" - -class CXFA_Color; -class CFX_Path; - -using FX_FillMode = int32_t; - -enum FX_DashStyle { - FX_DASHSTYLE_Solid = 0, - FX_DASHSTYLE_Dash = 1, - FX_DASHSTYLE_Dot = 2, - FX_DASHSTYLE_DashDot = 3, - FX_DASHSTYLE_DashDotDot = 4 -}; - -enum class FX_HatchStyle { - Horizontal = 0, - Vertical = 1, - ForwardDiagonal = 2, - BackwardDiagonal = 3, - Cross = 4, - DiagonalCross = 5 -}; - -class CFX_RenderDevice; - -class CFX_Graphics { - public: - explicit CFX_Graphics(CFX_RenderDevice* renderDevice); - ~CFX_Graphics(); - - void SaveGraphState(); - void RestoreGraphState(); - - CFX_RectF GetClipRect() const; - CFX_Matrix* GetMatrix(); - CFX_RenderDevice* GetRenderDevice(); - - void SetLineCap(CFX_GraphStateData::LineCap lineCap); - void SetLineDash(float dashPhase, float* dashArray, int32_t dashCount); - void SetLineDash(FX_DashStyle dashStyle); - void SetLineWidth(float lineWidth, bool isActOnDash = false); - void SetStrokeColor(CXFA_Color* color); - void SetFillColor(CXFA_Color* color); - void SetClipRect(const CFX_RectF& rect); - void StrokePath(CFX_Path* path, CFX_Matrix* matrix = nullptr); - void FillPath(CFX_Path* path, - FX_FillMode fillMode = FXFILL_WINDING, - CFX_Matrix* matrix = nullptr); - void StretchImage(const CFX_RetainPtr& source, - const CFX_RectF& rect, - CFX_Matrix* matrix = nullptr); - void ConcatMatrix(const CFX_Matrix* matrix); - - protected: - int32_t m_type; - - private: - struct TInfo { - TInfo(); - explicit TInfo(const TInfo& info); - TInfo& operator=(const TInfo& other); - - CFX_GraphStateData graphState; - CFX_Matrix CTM; - bool isActOnDash; - CXFA_Color* strokeColor; - CXFA_Color* fillColor; - } m_info; - - void RenderDeviceSetLineDash(FX_DashStyle dashStyle); - void RenderDeviceStrokePath(CFX_Path* path, CFX_Matrix* matrix); - void RenderDeviceFillPath(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix); - void RenderDeviceStretchImage(const CFX_RetainPtr& source, - const CFX_RectF& rect, - CFX_Matrix* matrix); - - void FillPathWithPattern(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix); - void FillPathWithShading(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix); - - void SetDIBitsWithMatrix(const CFX_RetainPtr& source, - CFX_Matrix* matrix); - - CFX_RenderDevice* const m_renderDevice; // Not owned. - std::vector> m_infoStack; -}; - -#endif // XFA_FXGRAPHICS_CFX_GRAPHICS_H_ diff --git a/xfa/fxgraphics/cfx_path.cpp b/xfa/fxgraphics/cfx_path.cpp deleted file mode 100644 index fc0051ad4c..0000000000 --- a/xfa/fxgraphics/cfx_path.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2016 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 "xfa/fxgraphics/cfx_path.h" - -#include "core/fxge/cfx_pathdata.h" -#include "third_party/base/ptr_util.h" - -CFX_Path::CFX_Path() {} - -CFX_Path::~CFX_Path() {} - -void CFX_Path::Clear() { - data_.Clear(); -} - -void CFX_Path::Close() { - data_.ClosePath(); -} - -void CFX_Path::MoveTo(const CFX_PointF& point) { - data_.AppendPoint(point, FXPT_TYPE::MoveTo, false); -} - -void CFX_Path::LineTo(const CFX_PointF& point) { - data_.AppendPoint(point, FXPT_TYPE::LineTo, false); -} - -void CFX_Path::BezierTo(const CFX_PointF& c1, - const CFX_PointF& c2, - const CFX_PointF& to) { - data_.AppendPoint(c1, FXPT_TYPE::BezierTo, false); - data_.AppendPoint(c2, FXPT_TYPE::BezierTo, false); - data_.AppendPoint(to, FXPT_TYPE::BezierTo, false); -} - -void CFX_Path::ArcTo(const CFX_PointF& pos, - const CFX_SizeF& size, - float start_angle, - float sweep_angle) { - CFX_SizeF new_size = size / 2.0f; - ArcToInternal(CFX_PointF(pos.x + new_size.width, pos.y + new_size.height), - new_size, start_angle, sweep_angle); -} - -void CFX_Path::ArcToInternal(const CFX_PointF& pos, - const CFX_SizeF& size, - float start_angle, - float sweep_angle) { - float x0 = cos(sweep_angle / 2); - float y0 = sin(sweep_angle / 2); - float tx = ((1.0f - x0) * 4) / (3 * 1.0f); - float ty = y0 - ((tx * x0) / y0); - - CFX_PointF points[] = {CFX_PointF(x0 + tx, -ty), CFX_PointF(x0 + tx, ty)}; - float sn = sin(start_angle + sweep_angle / 2); - float cs = cos(start_angle + sweep_angle / 2); - - CFX_PointF bezier; - bezier.x = pos.x + (size.width * ((points[0].x * cs) - (points[0].y * sn))); - bezier.y = pos.y + (size.height * ((points[0].x * sn) + (points[0].y * cs))); - data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); - - bezier.x = pos.x + (size.width * ((points[1].x * cs) - (points[1].y * sn))); - bezier.y = pos.y + (size.height * ((points[1].x * sn) + (points[1].y * cs))); - data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); - - bezier.x = pos.x + (size.width * cos(start_angle + sweep_angle)); - bezier.y = pos.y + (size.height * sin(start_angle + sweep_angle)); - data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); -} - -void CFX_Path::AddLine(const CFX_PointF& p1, const CFX_PointF& p2) { - data_.AppendPoint(p1, FXPT_TYPE::MoveTo, false); - data_.AppendPoint(p2, FXPT_TYPE::LineTo, false); -} - -void CFX_Path::AddRectangle(float left, float top, float width, float height) { - data_.AppendRect(left, top, left + width, top + height); -} - -void CFX_Path::AddEllipse(const CFX_RectF& rect) { - AddArc(rect.TopLeft(), rect.Size(), 0, FX_PI * 2); -} - -void CFX_Path::AddArc(const CFX_PointF& original_pos, - const CFX_SizeF& original_size, - float start_angle, - float sweep_angle) { - if (sweep_angle == 0) - return; - - const float bezier_arc_angle_epsilon = 0.01f; - while (start_angle > FX_PI * 2) - start_angle -= FX_PI * 2; - while (start_angle < 0) - start_angle += FX_PI * 2; - if (sweep_angle >= FX_PI * 2) - sweep_angle = FX_PI * 2; - if (sweep_angle <= -FX_PI * 2) - sweep_angle = -FX_PI * 2; - - CFX_SizeF size = original_size / 2; - CFX_PointF pos(original_pos.x + size.width, original_pos.y + size.height); - data_.AppendPoint(pos + CFX_PointF(size.width * cos(start_angle), - size.height * sin(start_angle)), - FXPT_TYPE::MoveTo, false); - - float total_sweep = 0; - float local_sweep = 0; - float prev_sweep = 0; - bool done = false; - do { - if (sweep_angle < 0) { - prev_sweep = total_sweep; - local_sweep = -FX_PI / 2; - total_sweep -= FX_PI / 2; - if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) { - local_sweep = sweep_angle - prev_sweep; - done = true; - } - } else { - prev_sweep = total_sweep; - local_sweep = FX_PI / 2; - total_sweep += FX_PI / 2; - if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) { - local_sweep = sweep_angle - prev_sweep; - done = true; - } - } - - ArcToInternal(pos, size, start_angle, local_sweep); - start_angle += local_sweep; - } while (!done); -} - -void CFX_Path::AddSubpath(CFX_Path* path) { - if (!path) - return; - data_.Append(&path->data_, nullptr); -} - -void CFX_Path::TransformBy(const CFX_Matrix& mt) { - data_.Transform(&mt); -} diff --git a/xfa/fxgraphics/cfx_path.h b/xfa/fxgraphics/cfx_path.h deleted file mode 100644 index 186465f810..0000000000 --- a/xfa/fxgraphics/cfx_path.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2016 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 - -#ifndef XFA_FXGRAPHICS_CFX_PATH_H_ -#define XFA_FXGRAPHICS_CFX_PATH_H_ - -#include "core/fxcrt/fx_system.h" -#include "core/fxge/cfx_pathdata.h" -#include "xfa/fxgraphics/cfx_graphics.h" - -class CFX_Path final { - public: - CFX_Path(); - ~CFX_Path(); - - const CFX_PathData* GetPathData() const { return &data_; } - - void Clear(); - bool IsEmpty() const { return data_.GetPoints().empty(); } - void TransformBy(const CFX_Matrix& mt); - - void Close(); - void MoveTo(const CFX_PointF& point); - void LineTo(const CFX_PointF& point); - void BezierTo(const CFX_PointF& c1, - const CFX_PointF& c2, - const CFX_PointF& to); - void ArcTo(const CFX_PointF& pos, - const CFX_SizeF& size, - float startAngle, - float sweepAngle); - - void AddLine(const CFX_PointF& p1, const CFX_PointF& p2); - void AddRectangle(float left, float top, float width, float height); - void AddEllipse(const CFX_RectF& rect); - void AddArc(const CFX_PointF& pos, - const CFX_SizeF& size, - float startAngle, - float sweepAngle); - - void AddSubpath(CFX_Path* path); - - private: - void ArcToInternal(const CFX_PointF& pos, - const CFX_SizeF& size, - float start_angle, - float sweep_angle); - - CFX_PathData data_; -}; - -#endif // XFA_FXGRAPHICS_CFX_PATH_H_ diff --git a/xfa/fxgraphics/cfx_pattern.cpp b/xfa/fxgraphics/cfx_pattern.cpp deleted file mode 100644 index a20ec24aa5..0000000000 --- a/xfa/fxgraphics/cfx_pattern.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2016 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 "xfa/fxgraphics/cfx_pattern.h" - -CFX_Pattern::CFX_Pattern(FX_HatchStyle hatchStyle, - const FX_ARGB foreArgb, - const FX_ARGB backArgb, - CFX_Matrix* matrix) - : m_hatchStyle(hatchStyle), m_foreArgb(foreArgb), m_backArgb(backArgb) { - if (matrix) - m_matrix = *matrix; - else - m_matrix.SetIdentity(); -} - -CFX_Pattern::~CFX_Pattern() {} diff --git a/xfa/fxgraphics/cfx_pattern.h b/xfa/fxgraphics/cfx_pattern.h deleted file mode 100644 index ef0008a3ea..0000000000 --- a/xfa/fxgraphics/cfx_pattern.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 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 - -#ifndef XFA_FXGRAPHICS_CFX_PATTERN_H_ -#define XFA_FXGRAPHICS_CFX_PATTERN_H_ - -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" -#include "xfa/fxgraphics/cfx_graphics.h" - -class CFX_DIBitmap; -class CFX_Matrix; - -class CFX_Pattern { - public: - CFX_Pattern(FX_HatchStyle hatchStyle, - const FX_ARGB foreArgb, - const FX_ARGB backArgb, - CFX_Matrix* matrix = nullptr); - - virtual ~CFX_Pattern(); - - private: - friend class CFX_Graphics; - - CFX_Matrix m_matrix; - - const FX_HatchStyle m_hatchStyle; - const FX_ARGB m_foreArgb; - const FX_ARGB m_backArgb; -}; - -#endif // XFA_FXGRAPHICS_CFX_PATTERN_H_ diff --git a/xfa/fxgraphics/cfx_shading.cpp b/xfa/fxgraphics/cfx_shading.cpp deleted file mode 100644 index b099bb97b1..0000000000 --- a/xfa/fxgraphics/cfx_shading.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2016 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 "xfa/fxgraphics/cfx_shading.h" - -CFX_Shading::CFX_Shading(const CFX_PointF& beginPoint, - const CFX_PointF& endPoint, - bool isExtendedBegin, - bool isExtendedEnd, - const FX_ARGB beginArgb, - const FX_ARGB endArgb) - : m_type(FX_SHADING_Axial), - m_beginPoint(beginPoint), - m_endPoint(endPoint), - m_beginRadius(0), - m_endRadius(0), - m_isExtendedBegin(isExtendedBegin), - m_isExtendedEnd(isExtendedEnd), - m_beginArgb(beginArgb), - m_endArgb(endArgb) { - InitArgbArray(); -} - -CFX_Shading::CFX_Shading(const CFX_PointF& beginPoint, - const CFX_PointF& endPoint, - const float beginRadius, - const float endRadius, - bool isExtendedBegin, - bool isExtendedEnd, - const FX_ARGB beginArgb, - const FX_ARGB endArgb) - : m_type(FX_SHADING_Radial), - m_beginPoint(beginPoint), - m_endPoint(endPoint), - m_beginRadius(beginRadius), - m_endRadius(endRadius), - m_isExtendedBegin(isExtendedBegin), - m_isExtendedEnd(isExtendedEnd), - m_beginArgb(beginArgb), - m_endArgb(endArgb) { - InitArgbArray(); -} - -CFX_Shading::~CFX_Shading() {} - -void CFX_Shading::InitArgbArray() { - int32_t a1; - int32_t r1; - int32_t g1; - int32_t b1; - std::tie(a1, r1, g1, b1) = ArgbDecode(m_beginArgb); - - int32_t a2; - int32_t r2; - int32_t g2; - int32_t b2; - std::tie(a2, r2, g2, b2) = ArgbDecode(m_endArgb); - - float f = static_cast(FX_SHADING_Steps - 1); - float aScale = 1.0 * (a2 - a1) / f; - float rScale = 1.0 * (r2 - r1) / f; - float gScale = 1.0 * (g2 - g1) / f; - float bScale = 1.0 * (b2 - b1) / f; - - for (int32_t i = 0; i < FX_SHADING_Steps; i++) { - int32_t a3 = static_cast(i * aScale); - int32_t r3 = static_cast(i * rScale); - int32_t g3 = static_cast(i * gScale); - int32_t b3 = static_cast(i * bScale); - - // TODO(dsinclair): Add overloads for FX_ARGB. pdfium:437 - m_argbArray[i] = - FXARGB_TODIB(FXARGB_MAKE(a1 + a3, r1 + r3, g1 + g3, b1 + b3)); - } -} diff --git a/xfa/fxgraphics/cfx_shading.h b/xfa/fxgraphics/cfx_shading.h deleted file mode 100644 index 1fb34d2b07..0000000000 --- a/xfa/fxgraphics/cfx_shading.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2016 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 - -#ifndef XFA_FXGRAPHICS_CFX_SHADING_H_ -#define XFA_FXGRAPHICS_CFX_SHADING_H_ - -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" -#include "core/fxge/fx_dib.h" - -#define FX_SHADING_Steps 256 - -enum CFX_Shading_Type { FX_SHADING_Axial = 1, FX_SHADING_Radial }; - -class CFX_Shading { - public: - // Axial shading. - CFX_Shading(const CFX_PointF& beginPoint, - const CFX_PointF& endPoint, - bool isExtendedBegin, - bool isExtendedEnd, - const FX_ARGB beginArgb, - const FX_ARGB endArgb); - - // Radial shading. - CFX_Shading(const CFX_PointF& beginPoint, - const CFX_PointF& endPoint, - const float beginRadius, - const float endRadius, - bool isExtendedBegin, - bool isExtendedEnd, - const FX_ARGB beginArgb, - const FX_ARGB endArgb); - virtual ~CFX_Shading(); - - private: - friend class CFX_Graphics; - - void InitArgbArray(); - - const CFX_Shading_Type m_type; - const CFX_PointF m_beginPoint; - const CFX_PointF m_endPoint; - const float m_beginRadius; - const float m_endRadius; - const bool m_isExtendedBegin; - const bool m_isExtendedEnd; - const FX_ARGB m_beginArgb; - const FX_ARGB m_endArgb; - FX_ARGB m_argbArray[FX_SHADING_Steps]; -}; - -#endif // XFA_FXGRAPHICS_CFX_SHADING_H_ diff --git a/xfa/fxgraphics/cxfa_color.cpp b/xfa/fxgraphics/cxfa_color.cpp index 27a0cbe569..79c0e5f794 100644 --- a/xfa/fxgraphics/cxfa_color.cpp +++ b/xfa/fxgraphics/cxfa_color.cpp @@ -12,11 +12,11 @@ CXFA_Color::CXFA_Color(const FX_ARGB argb) { Set(argb); } -CXFA_Color::CXFA_Color(CFX_Pattern* pattern, const FX_ARGB argb) { +CXFA_Color::CXFA_Color(CXFA_Pattern* pattern, const FX_ARGB argb) { Set(pattern, argb); } -CXFA_Color::CXFA_Color(CFX_Shading* shading) { +CXFA_Color::CXFA_Color(CXFA_Shading* shading) { Set(shading); } @@ -30,7 +30,7 @@ void CXFA_Color::Set(const FX_ARGB argb) { m_info.pattern = nullptr; } -void CXFA_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) { +void CXFA_Color::Set(CXFA_Pattern* pattern, const FX_ARGB argb) { if (!pattern) return; m_type = FX_COLOR_Pattern; @@ -38,7 +38,7 @@ void CXFA_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) { m_info.pattern = pattern; } -void CXFA_Color::Set(CFX_Shading* shading) { +void CXFA_Color::Set(CXFA_Shading* shading) { if (!shading) return; m_type = FX_COLOR_Shading; diff --git a/xfa/fxgraphics/cxfa_color.h b/xfa/fxgraphics/cxfa_color.h index 16ef1d7d4d..f5bba27586 100644 --- a/xfa/fxgraphics/cxfa_color.h +++ b/xfa/fxgraphics/cxfa_color.h @@ -8,10 +8,10 @@ #define XFA_FXGRAPHICS_CXFA_COLOR_H_ #include "core/fxge/fx_dib.h" -#include "xfa/fxgraphics/cfx_graphics.h" +#include "xfa/fxgraphics/cxfa_graphics.h" -class CFX_Pattern; -class CFX_Shading; +class CXFA_Pattern; +class CXFA_Shading; enum { FX_COLOR_None = 0, FX_COLOR_Solid, FX_COLOR_Pattern, FX_COLOR_Shading }; @@ -19,24 +19,24 @@ class CXFA_Color { public: CXFA_Color(); explicit CXFA_Color(const FX_ARGB argb); - explicit CXFA_Color(CFX_Shading* shading); - CXFA_Color(CFX_Pattern* pattern, const FX_ARGB argb); + explicit CXFA_Color(CXFA_Shading* shading); + CXFA_Color(CXFA_Pattern* pattern, const FX_ARGB argb); virtual ~CXFA_Color(); void Set(const FX_ARGB argb); - void Set(CFX_Pattern* pattern, const FX_ARGB argb); - void Set(CFX_Shading* shading); + void Set(CXFA_Pattern* pattern, const FX_ARGB argb); + void Set(CXFA_Shading* shading); private: - friend class CFX_Graphics; + friend class CXFA_Graphics; int32_t m_type; union { struct { FX_ARGB argb; - CFX_Pattern* pattern; + CXFA_Pattern* pattern; } m_info; - CFX_Shading* m_shading; + CXFA_Shading* m_shading; }; }; diff --git a/xfa/fxgraphics/cxfa_graphics.cpp b/xfa/fxgraphics/cxfa_graphics.cpp new file mode 100644 index 0000000000..8648abb81d --- /dev/null +++ b/xfa/fxgraphics/cxfa_graphics.cpp @@ -0,0 +1,536 @@ +// 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 "xfa/fxgraphics/cxfa_graphics.h" + +#include + +#include "core/fxge/cfx_defaultrenderdevice.h" +#include "core/fxge/cfx_renderdevice.h" +#include "core/fxge/cfx_unicodeencoding.h" +#include "third_party/base/ptr_util.h" +#include "xfa/fxgraphics/cxfa_color.h" +#include "xfa/fxgraphics/cxfa_path.h" +#include "xfa/fxgraphics/cxfa_pattern.h" +#include "xfa/fxgraphics/cxfa_shading.h" + +namespace { + +enum { + FX_CONTEXT_None = 0, + FX_CONTEXT_Device, +}; + +#define FX_HATCHSTYLE_Total 53 + +struct FX_HATCHDATA { + int32_t width; + int32_t height; + uint8_t maskBits[64]; +}; + +const FX_HATCHDATA hatchBitmapData[FX_HATCHSTYLE_Total] = { + {16, // Horizontal + 16, + { + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }}, + {16, // Vertical + 16, + { + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, + 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, + 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + }}, + {16, // ForwardDiagonal + 16, + { + 0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, + 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, + 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, + 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + }}, + {16, // BackwardDiagonal + 16, + { + 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, + 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, + 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, + 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + }}, + {16, // Cross + 16, + { + 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, + 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + }}, + {16, // DiagonalCross + 16, + { + 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, + 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, + 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, + 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, + 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, + }}, +}; + +} // namespace + +CXFA_Graphics::CXFA_Graphics(CFX_RenderDevice* renderDevice) + : m_type(FX_CONTEXT_None), m_renderDevice(renderDevice) { + if (!renderDevice) + return; + m_type = FX_CONTEXT_Device; +} + +CXFA_Graphics::~CXFA_Graphics() {} + +void CXFA_Graphics::SaveGraphState() { + if (m_type != FX_CONTEXT_Device || !m_renderDevice) + return; + + m_renderDevice->SaveState(); + m_infoStack.push_back(pdfium::MakeUnique(m_info)); +} + +void CXFA_Graphics::RestoreGraphState() { + if (m_type != FX_CONTEXT_Device || !m_renderDevice) + return; + + m_renderDevice->RestoreState(false); + if (m_infoStack.empty() || !m_infoStack.back()) + return; + + m_info = *m_infoStack.back(); + m_infoStack.pop_back(); + return; +} + +void CXFA_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) { + if (m_type == FX_CONTEXT_Device && m_renderDevice) { + m_info.graphState.m_LineCap = lineCap; + } +} + +void CXFA_Graphics::SetLineDash(float dashPhase, + float* dashArray, + int32_t dashCount) { + if (dashCount > 0 && !dashArray) + return; + + dashCount = dashCount < 0 ? 0 : dashCount; + if (m_type == FX_CONTEXT_Device && m_renderDevice) { + float scale = 1.0; + if (m_info.isActOnDash) { + scale = m_info.graphState.m_LineWidth; + } + m_info.graphState.m_DashPhase = dashPhase; + m_info.graphState.SetDashCount(dashCount); + for (int32_t i = 0; i < dashCount; i++) { + m_info.graphState.m_DashArray[i] = dashArray[i] * scale; + } + } +} + +void CXFA_Graphics::SetLineDash(FX_DashStyle dashStyle) { + if (m_type == FX_CONTEXT_Device && m_renderDevice) + RenderDeviceSetLineDash(dashStyle); +} + +void CXFA_Graphics::SetLineWidth(float lineWidth, bool isActOnDash) { + if (m_type == FX_CONTEXT_Device && m_renderDevice) { + m_info.graphState.m_LineWidth = lineWidth; + m_info.isActOnDash = isActOnDash; + } +} + +void CXFA_Graphics::SetStrokeColor(CXFA_Color* color) { + if (!color) + return; + if (m_type == FX_CONTEXT_Device && m_renderDevice) { + m_info.strokeColor = color; + } +} + +void CXFA_Graphics::SetFillColor(CXFA_Color* color) { + if (!color) + return; + if (m_type == FX_CONTEXT_Device && m_renderDevice) { + m_info.fillColor = color; + } +} + +void CXFA_Graphics::StrokePath(CXFA_Path* path, CFX_Matrix* matrix) { + if (!path) + return; + if (m_type == FX_CONTEXT_Device && m_renderDevice) + RenderDeviceStrokePath(path, matrix); +} + +void CXFA_Graphics::FillPath(CXFA_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { + if (!path) + return; + if (m_type == FX_CONTEXT_Device && m_renderDevice) + RenderDeviceFillPath(path, fillMode, matrix); +} + +void CXFA_Graphics::StretchImage(const CFX_RetainPtr& source, + const CFX_RectF& rect, + CFX_Matrix* matrix) { + if (!source) + return; + if (m_type == FX_CONTEXT_Device && m_renderDevice) + RenderDeviceStretchImage(source, rect, matrix); +} + +void CXFA_Graphics::ConcatMatrix(const CFX_Matrix* matrix) { + if (!matrix) + return; + if (m_type == FX_CONTEXT_Device && m_renderDevice) { + m_info.CTM.Concat(*matrix); + } +} + +CFX_Matrix* CXFA_Graphics::GetMatrix() { + if (m_type == FX_CONTEXT_Device && m_renderDevice) + return &m_info.CTM; + return nullptr; +} + +CFX_RectF CXFA_Graphics::GetClipRect() const { + if (m_type != FX_CONTEXT_Device || !m_renderDevice) + return CFX_RectF(); + + FX_RECT r = m_renderDevice->GetClipBox(); + return CFX_Rect(r.left, r.top, r.Width(), r.Height()).As(); +} + +void CXFA_Graphics::SetClipRect(const CFX_RectF& rect) { + if (m_type == FX_CONTEXT_Device && m_renderDevice) { + m_renderDevice->SetClip_Rect( + FX_RECT(FXSYS_round(rect.left), FXSYS_round(rect.top), + FXSYS_round(rect.right()), FXSYS_round(rect.bottom()))); + } +} + +CFX_RenderDevice* CXFA_Graphics::GetRenderDevice() { + return m_renderDevice; +} + +void CXFA_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) { + switch (dashStyle) { + case FX_DASHSTYLE_Solid: { + m_info.graphState.SetDashCount(0); + return; + } + case FX_DASHSTYLE_Dash: { + float dashArray[] = {3, 1}; + SetLineDash(0, dashArray, 2); + return; + } + case FX_DASHSTYLE_Dot: { + float dashArray[] = {1, 1}; + SetLineDash(0, dashArray, 2); + return; + } + case FX_DASHSTYLE_DashDot: { + float dashArray[] = {3, 1, 1, 1}; + SetLineDash(0, dashArray, 4); + return; + } + case FX_DASHSTYLE_DashDotDot: { + float dashArray[] = {4, 1, 2, 1, 2, 1}; + SetLineDash(0, dashArray, 6); + return; + } + default: + return; + } +} + +void CXFA_Graphics::RenderDeviceStrokePath(CXFA_Path* path, + CFX_Matrix* matrix) { + if (!m_info.strokeColor) + return; + CFX_Matrix m(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, + m_info.CTM.e, m_info.CTM.f); + if (matrix) { + m.Concat(*matrix); + } + switch (m_info.strokeColor->m_type) { + case FX_COLOR_Solid: { + m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState, 0x0, + m_info.strokeColor->m_info.argb, 0); + return; + } + default: + return; + } +} + +void CXFA_Graphics::RenderDeviceFillPath(CXFA_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { + if (!m_info.fillColor) + return; + CFX_Matrix m(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, + m_info.CTM.e, m_info.CTM.f); + if (matrix) { + m.Concat(*matrix); + } + switch (m_info.fillColor->m_type) { + case FX_COLOR_Solid: { + m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState, + m_info.fillColor->m_info.argb, 0x0, fillMode); + return; + } + case FX_COLOR_Pattern: + FillPathWithPattern(path, fillMode, &m); + return; + case FX_COLOR_Shading: + FillPathWithShading(path, fillMode, &m); + return; + default: + return; + } +} + +void CXFA_Graphics::RenderDeviceStretchImage( + const CFX_RetainPtr& source, + const CFX_RectF& rect, + CFX_Matrix* matrix) { + CFX_Matrix m1(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, + m_info.CTM.e, m_info.CTM.f); + if (matrix) { + m1.Concat(*matrix); + } + CFX_RetainPtr bmp1 = + source->StretchTo(static_cast(rect.Width()), + static_cast(rect.Height()), 0, nullptr); + CFX_Matrix m2(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top); + m2.Concat(m1); + + int32_t left; + int32_t top; + CFX_RetainPtr bmp2 = bmp1->FlipImage(false, true); + CFX_RetainPtr bmp3 = bmp2->TransformTo(&m2, &left, &top); + CFX_RectF r = GetClipRect(); + CFX_RetainPtr bitmap = m_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)); +} + +void CXFA_Graphics::FillPathWithPattern(CXFA_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { + CXFA_Pattern* pattern = m_info.fillColor->m_info.pattern; + CFX_RetainPtr bitmap = m_renderDevice->GetBitmap(); + int32_t width = bitmap->GetWidth(); + int32_t height = bitmap->GetHeight(); + auto bmp = pdfium::MakeRetain(); + bmp->Create(width, height, FXDIB_Argb); + m_renderDevice->GetDIBits(bmp, 0, 0); + + FX_HatchStyle hatchStyle = m_info.fillColor->m_info.pattern->m_hatchStyle; + const FX_HATCHDATA& data = hatchBitmapData[static_cast(hatchStyle)]; + + auto mask = pdfium::MakeRetain(); + mask->Create(data.width, data.height, FXDIB_1bppMask); + memcpy(mask->GetBuffer(), data.maskBits, mask->GetPitch() * data.height); + CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox(); + if (matrix) + matrix->TransformRect(rectf); + + FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top), + FXSYS_round(rectf.right), FXSYS_round(rectf.bottom)); + CFX_DefaultRenderDevice device; + device.Attach(bmp, false, nullptr, false); + device.FillRect(&rect, m_info.fillColor->m_info.pattern->m_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, + m_info.fillColor->m_info.pattern->m_foreArgb); + } + } + CFX_RenderDevice::StateRestorer restorer(m_renderDevice); + m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); + SetDIBitsWithMatrix(bmp, &pattern->m_matrix); +} + +void CXFA_Graphics::FillPathWithShading(CXFA_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { + CFX_RetainPtr bitmap = m_renderDevice->GetBitmap(); + int32_t width = bitmap->GetWidth(); + int32_t height = bitmap->GetHeight(); + float start_x = m_info.fillColor->m_shading->m_beginPoint.x; + float start_y = m_info.fillColor->m_shading->m_beginPoint.y; + float end_x = m_info.fillColor->m_shading->m_endPoint.x; + float end_y = m_info.fillColor->m_shading->m_endPoint.y; + auto bmp = pdfium::MakeRetain(); + bmp->Create(width, height, FXDIB_Argb); + m_renderDevice->GetDIBits(bmp, 0, 0); + int32_t pitch = bmp->GetPitch(); + bool result = false; + switch (m_info.fillColor->m_shading->m_type) { + case FX_SHADING_Axial: { + float x_span = end_x - start_x; + float y_span = end_y - start_y; + float axis_len_square = (x_span * x_span) + (y_span * y_span); + for (int32_t row = 0; row < height; row++) { + uint32_t* dib_buf = (uint32_t*)(bmp->GetBuffer() + row * pitch); + for (int32_t column = 0; column < width; column++) { + float x = (float)(column); + float y = (float)(row); + float scale = (((x - start_x) * x_span) + ((y - start_y) * y_span)) / + axis_len_square; + if (scale < 0) { + if (!m_info.fillColor->m_shading->m_isExtendedBegin) { + continue; + } + scale = 0; + } else if (scale > 1.0f) { + if (!m_info.fillColor->m_shading->m_isExtendedEnd) { + continue; + } + scale = 1.0f; + } + int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1)); + dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index]; + } + } + result = true; + break; + } + case FX_SHADING_Radial: { + float start_r = m_info.fillColor->m_shading->m_beginRadius; + float end_r = m_info.fillColor->m_shading->m_endRadius; + float a = ((start_x - end_x) * (start_x - end_x)) + + ((start_y - end_y) * (start_y - end_y)) - + ((start_r - end_r) * (start_r - end_r)); + for (int32_t row = 0; row < height; row++) { + uint32_t* dib_buf = (uint32_t*)(bmp->GetBuffer() + row * pitch); + for (int32_t column = 0; column < width; column++) { + float x = (float)(column); + float y = (float)(row); + float b = -2 * (((x - start_x) * (end_x - start_x)) + + ((y - start_y) * (end_y - start_y)) + + (start_r * (end_r - start_r))); + float c = ((x - start_x) * (x - start_x)) + + ((y - start_y) * (y - start_y)) - (start_r * start_r); + float s; + if (a == 0) { + s = -c / b; + } else { + float b2_4ac = (b * b) - 4 * (a * c); + if (b2_4ac < 0) { + continue; + } + float root = (sqrt(b2_4ac)); + float s1, s2; + if (a > 0) { + s1 = (-b - root) / (2 * a); + s2 = (-b + root) / (2 * a); + } else { + s2 = (-b - root) / (2 * a); + s1 = (-b + root) / (2 * a); + } + if (s2 <= 1.0f || m_info.fillColor->m_shading->m_isExtendedEnd) { + s = (s2); + } else { + s = (s1); + } + if ((start_r) + s * (end_r - start_r) < 0) { + continue; + } + } + if (s < 0) { + if (!m_info.fillColor->m_shading->m_isExtendedBegin) { + continue; + } + s = 0; + } + if (s > 1.0f) { + if (!m_info.fillColor->m_shading->m_isExtendedEnd) { + continue; + } + s = 1.0f; + } + int index = (int32_t)(s * (FX_SHADING_Steps - 1)); + dib_buf[column] = m_info.fillColor->m_shading->m_argbArray[index]; + } + } + result = true; + break; + } + default: { + result = false; + break; + } + } + if (result) { + CFX_RenderDevice::StateRestorer restorer(m_renderDevice); + m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); + SetDIBitsWithMatrix(bmp, matrix); + } +} + +void CXFA_Graphics::SetDIBitsWithMatrix( + const CFX_RetainPtr& source, + CFX_Matrix* matrix) { + if (matrix->IsIdentity()) { + m_renderDevice->SetDIBits(source, 0, 0); + } else { + CFX_Matrix m((float)source->GetWidth(), 0, 0, (float)source->GetHeight(), 0, + 0); + m.Concat(*matrix); + int32_t left; + int32_t top; + CFX_RetainPtr bmp1 = source->FlipImage(false, true); + CFX_RetainPtr bmp2 = bmp1->TransformTo(&m, &left, &top); + m_renderDevice->SetDIBits(bmp2, left, top); + } +} + +CXFA_Graphics::TInfo::TInfo() + : isActOnDash(false), strokeColor(nullptr), fillColor(nullptr) {} + +CXFA_Graphics::TInfo::TInfo(const TInfo& info) + : graphState(info.graphState), + CTM(info.CTM), + isActOnDash(info.isActOnDash), + strokeColor(info.strokeColor), + fillColor(info.fillColor) {} + +CXFA_Graphics::TInfo& CXFA_Graphics::TInfo::operator=(const TInfo& other) { + graphState.Copy(other.graphState); + CTM = other.CTM; + isActOnDash = other.isActOnDash; + strokeColor = other.strokeColor; + fillColor = other.fillColor; + return *this; +} diff --git a/xfa/fxgraphics/cxfa_graphics.h b/xfa/fxgraphics/cxfa_graphics.h new file mode 100644 index 0000000000..5492d4d3be --- /dev/null +++ b/xfa/fxgraphics/cxfa_graphics.h @@ -0,0 +1,111 @@ +// Copyright 2016 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 + +#ifndef XFA_FXGRAPHICS_CXFA_GRAPHICS_H_ +#define XFA_FXGRAPHICS_CXFA_GRAPHICS_H_ + +#include +#include + +#include "core/fxcrt/fx_system.h" +#include "core/fxge/cfx_defaultrenderdevice.h" +#include "core/fxge/cfx_graphstatedata.h" +#include "core/fxge/cfx_renderdevice.h" +#include "core/fxge/fx_dib.h" +#include "core/fxge/fx_font.h" + +class CXFA_Color; +class CXFA_Path; + +using FX_FillMode = int32_t; + +enum FX_DashStyle { + FX_DASHSTYLE_Solid = 0, + FX_DASHSTYLE_Dash = 1, + FX_DASHSTYLE_Dot = 2, + FX_DASHSTYLE_DashDot = 3, + FX_DASHSTYLE_DashDotDot = 4 +}; + +enum class FX_HatchStyle { + Horizontal = 0, + Vertical = 1, + ForwardDiagonal = 2, + BackwardDiagonal = 3, + Cross = 4, + DiagonalCross = 5 +}; + +class CFX_RenderDevice; + +class CXFA_Graphics { + public: + explicit CXFA_Graphics(CFX_RenderDevice* renderDevice); + ~CXFA_Graphics(); + + void SaveGraphState(); + void RestoreGraphState(); + + CFX_RectF GetClipRect() const; + CFX_Matrix* GetMatrix(); + CFX_RenderDevice* GetRenderDevice(); + + void SetLineCap(CFX_GraphStateData::LineCap lineCap); + void SetLineDash(float dashPhase, float* dashArray, int32_t dashCount); + void SetLineDash(FX_DashStyle dashStyle); + void SetLineWidth(float lineWidth, bool isActOnDash = false); + void SetStrokeColor(CXFA_Color* color); + void SetFillColor(CXFA_Color* color); + void SetClipRect(const CFX_RectF& rect); + void StrokePath(CXFA_Path* path, CFX_Matrix* matrix = nullptr); + void FillPath(CXFA_Path* path, + FX_FillMode fillMode = FXFILL_WINDING, + CFX_Matrix* matrix = nullptr); + void StretchImage(const CFX_RetainPtr& source, + const CFX_RectF& rect, + CFX_Matrix* matrix = nullptr); + void ConcatMatrix(const CFX_Matrix* matrix); + + protected: + int32_t m_type; + + private: + struct TInfo { + TInfo(); + explicit TInfo(const TInfo& info); + TInfo& operator=(const TInfo& other); + + CFX_GraphStateData graphState; + CFX_Matrix CTM; + bool isActOnDash; + CXFA_Color* strokeColor; + CXFA_Color* fillColor; + } m_info; + + void RenderDeviceSetLineDash(FX_DashStyle dashStyle); + void RenderDeviceStrokePath(CXFA_Path* path, CFX_Matrix* matrix); + void RenderDeviceFillPath(CXFA_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix); + void RenderDeviceStretchImage(const CFX_RetainPtr& source, + const CFX_RectF& rect, + CFX_Matrix* matrix); + + void FillPathWithPattern(CXFA_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix); + void FillPathWithShading(CXFA_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix); + + void SetDIBitsWithMatrix(const CFX_RetainPtr& source, + CFX_Matrix* matrix); + + CFX_RenderDevice* const m_renderDevice; // Not owned. + std::vector> m_infoStack; +}; + +#endif // XFA_FXGRAPHICS_CXFA_GRAPHICS_H_ diff --git a/xfa/fxgraphics/cxfa_path.cpp b/xfa/fxgraphics/cxfa_path.cpp new file mode 100644 index 0000000000..6d7ed0be58 --- /dev/null +++ b/xfa/fxgraphics/cxfa_path.cpp @@ -0,0 +1,148 @@ +// Copyright 2016 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 "xfa/fxgraphics/cxfa_path.h" + +#include "core/fxge/cfx_pathdata.h" +#include "third_party/base/ptr_util.h" + +CXFA_Path::CXFA_Path() {} + +CXFA_Path::~CXFA_Path() {} + +void CXFA_Path::Clear() { + data_.Clear(); +} + +void CXFA_Path::Close() { + data_.ClosePath(); +} + +void CXFA_Path::MoveTo(const CFX_PointF& point) { + data_.AppendPoint(point, FXPT_TYPE::MoveTo, false); +} + +void CXFA_Path::LineTo(const CFX_PointF& point) { + data_.AppendPoint(point, FXPT_TYPE::LineTo, false); +} + +void CXFA_Path::BezierTo(const CFX_PointF& c1, + const CFX_PointF& c2, + const CFX_PointF& to) { + data_.AppendPoint(c1, FXPT_TYPE::BezierTo, false); + data_.AppendPoint(c2, FXPT_TYPE::BezierTo, false); + data_.AppendPoint(to, FXPT_TYPE::BezierTo, false); +} + +void CXFA_Path::ArcTo(const CFX_PointF& pos, + const CFX_SizeF& size, + float start_angle, + float sweep_angle) { + CFX_SizeF new_size = size / 2.0f; + ArcToInternal(CFX_PointF(pos.x + new_size.width, pos.y + new_size.height), + new_size, start_angle, sweep_angle); +} + +void CXFA_Path::ArcToInternal(const CFX_PointF& pos, + const CFX_SizeF& size, + float start_angle, + float sweep_angle) { + float x0 = cos(sweep_angle / 2); + float y0 = sin(sweep_angle / 2); + float tx = ((1.0f - x0) * 4) / (3 * 1.0f); + float ty = y0 - ((tx * x0) / y0); + + CFX_PointF points[] = {CFX_PointF(x0 + tx, -ty), CFX_PointF(x0 + tx, ty)}; + float sn = sin(start_angle + sweep_angle / 2); + float cs = cos(start_angle + sweep_angle / 2); + + CFX_PointF bezier; + bezier.x = pos.x + (size.width * ((points[0].x * cs) - (points[0].y * sn))); + bezier.y = pos.y + (size.height * ((points[0].x * sn) + (points[0].y * cs))); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); + + bezier.x = pos.x + (size.width * ((points[1].x * cs) - (points[1].y * sn))); + bezier.y = pos.y + (size.height * ((points[1].x * sn) + (points[1].y * cs))); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); + + bezier.x = pos.x + (size.width * cos(start_angle + sweep_angle)); + bezier.y = pos.y + (size.height * sin(start_angle + sweep_angle)); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); +} + +void CXFA_Path::AddLine(const CFX_PointF& p1, const CFX_PointF& p2) { + data_.AppendPoint(p1, FXPT_TYPE::MoveTo, false); + data_.AppendPoint(p2, FXPT_TYPE::LineTo, false); +} + +void CXFA_Path::AddRectangle(float left, float top, float width, float height) { + data_.AppendRect(left, top, left + width, top + height); +} + +void CXFA_Path::AddEllipse(const CFX_RectF& rect) { + AddArc(rect.TopLeft(), rect.Size(), 0, FX_PI * 2); +} + +void CXFA_Path::AddArc(const CFX_PointF& original_pos, + const CFX_SizeF& original_size, + float start_angle, + float sweep_angle) { + if (sweep_angle == 0) + return; + + const float bezier_arc_angle_epsilon = 0.01f; + while (start_angle > FX_PI * 2) + start_angle -= FX_PI * 2; + while (start_angle < 0) + start_angle += FX_PI * 2; + if (sweep_angle >= FX_PI * 2) + sweep_angle = FX_PI * 2; + if (sweep_angle <= -FX_PI * 2) + sweep_angle = -FX_PI * 2; + + CFX_SizeF size = original_size / 2; + CFX_PointF pos(original_pos.x + size.width, original_pos.y + size.height); + data_.AppendPoint(pos + CFX_PointF(size.width * cos(start_angle), + size.height * sin(start_angle)), + FXPT_TYPE::MoveTo, false); + + float total_sweep = 0; + float local_sweep = 0; + float prev_sweep = 0; + bool done = false; + do { + if (sweep_angle < 0) { + prev_sweep = total_sweep; + local_sweep = -FX_PI / 2; + total_sweep -= FX_PI / 2; + if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } else { + prev_sweep = total_sweep; + local_sweep = FX_PI / 2; + total_sweep += FX_PI / 2; + if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } + + ArcToInternal(pos, size, start_angle, local_sweep); + start_angle += local_sweep; + } while (!done); +} + +void CXFA_Path::AddSubpath(CXFA_Path* path) { + if (!path) + return; + data_.Append(&path->data_, nullptr); +} + +void CXFA_Path::TransformBy(const CFX_Matrix& mt) { + data_.Transform(&mt); +} diff --git a/xfa/fxgraphics/cxfa_path.h b/xfa/fxgraphics/cxfa_path.h new file mode 100644 index 0000000000..9c71a4d5ff --- /dev/null +++ b/xfa/fxgraphics/cxfa_path.h @@ -0,0 +1,55 @@ +// Copyright 2016 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 + +#ifndef XFA_FXGRAPHICS_CXFA_PATH_H_ +#define XFA_FXGRAPHICS_CXFA_PATH_H_ + +#include "core/fxcrt/fx_system.h" +#include "core/fxge/cfx_pathdata.h" +#include "xfa/fxgraphics/cxfa_graphics.h" + +class CXFA_Path final { + public: + CXFA_Path(); + ~CXFA_Path(); + + const CFX_PathData* GetPathData() const { return &data_; } + + void Clear(); + bool IsEmpty() const { return data_.GetPoints().empty(); } + void TransformBy(const CFX_Matrix& mt); + + void Close(); + void MoveTo(const CFX_PointF& point); + void LineTo(const CFX_PointF& point); + void BezierTo(const CFX_PointF& c1, + const CFX_PointF& c2, + const CFX_PointF& to); + void ArcTo(const CFX_PointF& pos, + const CFX_SizeF& size, + float startAngle, + float sweepAngle); + + void AddLine(const CFX_PointF& p1, const CFX_PointF& p2); + void AddRectangle(float left, float top, float width, float height); + void AddEllipse(const CFX_RectF& rect); + void AddArc(const CFX_PointF& pos, + const CFX_SizeF& size, + float startAngle, + float sweepAngle); + + void AddSubpath(CXFA_Path* path); + + private: + void ArcToInternal(const CFX_PointF& pos, + const CFX_SizeF& size, + float start_angle, + float sweep_angle); + + CFX_PathData data_; +}; + +#endif // XFA_FXGRAPHICS_CXFA_PATH_H_ diff --git a/xfa/fxgraphics/cxfa_pattern.cpp b/xfa/fxgraphics/cxfa_pattern.cpp new file mode 100644 index 0000000000..ea6cea87a5 --- /dev/null +++ b/xfa/fxgraphics/cxfa_pattern.cpp @@ -0,0 +1,20 @@ +// Copyright 2016 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 "xfa/fxgraphics/cxfa_pattern.h" + +CXFA_Pattern::CXFA_Pattern(FX_HatchStyle hatchStyle, + const FX_ARGB foreArgb, + const FX_ARGB backArgb, + CFX_Matrix* matrix) + : m_hatchStyle(hatchStyle), m_foreArgb(foreArgb), m_backArgb(backArgb) { + if (matrix) + m_matrix = *matrix; + else + m_matrix.SetIdentity(); +} + +CXFA_Pattern::~CXFA_Pattern() {} diff --git a/xfa/fxgraphics/cxfa_pattern.h b/xfa/fxgraphics/cxfa_pattern.h new file mode 100644 index 0000000000..838ec98b01 --- /dev/null +++ b/xfa/fxgraphics/cxfa_pattern.h @@ -0,0 +1,36 @@ +// Copyright 2016 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 + +#ifndef XFA_FXGRAPHICS_CXFA_PATTERN_H_ +#define XFA_FXGRAPHICS_CXFA_PATTERN_H_ + +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" +#include "xfa/fxgraphics/cxfa_graphics.h" + +class CFX_DIBitmap; +class CFX_Matrix; + +class CXFA_Pattern { + public: + CXFA_Pattern(FX_HatchStyle hatchStyle, + const FX_ARGB foreArgb, + const FX_ARGB backArgb, + CFX_Matrix* matrix = nullptr); + + virtual ~CXFA_Pattern(); + + private: + friend class CXFA_Graphics; + + CFX_Matrix m_matrix; + + const FX_HatchStyle m_hatchStyle; + const FX_ARGB m_foreArgb; + const FX_ARGB m_backArgb; +}; + +#endif // XFA_FXGRAPHICS_CXFA_PATTERN_H_ diff --git a/xfa/fxgraphics/cxfa_shading.cpp b/xfa/fxgraphics/cxfa_shading.cpp new file mode 100644 index 0000000000..599a3f9d42 --- /dev/null +++ b/xfa/fxgraphics/cxfa_shading.cpp @@ -0,0 +1,78 @@ +// Copyright 2016 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 "xfa/fxgraphics/cxfa_shading.h" + +CXFA_Shading::CXFA_Shading(const CFX_PointF& beginPoint, + const CFX_PointF& endPoint, + bool isExtendedBegin, + bool isExtendedEnd, + const FX_ARGB beginArgb, + const FX_ARGB endArgb) + : m_type(FX_SHADING_Axial), + m_beginPoint(beginPoint), + m_endPoint(endPoint), + m_beginRadius(0), + m_endRadius(0), + m_isExtendedBegin(isExtendedBegin), + m_isExtendedEnd(isExtendedEnd), + m_beginArgb(beginArgb), + m_endArgb(endArgb) { + InitArgbArray(); +} + +CXFA_Shading::CXFA_Shading(const CFX_PointF& beginPoint, + const CFX_PointF& endPoint, + const float beginRadius, + const float endRadius, + bool isExtendedBegin, + bool isExtendedEnd, + const FX_ARGB beginArgb, + const FX_ARGB endArgb) + : m_type(FX_SHADING_Radial), + m_beginPoint(beginPoint), + m_endPoint(endPoint), + m_beginRadius(beginRadius), + m_endRadius(endRadius), + m_isExtendedBegin(isExtendedBegin), + m_isExtendedEnd(isExtendedEnd), + m_beginArgb(beginArgb), + m_endArgb(endArgb) { + InitArgbArray(); +} + +CXFA_Shading::~CXFA_Shading() {} + +void CXFA_Shading::InitArgbArray() { + int32_t a1; + int32_t r1; + int32_t g1; + int32_t b1; + std::tie(a1, r1, g1, b1) = ArgbDecode(m_beginArgb); + + int32_t a2; + int32_t r2; + int32_t g2; + int32_t b2; + std::tie(a2, r2, g2, b2) = ArgbDecode(m_endArgb); + + float f = static_cast(FX_SHADING_Steps - 1); + float aScale = 1.0 * (a2 - a1) / f; + float rScale = 1.0 * (r2 - r1) / f; + float gScale = 1.0 * (g2 - g1) / f; + float bScale = 1.0 * (b2 - b1) / f; + + for (int32_t i = 0; i < FX_SHADING_Steps; i++) { + int32_t a3 = static_cast(i * aScale); + int32_t r3 = static_cast(i * rScale); + int32_t g3 = static_cast(i * gScale); + int32_t b3 = static_cast(i * bScale); + + // TODO(dsinclair): Add overloads for FX_ARGB. pdfium:437 + m_argbArray[i] = + FXARGB_TODIB(FXARGB_MAKE(a1 + a3, r1 + r3, g1 + g3, b1 + b3)); + } +} diff --git a/xfa/fxgraphics/cxfa_shading.h b/xfa/fxgraphics/cxfa_shading.h new file mode 100644 index 0000000000..22ef941250 --- /dev/null +++ b/xfa/fxgraphics/cxfa_shading.h @@ -0,0 +1,56 @@ +// Copyright 2016 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 + +#ifndef XFA_FXGRAPHICS_CXFA_SHADING_H_ +#define XFA_FXGRAPHICS_CXFA_SHADING_H_ + +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" +#include "core/fxge/fx_dib.h" + +#define FX_SHADING_Steps 256 + +enum CXFA_Shading_Type { FX_SHADING_Axial = 1, FX_SHADING_Radial }; + +class CXFA_Shading { + public: + // Axial shading. + CXFA_Shading(const CFX_PointF& beginPoint, + const CFX_PointF& endPoint, + bool isExtendedBegin, + bool isExtendedEnd, + const FX_ARGB beginArgb, + const FX_ARGB endArgb); + + // Radial shading. + CXFA_Shading(const CFX_PointF& beginPoint, + const CFX_PointF& endPoint, + const float beginRadius, + const float endRadius, + bool isExtendedBegin, + bool isExtendedEnd, + const FX_ARGB beginArgb, + const FX_ARGB endArgb); + virtual ~CXFA_Shading(); + + private: + friend class CXFA_Graphics; + + void InitArgbArray(); + + const CXFA_Shading_Type m_type; + const CFX_PointF m_beginPoint; + const CFX_PointF m_endPoint; + const float m_beginRadius; + const float m_endRadius; + const bool m_isExtendedBegin; + const bool m_isExtendedEnd; + const FX_ARGB m_beginArgb; + const FX_ARGB m_endArgb; + FX_ARGB m_argbArray[FX_SHADING_Steps]; +}; + +#endif // XFA_FXGRAPHICS_CXFA_SHADING_H_ -- cgit v1.2.3