| Index: xfa/src/fxfa/src/app/xfa_ffwidget.cpp
|
| diff --git a/xfa/src/fxfa/src/app/xfa_ffwidget.cpp b/xfa/src/fxfa/src/app/xfa_ffwidget.cpp
|
| index 08194bade152b93ecfc0ad2200cd8b0832516c61..f97e272b04fd34c27ba3c2e2011ced9ff1e43904 100644
|
| --- a/xfa/src/fxfa/src/app/xfa_ffwidget.cpp
|
| +++ b/xfa/src/fxfa/src/app/xfa_ffwidget.cpp
|
| @@ -1,1959 +1,1959 @@
|
| -// 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 <algorithm>
|
| -
|
| -#include "xfa/src/foxitlib.h"
|
| -#include "xfa/src/fxfa/src/common/xfa_common.h"
|
| -#include "xfa_ffapp.h"
|
| -#include "xfa_ffdoc.h"
|
| -#include "xfa_ffdocview.h"
|
| -#include "xfa_ffwidget.h"
|
| -#include "xfa_ffpageview.h"
|
| -#include "xfa_textlayout.h"
|
| -CXFA_FFWidget::CXFA_FFWidget(CXFA_FFPageView* pPageView,
|
| - CXFA_WidgetAcc* pDataAcc)
|
| - : CXFA_ContentLayoutItem(pDataAcc->GetNode()),
|
| - m_pPageView(pPageView),
|
| - m_pDataAcc(pDataAcc) {
|
| - m_rtWidget.Set(0, 0, 0, 0);
|
| -}
|
| -CXFA_FFWidget::~CXFA_FFWidget() {}
|
| -IXFA_PageView* CXFA_FFWidget::GetPageView() {
|
| - return m_pPageView;
|
| -}
|
| -void CXFA_FFWidget::SetPageView(IXFA_PageView* pPageView) {
|
| - m_pPageView = static_cast<CXFA_FFPageView*>(pPageView);
|
| -}
|
| -void CXFA_FFWidget::GetWidgetRect(CFX_RectF& rtWidget) {
|
| - if ((m_dwStatus & XFA_WIDGETSTATUS_RectCached) == 0) {
|
| - m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
|
| - GetRect(m_rtWidget);
|
| - }
|
| - rtWidget = m_rtWidget;
|
| -}
|
| -CFX_RectF CXFA_FFWidget::ReCacheWidgetRect() {
|
| - m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
|
| - GetRect(m_rtWidget);
|
| - return m_rtWidget;
|
| -}
|
| -void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF& rtWidget) {
|
| - GetWidgetRect(rtWidget);
|
| - FX_FLOAT fValue = 0;
|
| - switch (m_pDataAcc->GetRotate()) {
|
| - case 90:
|
| - rtWidget.top = rtWidget.bottom();
|
| - fValue = rtWidget.width;
|
| - rtWidget.width = rtWidget.height;
|
| - rtWidget.height = fValue;
|
| - break;
|
| - case 180:
|
| - rtWidget.left = rtWidget.right();
|
| - rtWidget.top = rtWidget.bottom();
|
| - break;
|
| - case 270:
|
| - rtWidget.left = rtWidget.right();
|
| - fValue = rtWidget.width;
|
| - rtWidget.width = rtWidget.height;
|
| - rtWidget.height = fValue;
|
| - break;
|
| - }
|
| -}
|
| -FX_DWORD CXFA_FFWidget::GetStatus() {
|
| - return m_dwStatus;
|
| -}
|
| -void CXFA_FFWidget::ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved) {
|
| - m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::GetBBox(CFX_RectF& rtBox,
|
| - FX_DWORD dwStatus,
|
| - FX_BOOL bDrawFocus) {
|
| - if (bDrawFocus) {
|
| - return FALSE;
|
| - }
|
| -#ifndef _XFA_EMB
|
| - if (m_pPageView) {
|
| - m_pPageView->GetPageViewRect(rtBox);
|
| - }
|
| - return TRUE;
|
| -#endif
|
| - GetWidgetRect(rtBox);
|
| - return TRUE;
|
| -}
|
| -CXFA_WidgetAcc* CXFA_FFWidget::GetDataAcc() {
|
| - return m_pDataAcc;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::GetToolTip(CFX_WideString& wsToolTip) {
|
| - if (CXFA_Assist assist = m_pDataAcc->GetAssist()) {
|
| - if (CXFA_ToolTip toolTip = assist.GetToolTip()) {
|
| - return toolTip.GetTip(wsToolTip);
|
| - }
|
| - }
|
| - return GetCaptionText(wsToolTip);
|
| -}
|
| -void CXFA_FFWidget::RenderWidget(CFX_Graphics* pGS,
|
| - CFX_Matrix* pMatrix,
|
| - FX_DWORD dwStatus,
|
| - int32_t iRotate) {
|
| - if (!IsMatchVisibleStatus(dwStatus)) {
|
| - return;
|
| - }
|
| - CXFA_Border border = m_pDataAcc->GetBorder();
|
| - if (border) {
|
| - CFX_RectF rtBorder;
|
| - GetRectWithoutRotate(rtBorder);
|
| - CXFA_Margin margin = border.GetMargin();
|
| - if (margin.IsExistInXML()) {
|
| - XFA_RectWidthoutMargin(rtBorder, margin);
|
| - }
|
| - rtBorder.Normalize();
|
| - DrawBorder(pGS, border, rtBorder, pMatrix);
|
| - }
|
| -}
|
| -FX_BOOL CXFA_FFWidget::IsLoaded() {
|
| - return m_pPageView != NULL;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::LoadWidget() {
|
| - PerformLayout();
|
| - return TRUE;
|
| -}
|
| -void CXFA_FFWidget::UnloadWidget() {}
|
| -FX_BOOL CXFA_FFWidget::PerformLayout() {
|
| - ReCacheWidgetRect();
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::UpdateFWLData() {
|
| - return FALSE;
|
| -}
|
| -void CXFA_FFWidget::UpdateWidgetProperty() {}
|
| -void CXFA_FFWidget::DrawBorder(CFX_Graphics* pGS,
|
| - CXFA_Box box,
|
| - const CFX_RectF& rtBorder,
|
| - CFX_Matrix* pMatrix,
|
| - FX_DWORD dwFlags) {
|
| - XFA_DrawBox(box, pGS, rtBorder, pMatrix, dwFlags);
|
| -}
|
| -void CXFA_FFWidget::InvalidateWidget(const CFX_RectF* pRect) {
|
| - if (!pRect) {
|
| - CFX_RectF rtWidget;
|
| - GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
|
| - rtWidget.Inflate(2, 2);
|
| - GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, rtWidget,
|
| - XFA_INVALIDATE_CurrentPage);
|
| - } else {
|
| - GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, *pRect,
|
| - XFA_INVALIDATE_CurrentPage);
|
| - }
|
| -}
|
| -void CXFA_FFWidget::AddInvalidateRect(const CFX_RectF* pRect) {
|
| - CFX_RectF rtWidget;
|
| - if (pRect) {
|
| - rtWidget = *pRect;
|
| - } else {
|
| - GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
|
| - rtWidget.Inflate(2, 2);
|
| - }
|
| - m_pDocView->AddInvalidateRect(m_pPageView, rtWidget);
|
| -}
|
| -FX_BOOL CXFA_FFWidget::GetCaptionText(CFX_WideString& wsCap) {
|
| - CXFA_TextLayout* pCapTextlayout = m_pDataAcc->GetCaptionTextLayout();
|
| - if (!pCapTextlayout) {
|
| - return FALSE;
|
| - }
|
| - pCapTextlayout->GetText(wsCap);
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::IsFocused() {
|
| - return m_dwStatus & XFA_WIDGETSTATUS_Focused;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnMouseEnter() {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnMouseExit() {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnLButtonDown(FX_DWORD dwFlags,
|
| - FX_FLOAT fx,
|
| - FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnLButtonDblClk(FX_DWORD dwFlags,
|
| - FX_FLOAT fx,
|
| - FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnMouseWheel(FX_DWORD dwFlags,
|
| - int16_t zDelta,
|
| - FX_FLOAT fx,
|
| - FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnRButtonDown(FX_DWORD dwFlags,
|
| - FX_FLOAT fx,
|
| - FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnRButtonDblClk(FX_DWORD dwFlags,
|
| - FX_FLOAT fx,
|
| - FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -
|
| -FX_BOOL CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
|
| - CXFA_FFWidget* pParent = GetParent();
|
| - if (pParent != NULL && !pParent->IsAncestorOf(pOldWidget)) {
|
| - pParent->OnSetFocus(pOldWidget);
|
| - }
|
| - m_dwStatus |= XFA_WIDGETSTATUS_Focused;
|
| - CXFA_EventParam eParam;
|
| - eParam.m_eType = XFA_EVENT_Enter;
|
| - eParam.m_pTarget = m_pDataAcc;
|
| - m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Enter, &eParam);
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
|
| - m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
|
| - EventKillFocus();
|
| - if (pNewWidget != NULL) {
|
| - CXFA_FFWidget* pParent = GetParent();
|
| - if (pParent != NULL && !pParent->IsAncestorOf(pNewWidget)) {
|
| - pParent->OnKillFocus(pNewWidget);
|
| - }
|
| - }
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
|
| - return FALSE;
|
| -}
|
| -FX_DWORD CXFA_FFWidget::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
|
| - return FALSE;
|
| -}
|
| -void CXFA_FFWidget::Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy) {
|
| - CFX_Matrix mt;
|
| - GetRotateMatrix(mt);
|
| - if (mt.IsIdentity()) {
|
| - return;
|
| - }
|
| - CFX_Matrix mtReverse;
|
| - mtReverse.SetReverse(mt);
|
| - mtReverse.TransformPoint(fx, fy);
|
| -}
|
| -static void XFA_GetMatrix(CFX_Matrix& m,
|
| - int32_t iRotate,
|
| - int32_t at,
|
| - const CFX_RectF& rt) {
|
| - if (!iRotate) {
|
| - return;
|
| - }
|
| - FX_FLOAT fAnchorX, fAnchorY;
|
| - switch (at) {
|
| - case XFA_ATTRIBUTEENUM_TopLeft:
|
| - fAnchorX = rt.left, fAnchorY = rt.top;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_TopCenter:
|
| - fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.top;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_TopRight:
|
| - fAnchorX = rt.right(), fAnchorY = rt.top;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_MiddleLeft:
|
| - fAnchorX = rt.left, fAnchorY = (rt.top + rt.bottom()) / 2;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_MiddleCenter:
|
| - fAnchorX = (rt.left + rt.right()) / 2,
|
| - fAnchorY = (rt.top + rt.bottom()) / 2;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_MiddleRight:
|
| - fAnchorX = rt.right(), fAnchorY = (rt.top + rt.bottom()) / 2;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_BottomLeft:
|
| - fAnchorX = rt.left, fAnchorY = rt.bottom();
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_BottomCenter:
|
| - fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.bottom();
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_BottomRight:
|
| - fAnchorX = rt.right(), fAnchorY = rt.bottom();
|
| - break;
|
| - }
|
| - switch (iRotate) {
|
| - case 90:
|
| - m.a = 0, m.b = -1, m.c = 1, m.d = 0, m.e = fAnchorX - fAnchorY,
|
| - m.f = fAnchorX + fAnchorY;
|
| - break;
|
| - case 180:
|
| - m.a = -1, m.b = 0, m.c = 0, m.d = -1, m.e = fAnchorX * 2,
|
| - m.f = fAnchorY * 2;
|
| - break;
|
| - case 270:
|
| - m.a = 0, m.b = 1, m.c = -1, m.d = 0, m.e = fAnchorX + fAnchorY,
|
| - m.f = fAnchorY - fAnchorX;
|
| - break;
|
| - }
|
| -}
|
| -void CXFA_FFWidget::GetRotateMatrix(CFX_Matrix& mt) {
|
| - mt.Set(1, 0, 0, 1, 0, 0);
|
| - int32_t iRotate = m_pDataAcc->GetRotate();
|
| - if (!iRotate) {
|
| - return;
|
| - }
|
| - CFX_RectF rcWidget;
|
| - GetRectWithoutRotate(rcWidget);
|
| - XFA_ATTRIBUTEENUM at = XFA_ATTRIBUTEENUM_TopLeft;
|
| - XFA_GetMatrix(mt, iRotate, at, rcWidget);
|
| -}
|
| -FX_BOOL CXFA_FFWidget::IsLayoutRectEmpty() {
|
| - CFX_RectF rtLayout;
|
| - GetRectWithoutRotate(rtLayout);
|
| - return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
|
| -}
|
| -CXFA_FFWidget* CXFA_FFWidget::GetParent() {
|
| - CXFA_Node* pParentNode =
|
| - m_pDataAcc->GetNode()->GetNodeItem(XFA_NODEITEM_Parent);
|
| - if (pParentNode != NULL) {
|
| - CXFA_WidgetAcc* pParentWidgetAcc =
|
| - (CXFA_WidgetAcc*)pParentNode->GetWidgetData();
|
| - if (pParentWidgetAcc != NULL) {
|
| - return pParentWidgetAcc->GetNextWidget(NULL);
|
| - }
|
| - }
|
| - return NULL;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
|
| - if (!pWidget) {
|
| - return FALSE;
|
| - }
|
| - CXFA_Node* pNode = m_pDataAcc->GetNode();
|
| - CXFA_Node* pChildNode = pWidget->GetDataAcc()->GetNode();
|
| - while (pChildNode) {
|
| - if (pChildNode == pNode) {
|
| - return TRUE;
|
| - }
|
| - pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_Parent);
|
| - }
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_FFWidget::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
|
| - CFX_RectF rtWidget;
|
| - GetWidgetRect(rtWidget);
|
| - if (rtWidget.Contains(fx, fy)) {
|
| - return TRUE;
|
| - }
|
| - return FALSE;
|
| -}
|
| -CXFA_FFDocView* CXFA_FFWidget::GetDocView() {
|
| - return m_pDocView;
|
| -}
|
| -CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
|
| - return (CXFA_FFDoc*)m_pDocView->GetDoc();
|
| -}
|
| -CXFA_FFApp* CXFA_FFWidget::GetApp() {
|
| - return GetDoc()->GetApp();
|
| -}
|
| -IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() {
|
| - return GetApp()->GetAppProvider();
|
| -}
|
| -void CXFA_FFWidget::GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth) {
|
| - fMinWidth = fMaxWidth = 0;
|
| - FX_FLOAT fWidth = 0;
|
| - if (m_pDataAcc->GetWidth(fWidth)) {
|
| - fMinWidth = fMaxWidth = fWidth;
|
| - } else {
|
| - m_pDataAcc->GetMinWidth(fMinWidth);
|
| - m_pDataAcc->GetMaxWidth(fMaxWidth);
|
| - }
|
| -}
|
| -void CXFA_FFWidget::GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight) {
|
| - fMinHeight = fMaxHeight = 0;
|
| - FX_FLOAT fHeight = 0;
|
| - if (m_pDataAcc->GetHeight(fHeight)) {
|
| - fMinHeight = fMaxHeight = fHeight;
|
| - } else {
|
| - m_pDataAcc->GetMinHeight(fMinHeight);
|
| - m_pDataAcc->GetMaxHeight(fMaxHeight);
|
| - }
|
| -}
|
| -FX_BOOL CXFA_FFWidget::IsMatchVisibleStatus(FX_DWORD dwStatus) {
|
| - return m_dwStatus & XFA_WIDGETSTATUS_Visible;
|
| -}
|
| -void CXFA_FFWidget::EventKillFocus() {
|
| - if (m_dwStatus & XFA_WIDGETSTATUS_Access) {
|
| - m_dwStatus &= ~XFA_WIDGETSTATUS_Access;
|
| - return;
|
| - }
|
| - CXFA_EventParam eParam;
|
| - eParam.m_eType = XFA_EVENT_Exit;
|
| - eParam.m_pTarget = m_pDataAcc;
|
| - m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Exit, &eParam);
|
| -}
|
| -FX_BOOL CXFA_FFWidget::IsButtonDown() {
|
| - return (m_dwStatus & XFA_WIDGETSTATUS_ButtonDown) != 0;
|
| -}
|
| -void CXFA_FFWidget::SetButtonDown(FX_BOOL bSet) {
|
| - bSet ? m_dwStatus |= XFA_WIDGETSTATUS_ButtonDown
|
| - : m_dwStatus &= ~XFA_WIDGETSTATUS_ButtonDown;
|
| -}
|
| -int32_t XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics,
|
| - int32_t iStrokeType,
|
| - int32_t iCapType) {
|
| - switch (iStrokeType) {
|
| - case XFA_ATTRIBUTEENUM_DashDot: {
|
| - FX_FLOAT dashArray[] = {4, 1, 2, 1};
|
| - if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| - dashArray[1] = 2;
|
| - dashArray[3] = 2;
|
| - }
|
| - pGraphics->SetLineDash(0, dashArray, 4);
|
| - return FX_DASHSTYLE_DashDot;
|
| - }
|
| - case XFA_ATTRIBUTEENUM_DashDotDot: {
|
| - FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
|
| - if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| - dashArray[1] = 2;
|
| - dashArray[3] = 2;
|
| - dashArray[5] = 2;
|
| - }
|
| - pGraphics->SetLineDash(0, dashArray, 6);
|
| - return FX_DASHSTYLE_DashDotDot;
|
| - }
|
| - case XFA_ATTRIBUTEENUM_Dashed: {
|
| - FX_FLOAT dashArray[] = {5, 1};
|
| - if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| - dashArray[1] = 2;
|
| - }
|
| - pGraphics->SetLineDash(0, dashArray, 2);
|
| - return FX_DASHSTYLE_Dash;
|
| - }
|
| - case XFA_ATTRIBUTEENUM_Dotted: {
|
| - FX_FLOAT dashArray[] = {2, 1};
|
| - if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| - dashArray[1] = 2;
|
| - }
|
| - pGraphics->SetLineDash(0, dashArray, 2);
|
| - return FX_DASHSTYLE_Dot;
|
| - }
|
| - default:
|
| - break;
|
| - }
|
| - pGraphics->SetLineDash(FX_DASHSTYLE_Solid);
|
| - return FX_DASHSTYLE_Solid;
|
| -}
|
| -CFX_GraphStateData::LineCap XFA_LineCapToFXGE(int32_t iLineCap) {
|
| - switch (iLineCap) {
|
| - case XFA_ATTRIBUTEENUM_Round:
|
| - return CFX_GraphStateData::LineCapRound;
|
| - case XFA_ATTRIBUTEENUM_Butt:
|
| - return CFX_GraphStateData::LineCapButt;
|
| - default:
|
| - break;
|
| - }
|
| - return CFX_GraphStateData::LineCapSquare;
|
| -}
|
| -class CXFA_ImageRenderer {
|
| - public:
|
| - CXFA_ImageRenderer();
|
| - ~CXFA_ImageRenderer();
|
| - FX_BOOL Start(CFX_RenderDevice* pDevice,
|
| - CFX_DIBSource* pDIBSource,
|
| - FX_ARGB bitmap_argb,
|
| - int bitmap_alpha,
|
| - const CFX_Matrix* pImage2Device,
|
| - FX_DWORD flags,
|
| - int blendType = FXDIB_BLEND_NORMAL);
|
| - FX_BOOL Continue(IFX_Pause* pPause);
|
| -
|
| - protected:
|
| - CFX_RenderDevice* m_pDevice;
|
| - int m_Status;
|
| - CFX_Matrix m_ImageMatrix;
|
| - CFX_DIBSource* m_pDIBSource;
|
| - CFX_DIBitmap* m_pCloneConvert;
|
| - int m_BitmapAlpha;
|
| - FX_ARGB m_FillArgb;
|
| - FX_DWORD m_Flags;
|
| - CFX_ImageTransformer* m_pTransformer;
|
| - void* m_DeviceHandle;
|
| - int32_t m_BlendType;
|
| - FX_BOOL m_Result;
|
| - FX_BOOL m_bPrint;
|
| - FX_BOOL StartDIBSource();
|
| - void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
|
| - int left,
|
| - int top,
|
| - FX_ARGB mask_argb,
|
| - int bitmap_alpha,
|
| - int blend_mode,
|
| - int Transparency);
|
| -};
|
| -CXFA_ImageRenderer::CXFA_ImageRenderer() {
|
| - m_pDevice = NULL;
|
| - m_Status = 0;
|
| - m_pDIBSource = NULL;
|
| - m_pCloneConvert = NULL;
|
| - m_BitmapAlpha = 255;
|
| - m_FillArgb = 0;
|
| - m_Flags = 0;
|
| - m_pTransformer = NULL;
|
| - m_DeviceHandle = NULL;
|
| - m_BlendType = FXDIB_BLEND_NORMAL;
|
| - m_Result = TRUE;
|
| - m_bPrint = FALSE;
|
| -}
|
| -CXFA_ImageRenderer::~CXFA_ImageRenderer() {
|
| - if (m_pCloneConvert) {
|
| - delete m_pCloneConvert;
|
| - }
|
| - if (m_pTransformer) {
|
| - delete m_pTransformer;
|
| - }
|
| - if (m_DeviceHandle) {
|
| - m_pDevice->CancelDIBits(m_DeviceHandle);
|
| - }
|
| -}
|
| -FX_BOOL CXFA_ImageRenderer::Start(CFX_RenderDevice* pDevice,
|
| - CFX_DIBSource* pDIBSource,
|
| - FX_ARGB bitmap_argb,
|
| - int bitmap_alpha,
|
| - const CFX_Matrix* pImage2Device,
|
| - FX_DWORD flags,
|
| - int blendType) {
|
| - m_pDevice = pDevice;
|
| - m_pDIBSource = pDIBSource;
|
| - m_FillArgb = bitmap_argb;
|
| - m_BitmapAlpha = bitmap_alpha;
|
| - m_ImageMatrix = *pImage2Device;
|
| - m_Flags = flags;
|
| - m_BlendType = blendType;
|
| - return StartDIBSource();
|
| -}
|
| -FX_BOOL CXFA_ImageRenderer::StartDIBSource() {
|
| - if (m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
|
| - &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL,
|
| - m_BlendType)) {
|
| - if (m_DeviceHandle != NULL) {
|
| - m_Status = 3;
|
| - return TRUE;
|
| - }
|
| - return FALSE;
|
| - }
|
| - CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
|
| - FX_RECT image_rect = image_rect_f.GetOutterRect();
|
| - int dest_width = image_rect.Width();
|
| - int dest_height = image_rect.Height();
|
| - if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
|
| - (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
|
| - if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
|
| - m_Result = FALSE;
|
| - return FALSE;
|
| - }
|
| - CFX_DIBSource* pDib = m_pDIBSource;
|
| - if (m_pDIBSource->HasAlpha() &&
|
| - !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE) &&
|
| - !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
|
| - m_pCloneConvert = m_pDIBSource->CloneConvert(FXDIB_Rgb);
|
| - if (!m_pCloneConvert) {
|
| - m_Result = FALSE;
|
| - return FALSE;
|
| - }
|
| - pDib = m_pCloneConvert;
|
| - }
|
| - FX_RECT clip_box = m_pDevice->GetClipBox();
|
| - clip_box.Intersect(image_rect);
|
| - m_Status = 2;
|
| - m_pTransformer = new CFX_ImageTransformer;
|
| - m_pTransformer->Start(pDib, &m_ImageMatrix, m_Flags, &clip_box);
|
| - return TRUE;
|
| - }
|
| - if (m_ImageMatrix.a < 0) {
|
| - dest_width = -dest_width;
|
| - }
|
| - if (m_ImageMatrix.d > 0) {
|
| - dest_height = -dest_height;
|
| - }
|
| - int dest_left, dest_top;
|
| - dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
|
| - dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
|
| - if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
|
| - if (m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top, dest_width,
|
| - dest_height, m_Flags, NULL, m_BlendType)) {
|
| - return FALSE;
|
| - }
|
| - }
|
| - if (m_pDIBSource->IsAlphaMask()) {
|
| - if (m_BitmapAlpha != 255) {
|
| - m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
|
| - }
|
| - if (m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width,
|
| - dest_height, m_FillArgb, m_Flags)) {
|
| - return FALSE;
|
| - }
|
| - }
|
| - if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
|
| - m_Result = FALSE;
|
| - return TRUE;
|
| - }
|
| - FX_RECT clip_box = m_pDevice->GetClipBox();
|
| - FX_RECT dest_rect = clip_box;
|
| - dest_rect.Intersect(image_rect);
|
| - FX_RECT dest_clip(
|
| - dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
|
| - dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
|
| - CFX_DIBitmap* pStretched =
|
| - m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
|
| - if (pStretched) {
|
| - CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb,
|
| - m_BitmapAlpha, m_BlendType, FALSE);
|
| - delete pStretched;
|
| - pStretched = NULL;
|
| - }
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CXFA_ImageRenderer::Continue(IFX_Pause* pPause) {
|
| - if (m_Status == 2) {
|
| - if (m_pTransformer->Continue(pPause)) {
|
| - return TRUE;
|
| - }
|
| - CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
|
| - if (pBitmap == NULL) {
|
| - return FALSE;
|
| - }
|
| - if (pBitmap->IsAlphaMask()) {
|
| - if (m_BitmapAlpha != 255) {
|
| - m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
|
| - }
|
| - m_Result = m_pDevice->SetBitMask(pBitmap, m_pTransformer->m_ResultLeft,
|
| - m_pTransformer->m_ResultTop, m_FillArgb);
|
| - } else {
|
| - if (m_BitmapAlpha != 255) {
|
| - pBitmap->MultiplyAlpha(m_BitmapAlpha);
|
| - }
|
| - m_Result = m_pDevice->SetDIBits(pBitmap, m_pTransformer->m_ResultLeft,
|
| - m_pTransformer->m_ResultTop, m_BlendType);
|
| - }
|
| - delete pBitmap;
|
| - return FALSE;
|
| - } else if (m_Status == 3) {
|
| - return m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
|
| - }
|
| - return FALSE;
|
| -}
|
| -void CXFA_ImageRenderer::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
|
| - int left,
|
| - int top,
|
| - FX_ARGB mask_argb,
|
| - int bitmap_alpha,
|
| - int blend_mode,
|
| - int Transparency) {
|
| - if (pDIBitmap == NULL) {
|
| - return;
|
| - }
|
| - FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
|
| - FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
|
| - if (blend_mode == FXDIB_BLEND_NORMAL) {
|
| - if (!pDIBitmap->IsAlphaMask()) {
|
| - if (bitmap_alpha < 255) {
|
| - pDIBitmap->MultiplyAlpha(bitmap_alpha);
|
| - }
|
| - if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
|
| - return;
|
| - }
|
| - } else {
|
| - FX_DWORD fill_argb = (mask_argb);
|
| - if (bitmap_alpha < 255) {
|
| - ((uint8_t*)&fill_argb)[3] =
|
| - ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
|
| - }
|
| - if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
|
| - return;
|
| - }
|
| - }
|
| - }
|
| - FX_BOOL bBackAlphaRequired = blend_mode && bIsolated;
|
| - FX_BOOL bGetBackGround =
|
| - ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
|
| - (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
|
| - (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
|
| - if (bGetBackGround) {
|
| - if (bIsolated || !bGroup) {
|
| - if (pDIBitmap->IsAlphaMask()) {
|
| - return;
|
| - }
|
| - m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
|
| - } else {
|
| - FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
|
| - top + pDIBitmap->GetHeight());
|
| - rect.Intersect(m_pDevice->GetClipBox());
|
| - CFX_DIBitmap* pClone = NULL;
|
| - FX_BOOL bClone = FALSE;
|
| - if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
|
| - bClone = TRUE;
|
| - pClone = m_pDevice->GetBackDrop()->Clone(&rect);
|
| - CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
|
| - pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
|
| - pForeBitmap, rect.left, rect.top);
|
| - left = left >= 0 ? 0 : left;
|
| - top = top >= 0 ? 0 : top;
|
| - if (!pDIBitmap->IsAlphaMask())
|
| - pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
|
| - pDIBitmap, left, top, blend_mode);
|
| - else
|
| - pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
|
| - pDIBitmap, mask_argb, left, top, blend_mode);
|
| - } else {
|
| - pClone = pDIBitmap;
|
| - }
|
| - if (m_pDevice->GetBackDrop()) {
|
| - m_pDevice->SetDIBits(pClone, rect.left, rect.top);
|
| - } else {
|
| - if (pDIBitmap->IsAlphaMask()) {
|
| - return;
|
| - }
|
| - m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
|
| - }
|
| - if (bClone) {
|
| - delete pClone;
|
| - }
|
| - }
|
| - return;
|
| - }
|
| - if (pDIBitmap->HasAlpha() &&
|
| - !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE)) {
|
| - CFX_DIBitmap* pCloneConvert = pDIBitmap->CloneConvert(FXDIB_Rgb);
|
| - if (!pCloneConvert) {
|
| - return;
|
| - }
|
| - CXFA_ImageRenderer imageRender;
|
| - FX_BOOL bRet = imageRender.Start(m_pDevice, pCloneConvert, m_FillArgb,
|
| - m_BitmapAlpha, &m_ImageMatrix, m_Flags);
|
| - while (bRet) {
|
| - bRet = imageRender.Continue(NULL);
|
| - }
|
| - delete pCloneConvert;
|
| - return;
|
| - }
|
| -}
|
| -void XFA_DrawImage(CFX_Graphics* pGS,
|
| - const CFX_RectF& rtImage,
|
| - CFX_Matrix* pMatrix,
|
| - CFX_DIBitmap* pDIBitmap,
|
| - int32_t iAspect,
|
| - int32_t iImageXDpi,
|
| - int32_t iImageYDpi,
|
| - int32_t iHorzAlign,
|
| - int32_t iVertAlign) {
|
| - if (rtImage.IsEmpty()) {
|
| - return;
|
| - }
|
| - if (!pDIBitmap || !pDIBitmap->GetBuffer()) {
|
| - return;
|
| - }
|
| - FX_FLOAT fWidth =
|
| - XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
|
| - FX_FLOAT fHeight =
|
| - XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
|
| - CFX_RectF rtFit;
|
| - rtFit.Set(rtImage.left, rtImage.top, fWidth, fHeight);
|
| - switch (iAspect) {
|
| - case XFA_ATTRIBUTEENUM_Fit: {
|
| - FX_FLOAT f1 = rtImage.height / rtFit.height;
|
| - FX_FLOAT f2 = rtImage.width / rtFit.width;
|
| - f1 = std::min(f1, f2);
|
| - rtFit.height = rtFit.height * f1;
|
| - rtFit.width = rtFit.width * f1;
|
| - } break;
|
| - case XFA_ATTRIBUTEENUM_Actual:
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_Height: {
|
| - FX_FLOAT f1 = rtImage.height / rtFit.height;
|
| - rtFit.height = rtImage.height;
|
| - rtFit.width = f1 * rtFit.width;
|
| - } break;
|
| - case XFA_ATTRIBUTEENUM_None:
|
| - rtFit.height = rtImage.height;
|
| - rtFit.width = rtImage.width;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_Width: {
|
| - FX_FLOAT f1 = rtImage.width / rtFit.width;
|
| - rtFit.width = rtImage.width;
|
| - rtFit.height = rtFit.height * f1;
|
| - } break;
|
| - }
|
| - if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
|
| - rtFit.left += (rtImage.width - rtFit.width) / 2;
|
| - } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
|
| - rtFit.left = rtImage.right() - rtFit.width;
|
| - }
|
| - if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
|
| - rtFit.top += (rtImage.height - rtFit.height) / 2;
|
| - } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
|
| - rtFit.top = rtImage.bottom() - rtImage.height;
|
| - }
|
| - CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
|
| - pRenderDevice->SaveState();
|
| - CFX_PathData path;
|
| - path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
|
| - pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING);
|
| - CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
|
| - mtImage.Concat(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top);
|
| - mtImage.Concat(*pMatrix);
|
| - CXFA_ImageRenderer imageRender;
|
| - FX_BOOL bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage,
|
| - FXDIB_INTERPOL);
|
| - while (bRet) {
|
| - bRet = imageRender.Continue(NULL);
|
| - }
|
| - pRenderDevice->RestoreState();
|
| -}
|
| -const static uint8_t g_inv_base64[128] = {
|
| - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
| - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
| - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
|
| - 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
| - 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
| - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
| - 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
|
| - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
| - 49, 50, 51, 255, 255, 255, 255, 255,
|
| -};
|
| -static uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
|
| - uint8_t* pCP;
|
| - int32_t i = 0, j = 0;
|
| - if (iLen == 0) {
|
| - iLen = FXSYS_strlen((FX_CHAR*)pStr);
|
| - }
|
| - pCP = FX_Alloc(uint8_t, iLen + 1);
|
| - for (; i < iLen; i++) {
|
| - if ((pStr[i] & 128) == 0) {
|
| - if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
|
| - pCP[j++] = pStr[i];
|
| - }
|
| - }
|
| - }
|
| - pCP[j] = '\0';
|
| - return pCP;
|
| -}
|
| -static int32_t XFA_Base64Decode(const FX_CHAR* pStr, uint8_t* pOutBuffer) {
|
| - if (pStr == NULL) {
|
| - return 0;
|
| - }
|
| - uint8_t* pBuffer =
|
| - XFA_RemoveBase64Whitespace((uint8_t*)pStr, FXSYS_strlen((FX_CHAR*)pStr));
|
| - if (pBuffer == NULL) {
|
| - return 0;
|
| - }
|
| - int32_t iLen = FXSYS_strlen((FX_CHAR*)pBuffer);
|
| - int32_t i = 0, j = 0;
|
| - FX_DWORD dwLimb = 0;
|
| - for (; i + 3 < iLen; i += 4) {
|
| - if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
|
| - pBuffer[i + 3] == '=') {
|
| - if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
|
| - break;
|
| - }
|
| - if (pBuffer[i + 2] == '=') {
|
| - dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 6) |
|
| - ((FX_DWORD)g_inv_base64[pBuffer[i + 1]]);
|
| - pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
|
| - j++;
|
| - } else {
|
| - dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 12) |
|
| - ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 6) |
|
| - ((FX_DWORD)g_inv_base64[pBuffer[i + 2]]);
|
| - pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
|
| - pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
|
| - j += 2;
|
| - }
|
| - } else {
|
| - dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 18) |
|
| - ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 12) |
|
| - ((FX_DWORD)g_inv_base64[pBuffer[i + 2]] << 6) |
|
| - ((FX_DWORD)g_inv_base64[pBuffer[i + 3]]);
|
| - pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
|
| - pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
|
| - pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
|
| - j += 3;
|
| - }
|
| - }
|
| - FX_Free(pBuffer);
|
| - return j;
|
| -}
|
| -static FX_CHAR g_base64_chars[] =
|
| - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
| -FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len) {
|
| - FX_CHAR* out = NULL;
|
| - int i, j;
|
| - FX_DWORD limb;
|
| - out = FX_Alloc(FX_CHAR, ((buf_len * 8 + 5) / 6) + 5);
|
| - for (i = 0, j = 0, limb = 0; i + 2 < buf_len; i += 3, j += 4) {
|
| - limb = ((FX_DWORD)buf[i] << 16) | ((FX_DWORD)buf[i + 1] << 8) |
|
| - ((FX_DWORD)buf[i + 2]);
|
| - out[j] = g_base64_chars[(limb >> 18) & 63];
|
| - out[j + 1] = g_base64_chars[(limb >> 12) & 63];
|
| - out[j + 2] = g_base64_chars[(limb >> 6) & 63];
|
| - out[j + 3] = g_base64_chars[(limb)&63];
|
| - }
|
| - switch (buf_len - i) {
|
| - case 0:
|
| - break;
|
| - case 1:
|
| - limb = ((FX_DWORD)buf[i]);
|
| - out[j++] = g_base64_chars[(limb >> 2) & 63];
|
| - out[j++] = g_base64_chars[(limb << 4) & 63];
|
| - out[j++] = '=';
|
| - out[j++] = '=';
|
| - break;
|
| - case 2:
|
| - limb = ((FX_DWORD)buf[i] << 8) | ((FX_DWORD)buf[i + 1]);
|
| - out[j++] = g_base64_chars[(limb >> 10) & 63];
|
| - out[j++] = g_base64_chars[(limb >> 4) & 63];
|
| - out[j++] = g_base64_chars[(limb << 2) & 63];
|
| - out[j++] = '=';
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - out[j] = '\0';
|
| - return out;
|
| -}
|
| -FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideStringC& wsType) {
|
| - CFX_WideString wsContentType(wsType);
|
| - wsContentType.MakeLower();
|
| - if (wsContentType == FX_WSTRC(L"image/jpg")) {
|
| - return FXCODEC_IMAGE_JPG;
|
| - }
|
| - if (wsContentType == FX_WSTRC(L"image/png")) {
|
| - return FXCODEC_IMAGE_PNG;
|
| - }
|
| - if (wsContentType == FX_WSTRC(L"image/gif")) {
|
| - return FXCODEC_IMAGE_GIF;
|
| - }
|
| - if (wsContentType == FX_WSTRC(L"image/bmp")) {
|
| - return FXCODEC_IMAGE_BMP;
|
| - }
|
| - if (wsContentType == FX_WSTRC(L"image/tif")) {
|
| - return FXCODEC_IMAGE_TIF;
|
| - }
|
| - return FXCODEC_IMAGE_UNKNOWN;
|
| -}
|
| -CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc,
|
| - CXFA_Image* pImage,
|
| - FX_BOOL& bNameImage,
|
| - int32_t& iImageXDpi,
|
| - int32_t& iImageYDpi) {
|
| - CFX_WideString wsHref;
|
| - pImage->GetHref(wsHref);
|
| - CFX_WideString wsImage;
|
| - pImage->GetContent(wsImage);
|
| - if (wsHref.IsEmpty() && wsImage.IsEmpty()) {
|
| - return NULL;
|
| - }
|
| - CFX_WideString wsContentType;
|
| - pImage->GetContentType(wsContentType);
|
| - FXCODEC_IMAGE_TYPE type = XFA_GetImageType(wsContentType);
|
| - CFX_ByteString bsContent;
|
| - uint8_t* pImageBuffer = NULL;
|
| - IFX_FileRead* pImageFileRead = NULL;
|
| - if (wsImage.GetLength() > 0) {
|
| - XFA_ATTRIBUTEENUM iEncoding =
|
| - (XFA_ATTRIBUTEENUM)pImage->GetTransferEncoding();
|
| - if (iEncoding == XFA_ATTRIBUTEENUM_Base64) {
|
| - CFX_ByteString bsData = wsImage.UTF8Encode();
|
| - int32_t iLength = bsData.GetLength();
|
| - pImageBuffer = FX_Alloc(uint8_t, iLength);
|
| - int32_t iRead = XFA_Base64Decode((const FX_CHAR*)bsData, pImageBuffer);
|
| - if (iRead > 0) {
|
| - pImageFileRead = FX_CreateMemoryStream(pImageBuffer, iRead);
|
| - }
|
| - } else {
|
| - bsContent = CFX_ByteString::FromUnicode(wsImage);
|
| - pImageFileRead = FX_CreateMemoryStream(
|
| - (uint8_t*)(const uint8_t*)bsContent, bsContent.GetLength());
|
| - }
|
| - } else {
|
| - CFX_WideString wsURL = wsHref;
|
| - if (wsURL.Left(7) != FX_WSTRC(L"http://") &&
|
| - wsURL.Left(6) != FX_WSTRC(L"ftp://")) {
|
| - CFX_DIBitmap* pBitmap =
|
| - pDoc->GetPDFNamedImage(wsURL, iImageXDpi, iImageYDpi);
|
| - if (pBitmap != NULL) {
|
| - bNameImage = TRUE;
|
| - return pBitmap;
|
| - }
|
| - }
|
| - pImageFileRead = pDoc->GetDocProvider()->OpenLinkedFile(pDoc, wsURL);
|
| - }
|
| - if (!pImageFileRead) {
|
| - FX_Free(pImageBuffer);
|
| - return NULL;
|
| - }
|
| - bNameImage = FALSE;
|
| - CFX_DIBitmap* pBitmap =
|
| - XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
|
| - FX_Free(pImageBuffer);
|
| - pImageFileRead->Release();
|
| - return pBitmap;
|
| -}
|
| -static FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
|
| - int32_t iComponents,
|
| - int32_t iBitsPerComponent) {
|
| - FXDIB_Format dibFormat = FXDIB_Argb;
|
| - switch (type) {
|
| - case FXCODEC_IMAGE_BMP:
|
| - case FXCODEC_IMAGE_JPG:
|
| - case FXCODEC_IMAGE_TIF: {
|
| - dibFormat = FXDIB_Rgb32;
|
| - int32_t bpp = iComponents * iBitsPerComponent;
|
| - if (bpp <= 24) {
|
| - dibFormat = FXDIB_Rgb;
|
| - }
|
| - } break;
|
| - case FXCODEC_IMAGE_PNG:
|
| - default:
|
| - break;
|
| - }
|
| - return dibFormat;
|
| -}
|
| -CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead,
|
| - FXCODEC_IMAGE_TYPE type,
|
| - int32_t& iImageXDpi,
|
| - int32_t& iImageYDpi) {
|
| - CFX_GEModule* pGeModule = CFX_GEModule::Get();
|
| - if (!pGeModule) {
|
| - return NULL;
|
| - }
|
| - CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
|
| - if (!pCodecMgr) {
|
| - return NULL;
|
| - }
|
| - CFX_DIBAttribute dibAttr;
|
| - CFX_DIBitmap* pBitmap = NULL;
|
| - ICodec_ProgressiveDecoder* pProgressiveDecoder =
|
| - pCodecMgr->CreateProgressiveDecoder();
|
| - pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr);
|
| - switch (dibAttr.m_wDPIUnit) {
|
| - case FXCODEC_RESUNIT_CENTIMETER:
|
| - dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI * 2.54f);
|
| - dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI * 2.54f);
|
| - break;
|
| - case FXCODEC_RESUNIT_METER:
|
| - dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI / (FX_FLOAT)100 * 2.54f);
|
| - dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI / (FX_FLOAT)100 * 2.54f);
|
| - break;
|
| - ;
|
| - default:
|
| - break;
|
| - }
|
| - iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
|
| - iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
|
| - if (pProgressiveDecoder->GetWidth() > 0 &&
|
| - pProgressiveDecoder->GetHeight() > 0) {
|
| - type = pProgressiveDecoder->GetType();
|
| - int32_t iComponents = pProgressiveDecoder->GetNumComponents();
|
| - int32_t iBpc = pProgressiveDecoder->GetBPC();
|
| - FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
|
| - pBitmap = new CFX_DIBitmap();
|
| - pBitmap->Create(pProgressiveDecoder->GetWidth(),
|
| - pProgressiveDecoder->GetHeight(), dibFormat);
|
| - pBitmap->Clear(0xffffffff);
|
| - int32_t nFrames;
|
| - if ((pProgressiveDecoder->GetFrames(nFrames) ==
|
| - FXCODEC_STATUS_DECODE_READY) &&
|
| - (nFrames > 0)) {
|
| - pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(),
|
| - pBitmap->GetHeight());
|
| - pProgressiveDecoder->ContinueDecode();
|
| - }
|
| - }
|
| - delete pProgressiveDecoder;
|
| - return pBitmap;
|
| -}
|
| -void XFA_RectWidthoutMargin(CFX_RectF& rt, const CXFA_Margin& mg, FX_BOOL bUI) {
|
| - if (!mg) {
|
| - return;
|
| - }
|
| - FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
|
| - mg.GetLeftInset(fLeftInset);
|
| - mg.GetTopInset(fTopInset);
|
| - mg.GetRightInset(fRightInset);
|
| - mg.GetBottomInset(fBottomInset);
|
| - rt.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
|
| -}
|
| -CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
|
| - XFA_ELEMENT iType = pLayoutItem->GetFormNode()->GetClassID();
|
| - if (XFA_IsCreateWidget(iType)) {
|
| - return static_cast<CXFA_FFWidget*>(pLayoutItem);
|
| - }
|
| - return nullptr;
|
| -}
|
| -FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType) {
|
| - return iType == XFA_ELEMENT_Field || iType == XFA_ELEMENT_Draw ||
|
| - iType == XFA_ELEMENT_Subform || iType == XFA_ELEMENT_ExclGroup;
|
| -}
|
| -static void XFA_BOX_GetPath_Arc(CXFA_Box box,
|
| - CFX_RectF rtDraw,
|
| - CFX_Path& fillPath,
|
| - FX_DWORD dwFlags) {
|
| - FX_FLOAT a, b;
|
| - a = rtDraw.width / 2.0f;
|
| - b = rtDraw.height / 2.0f;
|
| - if (box.IsCircular() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
|
| - a = b = std::min(a, b);
|
| - }
|
| - CFX_PointF center = rtDraw.Center();
|
| - rtDraw.left = center.x - a;
|
| - rtDraw.top = center.y - b;
|
| - rtDraw.width = a + a;
|
| - rtDraw.height = b + b;
|
| - FX_FLOAT startAngle = 0, sweepAngle = 360;
|
| - FX_BOOL bStart = box.GetStartAngle(startAngle);
|
| - FX_BOOL bEnd = box.GetSweepAngle(sweepAngle);
|
| - if (!bStart && !bEnd) {
|
| - fillPath.AddEllipse(rtDraw);
|
| - return;
|
| - }
|
| - startAngle = -startAngle * FX_PI / 180.0f;
|
| - sweepAngle = -sweepAngle * FX_PI / 180.0f;
|
| - fillPath.AddArc(rtDraw.left, rtDraw.top, rtDraw.width, rtDraw.height,
|
| - startAngle, sweepAngle);
|
| -}
|
| -static void XFA_BOX_GetPath(CXFA_Box box,
|
| - const CXFA_StrokeArray& strokes,
|
| - CFX_RectF rtWidget,
|
| - CFX_Path& path,
|
| - int32_t nIndex,
|
| - FX_BOOL bStart,
|
| - FX_BOOL bCorner) {
|
| - FXSYS_assert(nIndex >= 0 && nIndex < 8);
|
| - FX_BOOL bInverted, bRound;
|
| - FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny, offsetY, offsetX,
|
| - offsetEX, offsetEY;
|
| - CFX_PointF cpStart, cp, cp1, cp2;
|
| - CFX_RectF rtRadius;
|
| - int32_t n = (nIndex & 1) ? nIndex - 1 : nIndex;
|
| - CXFA_Corner corner1 = (CXFA_Node*)strokes[n];
|
| - CXFA_Corner corner2 = (CXFA_Node*)strokes[(n + 2) % 8];
|
| - fRadius1 = bCorner ? corner1.GetRadius() : 0;
|
| - fRadius2 = bCorner ? corner2.GetRadius() : 0;
|
| - bInverted = corner1.IsInverted();
|
| - offsetY = 0.0f;
|
| - offsetX = 0.0f;
|
| - bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
|
| - FX_FLOAT halfAfter = 0.0f;
|
| - FX_FLOAT halfBefore = 0.0f;
|
| - CXFA_Stroke stroke = strokes[nIndex];
|
| - if (stroke.IsCorner()) {
|
| - CXFA_Stroke edgeBefore = strokes[(nIndex + 1 * 8 - 1) % 8];
|
| - CXFA_Stroke edgeAfter = strokes[nIndex + 1];
|
| - if (stroke.IsInverted()) {
|
| - if (!stroke.SameStyles(edgeBefore)) {
|
| - halfBefore = edgeBefore.GetThickness() / 2;
|
| - }
|
| - if (!stroke.SameStyles(edgeAfter)) {
|
| - halfAfter = edgeAfter.GetThickness() / 2;
|
| - }
|
| - }
|
| - } else {
|
| - CXFA_Stroke edgeBefore = strokes[(nIndex + 8 - 2) % 8];
|
| - CXFA_Stroke edgeAfter = strokes[(nIndex + 2) % 8];
|
| - if (!bRound && !bInverted) {
|
| - { halfBefore = edgeBefore.GetThickness() / 2; }
|
| - { halfAfter = edgeAfter.GetThickness() / 2; }
|
| - }
|
| - }
|
| - offsetEX = 0.0f;
|
| - offsetEY = 0.0f;
|
| - if (bRound) {
|
| - sy = FX_PI / 2;
|
| - }
|
| - switch (nIndex) {
|
| - case 0:
|
| - case 1:
|
| - cp1 = rtWidget.TopLeft();
|
| - cp2 = rtWidget.TopRight();
|
| - if (nIndex == 0) {
|
| - cpStart.x = cp1.x - halfBefore;
|
| - cpStart.y = cp1.y + fRadius1, offsetY = -halfAfter;
|
| - } else {
|
| - cpStart.x = cp1.x + fRadius1 - halfBefore, cpStart.y = cp1.y,
|
| - offsetEX = halfAfter;
|
| - }
|
| - vx = 1, vy = 1;
|
| - nx = -1, ny = 0;
|
| - if (bRound) {
|
| - sx = bInverted ? FX_PI / 2 : FX_PI;
|
| - } else {
|
| - sx = 1, sy = 0;
|
| - }
|
| - break;
|
| - case 2:
|
| - case 3:
|
| - cp1 = rtWidget.TopRight();
|
| - cp2 = rtWidget.BottomRight();
|
| - if (nIndex == 2) {
|
| - cpStart.x = cp1.x - fRadius1, cpStart.y = cp1.y - halfBefore,
|
| - offsetX = halfAfter;
|
| - } else {
|
| - cpStart.x = cp1.x, cpStart.y = cp1.y + fRadius1 - halfBefore,
|
| - offsetEY = halfAfter;
|
| - }
|
| - vx = -1, vy = 1;
|
| - nx = 0, ny = -1;
|
| - if (bRound) {
|
| - sx = bInverted ? FX_PI : FX_PI * 3 / 2;
|
| - } else {
|
| - sx = 0, sy = 1;
|
| - }
|
| - break;
|
| - case 4:
|
| - case 5:
|
| - cp1 = rtWidget.BottomRight();
|
| - cp2 = rtWidget.BottomLeft();
|
| - if (nIndex == 4) {
|
| - cpStart.x = cp1.x + halfBefore, cpStart.y = cp1.y - fRadius1,
|
| - offsetY = halfAfter;
|
| - } else {
|
| - cpStart.x = cp1.x - fRadius1 + halfBefore, cpStart.y = cp1.y,
|
| - offsetEX = -halfAfter;
|
| - }
|
| - vx = -1, vy = -1;
|
| - nx = 1, ny = 0;
|
| - if (bRound) {
|
| - sx = bInverted ? FX_PI * 3 / 2 : 0;
|
| - } else {
|
| - sx = -1, sy = 0;
|
| - }
|
| - break;
|
| - case 6:
|
| - case 7:
|
| - cp1 = rtWidget.BottomLeft();
|
| - cp2 = rtWidget.TopLeft();
|
| - if (nIndex == 6) {
|
| - cpStart.x = cp1.x + fRadius1, cpStart.y = cp1.y + halfBefore,
|
| - offsetX = -halfAfter;
|
| - } else {
|
| - cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore,
|
| - offsetEY = -halfAfter;
|
| - }
|
| - vx = 1, vy = -1;
|
| - nx = 0, ny = 1;
|
| - if (bRound) {
|
| - sx = bInverted ? 0 : FX_PI / 2;
|
| - } else {
|
| - sx = 0, sy = -1;
|
| - }
|
| - break;
|
| - }
|
| - if (bStart) {
|
| - path.MoveTo(cpStart.x, cpStart.y);
|
| - }
|
| - if (nIndex & 1) {
|
| - path.LineTo(cp2.x + fRadius2 * nx + offsetEX,
|
| - cp2.y + fRadius2 * ny + offsetEY);
|
| - return;
|
| - }
|
| - if (bRound) {
|
| - if (fRadius1 < 0) {
|
| - sx -= FX_PI;
|
| - }
|
| - if (bInverted) {
|
| - sy *= -1;
|
| - }
|
| - rtRadius.Set(cp1.x + offsetX * 2, cp1.y + offsetY * 2,
|
| - fRadius1 * 2 * vx - offsetX * 2,
|
| - fRadius1 * 2 * vy - offsetY * 2);
|
| - rtRadius.Normalize();
|
| - if (bInverted) {
|
| - rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
|
| - }
|
| - path.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx,
|
| - sy);
|
| - } else {
|
| - if (bInverted) {
|
| - cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
|
| - } else {
|
| - cp = cp1;
|
| - }
|
| - path.LineTo(cp.x, cp.y);
|
| - path.LineTo(cp1.x + fRadius1 * sx + offsetX,
|
| - cp1.y + fRadius1 * sy + offsetY);
|
| - }
|
| -}
|
| -static void XFA_BOX_GetFillPath(CXFA_Box box,
|
| - const CXFA_StrokeArray& strokes,
|
| - CFX_RectF rtWidget,
|
| - CFX_Path& fillPath,
|
| - FX_WORD dwFlags) {
|
| - if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
|
| - CXFA_Edge edge = box.GetEdge(0);
|
| - FX_FLOAT fThickness = edge.GetThickness();
|
| - if (fThickness < 0) {
|
| - fThickness = 0;
|
| - }
|
| - FX_FLOAT fHalf = fThickness / 2;
|
| - int32_t iHand = box.GetHand();
|
| - if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| - rtWidget.Inflate(fHalf, fHalf);
|
| - } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| - rtWidget.Deflate(fHalf, fHalf);
|
| - }
|
| - XFA_BOX_GetPath_Arc(box, rtWidget, fillPath, dwFlags);
|
| - return;
|
| - }
|
| - FX_BOOL bSameStyles = TRUE;
|
| - int32_t i;
|
| - CXFA_Stroke stroke1 = strokes[0];
|
| - for (i = 1; i < 8; i++) {
|
| - CXFA_Stroke stroke2 = strokes[i];
|
| - if (!stroke1.SameStyles(stroke2)) {
|
| - bSameStyles = FALSE;
|
| - break;
|
| - }
|
| - stroke1 = stroke2;
|
| - }
|
| - if (bSameStyles) {
|
| - stroke1 = strokes[0];
|
| - for (i = 2; i < 8; i += 2) {
|
| - CXFA_Stroke stroke2 = strokes[i];
|
| - if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
|
| - XFA_STROKE_SAMESTYLE_Corner)) {
|
| - bSameStyles = FALSE;
|
| - break;
|
| - }
|
| - stroke1 = stroke2;
|
| - }
|
| - if (bSameStyles) {
|
| - stroke1 = strokes[0];
|
| - if (stroke1.IsInverted()) {
|
| - bSameStyles = FALSE;
|
| - }
|
| - if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
|
| - bSameStyles = FALSE;
|
| - }
|
| - }
|
| - }
|
| - if (bSameStyles) {
|
| - fillPath.AddRectangle(rtWidget.left, rtWidget.top, rtWidget.width,
|
| - rtWidget.height);
|
| - return;
|
| - }
|
| - FX_BOOL bInverted, bRound;
|
| - FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny;
|
| - CFX_PointF cp, cp1, cp2;
|
| - CFX_RectF rtRadius;
|
| - for (int32_t i = 0; i < 8; i += 2) {
|
| - CXFA_Corner corner1 = (CXFA_Node*)strokes[i];
|
| - CXFA_Corner corner2 = (CXFA_Node*)strokes[(i + 2) % 8];
|
| - fRadius1 = corner1.GetRadius();
|
| - fRadius2 = corner2.GetRadius();
|
| - bInverted = corner1.IsInverted();
|
| - bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
|
| - if (bRound) {
|
| - sy = FX_PI / 2;
|
| - }
|
| - switch (i) {
|
| - case 0:
|
| - cp1 = rtWidget.TopLeft();
|
| - cp2 = rtWidget.TopRight();
|
| - vx = 1, vy = 1;
|
| - nx = -1, ny = 0;
|
| - if (bRound) {
|
| - sx = bInverted ? FX_PI / 2 : FX_PI;
|
| - } else {
|
| - sx = 1, sy = 0;
|
| - }
|
| - break;
|
| - case 2:
|
| - cp1 = rtWidget.TopRight();
|
| - cp2 = rtWidget.BottomRight();
|
| - vx = -1, vy = 1;
|
| - nx = 0, ny = -1;
|
| - if (bRound) {
|
| - sx = bInverted ? FX_PI : FX_PI * 3 / 2;
|
| - } else {
|
| - sx = 0, sy = 1;
|
| - }
|
| - break;
|
| - case 4:
|
| - cp1 = rtWidget.BottomRight();
|
| - cp2 = rtWidget.BottomLeft();
|
| - vx = -1, vy = -1;
|
| - nx = 1, ny = 0;
|
| - if (bRound) {
|
| - sx = bInverted ? FX_PI * 3 / 2 : 0;
|
| - } else {
|
| - sx = -1, sy = 0;
|
| - }
|
| - break;
|
| - case 6:
|
| - cp1 = rtWidget.BottomLeft();
|
| - cp2 = rtWidget.TopLeft();
|
| - vx = 1, vy = -1;
|
| - nx = 0, ny = 1;
|
| - if (bRound) {
|
| - sx = bInverted ? 0 : FX_PI / 2;
|
| - } else {
|
| - sx = 0, sy = -1;
|
| - }
|
| - break;
|
| - }
|
| - if (i == 0) {
|
| - fillPath.MoveTo(cp1.x, cp1.y + fRadius1);
|
| - }
|
| - if (bRound) {
|
| - if (fRadius1 < 0) {
|
| - sx -= FX_PI;
|
| - }
|
| - if (bInverted) {
|
| - sy *= -1;
|
| - }
|
| - rtRadius.Set(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy);
|
| - rtRadius.Normalize();
|
| - if (bInverted) {
|
| - rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
|
| - }
|
| - fillPath.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width,
|
| - rtRadius.height, sx, sy);
|
| - } else {
|
| - if (bInverted) {
|
| - cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
|
| - } else {
|
| - cp = cp1;
|
| - }
|
| - fillPath.LineTo(cp.x, cp.y);
|
| - fillPath.LineTo(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy);
|
| - }
|
| - fillPath.LineTo(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny);
|
| - }
|
| -}
|
| -static void XFA_BOX_Fill_Radial(CXFA_Box box,
|
| - CFX_Graphics* pGS,
|
| - CFX_Path& fillPath,
|
| - CFX_RectF rtFill,
|
| - CFX_Matrix* pMatrix) {
|
| - CXFA_Fill fill = box.GetFill();
|
| - FX_ARGB crStart, crEnd;
|
| - crStart = fill.GetColor();
|
| - int32_t iType = fill.GetRadial(crEnd);
|
| - CFX_Shading shading;
|
| - if (iType != XFA_ATTRIBUTEENUM_ToEdge) {
|
| - FX_ARGB temp = crEnd;
|
| - crEnd = crStart;
|
| - crStart = temp;
|
| - }
|
| - shading.CreateRadial(rtFill.Center(), rtFill.Center(), 0,
|
| - FXSYS_sqrt(rtFill.Width() * rtFill.Width() +
|
| - rtFill.Height() * rtFill.Height()) /
|
| - 2,
|
| - TRUE, TRUE, crStart, crEnd);
|
| - CFX_Color cr(&shading);
|
| - pGS->SetFillColor(&cr);
|
| - pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| -}
|
| -static void XFA_BOX_Fill_Pattern(CXFA_Box box,
|
| - CFX_Graphics* pGS,
|
| - CFX_Path& fillPath,
|
| - CFX_RectF rtFill,
|
| - CFX_Matrix* pMatrix) {
|
| - CXFA_Fill fill = box.GetFill();
|
| - FX_ARGB crStart, crEnd;
|
| - crStart = fill.GetColor();
|
| - int32_t iType = fill.GetPattern(crEnd);
|
| - int32_t iHatch = FX_HATCHSTYLE_Cross;
|
| - switch (iType) {
|
| - case XFA_ATTRIBUTEENUM_CrossDiagonal:
|
| - iHatch = FX_HATCHSTYLE_DiagonalCross;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_DiagonalLeft:
|
| - iHatch = FX_HATCHSTYLE_ForwardDiagonal;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_DiagonalRight:
|
| - iHatch = FX_HATCHSTYLE_BackwardDiagonal;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_Horizontal:
|
| - iHatch = FX_HATCHSTYLE_Horizontal;
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_Vertical:
|
| - iHatch = FX_HATCHSTYLE_Vertical;
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - CFX_Pattern pattern;
|
| - pattern.Create(iHatch, crEnd, crStart);
|
| - CFX_Color cr(&pattern);
|
| - pGS->SetFillColor(&cr);
|
| - pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| -}
|
| -static void XFA_BOX_Fill_Linear(CXFA_Box box,
|
| - CFX_Graphics* pGS,
|
| - CFX_Path& fillPath,
|
| - CFX_RectF rtFill,
|
| - CFX_Matrix* pMatrix) {
|
| - CXFA_Fill fill = box.GetFill();
|
| - FX_ARGB crStart, crEnd;
|
| - crStart = fill.GetColor();
|
| - int32_t iType = fill.GetLinear(crEnd);
|
| - CFX_PointF ptStart, ptEnd;
|
| - switch (iType) {
|
| - case XFA_ATTRIBUTEENUM_ToRight:
|
| - ptStart.Set(rtFill.left, rtFill.top);
|
| - ptEnd.Set(rtFill.right(), rtFill.top);
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_ToBottom:
|
| - ptStart.Set(rtFill.left, rtFill.top);
|
| - ptEnd.Set(rtFill.left, rtFill.bottom());
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_ToLeft:
|
| - ptStart.Set(rtFill.right(), rtFill.top);
|
| - ptEnd.Set(rtFill.left, rtFill.top);
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_ToTop:
|
| - ptStart.Set(rtFill.left, rtFill.bottom());
|
| - ptEnd.Set(rtFill.left, rtFill.top);
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - CFX_Shading shading;
|
| - shading.CreateAxial(ptStart, ptEnd, FALSE, FALSE, crStart, crEnd);
|
| - CFX_Color cr(&shading);
|
| - pGS->SetFillColor(&cr);
|
| - pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| -}
|
| -static void XFA_BOX_Fill(CXFA_Box box,
|
| - const CXFA_StrokeArray& strokes,
|
| - CFX_Graphics* pGS,
|
| - const CFX_RectF& rtWidget,
|
| - CFX_Matrix* pMatrix,
|
| - FX_DWORD dwFlags) {
|
| - CXFA_Fill fill = box.GetFill();
|
| - if (!fill.IsExistInXML() || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
|
| - return;
|
| - }
|
| - pGS->SaveGraphState();
|
| - CFX_Path fillPath;
|
| - fillPath.Create();
|
| - XFA_BOX_GetFillPath(box, strokes, rtWidget, fillPath,
|
| - (dwFlags & XFA_DRAWBOX_ForceRound) != 0);
|
| - fillPath.Close();
|
| - int32_t eType = fill.GetFillType();
|
| - switch (eType) {
|
| - case XFA_ELEMENT_Radial:
|
| - XFA_BOX_Fill_Radial(box, pGS, fillPath, rtWidget, pMatrix);
|
| - break;
|
| - case XFA_ELEMENT_Pattern:
|
| - XFA_BOX_Fill_Pattern(box, pGS, fillPath, rtWidget, pMatrix);
|
| - break;
|
| - case XFA_ELEMENT_Linear:
|
| - XFA_BOX_Fill_Linear(box, pGS, fillPath, rtWidget, pMatrix);
|
| - break;
|
| - default: {
|
| - FX_ARGB cr;
|
| - if (eType == XFA_ELEMENT_Stipple) {
|
| - int32_t iRate = fill.GetStipple(cr);
|
| - if (iRate == 0) {
|
| - iRate = 100;
|
| - }
|
| - int32_t a = 0;
|
| - FX_COLORREF rgb;
|
| - ArgbDecode(cr, a, rgb);
|
| - cr = ArgbEncode(iRate * a / 100, rgb);
|
| - } else {
|
| - cr = fill.GetColor();
|
| - }
|
| - CFX_Color fillColor(cr);
|
| - pGS->SetFillColor(&fillColor);
|
| - pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| - } break;
|
| - }
|
| - pGS->RestoreGraphState();
|
| -}
|
| -static void XFA_BOX_StrokePath(CXFA_Stroke stroke,
|
| - CFX_Path* pPath,
|
| - CFX_Graphics* pGS,
|
| - CFX_Matrix* pMatrix) {
|
| - if (!stroke.IsExistInXML() || !stroke.IsVisible()) {
|
| - return;
|
| - }
|
| - FX_FLOAT fThickness = stroke.GetThickness();
|
| - if (fThickness < 0.001f) {
|
| - return;
|
| - }
|
| - pGS->SaveGraphState();
|
| - if (stroke.IsCorner() && fThickness > 2 * stroke.GetRadius()) {
|
| - fThickness = 2 * stroke.GetRadius();
|
| - }
|
| - pGS->SetLineWidth(fThickness, TRUE);
|
| - pGS->SetLineCap(CFX_GraphStateData::LineCapButt);
|
| - XFA_StrokeTypeSetLineDash(pGS, stroke.GetStrokeType(),
|
| - XFA_ATTRIBUTEENUM_Butt);
|
| - CFX_Color fxColor(stroke.GetColor());
|
| - pGS->SetStrokeColor(&fxColor);
|
| - pGS->StrokePath(pPath, pMatrix);
|
| - pGS->RestoreGraphState();
|
| -}
|
| -static void XFA_BOX_StrokeArc(CXFA_Box box,
|
| - CFX_Graphics* pGS,
|
| - CFX_RectF rtWidget,
|
| - CFX_Matrix* pMatrix,
|
| - FX_DWORD dwFlags) {
|
| - CXFA_Edge edge = box.GetEdge(0);
|
| - if (!edge.IsExistInXML() || !edge.IsVisible()) {
|
| - return;
|
| - }
|
| - FX_BOOL bVisible = FALSE;
|
| - FX_FLOAT fThickness = 0;
|
| - int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
|
| - if (i3DType) {
|
| - if (bVisible && fThickness >= 0.001f) {
|
| - dwFlags |= XFA_DRAWBOX_Lowered3D;
|
| - }
|
| - }
|
| - FX_FLOAT fHalf = edge.GetThickness() / 2;
|
| - if (fHalf < 0) {
|
| - fHalf = 0;
|
| - }
|
| - int32_t iHand = box.GetHand();
|
| - if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| - rtWidget.Inflate(fHalf, fHalf);
|
| - } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| - rtWidget.Deflate(fHalf, fHalf);
|
| - }
|
| - if ((dwFlags & XFA_DRAWBOX_ForceRound) == 0 ||
|
| - (dwFlags & XFA_DRAWBOX_Lowered3D) == 0) {
|
| - if (fHalf < 0.001f) {
|
| - return;
|
| - }
|
| - CFX_Path arcPath;
|
| - arcPath.Create();
|
| - XFA_BOX_GetPath_Arc(box, rtWidget, arcPath, dwFlags);
|
| - XFA_BOX_StrokePath(edge, &arcPath, pGS, pMatrix);
|
| - return;
|
| - }
|
| - pGS->SaveGraphState();
|
| - pGS->SetLineWidth(fHalf);
|
| - FX_FLOAT a, b;
|
| - a = rtWidget.width / 2.0f;
|
| - b = rtWidget.height / 2.0f;
|
| - if (dwFlags & XFA_DRAWBOX_ForceRound) {
|
| - a = b = std::min(a, b);
|
| - }
|
| - CFX_PointF center = rtWidget.Center();
|
| - rtWidget.left = center.x - a;
|
| - rtWidget.top = center.y - b;
|
| - rtWidget.width = a + a;
|
| - rtWidget.height = b + b;
|
| - FX_FLOAT startAngle = 0, sweepAngle = 360;
|
| - startAngle = startAngle * FX_PI / 180.0f;
|
| - sweepAngle = -sweepAngle * FX_PI / 180.0f;
|
| - CFX_Path arcPath;
|
| - arcPath.Create();
|
| - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| - 3.0f * FX_PI / 4.0f, FX_PI);
|
| - CFX_Color cr(0xFF808080);
|
| - pGS->SetStrokeColor(&cr);
|
| - pGS->StrokePath(&arcPath, pMatrix);
|
| - arcPath.Clear();
|
| - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| - -1.0f * FX_PI / 4.0f, FX_PI);
|
| - cr.Set(0xFFFFFFFF);
|
| - pGS->SetStrokeColor(&cr);
|
| - pGS->StrokePath(&arcPath, pMatrix);
|
| - rtWidget.Deflate(fHalf, fHalf);
|
| - arcPath.Clear();
|
| - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| - 3.0f * FX_PI / 4.0f, FX_PI);
|
| - cr.Set(0xFF404040);
|
| - pGS->SetStrokeColor(&cr);
|
| - pGS->StrokePath(&arcPath, pMatrix);
|
| - arcPath.Clear();
|
| - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| - -1.0f * FX_PI / 4.0f, FX_PI);
|
| - cr.Set(0xFFC0C0C0);
|
| - pGS->SetStrokeColor(&cr);
|
| - pGS->StrokePath(&arcPath, pMatrix);
|
| - pGS->RestoreGraphState();
|
| -}
|
| -static void XFA_Draw3DRect(CFX_Graphics* pGraphic,
|
| - const CFX_RectF& rt,
|
| - FX_FLOAT fLineWidth,
|
| - CFX_Matrix* pMatrix,
|
| - FX_ARGB argbTopLeft,
|
| - FX_ARGB argbBottomRight) {
|
| - CFX_Color crLT(argbTopLeft);
|
| - pGraphic->SetFillColor(&crLT);
|
| - FX_FLOAT fBottom = rt.bottom();
|
| - FX_FLOAT fRight = rt.right();
|
| - CFX_Path pathLT;
|
| - pathLT.Create();
|
| - pathLT.MoveTo(rt.left, fBottom);
|
| - pathLT.LineTo(rt.left, rt.top);
|
| - pathLT.LineTo(fRight, rt.top);
|
| - pathLT.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
|
| - pathLT.LineTo(rt.left + fLineWidth, rt.top + fLineWidth);
|
| - pathLT.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
|
| - pathLT.LineTo(rt.left, fBottom);
|
| - pGraphic->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
|
| - CFX_Color crRB(argbBottomRight);
|
| - pGraphic->SetFillColor(&crRB);
|
| - CFX_Path pathRB;
|
| - pathRB.Create();
|
| - pathRB.MoveTo(fRight, rt.top);
|
| - pathRB.LineTo(fRight, fBottom);
|
| - pathRB.LineTo(rt.left, fBottom);
|
| - pathRB.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
|
| - pathRB.LineTo(fRight - fLineWidth, fBottom - fLineWidth);
|
| - pathRB.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
|
| - pathRB.LineTo(fRight, rt.top);
|
| - pGraphic->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
|
| -}
|
| -static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS,
|
| - CFX_RectF rt,
|
| - FX_FLOAT fThickness,
|
| - CFX_Matrix* pMatrix) {
|
| - FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| - CFX_RectF rtInner(rt);
|
| - rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| - CFX_Color cr(0xFF000000);
|
| - pGS->SetFillColor(&cr);
|
| - CFX_Path path;
|
| - path.Create();
|
| - path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
|
| - path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
|
| - pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
|
| - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF808080, 0xFFC0C0C0);
|
| -}
|
| -static void XFA_BOX_Stroke_3DRect_Raised(CFX_Graphics* pGS,
|
| - CFX_RectF rt,
|
| - FX_FLOAT fThickness,
|
| - CFX_Matrix* pMatrix) {
|
| - FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| - CFX_RectF rtInner(rt);
|
| - rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| - CFX_Color cr(0xFF000000);
|
| - pGS->SetFillColor(&cr);
|
| - CFX_Path path;
|
| - path.Create();
|
| - path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
|
| - path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
|
| - pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
|
| - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
|
| -}
|
| -static void XFA_BOX_Stroke_3DRect_Etched(CFX_Graphics* pGS,
|
| - CFX_RectF rt,
|
| - FX_FLOAT fThickness,
|
| - CFX_Matrix* pMatrix) {
|
| - FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| - XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFFFFFFFF);
|
| - CFX_RectF rtInner(rt);
|
| - rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
|
| -}
|
| -static void XFA_BOX_Stroke_3DRect_Embossed(CFX_Graphics* pGS,
|
| - CFX_RectF rt,
|
| - FX_FLOAT fThickness,
|
| - CFX_Matrix* pMatrix) {
|
| - FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| - XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFF000000);
|
| - CFX_RectF rtInner(rt);
|
| - rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF000000, 0xFF808080);
|
| -}
|
| -static void XFA_BOX_Stroke_Rect(CXFA_Box box,
|
| - const CXFA_StrokeArray& strokes,
|
| - CFX_Graphics* pGS,
|
| - CFX_RectF rtWidget,
|
| - CFX_Matrix* pMatrix) {
|
| - FX_BOOL bVisible = FALSE;
|
| - FX_FLOAT fThickness = 0;
|
| - int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
|
| - if (i3DType) {
|
| - if (!bVisible || fThickness < 0.001f) {
|
| - return;
|
| - }
|
| - switch (i3DType) {
|
| - case XFA_ATTRIBUTEENUM_Lowered:
|
| - XFA_BOX_Stroke_3DRect_Lowered(pGS, rtWidget, fThickness, pMatrix);
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_Raised:
|
| - XFA_BOX_Stroke_3DRect_Raised(pGS, rtWidget, fThickness, pMatrix);
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_Etched:
|
| - XFA_BOX_Stroke_3DRect_Etched(pGS, rtWidget, fThickness, pMatrix);
|
| - break;
|
| - case XFA_ATTRIBUTEENUM_Embossed:
|
| - XFA_BOX_Stroke_3DRect_Embossed(pGS, rtWidget, fThickness, pMatrix);
|
| - break;
|
| - }
|
| - return;
|
| - }
|
| - FX_BOOL bClose = FALSE;
|
| - FX_BOOL bSameStyles = TRUE;
|
| - int32_t i;
|
| - CXFA_Stroke stroke1 = strokes[0];
|
| - for (i = 1; i < 8; i++) {
|
| - CXFA_Stroke stroke2 = strokes[i];
|
| - if (!stroke1.SameStyles(stroke2)) {
|
| - bSameStyles = FALSE;
|
| - break;
|
| - }
|
| - stroke1 = stroke2;
|
| - }
|
| - if (bSameStyles) {
|
| - stroke1 = strokes[0];
|
| - bClose = TRUE;
|
| - for (i = 2; i < 8; i += 2) {
|
| - CXFA_Stroke stroke2 = strokes[i];
|
| - if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
|
| - XFA_STROKE_SAMESTYLE_Corner)) {
|
| - bSameStyles = FALSE;
|
| - break;
|
| - }
|
| - stroke1 = stroke2;
|
| - }
|
| - if (bSameStyles) {
|
| - stroke1 = strokes[0];
|
| - if (stroke1.IsInverted()) {
|
| - bSameStyles = FALSE;
|
| - }
|
| - if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
|
| - bSameStyles = FALSE;
|
| - }
|
| - }
|
| - }
|
| - FX_BOOL bStart = TRUE;
|
| - CFX_Path path;
|
| - path.Create();
|
| - for (i = 0; i < 8; i++) {
|
| - CXFA_Stroke stroke1 = strokes[i];
|
| - if ((i % 1) == 0 && stroke1.GetRadius() < 0) {
|
| - FX_BOOL bEmpty = path.IsEmpty();
|
| - if (!bEmpty) {
|
| - XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
|
| - path.Clear();
|
| - }
|
| - bStart = TRUE;
|
| - continue;
|
| - }
|
| - XFA_BOX_GetPath(box, strokes, rtWidget, path, i, bStart, !bSameStyles);
|
| - CXFA_Stroke stroke2 = strokes[(i + 1) % 8];
|
| - bStart = !stroke1.SameStyles(stroke2);
|
| - if (bStart) {
|
| - XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
|
| - path.Clear();
|
| - }
|
| - }
|
| - FX_BOOL bEmpty = path.IsEmpty();
|
| - if (!bEmpty) {
|
| - if (bClose) {
|
| - path.Close();
|
| - }
|
| - XFA_BOX_StrokePath(strokes[7], &path, pGS, pMatrix);
|
| - }
|
| -}
|
| -static void XFA_BOX_Stroke(CXFA_Box box,
|
| - const CXFA_StrokeArray& strokes,
|
| - CFX_Graphics* pGS,
|
| - CFX_RectF rtWidget,
|
| - CFX_Matrix* pMatrix,
|
| - FX_DWORD dwFlags) {
|
| - if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
|
| - XFA_BOX_StrokeArc(box, pGS, rtWidget, pMatrix, dwFlags);
|
| - return;
|
| - }
|
| - FX_BOOL bVisible = FALSE;
|
| - for (int32_t j = 0; j < 4; j++) {
|
| - bVisible |= strokes[j * 2 + 1].IsVisible();
|
| - if (bVisible) {
|
| - break;
|
| - }
|
| - }
|
| - if (!bVisible) {
|
| - return;
|
| - }
|
| - for (int32_t i = 1; i < 8; i += 2) {
|
| - CXFA_Edge edge = (CXFA_Node*)strokes[i];
|
| - FX_FLOAT fThickness = edge.GetThickness();
|
| - if (fThickness < 0) {
|
| - fThickness = 0;
|
| - }
|
| - FX_FLOAT fHalf = fThickness / 2;
|
| - int32_t iHand = box.GetHand();
|
| - switch (i) {
|
| - case 1:
|
| - if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| - rtWidget.top -= fHalf;
|
| - rtWidget.height += fHalf;
|
| - } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| - rtWidget.top += fHalf;
|
| - rtWidget.height -= fHalf;
|
| - }
|
| - break;
|
| - case 3:
|
| - if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| - rtWidget.width += fHalf;
|
| - } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| - rtWidget.width -= fHalf;
|
| - }
|
| - break;
|
| - case 5:
|
| - if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| - rtWidget.height += fHalf;
|
| - } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| - rtWidget.height -= fHalf;
|
| - }
|
| - break;
|
| - case 7:
|
| - if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| - rtWidget.left -= fHalf;
|
| - rtWidget.width += fHalf;
|
| - } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| - rtWidget.left += fHalf;
|
| - rtWidget.width -= fHalf;
|
| - }
|
| - break;
|
| - }
|
| - }
|
| - XFA_BOX_Stroke_Rect(box, strokes, pGS, rtWidget, pMatrix);
|
| -}
|
| -void XFA_DrawBox(CXFA_Box box,
|
| - CFX_Graphics* pGS,
|
| - const CFX_RectF& rtWidget,
|
| - CFX_Matrix* pMatrix,
|
| - FX_DWORD dwFlags) {
|
| - if (!box || box.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
|
| - return;
|
| - }
|
| - int32_t iType = box.GetClassID();
|
| - if (iType != XFA_ELEMENT_Arc && iType != XFA_ELEMENT_Border &&
|
| - iType != XFA_ELEMENT_Rectangle) {
|
| - return;
|
| - }
|
| - CXFA_StrokeArray strokes;
|
| - if (!(dwFlags & XFA_DRAWBOX_ForceRound) && iType != XFA_ELEMENT_Arc) {
|
| - box.GetStrokes(strokes);
|
| - }
|
| - XFA_BOX_Fill(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
|
| - XFA_BOX_Stroke(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
|
| -}
|
| +// 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 <algorithm>
|
| +
|
| +#include "xfa/src/foxitlib.h"
|
| +#include "xfa/src/fxfa/src/common/xfa_common.h"
|
| +#include "xfa_ffapp.h"
|
| +#include "xfa_ffdoc.h"
|
| +#include "xfa_ffdocview.h"
|
| +#include "xfa_ffwidget.h"
|
| +#include "xfa_ffpageview.h"
|
| +#include "xfa_textlayout.h"
|
| +CXFA_FFWidget::CXFA_FFWidget(CXFA_FFPageView* pPageView,
|
| + CXFA_WidgetAcc* pDataAcc)
|
| + : CXFA_ContentLayoutItem(pDataAcc->GetNode()),
|
| + m_pPageView(pPageView),
|
| + m_pDataAcc(pDataAcc) {
|
| + m_rtWidget.Set(0, 0, 0, 0);
|
| +}
|
| +CXFA_FFWidget::~CXFA_FFWidget() {}
|
| +IXFA_PageView* CXFA_FFWidget::GetPageView() {
|
| + return m_pPageView;
|
| +}
|
| +void CXFA_FFWidget::SetPageView(IXFA_PageView* pPageView) {
|
| + m_pPageView = static_cast<CXFA_FFPageView*>(pPageView);
|
| +}
|
| +void CXFA_FFWidget::GetWidgetRect(CFX_RectF& rtWidget) {
|
| + if ((m_dwStatus & XFA_WIDGETSTATUS_RectCached) == 0) {
|
| + m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
|
| + GetRect(m_rtWidget);
|
| + }
|
| + rtWidget = m_rtWidget;
|
| +}
|
| +CFX_RectF CXFA_FFWidget::ReCacheWidgetRect() {
|
| + m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
|
| + GetRect(m_rtWidget);
|
| + return m_rtWidget;
|
| +}
|
| +void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF& rtWidget) {
|
| + GetWidgetRect(rtWidget);
|
| + FX_FLOAT fValue = 0;
|
| + switch (m_pDataAcc->GetRotate()) {
|
| + case 90:
|
| + rtWidget.top = rtWidget.bottom();
|
| + fValue = rtWidget.width;
|
| + rtWidget.width = rtWidget.height;
|
| + rtWidget.height = fValue;
|
| + break;
|
| + case 180:
|
| + rtWidget.left = rtWidget.right();
|
| + rtWidget.top = rtWidget.bottom();
|
| + break;
|
| + case 270:
|
| + rtWidget.left = rtWidget.right();
|
| + fValue = rtWidget.width;
|
| + rtWidget.width = rtWidget.height;
|
| + rtWidget.height = fValue;
|
| + break;
|
| + }
|
| +}
|
| +FX_DWORD CXFA_FFWidget::GetStatus() {
|
| + return m_dwStatus;
|
| +}
|
| +void CXFA_FFWidget::ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved) {
|
| + m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::GetBBox(CFX_RectF& rtBox,
|
| + FX_DWORD dwStatus,
|
| + FX_BOOL bDrawFocus) {
|
| + if (bDrawFocus) {
|
| + return FALSE;
|
| + }
|
| +#ifndef _XFA_EMB
|
| + if (m_pPageView) {
|
| + m_pPageView->GetPageViewRect(rtBox);
|
| + }
|
| + return TRUE;
|
| +#endif
|
| + GetWidgetRect(rtBox);
|
| + return TRUE;
|
| +}
|
| +CXFA_WidgetAcc* CXFA_FFWidget::GetDataAcc() {
|
| + return m_pDataAcc;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::GetToolTip(CFX_WideString& wsToolTip) {
|
| + if (CXFA_Assist assist = m_pDataAcc->GetAssist()) {
|
| + if (CXFA_ToolTip toolTip = assist.GetToolTip()) {
|
| + return toolTip.GetTip(wsToolTip);
|
| + }
|
| + }
|
| + return GetCaptionText(wsToolTip);
|
| +}
|
| +void CXFA_FFWidget::RenderWidget(CFX_Graphics* pGS,
|
| + CFX_Matrix* pMatrix,
|
| + FX_DWORD dwStatus,
|
| + int32_t iRotate) {
|
| + if (!IsMatchVisibleStatus(dwStatus)) {
|
| + return;
|
| + }
|
| + CXFA_Border border = m_pDataAcc->GetBorder();
|
| + if (border) {
|
| + CFX_RectF rtBorder;
|
| + GetRectWithoutRotate(rtBorder);
|
| + CXFA_Margin margin = border.GetMargin();
|
| + if (margin.IsExistInXML()) {
|
| + XFA_RectWidthoutMargin(rtBorder, margin);
|
| + }
|
| + rtBorder.Normalize();
|
| + DrawBorder(pGS, border, rtBorder, pMatrix);
|
| + }
|
| +}
|
| +FX_BOOL CXFA_FFWidget::IsLoaded() {
|
| + return m_pPageView != NULL;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::LoadWidget() {
|
| + PerformLayout();
|
| + return TRUE;
|
| +}
|
| +void CXFA_FFWidget::UnloadWidget() {}
|
| +FX_BOOL CXFA_FFWidget::PerformLayout() {
|
| + ReCacheWidgetRect();
|
| + return TRUE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::UpdateFWLData() {
|
| + return FALSE;
|
| +}
|
| +void CXFA_FFWidget::UpdateWidgetProperty() {}
|
| +void CXFA_FFWidget::DrawBorder(CFX_Graphics* pGS,
|
| + CXFA_Box box,
|
| + const CFX_RectF& rtBorder,
|
| + CFX_Matrix* pMatrix,
|
| + FX_DWORD dwFlags) {
|
| + XFA_DrawBox(box, pGS, rtBorder, pMatrix, dwFlags);
|
| +}
|
| +void CXFA_FFWidget::InvalidateWidget(const CFX_RectF* pRect) {
|
| + if (!pRect) {
|
| + CFX_RectF rtWidget;
|
| + GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
|
| + rtWidget.Inflate(2, 2);
|
| + GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, rtWidget,
|
| + XFA_INVALIDATE_CurrentPage);
|
| + } else {
|
| + GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, *pRect,
|
| + XFA_INVALIDATE_CurrentPage);
|
| + }
|
| +}
|
| +void CXFA_FFWidget::AddInvalidateRect(const CFX_RectF* pRect) {
|
| + CFX_RectF rtWidget;
|
| + if (pRect) {
|
| + rtWidget = *pRect;
|
| + } else {
|
| + GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
|
| + rtWidget.Inflate(2, 2);
|
| + }
|
| + m_pDocView->AddInvalidateRect(m_pPageView, rtWidget);
|
| +}
|
| +FX_BOOL CXFA_FFWidget::GetCaptionText(CFX_WideString& wsCap) {
|
| + CXFA_TextLayout* pCapTextlayout = m_pDataAcc->GetCaptionTextLayout();
|
| + if (!pCapTextlayout) {
|
| + return FALSE;
|
| + }
|
| + pCapTextlayout->GetText(wsCap);
|
| + return TRUE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::IsFocused() {
|
| + return m_dwStatus & XFA_WIDGETSTATUS_Focused;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnMouseEnter() {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnMouseExit() {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnLButtonDown(FX_DWORD dwFlags,
|
| + FX_FLOAT fx,
|
| + FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnLButtonDblClk(FX_DWORD dwFlags,
|
| + FX_FLOAT fx,
|
| + FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnMouseWheel(FX_DWORD dwFlags,
|
| + int16_t zDelta,
|
| + FX_FLOAT fx,
|
| + FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnRButtonDown(FX_DWORD dwFlags,
|
| + FX_FLOAT fx,
|
| + FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnRButtonDblClk(FX_DWORD dwFlags,
|
| + FX_FLOAT fx,
|
| + FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +
|
| +FX_BOOL CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
|
| + CXFA_FFWidget* pParent = GetParent();
|
| + if (pParent != NULL && !pParent->IsAncestorOf(pOldWidget)) {
|
| + pParent->OnSetFocus(pOldWidget);
|
| + }
|
| + m_dwStatus |= XFA_WIDGETSTATUS_Focused;
|
| + CXFA_EventParam eParam;
|
| + eParam.m_eType = XFA_EVENT_Enter;
|
| + eParam.m_pTarget = m_pDataAcc;
|
| + m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Enter, &eParam);
|
| + return TRUE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
|
| + m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
|
| + EventKillFocus();
|
| + if (pNewWidget != NULL) {
|
| + CXFA_FFWidget* pParent = GetParent();
|
| + if (pParent != NULL && !pParent->IsAncestorOf(pNewWidget)) {
|
| + pParent->OnKillFocus(pNewWidget);
|
| + }
|
| + }
|
| + return TRUE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
|
| + return FALSE;
|
| +}
|
| +FX_DWORD CXFA_FFWidget::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
|
| + return FALSE;
|
| +}
|
| +void CXFA_FFWidget::Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy) {
|
| + CFX_Matrix mt;
|
| + GetRotateMatrix(mt);
|
| + if (mt.IsIdentity()) {
|
| + return;
|
| + }
|
| + CFX_Matrix mtReverse;
|
| + mtReverse.SetReverse(mt);
|
| + mtReverse.TransformPoint(fx, fy);
|
| +}
|
| +static void XFA_GetMatrix(CFX_Matrix& m,
|
| + int32_t iRotate,
|
| + int32_t at,
|
| + const CFX_RectF& rt) {
|
| + if (!iRotate) {
|
| + return;
|
| + }
|
| + FX_FLOAT fAnchorX, fAnchorY;
|
| + switch (at) {
|
| + case XFA_ATTRIBUTEENUM_TopLeft:
|
| + fAnchorX = rt.left, fAnchorY = rt.top;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_TopCenter:
|
| + fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.top;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_TopRight:
|
| + fAnchorX = rt.right(), fAnchorY = rt.top;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_MiddleLeft:
|
| + fAnchorX = rt.left, fAnchorY = (rt.top + rt.bottom()) / 2;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_MiddleCenter:
|
| + fAnchorX = (rt.left + rt.right()) / 2,
|
| + fAnchorY = (rt.top + rt.bottom()) / 2;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_MiddleRight:
|
| + fAnchorX = rt.right(), fAnchorY = (rt.top + rt.bottom()) / 2;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_BottomLeft:
|
| + fAnchorX = rt.left, fAnchorY = rt.bottom();
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_BottomCenter:
|
| + fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.bottom();
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_BottomRight:
|
| + fAnchorX = rt.right(), fAnchorY = rt.bottom();
|
| + break;
|
| + }
|
| + switch (iRotate) {
|
| + case 90:
|
| + m.a = 0, m.b = -1, m.c = 1, m.d = 0, m.e = fAnchorX - fAnchorY,
|
| + m.f = fAnchorX + fAnchorY;
|
| + break;
|
| + case 180:
|
| + m.a = -1, m.b = 0, m.c = 0, m.d = -1, m.e = fAnchorX * 2,
|
| + m.f = fAnchorY * 2;
|
| + break;
|
| + case 270:
|
| + m.a = 0, m.b = 1, m.c = -1, m.d = 0, m.e = fAnchorX + fAnchorY,
|
| + m.f = fAnchorY - fAnchorX;
|
| + break;
|
| + }
|
| +}
|
| +void CXFA_FFWidget::GetRotateMatrix(CFX_Matrix& mt) {
|
| + mt.Set(1, 0, 0, 1, 0, 0);
|
| + int32_t iRotate = m_pDataAcc->GetRotate();
|
| + if (!iRotate) {
|
| + return;
|
| + }
|
| + CFX_RectF rcWidget;
|
| + GetRectWithoutRotate(rcWidget);
|
| + XFA_ATTRIBUTEENUM at = XFA_ATTRIBUTEENUM_TopLeft;
|
| + XFA_GetMatrix(mt, iRotate, at, rcWidget);
|
| +}
|
| +FX_BOOL CXFA_FFWidget::IsLayoutRectEmpty() {
|
| + CFX_RectF rtLayout;
|
| + GetRectWithoutRotate(rtLayout);
|
| + return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
|
| +}
|
| +CXFA_FFWidget* CXFA_FFWidget::GetParent() {
|
| + CXFA_Node* pParentNode =
|
| + m_pDataAcc->GetNode()->GetNodeItem(XFA_NODEITEM_Parent);
|
| + if (pParentNode != NULL) {
|
| + CXFA_WidgetAcc* pParentWidgetAcc =
|
| + (CXFA_WidgetAcc*)pParentNode->GetWidgetData();
|
| + if (pParentWidgetAcc != NULL) {
|
| + return pParentWidgetAcc->GetNextWidget(NULL);
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
|
| + if (!pWidget) {
|
| + return FALSE;
|
| + }
|
| + CXFA_Node* pNode = m_pDataAcc->GetNode();
|
| + CXFA_Node* pChildNode = pWidget->GetDataAcc()->GetNode();
|
| + while (pChildNode) {
|
| + if (pChildNode == pNode) {
|
| + return TRUE;
|
| + }
|
| + pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_Parent);
|
| + }
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_FFWidget::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
|
| + CFX_RectF rtWidget;
|
| + GetWidgetRect(rtWidget);
|
| + if (rtWidget.Contains(fx, fy)) {
|
| + return TRUE;
|
| + }
|
| + return FALSE;
|
| +}
|
| +CXFA_FFDocView* CXFA_FFWidget::GetDocView() {
|
| + return m_pDocView;
|
| +}
|
| +CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
|
| + return (CXFA_FFDoc*)m_pDocView->GetDoc();
|
| +}
|
| +CXFA_FFApp* CXFA_FFWidget::GetApp() {
|
| + return GetDoc()->GetApp();
|
| +}
|
| +IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() {
|
| + return GetApp()->GetAppProvider();
|
| +}
|
| +void CXFA_FFWidget::GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth) {
|
| + fMinWidth = fMaxWidth = 0;
|
| + FX_FLOAT fWidth = 0;
|
| + if (m_pDataAcc->GetWidth(fWidth)) {
|
| + fMinWidth = fMaxWidth = fWidth;
|
| + } else {
|
| + m_pDataAcc->GetMinWidth(fMinWidth);
|
| + m_pDataAcc->GetMaxWidth(fMaxWidth);
|
| + }
|
| +}
|
| +void CXFA_FFWidget::GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight) {
|
| + fMinHeight = fMaxHeight = 0;
|
| + FX_FLOAT fHeight = 0;
|
| + if (m_pDataAcc->GetHeight(fHeight)) {
|
| + fMinHeight = fMaxHeight = fHeight;
|
| + } else {
|
| + m_pDataAcc->GetMinHeight(fMinHeight);
|
| + m_pDataAcc->GetMaxHeight(fMaxHeight);
|
| + }
|
| +}
|
| +FX_BOOL CXFA_FFWidget::IsMatchVisibleStatus(FX_DWORD dwStatus) {
|
| + return m_dwStatus & XFA_WIDGETSTATUS_Visible;
|
| +}
|
| +void CXFA_FFWidget::EventKillFocus() {
|
| + if (m_dwStatus & XFA_WIDGETSTATUS_Access) {
|
| + m_dwStatus &= ~XFA_WIDGETSTATUS_Access;
|
| + return;
|
| + }
|
| + CXFA_EventParam eParam;
|
| + eParam.m_eType = XFA_EVENT_Exit;
|
| + eParam.m_pTarget = m_pDataAcc;
|
| + m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Exit, &eParam);
|
| +}
|
| +FX_BOOL CXFA_FFWidget::IsButtonDown() {
|
| + return (m_dwStatus & XFA_WIDGETSTATUS_ButtonDown) != 0;
|
| +}
|
| +void CXFA_FFWidget::SetButtonDown(FX_BOOL bSet) {
|
| + bSet ? m_dwStatus |= XFA_WIDGETSTATUS_ButtonDown
|
| + : m_dwStatus &= ~XFA_WIDGETSTATUS_ButtonDown;
|
| +}
|
| +int32_t XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics,
|
| + int32_t iStrokeType,
|
| + int32_t iCapType) {
|
| + switch (iStrokeType) {
|
| + case XFA_ATTRIBUTEENUM_DashDot: {
|
| + FX_FLOAT dashArray[] = {4, 1, 2, 1};
|
| + if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| + dashArray[1] = 2;
|
| + dashArray[3] = 2;
|
| + }
|
| + pGraphics->SetLineDash(0, dashArray, 4);
|
| + return FX_DASHSTYLE_DashDot;
|
| + }
|
| + case XFA_ATTRIBUTEENUM_DashDotDot: {
|
| + FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
|
| + if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| + dashArray[1] = 2;
|
| + dashArray[3] = 2;
|
| + dashArray[5] = 2;
|
| + }
|
| + pGraphics->SetLineDash(0, dashArray, 6);
|
| + return FX_DASHSTYLE_DashDotDot;
|
| + }
|
| + case XFA_ATTRIBUTEENUM_Dashed: {
|
| + FX_FLOAT dashArray[] = {5, 1};
|
| + if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| + dashArray[1] = 2;
|
| + }
|
| + pGraphics->SetLineDash(0, dashArray, 2);
|
| + return FX_DASHSTYLE_Dash;
|
| + }
|
| + case XFA_ATTRIBUTEENUM_Dotted: {
|
| + FX_FLOAT dashArray[] = {2, 1};
|
| + if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
|
| + dashArray[1] = 2;
|
| + }
|
| + pGraphics->SetLineDash(0, dashArray, 2);
|
| + return FX_DASHSTYLE_Dot;
|
| + }
|
| + default:
|
| + break;
|
| + }
|
| + pGraphics->SetLineDash(FX_DASHSTYLE_Solid);
|
| + return FX_DASHSTYLE_Solid;
|
| +}
|
| +CFX_GraphStateData::LineCap XFA_LineCapToFXGE(int32_t iLineCap) {
|
| + switch (iLineCap) {
|
| + case XFA_ATTRIBUTEENUM_Round:
|
| + return CFX_GraphStateData::LineCapRound;
|
| + case XFA_ATTRIBUTEENUM_Butt:
|
| + return CFX_GraphStateData::LineCapButt;
|
| + default:
|
| + break;
|
| + }
|
| + return CFX_GraphStateData::LineCapSquare;
|
| +}
|
| +class CXFA_ImageRenderer {
|
| + public:
|
| + CXFA_ImageRenderer();
|
| + ~CXFA_ImageRenderer();
|
| + FX_BOOL Start(CFX_RenderDevice* pDevice,
|
| + CFX_DIBSource* pDIBSource,
|
| + FX_ARGB bitmap_argb,
|
| + int bitmap_alpha,
|
| + const CFX_Matrix* pImage2Device,
|
| + FX_DWORD flags,
|
| + int blendType = FXDIB_BLEND_NORMAL);
|
| + FX_BOOL Continue(IFX_Pause* pPause);
|
| +
|
| + protected:
|
| + CFX_RenderDevice* m_pDevice;
|
| + int m_Status;
|
| + CFX_Matrix m_ImageMatrix;
|
| + CFX_DIBSource* m_pDIBSource;
|
| + CFX_DIBitmap* m_pCloneConvert;
|
| + int m_BitmapAlpha;
|
| + FX_ARGB m_FillArgb;
|
| + FX_DWORD m_Flags;
|
| + CFX_ImageTransformer* m_pTransformer;
|
| + void* m_DeviceHandle;
|
| + int32_t m_BlendType;
|
| + FX_BOOL m_Result;
|
| + FX_BOOL m_bPrint;
|
| + FX_BOOL StartDIBSource();
|
| + void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
|
| + int left,
|
| + int top,
|
| + FX_ARGB mask_argb,
|
| + int bitmap_alpha,
|
| + int blend_mode,
|
| + int Transparency);
|
| +};
|
| +CXFA_ImageRenderer::CXFA_ImageRenderer() {
|
| + m_pDevice = NULL;
|
| + m_Status = 0;
|
| + m_pDIBSource = NULL;
|
| + m_pCloneConvert = NULL;
|
| + m_BitmapAlpha = 255;
|
| + m_FillArgb = 0;
|
| + m_Flags = 0;
|
| + m_pTransformer = NULL;
|
| + m_DeviceHandle = NULL;
|
| + m_BlendType = FXDIB_BLEND_NORMAL;
|
| + m_Result = TRUE;
|
| + m_bPrint = FALSE;
|
| +}
|
| +CXFA_ImageRenderer::~CXFA_ImageRenderer() {
|
| + if (m_pCloneConvert) {
|
| + delete m_pCloneConvert;
|
| + }
|
| + if (m_pTransformer) {
|
| + delete m_pTransformer;
|
| + }
|
| + if (m_DeviceHandle) {
|
| + m_pDevice->CancelDIBits(m_DeviceHandle);
|
| + }
|
| +}
|
| +FX_BOOL CXFA_ImageRenderer::Start(CFX_RenderDevice* pDevice,
|
| + CFX_DIBSource* pDIBSource,
|
| + FX_ARGB bitmap_argb,
|
| + int bitmap_alpha,
|
| + const CFX_Matrix* pImage2Device,
|
| + FX_DWORD flags,
|
| + int blendType) {
|
| + m_pDevice = pDevice;
|
| + m_pDIBSource = pDIBSource;
|
| + m_FillArgb = bitmap_argb;
|
| + m_BitmapAlpha = bitmap_alpha;
|
| + m_ImageMatrix = *pImage2Device;
|
| + m_Flags = flags;
|
| + m_BlendType = blendType;
|
| + return StartDIBSource();
|
| +}
|
| +FX_BOOL CXFA_ImageRenderer::StartDIBSource() {
|
| + if (m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
|
| + &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL,
|
| + m_BlendType)) {
|
| + if (m_DeviceHandle != NULL) {
|
| + m_Status = 3;
|
| + return TRUE;
|
| + }
|
| + return FALSE;
|
| + }
|
| + CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
|
| + FX_RECT image_rect = image_rect_f.GetOutterRect();
|
| + int dest_width = image_rect.Width();
|
| + int dest_height = image_rect.Height();
|
| + if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
|
| + (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
|
| + if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
|
| + m_Result = FALSE;
|
| + return FALSE;
|
| + }
|
| + CFX_DIBSource* pDib = m_pDIBSource;
|
| + if (m_pDIBSource->HasAlpha() &&
|
| + !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE) &&
|
| + !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
|
| + m_pCloneConvert = m_pDIBSource->CloneConvert(FXDIB_Rgb);
|
| + if (!m_pCloneConvert) {
|
| + m_Result = FALSE;
|
| + return FALSE;
|
| + }
|
| + pDib = m_pCloneConvert;
|
| + }
|
| + FX_RECT clip_box = m_pDevice->GetClipBox();
|
| + clip_box.Intersect(image_rect);
|
| + m_Status = 2;
|
| + m_pTransformer = new CFX_ImageTransformer;
|
| + m_pTransformer->Start(pDib, &m_ImageMatrix, m_Flags, &clip_box);
|
| + return TRUE;
|
| + }
|
| + if (m_ImageMatrix.a < 0) {
|
| + dest_width = -dest_width;
|
| + }
|
| + if (m_ImageMatrix.d > 0) {
|
| + dest_height = -dest_height;
|
| + }
|
| + int dest_left, dest_top;
|
| + dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
|
| + dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
|
| + if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
|
| + if (m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top, dest_width,
|
| + dest_height, m_Flags, NULL, m_BlendType)) {
|
| + return FALSE;
|
| + }
|
| + }
|
| + if (m_pDIBSource->IsAlphaMask()) {
|
| + if (m_BitmapAlpha != 255) {
|
| + m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
|
| + }
|
| + if (m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width,
|
| + dest_height, m_FillArgb, m_Flags)) {
|
| + return FALSE;
|
| + }
|
| + }
|
| + if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
|
| + m_Result = FALSE;
|
| + return TRUE;
|
| + }
|
| + FX_RECT clip_box = m_pDevice->GetClipBox();
|
| + FX_RECT dest_rect = clip_box;
|
| + dest_rect.Intersect(image_rect);
|
| + FX_RECT dest_clip(
|
| + dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
|
| + dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
|
| + CFX_DIBitmap* pStretched =
|
| + m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
|
| + if (pStretched) {
|
| + CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb,
|
| + m_BitmapAlpha, m_BlendType, FALSE);
|
| + delete pStretched;
|
| + pStretched = NULL;
|
| + }
|
| + return FALSE;
|
| +}
|
| +FX_BOOL CXFA_ImageRenderer::Continue(IFX_Pause* pPause) {
|
| + if (m_Status == 2) {
|
| + if (m_pTransformer->Continue(pPause)) {
|
| + return TRUE;
|
| + }
|
| + CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
|
| + if (pBitmap == NULL) {
|
| + return FALSE;
|
| + }
|
| + if (pBitmap->IsAlphaMask()) {
|
| + if (m_BitmapAlpha != 255) {
|
| + m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
|
| + }
|
| + m_Result = m_pDevice->SetBitMask(pBitmap, m_pTransformer->m_ResultLeft,
|
| + m_pTransformer->m_ResultTop, m_FillArgb);
|
| + } else {
|
| + if (m_BitmapAlpha != 255) {
|
| + pBitmap->MultiplyAlpha(m_BitmapAlpha);
|
| + }
|
| + m_Result = m_pDevice->SetDIBits(pBitmap, m_pTransformer->m_ResultLeft,
|
| + m_pTransformer->m_ResultTop, m_BlendType);
|
| + }
|
| + delete pBitmap;
|
| + return FALSE;
|
| + } else if (m_Status == 3) {
|
| + return m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
|
| + }
|
| + return FALSE;
|
| +}
|
| +void CXFA_ImageRenderer::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
|
| + int left,
|
| + int top,
|
| + FX_ARGB mask_argb,
|
| + int bitmap_alpha,
|
| + int blend_mode,
|
| + int Transparency) {
|
| + if (pDIBitmap == NULL) {
|
| + return;
|
| + }
|
| + FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
|
| + FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
|
| + if (blend_mode == FXDIB_BLEND_NORMAL) {
|
| + if (!pDIBitmap->IsAlphaMask()) {
|
| + if (bitmap_alpha < 255) {
|
| + pDIBitmap->MultiplyAlpha(bitmap_alpha);
|
| + }
|
| + if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
|
| + return;
|
| + }
|
| + } else {
|
| + FX_DWORD fill_argb = (mask_argb);
|
| + if (bitmap_alpha < 255) {
|
| + ((uint8_t*)&fill_argb)[3] =
|
| + ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
|
| + }
|
| + if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
|
| + return;
|
| + }
|
| + }
|
| + }
|
| + FX_BOOL bBackAlphaRequired = blend_mode && bIsolated;
|
| + FX_BOOL bGetBackGround =
|
| + ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
|
| + (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
|
| + (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
|
| + if (bGetBackGround) {
|
| + if (bIsolated || !bGroup) {
|
| + if (pDIBitmap->IsAlphaMask()) {
|
| + return;
|
| + }
|
| + m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
|
| + } else {
|
| + FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
|
| + top + pDIBitmap->GetHeight());
|
| + rect.Intersect(m_pDevice->GetClipBox());
|
| + CFX_DIBitmap* pClone = NULL;
|
| + FX_BOOL bClone = FALSE;
|
| + if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
|
| + bClone = TRUE;
|
| + pClone = m_pDevice->GetBackDrop()->Clone(&rect);
|
| + CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
|
| + pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
|
| + pForeBitmap, rect.left, rect.top);
|
| + left = left >= 0 ? 0 : left;
|
| + top = top >= 0 ? 0 : top;
|
| + if (!pDIBitmap->IsAlphaMask())
|
| + pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
|
| + pDIBitmap, left, top, blend_mode);
|
| + else
|
| + pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
|
| + pDIBitmap, mask_argb, left, top, blend_mode);
|
| + } else {
|
| + pClone = pDIBitmap;
|
| + }
|
| + if (m_pDevice->GetBackDrop()) {
|
| + m_pDevice->SetDIBits(pClone, rect.left, rect.top);
|
| + } else {
|
| + if (pDIBitmap->IsAlphaMask()) {
|
| + return;
|
| + }
|
| + m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
|
| + }
|
| + if (bClone) {
|
| + delete pClone;
|
| + }
|
| + }
|
| + return;
|
| + }
|
| + if (pDIBitmap->HasAlpha() &&
|
| + !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE)) {
|
| + CFX_DIBitmap* pCloneConvert = pDIBitmap->CloneConvert(FXDIB_Rgb);
|
| + if (!pCloneConvert) {
|
| + return;
|
| + }
|
| + CXFA_ImageRenderer imageRender;
|
| + FX_BOOL bRet = imageRender.Start(m_pDevice, pCloneConvert, m_FillArgb,
|
| + m_BitmapAlpha, &m_ImageMatrix, m_Flags);
|
| + while (bRet) {
|
| + bRet = imageRender.Continue(NULL);
|
| + }
|
| + delete pCloneConvert;
|
| + return;
|
| + }
|
| +}
|
| +void XFA_DrawImage(CFX_Graphics* pGS,
|
| + const CFX_RectF& rtImage,
|
| + CFX_Matrix* pMatrix,
|
| + CFX_DIBitmap* pDIBitmap,
|
| + int32_t iAspect,
|
| + int32_t iImageXDpi,
|
| + int32_t iImageYDpi,
|
| + int32_t iHorzAlign,
|
| + int32_t iVertAlign) {
|
| + if (rtImage.IsEmpty()) {
|
| + return;
|
| + }
|
| + if (!pDIBitmap || !pDIBitmap->GetBuffer()) {
|
| + return;
|
| + }
|
| + FX_FLOAT fWidth =
|
| + XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
|
| + FX_FLOAT fHeight =
|
| + XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
|
| + CFX_RectF rtFit;
|
| + rtFit.Set(rtImage.left, rtImage.top, fWidth, fHeight);
|
| + switch (iAspect) {
|
| + case XFA_ATTRIBUTEENUM_Fit: {
|
| + FX_FLOAT f1 = rtImage.height / rtFit.height;
|
| + FX_FLOAT f2 = rtImage.width / rtFit.width;
|
| + f1 = std::min(f1, f2);
|
| + rtFit.height = rtFit.height * f1;
|
| + rtFit.width = rtFit.width * f1;
|
| + } break;
|
| + case XFA_ATTRIBUTEENUM_Actual:
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_Height: {
|
| + FX_FLOAT f1 = rtImage.height / rtFit.height;
|
| + rtFit.height = rtImage.height;
|
| + rtFit.width = f1 * rtFit.width;
|
| + } break;
|
| + case XFA_ATTRIBUTEENUM_None:
|
| + rtFit.height = rtImage.height;
|
| + rtFit.width = rtImage.width;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_Width: {
|
| + FX_FLOAT f1 = rtImage.width / rtFit.width;
|
| + rtFit.width = rtImage.width;
|
| + rtFit.height = rtFit.height * f1;
|
| + } break;
|
| + }
|
| + if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
|
| + rtFit.left += (rtImage.width - rtFit.width) / 2;
|
| + } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
|
| + rtFit.left = rtImage.right() - rtFit.width;
|
| + }
|
| + if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
|
| + rtFit.top += (rtImage.height - rtFit.height) / 2;
|
| + } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
|
| + rtFit.top = rtImage.bottom() - rtImage.height;
|
| + }
|
| + CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
|
| + pRenderDevice->SaveState();
|
| + CFX_PathData path;
|
| + path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
|
| + pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING);
|
| + CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
|
| + mtImage.Concat(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top);
|
| + mtImage.Concat(*pMatrix);
|
| + CXFA_ImageRenderer imageRender;
|
| + FX_BOOL bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage,
|
| + FXDIB_INTERPOL);
|
| + while (bRet) {
|
| + bRet = imageRender.Continue(NULL);
|
| + }
|
| + pRenderDevice->RestoreState();
|
| +}
|
| +const static uint8_t g_inv_base64[128] = {
|
| + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
| + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
| + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
|
| + 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
| + 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
| + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
| + 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
|
| + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
| + 49, 50, 51, 255, 255, 255, 255, 255,
|
| +};
|
| +static uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
|
| + uint8_t* pCP;
|
| + int32_t i = 0, j = 0;
|
| + if (iLen == 0) {
|
| + iLen = FXSYS_strlen((FX_CHAR*)pStr);
|
| + }
|
| + pCP = FX_Alloc(uint8_t, iLen + 1);
|
| + for (; i < iLen; i++) {
|
| + if ((pStr[i] & 128) == 0) {
|
| + if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
|
| + pCP[j++] = pStr[i];
|
| + }
|
| + }
|
| + }
|
| + pCP[j] = '\0';
|
| + return pCP;
|
| +}
|
| +static int32_t XFA_Base64Decode(const FX_CHAR* pStr, uint8_t* pOutBuffer) {
|
| + if (pStr == NULL) {
|
| + return 0;
|
| + }
|
| + uint8_t* pBuffer =
|
| + XFA_RemoveBase64Whitespace((uint8_t*)pStr, FXSYS_strlen((FX_CHAR*)pStr));
|
| + if (pBuffer == NULL) {
|
| + return 0;
|
| + }
|
| + int32_t iLen = FXSYS_strlen((FX_CHAR*)pBuffer);
|
| + int32_t i = 0, j = 0;
|
| + FX_DWORD dwLimb = 0;
|
| + for (; i + 3 < iLen; i += 4) {
|
| + if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
|
| + pBuffer[i + 3] == '=') {
|
| + if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
|
| + break;
|
| + }
|
| + if (pBuffer[i + 2] == '=') {
|
| + dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 6) |
|
| + ((FX_DWORD)g_inv_base64[pBuffer[i + 1]]);
|
| + pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
|
| + j++;
|
| + } else {
|
| + dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 12) |
|
| + ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 6) |
|
| + ((FX_DWORD)g_inv_base64[pBuffer[i + 2]]);
|
| + pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
|
| + pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
|
| + j += 2;
|
| + }
|
| + } else {
|
| + dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 18) |
|
| + ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 12) |
|
| + ((FX_DWORD)g_inv_base64[pBuffer[i + 2]] << 6) |
|
| + ((FX_DWORD)g_inv_base64[pBuffer[i + 3]]);
|
| + pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
|
| + pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
|
| + pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
|
| + j += 3;
|
| + }
|
| + }
|
| + FX_Free(pBuffer);
|
| + return j;
|
| +}
|
| +static FX_CHAR g_base64_chars[] =
|
| + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
| +FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len) {
|
| + FX_CHAR* out = NULL;
|
| + int i, j;
|
| + FX_DWORD limb;
|
| + out = FX_Alloc(FX_CHAR, ((buf_len * 8 + 5) / 6) + 5);
|
| + for (i = 0, j = 0, limb = 0; i + 2 < buf_len; i += 3, j += 4) {
|
| + limb = ((FX_DWORD)buf[i] << 16) | ((FX_DWORD)buf[i + 1] << 8) |
|
| + ((FX_DWORD)buf[i + 2]);
|
| + out[j] = g_base64_chars[(limb >> 18) & 63];
|
| + out[j + 1] = g_base64_chars[(limb >> 12) & 63];
|
| + out[j + 2] = g_base64_chars[(limb >> 6) & 63];
|
| + out[j + 3] = g_base64_chars[(limb)&63];
|
| + }
|
| + switch (buf_len - i) {
|
| + case 0:
|
| + break;
|
| + case 1:
|
| + limb = ((FX_DWORD)buf[i]);
|
| + out[j++] = g_base64_chars[(limb >> 2) & 63];
|
| + out[j++] = g_base64_chars[(limb << 4) & 63];
|
| + out[j++] = '=';
|
| + out[j++] = '=';
|
| + break;
|
| + case 2:
|
| + limb = ((FX_DWORD)buf[i] << 8) | ((FX_DWORD)buf[i + 1]);
|
| + out[j++] = g_base64_chars[(limb >> 10) & 63];
|
| + out[j++] = g_base64_chars[(limb >> 4) & 63];
|
| + out[j++] = g_base64_chars[(limb << 2) & 63];
|
| + out[j++] = '=';
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + out[j] = '\0';
|
| + return out;
|
| +}
|
| +FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideStringC& wsType) {
|
| + CFX_WideString wsContentType(wsType);
|
| + wsContentType.MakeLower();
|
| + if (wsContentType == FX_WSTRC(L"image/jpg")) {
|
| + return FXCODEC_IMAGE_JPG;
|
| + }
|
| + if (wsContentType == FX_WSTRC(L"image/png")) {
|
| + return FXCODEC_IMAGE_PNG;
|
| + }
|
| + if (wsContentType == FX_WSTRC(L"image/gif")) {
|
| + return FXCODEC_IMAGE_GIF;
|
| + }
|
| + if (wsContentType == FX_WSTRC(L"image/bmp")) {
|
| + return FXCODEC_IMAGE_BMP;
|
| + }
|
| + if (wsContentType == FX_WSTRC(L"image/tif")) {
|
| + return FXCODEC_IMAGE_TIF;
|
| + }
|
| + return FXCODEC_IMAGE_UNKNOWN;
|
| +}
|
| +CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc,
|
| + CXFA_Image* pImage,
|
| + FX_BOOL& bNameImage,
|
| + int32_t& iImageXDpi,
|
| + int32_t& iImageYDpi) {
|
| + CFX_WideString wsHref;
|
| + pImage->GetHref(wsHref);
|
| + CFX_WideString wsImage;
|
| + pImage->GetContent(wsImage);
|
| + if (wsHref.IsEmpty() && wsImage.IsEmpty()) {
|
| + return NULL;
|
| + }
|
| + CFX_WideString wsContentType;
|
| + pImage->GetContentType(wsContentType);
|
| + FXCODEC_IMAGE_TYPE type = XFA_GetImageType(wsContentType);
|
| + CFX_ByteString bsContent;
|
| + uint8_t* pImageBuffer = NULL;
|
| + IFX_FileRead* pImageFileRead = NULL;
|
| + if (wsImage.GetLength() > 0) {
|
| + XFA_ATTRIBUTEENUM iEncoding =
|
| + (XFA_ATTRIBUTEENUM)pImage->GetTransferEncoding();
|
| + if (iEncoding == XFA_ATTRIBUTEENUM_Base64) {
|
| + CFX_ByteString bsData = wsImage.UTF8Encode();
|
| + int32_t iLength = bsData.GetLength();
|
| + pImageBuffer = FX_Alloc(uint8_t, iLength);
|
| + int32_t iRead = XFA_Base64Decode((const FX_CHAR*)bsData, pImageBuffer);
|
| + if (iRead > 0) {
|
| + pImageFileRead = FX_CreateMemoryStream(pImageBuffer, iRead);
|
| + }
|
| + } else {
|
| + bsContent = CFX_ByteString::FromUnicode(wsImage);
|
| + pImageFileRead = FX_CreateMemoryStream(
|
| + (uint8_t*)(const uint8_t*)bsContent, bsContent.GetLength());
|
| + }
|
| + } else {
|
| + CFX_WideString wsURL = wsHref;
|
| + if (wsURL.Left(7) != FX_WSTRC(L"http://") &&
|
| + wsURL.Left(6) != FX_WSTRC(L"ftp://")) {
|
| + CFX_DIBitmap* pBitmap =
|
| + pDoc->GetPDFNamedImage(wsURL, iImageXDpi, iImageYDpi);
|
| + if (pBitmap != NULL) {
|
| + bNameImage = TRUE;
|
| + return pBitmap;
|
| + }
|
| + }
|
| + pImageFileRead = pDoc->GetDocProvider()->OpenLinkedFile(pDoc, wsURL);
|
| + }
|
| + if (!pImageFileRead) {
|
| + FX_Free(pImageBuffer);
|
| + return NULL;
|
| + }
|
| + bNameImage = FALSE;
|
| + CFX_DIBitmap* pBitmap =
|
| + XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
|
| + FX_Free(pImageBuffer);
|
| + pImageFileRead->Release();
|
| + return pBitmap;
|
| +}
|
| +static FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
|
| + int32_t iComponents,
|
| + int32_t iBitsPerComponent) {
|
| + FXDIB_Format dibFormat = FXDIB_Argb;
|
| + switch (type) {
|
| + case FXCODEC_IMAGE_BMP:
|
| + case FXCODEC_IMAGE_JPG:
|
| + case FXCODEC_IMAGE_TIF: {
|
| + dibFormat = FXDIB_Rgb32;
|
| + int32_t bpp = iComponents * iBitsPerComponent;
|
| + if (bpp <= 24) {
|
| + dibFormat = FXDIB_Rgb;
|
| + }
|
| + } break;
|
| + case FXCODEC_IMAGE_PNG:
|
| + default:
|
| + break;
|
| + }
|
| + return dibFormat;
|
| +}
|
| +CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead,
|
| + FXCODEC_IMAGE_TYPE type,
|
| + int32_t& iImageXDpi,
|
| + int32_t& iImageYDpi) {
|
| + CFX_GEModule* pGeModule = CFX_GEModule::Get();
|
| + if (!pGeModule) {
|
| + return NULL;
|
| + }
|
| + CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
|
| + if (!pCodecMgr) {
|
| + return NULL;
|
| + }
|
| + CFX_DIBAttribute dibAttr;
|
| + CFX_DIBitmap* pBitmap = NULL;
|
| + ICodec_ProgressiveDecoder* pProgressiveDecoder =
|
| + pCodecMgr->CreateProgressiveDecoder();
|
| + pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr);
|
| + switch (dibAttr.m_wDPIUnit) {
|
| + case FXCODEC_RESUNIT_CENTIMETER:
|
| + dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI * 2.54f);
|
| + dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI * 2.54f);
|
| + break;
|
| + case FXCODEC_RESUNIT_METER:
|
| + dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI / (FX_FLOAT)100 * 2.54f);
|
| + dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI / (FX_FLOAT)100 * 2.54f);
|
| + break;
|
| + ;
|
| + default:
|
| + break;
|
| + }
|
| + iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
|
| + iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
|
| + if (pProgressiveDecoder->GetWidth() > 0 &&
|
| + pProgressiveDecoder->GetHeight() > 0) {
|
| + type = pProgressiveDecoder->GetType();
|
| + int32_t iComponents = pProgressiveDecoder->GetNumComponents();
|
| + int32_t iBpc = pProgressiveDecoder->GetBPC();
|
| + FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
|
| + pBitmap = new CFX_DIBitmap();
|
| + pBitmap->Create(pProgressiveDecoder->GetWidth(),
|
| + pProgressiveDecoder->GetHeight(), dibFormat);
|
| + pBitmap->Clear(0xffffffff);
|
| + int32_t nFrames;
|
| + if ((pProgressiveDecoder->GetFrames(nFrames) ==
|
| + FXCODEC_STATUS_DECODE_READY) &&
|
| + (nFrames > 0)) {
|
| + pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(),
|
| + pBitmap->GetHeight());
|
| + pProgressiveDecoder->ContinueDecode();
|
| + }
|
| + }
|
| + delete pProgressiveDecoder;
|
| + return pBitmap;
|
| +}
|
| +void XFA_RectWidthoutMargin(CFX_RectF& rt, const CXFA_Margin& mg, FX_BOOL bUI) {
|
| + if (!mg) {
|
| + return;
|
| + }
|
| + FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
|
| + mg.GetLeftInset(fLeftInset);
|
| + mg.GetTopInset(fTopInset);
|
| + mg.GetRightInset(fRightInset);
|
| + mg.GetBottomInset(fBottomInset);
|
| + rt.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
|
| +}
|
| +CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
|
| + XFA_ELEMENT iType = pLayoutItem->GetFormNode()->GetClassID();
|
| + if (XFA_IsCreateWidget(iType)) {
|
| + return static_cast<CXFA_FFWidget*>(pLayoutItem);
|
| + }
|
| + return nullptr;
|
| +}
|
| +FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType) {
|
| + return iType == XFA_ELEMENT_Field || iType == XFA_ELEMENT_Draw ||
|
| + iType == XFA_ELEMENT_Subform || iType == XFA_ELEMENT_ExclGroup;
|
| +}
|
| +static void XFA_BOX_GetPath_Arc(CXFA_Box box,
|
| + CFX_RectF rtDraw,
|
| + CFX_Path& fillPath,
|
| + FX_DWORD dwFlags) {
|
| + FX_FLOAT a, b;
|
| + a = rtDraw.width / 2.0f;
|
| + b = rtDraw.height / 2.0f;
|
| + if (box.IsCircular() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
|
| + a = b = std::min(a, b);
|
| + }
|
| + CFX_PointF center = rtDraw.Center();
|
| + rtDraw.left = center.x - a;
|
| + rtDraw.top = center.y - b;
|
| + rtDraw.width = a + a;
|
| + rtDraw.height = b + b;
|
| + FX_FLOAT startAngle = 0, sweepAngle = 360;
|
| + FX_BOOL bStart = box.GetStartAngle(startAngle);
|
| + FX_BOOL bEnd = box.GetSweepAngle(sweepAngle);
|
| + if (!bStart && !bEnd) {
|
| + fillPath.AddEllipse(rtDraw);
|
| + return;
|
| + }
|
| + startAngle = -startAngle * FX_PI / 180.0f;
|
| + sweepAngle = -sweepAngle * FX_PI / 180.0f;
|
| + fillPath.AddArc(rtDraw.left, rtDraw.top, rtDraw.width, rtDraw.height,
|
| + startAngle, sweepAngle);
|
| +}
|
| +static void XFA_BOX_GetPath(CXFA_Box box,
|
| + const CXFA_StrokeArray& strokes,
|
| + CFX_RectF rtWidget,
|
| + CFX_Path& path,
|
| + int32_t nIndex,
|
| + FX_BOOL bStart,
|
| + FX_BOOL bCorner) {
|
| + FXSYS_assert(nIndex >= 0 && nIndex < 8);
|
| + FX_BOOL bInverted, bRound;
|
| + FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny, offsetY, offsetX,
|
| + offsetEX, offsetEY;
|
| + CFX_PointF cpStart, cp, cp1, cp2;
|
| + CFX_RectF rtRadius;
|
| + int32_t n = (nIndex & 1) ? nIndex - 1 : nIndex;
|
| + CXFA_Corner corner1 = (CXFA_Node*)strokes[n];
|
| + CXFA_Corner corner2 = (CXFA_Node*)strokes[(n + 2) % 8];
|
| + fRadius1 = bCorner ? corner1.GetRadius() : 0;
|
| + fRadius2 = bCorner ? corner2.GetRadius() : 0;
|
| + bInverted = corner1.IsInverted();
|
| + offsetY = 0.0f;
|
| + offsetX = 0.0f;
|
| + bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
|
| + FX_FLOAT halfAfter = 0.0f;
|
| + FX_FLOAT halfBefore = 0.0f;
|
| + CXFA_Stroke stroke = strokes[nIndex];
|
| + if (stroke.IsCorner()) {
|
| + CXFA_Stroke edgeBefore = strokes[(nIndex + 1 * 8 - 1) % 8];
|
| + CXFA_Stroke edgeAfter = strokes[nIndex + 1];
|
| + if (stroke.IsInverted()) {
|
| + if (!stroke.SameStyles(edgeBefore)) {
|
| + halfBefore = edgeBefore.GetThickness() / 2;
|
| + }
|
| + if (!stroke.SameStyles(edgeAfter)) {
|
| + halfAfter = edgeAfter.GetThickness() / 2;
|
| + }
|
| + }
|
| + } else {
|
| + CXFA_Stroke edgeBefore = strokes[(nIndex + 8 - 2) % 8];
|
| + CXFA_Stroke edgeAfter = strokes[(nIndex + 2) % 8];
|
| + if (!bRound && !bInverted) {
|
| + { halfBefore = edgeBefore.GetThickness() / 2; }
|
| + { halfAfter = edgeAfter.GetThickness() / 2; }
|
| + }
|
| + }
|
| + offsetEX = 0.0f;
|
| + offsetEY = 0.0f;
|
| + if (bRound) {
|
| + sy = FX_PI / 2;
|
| + }
|
| + switch (nIndex) {
|
| + case 0:
|
| + case 1:
|
| + cp1 = rtWidget.TopLeft();
|
| + cp2 = rtWidget.TopRight();
|
| + if (nIndex == 0) {
|
| + cpStart.x = cp1.x - halfBefore;
|
| + cpStart.y = cp1.y + fRadius1, offsetY = -halfAfter;
|
| + } else {
|
| + cpStart.x = cp1.x + fRadius1 - halfBefore, cpStart.y = cp1.y,
|
| + offsetEX = halfAfter;
|
| + }
|
| + vx = 1, vy = 1;
|
| + nx = -1, ny = 0;
|
| + if (bRound) {
|
| + sx = bInverted ? FX_PI / 2 : FX_PI;
|
| + } else {
|
| + sx = 1, sy = 0;
|
| + }
|
| + break;
|
| + case 2:
|
| + case 3:
|
| + cp1 = rtWidget.TopRight();
|
| + cp2 = rtWidget.BottomRight();
|
| + if (nIndex == 2) {
|
| + cpStart.x = cp1.x - fRadius1, cpStart.y = cp1.y - halfBefore,
|
| + offsetX = halfAfter;
|
| + } else {
|
| + cpStart.x = cp1.x, cpStart.y = cp1.y + fRadius1 - halfBefore,
|
| + offsetEY = halfAfter;
|
| + }
|
| + vx = -1, vy = 1;
|
| + nx = 0, ny = -1;
|
| + if (bRound) {
|
| + sx = bInverted ? FX_PI : FX_PI * 3 / 2;
|
| + } else {
|
| + sx = 0, sy = 1;
|
| + }
|
| + break;
|
| + case 4:
|
| + case 5:
|
| + cp1 = rtWidget.BottomRight();
|
| + cp2 = rtWidget.BottomLeft();
|
| + if (nIndex == 4) {
|
| + cpStart.x = cp1.x + halfBefore, cpStart.y = cp1.y - fRadius1,
|
| + offsetY = halfAfter;
|
| + } else {
|
| + cpStart.x = cp1.x - fRadius1 + halfBefore, cpStart.y = cp1.y,
|
| + offsetEX = -halfAfter;
|
| + }
|
| + vx = -1, vy = -1;
|
| + nx = 1, ny = 0;
|
| + if (bRound) {
|
| + sx = bInverted ? FX_PI * 3 / 2 : 0;
|
| + } else {
|
| + sx = -1, sy = 0;
|
| + }
|
| + break;
|
| + case 6:
|
| + case 7:
|
| + cp1 = rtWidget.BottomLeft();
|
| + cp2 = rtWidget.TopLeft();
|
| + if (nIndex == 6) {
|
| + cpStart.x = cp1.x + fRadius1, cpStart.y = cp1.y + halfBefore,
|
| + offsetX = -halfAfter;
|
| + } else {
|
| + cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore,
|
| + offsetEY = -halfAfter;
|
| + }
|
| + vx = 1, vy = -1;
|
| + nx = 0, ny = 1;
|
| + if (bRound) {
|
| + sx = bInverted ? 0 : FX_PI / 2;
|
| + } else {
|
| + sx = 0, sy = -1;
|
| + }
|
| + break;
|
| + }
|
| + if (bStart) {
|
| + path.MoveTo(cpStart.x, cpStart.y);
|
| + }
|
| + if (nIndex & 1) {
|
| + path.LineTo(cp2.x + fRadius2 * nx + offsetEX,
|
| + cp2.y + fRadius2 * ny + offsetEY);
|
| + return;
|
| + }
|
| + if (bRound) {
|
| + if (fRadius1 < 0) {
|
| + sx -= FX_PI;
|
| + }
|
| + if (bInverted) {
|
| + sy *= -1;
|
| + }
|
| + rtRadius.Set(cp1.x + offsetX * 2, cp1.y + offsetY * 2,
|
| + fRadius1 * 2 * vx - offsetX * 2,
|
| + fRadius1 * 2 * vy - offsetY * 2);
|
| + rtRadius.Normalize();
|
| + if (bInverted) {
|
| + rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
|
| + }
|
| + path.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx,
|
| + sy);
|
| + } else {
|
| + if (bInverted) {
|
| + cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
|
| + } else {
|
| + cp = cp1;
|
| + }
|
| + path.LineTo(cp.x, cp.y);
|
| + path.LineTo(cp1.x + fRadius1 * sx + offsetX,
|
| + cp1.y + fRadius1 * sy + offsetY);
|
| + }
|
| +}
|
| +static void XFA_BOX_GetFillPath(CXFA_Box box,
|
| + const CXFA_StrokeArray& strokes,
|
| + CFX_RectF rtWidget,
|
| + CFX_Path& fillPath,
|
| + FX_WORD dwFlags) {
|
| + if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
|
| + CXFA_Edge edge = box.GetEdge(0);
|
| + FX_FLOAT fThickness = edge.GetThickness();
|
| + if (fThickness < 0) {
|
| + fThickness = 0;
|
| + }
|
| + FX_FLOAT fHalf = fThickness / 2;
|
| + int32_t iHand = box.GetHand();
|
| + if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| + rtWidget.Inflate(fHalf, fHalf);
|
| + } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| + rtWidget.Deflate(fHalf, fHalf);
|
| + }
|
| + XFA_BOX_GetPath_Arc(box, rtWidget, fillPath, dwFlags);
|
| + return;
|
| + }
|
| + FX_BOOL bSameStyles = TRUE;
|
| + int32_t i;
|
| + CXFA_Stroke stroke1 = strokes[0];
|
| + for (i = 1; i < 8; i++) {
|
| + CXFA_Stroke stroke2 = strokes[i];
|
| + if (!stroke1.SameStyles(stroke2)) {
|
| + bSameStyles = FALSE;
|
| + break;
|
| + }
|
| + stroke1 = stroke2;
|
| + }
|
| + if (bSameStyles) {
|
| + stroke1 = strokes[0];
|
| + for (i = 2; i < 8; i += 2) {
|
| + CXFA_Stroke stroke2 = strokes[i];
|
| + if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
|
| + XFA_STROKE_SAMESTYLE_Corner)) {
|
| + bSameStyles = FALSE;
|
| + break;
|
| + }
|
| + stroke1 = stroke2;
|
| + }
|
| + if (bSameStyles) {
|
| + stroke1 = strokes[0];
|
| + if (stroke1.IsInverted()) {
|
| + bSameStyles = FALSE;
|
| + }
|
| + if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
|
| + bSameStyles = FALSE;
|
| + }
|
| + }
|
| + }
|
| + if (bSameStyles) {
|
| + fillPath.AddRectangle(rtWidget.left, rtWidget.top, rtWidget.width,
|
| + rtWidget.height);
|
| + return;
|
| + }
|
| + FX_BOOL bInverted, bRound;
|
| + FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny;
|
| + CFX_PointF cp, cp1, cp2;
|
| + CFX_RectF rtRadius;
|
| + for (int32_t i = 0; i < 8; i += 2) {
|
| + CXFA_Corner corner1 = (CXFA_Node*)strokes[i];
|
| + CXFA_Corner corner2 = (CXFA_Node*)strokes[(i + 2) % 8];
|
| + fRadius1 = corner1.GetRadius();
|
| + fRadius2 = corner2.GetRadius();
|
| + bInverted = corner1.IsInverted();
|
| + bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
|
| + if (bRound) {
|
| + sy = FX_PI / 2;
|
| + }
|
| + switch (i) {
|
| + case 0:
|
| + cp1 = rtWidget.TopLeft();
|
| + cp2 = rtWidget.TopRight();
|
| + vx = 1, vy = 1;
|
| + nx = -1, ny = 0;
|
| + if (bRound) {
|
| + sx = bInverted ? FX_PI / 2 : FX_PI;
|
| + } else {
|
| + sx = 1, sy = 0;
|
| + }
|
| + break;
|
| + case 2:
|
| + cp1 = rtWidget.TopRight();
|
| + cp2 = rtWidget.BottomRight();
|
| + vx = -1, vy = 1;
|
| + nx = 0, ny = -1;
|
| + if (bRound) {
|
| + sx = bInverted ? FX_PI : FX_PI * 3 / 2;
|
| + } else {
|
| + sx = 0, sy = 1;
|
| + }
|
| + break;
|
| + case 4:
|
| + cp1 = rtWidget.BottomRight();
|
| + cp2 = rtWidget.BottomLeft();
|
| + vx = -1, vy = -1;
|
| + nx = 1, ny = 0;
|
| + if (bRound) {
|
| + sx = bInverted ? FX_PI * 3 / 2 : 0;
|
| + } else {
|
| + sx = -1, sy = 0;
|
| + }
|
| + break;
|
| + case 6:
|
| + cp1 = rtWidget.BottomLeft();
|
| + cp2 = rtWidget.TopLeft();
|
| + vx = 1, vy = -1;
|
| + nx = 0, ny = 1;
|
| + if (bRound) {
|
| + sx = bInverted ? 0 : FX_PI / 2;
|
| + } else {
|
| + sx = 0, sy = -1;
|
| + }
|
| + break;
|
| + }
|
| + if (i == 0) {
|
| + fillPath.MoveTo(cp1.x, cp1.y + fRadius1);
|
| + }
|
| + if (bRound) {
|
| + if (fRadius1 < 0) {
|
| + sx -= FX_PI;
|
| + }
|
| + if (bInverted) {
|
| + sy *= -1;
|
| + }
|
| + rtRadius.Set(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy);
|
| + rtRadius.Normalize();
|
| + if (bInverted) {
|
| + rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
|
| + }
|
| + fillPath.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width,
|
| + rtRadius.height, sx, sy);
|
| + } else {
|
| + if (bInverted) {
|
| + cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
|
| + } else {
|
| + cp = cp1;
|
| + }
|
| + fillPath.LineTo(cp.x, cp.y);
|
| + fillPath.LineTo(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy);
|
| + }
|
| + fillPath.LineTo(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny);
|
| + }
|
| +}
|
| +static void XFA_BOX_Fill_Radial(CXFA_Box box,
|
| + CFX_Graphics* pGS,
|
| + CFX_Path& fillPath,
|
| + CFX_RectF rtFill,
|
| + CFX_Matrix* pMatrix) {
|
| + CXFA_Fill fill = box.GetFill();
|
| + FX_ARGB crStart, crEnd;
|
| + crStart = fill.GetColor();
|
| + int32_t iType = fill.GetRadial(crEnd);
|
| + CFX_Shading shading;
|
| + if (iType != XFA_ATTRIBUTEENUM_ToEdge) {
|
| + FX_ARGB temp = crEnd;
|
| + crEnd = crStart;
|
| + crStart = temp;
|
| + }
|
| + shading.CreateRadial(rtFill.Center(), rtFill.Center(), 0,
|
| + FXSYS_sqrt(rtFill.Width() * rtFill.Width() +
|
| + rtFill.Height() * rtFill.Height()) /
|
| + 2,
|
| + TRUE, TRUE, crStart, crEnd);
|
| + CFX_Color cr(&shading);
|
| + pGS->SetFillColor(&cr);
|
| + pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| +}
|
| +static void XFA_BOX_Fill_Pattern(CXFA_Box box,
|
| + CFX_Graphics* pGS,
|
| + CFX_Path& fillPath,
|
| + CFX_RectF rtFill,
|
| + CFX_Matrix* pMatrix) {
|
| + CXFA_Fill fill = box.GetFill();
|
| + FX_ARGB crStart, crEnd;
|
| + crStart = fill.GetColor();
|
| + int32_t iType = fill.GetPattern(crEnd);
|
| + int32_t iHatch = FX_HATCHSTYLE_Cross;
|
| + switch (iType) {
|
| + case XFA_ATTRIBUTEENUM_CrossDiagonal:
|
| + iHatch = FX_HATCHSTYLE_DiagonalCross;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_DiagonalLeft:
|
| + iHatch = FX_HATCHSTYLE_ForwardDiagonal;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_DiagonalRight:
|
| + iHatch = FX_HATCHSTYLE_BackwardDiagonal;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_Horizontal:
|
| + iHatch = FX_HATCHSTYLE_Horizontal;
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_Vertical:
|
| + iHatch = FX_HATCHSTYLE_Vertical;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + CFX_Pattern pattern;
|
| + pattern.Create(iHatch, crEnd, crStart);
|
| + CFX_Color cr(&pattern);
|
| + pGS->SetFillColor(&cr);
|
| + pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| +}
|
| +static void XFA_BOX_Fill_Linear(CXFA_Box box,
|
| + CFX_Graphics* pGS,
|
| + CFX_Path& fillPath,
|
| + CFX_RectF rtFill,
|
| + CFX_Matrix* pMatrix) {
|
| + CXFA_Fill fill = box.GetFill();
|
| + FX_ARGB crStart, crEnd;
|
| + crStart = fill.GetColor();
|
| + int32_t iType = fill.GetLinear(crEnd);
|
| + CFX_PointF ptStart, ptEnd;
|
| + switch (iType) {
|
| + case XFA_ATTRIBUTEENUM_ToRight:
|
| + ptStart.Set(rtFill.left, rtFill.top);
|
| + ptEnd.Set(rtFill.right(), rtFill.top);
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_ToBottom:
|
| + ptStart.Set(rtFill.left, rtFill.top);
|
| + ptEnd.Set(rtFill.left, rtFill.bottom());
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_ToLeft:
|
| + ptStart.Set(rtFill.right(), rtFill.top);
|
| + ptEnd.Set(rtFill.left, rtFill.top);
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_ToTop:
|
| + ptStart.Set(rtFill.left, rtFill.bottom());
|
| + ptEnd.Set(rtFill.left, rtFill.top);
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + CFX_Shading shading;
|
| + shading.CreateAxial(ptStart, ptEnd, FALSE, FALSE, crStart, crEnd);
|
| + CFX_Color cr(&shading);
|
| + pGS->SetFillColor(&cr);
|
| + pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| +}
|
| +static void XFA_BOX_Fill(CXFA_Box box,
|
| + const CXFA_StrokeArray& strokes,
|
| + CFX_Graphics* pGS,
|
| + const CFX_RectF& rtWidget,
|
| + CFX_Matrix* pMatrix,
|
| + FX_DWORD dwFlags) {
|
| + CXFA_Fill fill = box.GetFill();
|
| + if (!fill.IsExistInXML() || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
|
| + return;
|
| + }
|
| + pGS->SaveGraphState();
|
| + CFX_Path fillPath;
|
| + fillPath.Create();
|
| + XFA_BOX_GetFillPath(box, strokes, rtWidget, fillPath,
|
| + (dwFlags & XFA_DRAWBOX_ForceRound) != 0);
|
| + fillPath.Close();
|
| + int32_t eType = fill.GetFillType();
|
| + switch (eType) {
|
| + case XFA_ELEMENT_Radial:
|
| + XFA_BOX_Fill_Radial(box, pGS, fillPath, rtWidget, pMatrix);
|
| + break;
|
| + case XFA_ELEMENT_Pattern:
|
| + XFA_BOX_Fill_Pattern(box, pGS, fillPath, rtWidget, pMatrix);
|
| + break;
|
| + case XFA_ELEMENT_Linear:
|
| + XFA_BOX_Fill_Linear(box, pGS, fillPath, rtWidget, pMatrix);
|
| + break;
|
| + default: {
|
| + FX_ARGB cr;
|
| + if (eType == XFA_ELEMENT_Stipple) {
|
| + int32_t iRate = fill.GetStipple(cr);
|
| + if (iRate == 0) {
|
| + iRate = 100;
|
| + }
|
| + int32_t a = 0;
|
| + FX_COLORREF rgb;
|
| + ArgbDecode(cr, a, rgb);
|
| + cr = ArgbEncode(iRate * a / 100, rgb);
|
| + } else {
|
| + cr = fill.GetColor();
|
| + }
|
| + CFX_Color fillColor(cr);
|
| + pGS->SetFillColor(&fillColor);
|
| + pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
|
| + } break;
|
| + }
|
| + pGS->RestoreGraphState();
|
| +}
|
| +static void XFA_BOX_StrokePath(CXFA_Stroke stroke,
|
| + CFX_Path* pPath,
|
| + CFX_Graphics* pGS,
|
| + CFX_Matrix* pMatrix) {
|
| + if (!stroke.IsExistInXML() || !stroke.IsVisible()) {
|
| + return;
|
| + }
|
| + FX_FLOAT fThickness = stroke.GetThickness();
|
| + if (fThickness < 0.001f) {
|
| + return;
|
| + }
|
| + pGS->SaveGraphState();
|
| + if (stroke.IsCorner() && fThickness > 2 * stroke.GetRadius()) {
|
| + fThickness = 2 * stroke.GetRadius();
|
| + }
|
| + pGS->SetLineWidth(fThickness, TRUE);
|
| + pGS->SetLineCap(CFX_GraphStateData::LineCapButt);
|
| + XFA_StrokeTypeSetLineDash(pGS, stroke.GetStrokeType(),
|
| + XFA_ATTRIBUTEENUM_Butt);
|
| + CFX_Color fxColor(stroke.GetColor());
|
| + pGS->SetStrokeColor(&fxColor);
|
| + pGS->StrokePath(pPath, pMatrix);
|
| + pGS->RestoreGraphState();
|
| +}
|
| +static void XFA_BOX_StrokeArc(CXFA_Box box,
|
| + CFX_Graphics* pGS,
|
| + CFX_RectF rtWidget,
|
| + CFX_Matrix* pMatrix,
|
| + FX_DWORD dwFlags) {
|
| + CXFA_Edge edge = box.GetEdge(0);
|
| + if (!edge.IsExistInXML() || !edge.IsVisible()) {
|
| + return;
|
| + }
|
| + FX_BOOL bVisible = FALSE;
|
| + FX_FLOAT fThickness = 0;
|
| + int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
|
| + if (i3DType) {
|
| + if (bVisible && fThickness >= 0.001f) {
|
| + dwFlags |= XFA_DRAWBOX_Lowered3D;
|
| + }
|
| + }
|
| + FX_FLOAT fHalf = edge.GetThickness() / 2;
|
| + if (fHalf < 0) {
|
| + fHalf = 0;
|
| + }
|
| + int32_t iHand = box.GetHand();
|
| + if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| + rtWidget.Inflate(fHalf, fHalf);
|
| + } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| + rtWidget.Deflate(fHalf, fHalf);
|
| + }
|
| + if ((dwFlags & XFA_DRAWBOX_ForceRound) == 0 ||
|
| + (dwFlags & XFA_DRAWBOX_Lowered3D) == 0) {
|
| + if (fHalf < 0.001f) {
|
| + return;
|
| + }
|
| + CFX_Path arcPath;
|
| + arcPath.Create();
|
| + XFA_BOX_GetPath_Arc(box, rtWidget, arcPath, dwFlags);
|
| + XFA_BOX_StrokePath(edge, &arcPath, pGS, pMatrix);
|
| + return;
|
| + }
|
| + pGS->SaveGraphState();
|
| + pGS->SetLineWidth(fHalf);
|
| + FX_FLOAT a, b;
|
| + a = rtWidget.width / 2.0f;
|
| + b = rtWidget.height / 2.0f;
|
| + if (dwFlags & XFA_DRAWBOX_ForceRound) {
|
| + a = b = std::min(a, b);
|
| + }
|
| + CFX_PointF center = rtWidget.Center();
|
| + rtWidget.left = center.x - a;
|
| + rtWidget.top = center.y - b;
|
| + rtWidget.width = a + a;
|
| + rtWidget.height = b + b;
|
| + FX_FLOAT startAngle = 0, sweepAngle = 360;
|
| + startAngle = startAngle * FX_PI / 180.0f;
|
| + sweepAngle = -sweepAngle * FX_PI / 180.0f;
|
| + CFX_Path arcPath;
|
| + arcPath.Create();
|
| + arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| + 3.0f * FX_PI / 4.0f, FX_PI);
|
| + CFX_Color cr(0xFF808080);
|
| + pGS->SetStrokeColor(&cr);
|
| + pGS->StrokePath(&arcPath, pMatrix);
|
| + arcPath.Clear();
|
| + arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| + -1.0f * FX_PI / 4.0f, FX_PI);
|
| + cr.Set(0xFFFFFFFF);
|
| + pGS->SetStrokeColor(&cr);
|
| + pGS->StrokePath(&arcPath, pMatrix);
|
| + rtWidget.Deflate(fHalf, fHalf);
|
| + arcPath.Clear();
|
| + arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| + 3.0f * FX_PI / 4.0f, FX_PI);
|
| + cr.Set(0xFF404040);
|
| + pGS->SetStrokeColor(&cr);
|
| + pGS->StrokePath(&arcPath, pMatrix);
|
| + arcPath.Clear();
|
| + arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
|
| + -1.0f * FX_PI / 4.0f, FX_PI);
|
| + cr.Set(0xFFC0C0C0);
|
| + pGS->SetStrokeColor(&cr);
|
| + pGS->StrokePath(&arcPath, pMatrix);
|
| + pGS->RestoreGraphState();
|
| +}
|
| +static void XFA_Draw3DRect(CFX_Graphics* pGraphic,
|
| + const CFX_RectF& rt,
|
| + FX_FLOAT fLineWidth,
|
| + CFX_Matrix* pMatrix,
|
| + FX_ARGB argbTopLeft,
|
| + FX_ARGB argbBottomRight) {
|
| + CFX_Color crLT(argbTopLeft);
|
| + pGraphic->SetFillColor(&crLT);
|
| + FX_FLOAT fBottom = rt.bottom();
|
| + FX_FLOAT fRight = rt.right();
|
| + CFX_Path pathLT;
|
| + pathLT.Create();
|
| + pathLT.MoveTo(rt.left, fBottom);
|
| + pathLT.LineTo(rt.left, rt.top);
|
| + pathLT.LineTo(fRight, rt.top);
|
| + pathLT.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
|
| + pathLT.LineTo(rt.left + fLineWidth, rt.top + fLineWidth);
|
| + pathLT.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
|
| + pathLT.LineTo(rt.left, fBottom);
|
| + pGraphic->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
|
| + CFX_Color crRB(argbBottomRight);
|
| + pGraphic->SetFillColor(&crRB);
|
| + CFX_Path pathRB;
|
| + pathRB.Create();
|
| + pathRB.MoveTo(fRight, rt.top);
|
| + pathRB.LineTo(fRight, fBottom);
|
| + pathRB.LineTo(rt.left, fBottom);
|
| + pathRB.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
|
| + pathRB.LineTo(fRight - fLineWidth, fBottom - fLineWidth);
|
| + pathRB.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
|
| + pathRB.LineTo(fRight, rt.top);
|
| + pGraphic->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
|
| +}
|
| +static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS,
|
| + CFX_RectF rt,
|
| + FX_FLOAT fThickness,
|
| + CFX_Matrix* pMatrix) {
|
| + FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| + CFX_RectF rtInner(rt);
|
| + rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| + CFX_Color cr(0xFF000000);
|
| + pGS->SetFillColor(&cr);
|
| + CFX_Path path;
|
| + path.Create();
|
| + path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
|
| + path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
|
| + pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
|
| + XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF808080, 0xFFC0C0C0);
|
| +}
|
| +static void XFA_BOX_Stroke_3DRect_Raised(CFX_Graphics* pGS,
|
| + CFX_RectF rt,
|
| + FX_FLOAT fThickness,
|
| + CFX_Matrix* pMatrix) {
|
| + FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| + CFX_RectF rtInner(rt);
|
| + rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| + CFX_Color cr(0xFF000000);
|
| + pGS->SetFillColor(&cr);
|
| + CFX_Path path;
|
| + path.Create();
|
| + path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
|
| + path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
|
| + pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
|
| + XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
|
| +}
|
| +static void XFA_BOX_Stroke_3DRect_Etched(CFX_Graphics* pGS,
|
| + CFX_RectF rt,
|
| + FX_FLOAT fThickness,
|
| + CFX_Matrix* pMatrix) {
|
| + FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| + XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFFFFFFFF);
|
| + CFX_RectF rtInner(rt);
|
| + rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| + XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
|
| +}
|
| +static void XFA_BOX_Stroke_3DRect_Embossed(CFX_Graphics* pGS,
|
| + CFX_RectF rt,
|
| + FX_FLOAT fThickness,
|
| + CFX_Matrix* pMatrix) {
|
| + FX_FLOAT fHalfWidth = fThickness / 2.0f;
|
| + XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFF000000);
|
| + CFX_RectF rtInner(rt);
|
| + rtInner.Deflate(fHalfWidth, fHalfWidth);
|
| + XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF000000, 0xFF808080);
|
| +}
|
| +static void XFA_BOX_Stroke_Rect(CXFA_Box box,
|
| + const CXFA_StrokeArray& strokes,
|
| + CFX_Graphics* pGS,
|
| + CFX_RectF rtWidget,
|
| + CFX_Matrix* pMatrix) {
|
| + FX_BOOL bVisible = FALSE;
|
| + FX_FLOAT fThickness = 0;
|
| + int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
|
| + if (i3DType) {
|
| + if (!bVisible || fThickness < 0.001f) {
|
| + return;
|
| + }
|
| + switch (i3DType) {
|
| + case XFA_ATTRIBUTEENUM_Lowered:
|
| + XFA_BOX_Stroke_3DRect_Lowered(pGS, rtWidget, fThickness, pMatrix);
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_Raised:
|
| + XFA_BOX_Stroke_3DRect_Raised(pGS, rtWidget, fThickness, pMatrix);
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_Etched:
|
| + XFA_BOX_Stroke_3DRect_Etched(pGS, rtWidget, fThickness, pMatrix);
|
| + break;
|
| + case XFA_ATTRIBUTEENUM_Embossed:
|
| + XFA_BOX_Stroke_3DRect_Embossed(pGS, rtWidget, fThickness, pMatrix);
|
| + break;
|
| + }
|
| + return;
|
| + }
|
| + FX_BOOL bClose = FALSE;
|
| + FX_BOOL bSameStyles = TRUE;
|
| + int32_t i;
|
| + CXFA_Stroke stroke1 = strokes[0];
|
| + for (i = 1; i < 8; i++) {
|
| + CXFA_Stroke stroke2 = strokes[i];
|
| + if (!stroke1.SameStyles(stroke2)) {
|
| + bSameStyles = FALSE;
|
| + break;
|
| + }
|
| + stroke1 = stroke2;
|
| + }
|
| + if (bSameStyles) {
|
| + stroke1 = strokes[0];
|
| + bClose = TRUE;
|
| + for (i = 2; i < 8; i += 2) {
|
| + CXFA_Stroke stroke2 = strokes[i];
|
| + if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
|
| + XFA_STROKE_SAMESTYLE_Corner)) {
|
| + bSameStyles = FALSE;
|
| + break;
|
| + }
|
| + stroke1 = stroke2;
|
| + }
|
| + if (bSameStyles) {
|
| + stroke1 = strokes[0];
|
| + if (stroke1.IsInverted()) {
|
| + bSameStyles = FALSE;
|
| + }
|
| + if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
|
| + bSameStyles = FALSE;
|
| + }
|
| + }
|
| + }
|
| + FX_BOOL bStart = TRUE;
|
| + CFX_Path path;
|
| + path.Create();
|
| + for (i = 0; i < 8; i++) {
|
| + CXFA_Stroke stroke1 = strokes[i];
|
| + if ((i % 1) == 0 && stroke1.GetRadius() < 0) {
|
| + FX_BOOL bEmpty = path.IsEmpty();
|
| + if (!bEmpty) {
|
| + XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
|
| + path.Clear();
|
| + }
|
| + bStart = TRUE;
|
| + continue;
|
| + }
|
| + XFA_BOX_GetPath(box, strokes, rtWidget, path, i, bStart, !bSameStyles);
|
| + CXFA_Stroke stroke2 = strokes[(i + 1) % 8];
|
| + bStart = !stroke1.SameStyles(stroke2);
|
| + if (bStart) {
|
| + XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
|
| + path.Clear();
|
| + }
|
| + }
|
| + FX_BOOL bEmpty = path.IsEmpty();
|
| + if (!bEmpty) {
|
| + if (bClose) {
|
| + path.Close();
|
| + }
|
| + XFA_BOX_StrokePath(strokes[7], &path, pGS, pMatrix);
|
| + }
|
| +}
|
| +static void XFA_BOX_Stroke(CXFA_Box box,
|
| + const CXFA_StrokeArray& strokes,
|
| + CFX_Graphics* pGS,
|
| + CFX_RectF rtWidget,
|
| + CFX_Matrix* pMatrix,
|
| + FX_DWORD dwFlags) {
|
| + if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
|
| + XFA_BOX_StrokeArc(box, pGS, rtWidget, pMatrix, dwFlags);
|
| + return;
|
| + }
|
| + FX_BOOL bVisible = FALSE;
|
| + for (int32_t j = 0; j < 4; j++) {
|
| + bVisible |= strokes[j * 2 + 1].IsVisible();
|
| + if (bVisible) {
|
| + break;
|
| + }
|
| + }
|
| + if (!bVisible) {
|
| + return;
|
| + }
|
| + for (int32_t i = 1; i < 8; i += 2) {
|
| + CXFA_Edge edge = (CXFA_Node*)strokes[i];
|
| + FX_FLOAT fThickness = edge.GetThickness();
|
| + if (fThickness < 0) {
|
| + fThickness = 0;
|
| + }
|
| + FX_FLOAT fHalf = fThickness / 2;
|
| + int32_t iHand = box.GetHand();
|
| + switch (i) {
|
| + case 1:
|
| + if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| + rtWidget.top -= fHalf;
|
| + rtWidget.height += fHalf;
|
| + } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| + rtWidget.top += fHalf;
|
| + rtWidget.height -= fHalf;
|
| + }
|
| + break;
|
| + case 3:
|
| + if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| + rtWidget.width += fHalf;
|
| + } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| + rtWidget.width -= fHalf;
|
| + }
|
| + break;
|
| + case 5:
|
| + if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| + rtWidget.height += fHalf;
|
| + } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| + rtWidget.height -= fHalf;
|
| + }
|
| + break;
|
| + case 7:
|
| + if (iHand == XFA_ATTRIBUTEENUM_Left) {
|
| + rtWidget.left -= fHalf;
|
| + rtWidget.width += fHalf;
|
| + } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
|
| + rtWidget.left += fHalf;
|
| + rtWidget.width -= fHalf;
|
| + }
|
| + break;
|
| + }
|
| + }
|
| + XFA_BOX_Stroke_Rect(box, strokes, pGS, rtWidget, pMatrix);
|
| +}
|
| +void XFA_DrawBox(CXFA_Box box,
|
| + CFX_Graphics* pGS,
|
| + const CFX_RectF& rtWidget,
|
| + CFX_Matrix* pMatrix,
|
| + FX_DWORD dwFlags) {
|
| + if (!box || box.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
|
| + return;
|
| + }
|
| + int32_t iType = box.GetClassID();
|
| + if (iType != XFA_ELEMENT_Arc && iType != XFA_ELEMENT_Border &&
|
| + iType != XFA_ELEMENT_Rectangle) {
|
| + return;
|
| + }
|
| + CXFA_StrokeArray strokes;
|
| + if (!(dwFlags & XFA_DRAWBOX_ForceRound) && iType != XFA_ELEMENT_Arc) {
|
| + box.GetStrokes(strokes);
|
| + }
|
| + XFA_BOX_Fill(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
|
| + XFA_BOX_Stroke(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
|
| +}
|
|
|