blob: db05f7624168cf86cd8c6807e3f2dd475c566f36 [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "xfa/fde/fde_gedevice.h"
8
9#include <algorithm>
Dan Sinclair85c8e7f2016-11-21 13:50:32 -050010#include <memory>
Dan Sinclair1770c022016-03-14 14:14:16 -040011
dsinclair74a34fc2016-09-29 16:41:42 -070012#include "core/fxge/cfx_gemodule.h"
13#include "core/fxge/cfx_graphstatedata.h"
14#include "core/fxge/cfx_renderdevice.h"
15#include "core/fxge/cfx_substfont.h"
dsinclairacd0d592016-04-21 11:06:27 -070016#include "xfa/fde/cfde_path.h"
dsinclair25c223d2016-04-12 09:51:45 -070017#include "xfa/fde/fde_object.h"
npm8f3eb602016-11-11 17:16:23 -080018#include "xfa/fgas/font/cfgas_fontmgr.h"
npm4b91a2d2016-11-21 15:19:44 -080019#include "xfa/fgas/font/cfgas_gefont.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040020
dsinclairacd0d592016-04-21 11:06:27 -070021CFDE_RenderDevice::CFDE_RenderDevice(CFX_RenderDevice* pDevice,
tsepezd19e9122016-11-02 15:43:18 -070022 bool bOwnerDevice)
23 : m_pDevice(pDevice), m_bOwnerDevice(bOwnerDevice), m_iCharCount(0) {
dsinclair43854a52016-04-27 12:26:00 -070024 ASSERT(pDevice);
dsinclairacd0d592016-04-21 11:06:27 -070025
Dan Sinclair1770c022016-03-14 14:14:16 -040026 FX_RECT rt = m_pDevice->GetClipBox();
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050027 m_rtClip = CFX_RectF(
28 static_cast<FX_FLOAT>(rt.left), static_cast<FX_FLOAT>(rt.top),
29 static_cast<FX_FLOAT>(rt.Width()), static_cast<FX_FLOAT>(rt.Height()));
Dan Sinclair1770c022016-03-14 14:14:16 -040030}
dsinclairacd0d592016-04-21 11:06:27 -070031
32CFDE_RenderDevice::~CFDE_RenderDevice() {
Dan Sinclair1770c022016-03-14 14:14:16 -040033 if (m_bOwnerDevice)
34 delete m_pDevice;
35}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050036
dsinclairacd0d592016-04-21 11:06:27 -070037int32_t CFDE_RenderDevice::GetWidth() const {
Dan Sinclair1770c022016-03-14 14:14:16 -040038 return m_pDevice->GetWidth();
39}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050040
dsinclairacd0d592016-04-21 11:06:27 -070041int32_t CFDE_RenderDevice::GetHeight() const {
Dan Sinclair1770c022016-03-14 14:14:16 -040042 return m_pDevice->GetHeight();
43}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050044
dsinclairfe433f12016-06-06 12:03:31 -070045void CFDE_RenderDevice::SaveState() {
Dan Sinclair1770c022016-03-14 14:14:16 -040046 m_pDevice->SaveState();
Dan Sinclair1770c022016-03-14 14:14:16 -040047}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050048
dsinclairfe433f12016-06-06 12:03:31 -070049void CFDE_RenderDevice::RestoreState() {
thestig41846a02016-05-26 10:45:30 -070050 m_pDevice->RestoreState(false);
Dan Sinclair1770c022016-03-14 14:14:16 -040051 const FX_RECT& rt = m_pDevice->GetClipBox();
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050052 m_rtClip = CFX_RectF(
53 static_cast<FX_FLOAT>(rt.left), static_cast<FX_FLOAT>(rt.top),
54 static_cast<FX_FLOAT>(rt.Width()), static_cast<FX_FLOAT>(rt.Height()));
Dan Sinclair1770c022016-03-14 14:14:16 -040055}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050056
tsepezd19e9122016-11-02 15:43:18 -070057bool CFDE_RenderDevice::SetClipRect(const CFX_RectF& rtClip) {
Dan Sinclair1770c022016-03-14 14:14:16 -040058 m_rtClip = rtClip;
59 return m_pDevice->SetClip_Rect(FX_RECT((int32_t)FXSYS_floor(rtClip.left),
60 (int32_t)FXSYS_floor(rtClip.top),
61 (int32_t)FXSYS_ceil(rtClip.right()),
62 (int32_t)FXSYS_ceil(rtClip.bottom())));
63}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050064
dsinclairacd0d592016-04-21 11:06:27 -070065const CFX_RectF& CFDE_RenderDevice::GetClipRect() {
Dan Sinclair1770c022016-03-14 14:14:16 -040066 return m_rtClip;
67}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050068
tsepezd19e9122016-11-02 15:43:18 -070069bool CFDE_RenderDevice::SetClipPath(const CFDE_Path* pClip) {
70 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -040071}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050072
dsinclairacd0d592016-04-21 11:06:27 -070073CFDE_Path* CFDE_RenderDevice::GetClipPath() const {
thestigcfb77cc2016-06-10 12:21:53 -070074 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -040075}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050076
dsinclairacd0d592016-04-21 11:06:27 -070077FX_FLOAT CFDE_RenderDevice::GetDpiX() const {
Dan Sinclair1770c022016-03-14 14:14:16 -040078 return 96;
79}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050080
dsinclairacd0d592016-04-21 11:06:27 -070081FX_FLOAT CFDE_RenderDevice::GetDpiY() const {
Dan Sinclair1770c022016-03-14 14:14:16 -040082 return 96;
83}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050084
tsepezd19e9122016-11-02 15:43:18 -070085bool CFDE_RenderDevice::DrawImage(CFX_DIBSource* pDib,
86 const CFX_RectF* pSrcRect,
87 const CFX_RectF& dstRect,
88 const CFX_Matrix* pImgMatrix,
89 const CFX_Matrix* pDevMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -040090 CFX_RectF srcRect;
91 if (pSrcRect) {
92 srcRect = *pSrcRect;
93 } else {
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050094 srcRect = CFX_RectF(0, 0, static_cast<FX_FLOAT>(pDib->GetWidth()),
95 static_cast<FX_FLOAT>(pDib->GetHeight()));
Dan Sinclair1770c022016-03-14 14:14:16 -040096 }
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050097
98 if (srcRect.IsEmpty())
tsepezd19e9122016-11-02 15:43:18 -070099 return false;
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500100
Dan Sinclair1770c022016-03-14 14:14:16 -0400101 CFX_Matrix dib2fxdev;
102 if (pImgMatrix) {
103 dib2fxdev = *pImgMatrix;
104 } else {
105 dib2fxdev.SetIdentity();
106 }
107 dib2fxdev.a = dstRect.width;
108 dib2fxdev.d = -dstRect.height;
109 dib2fxdev.e = dstRect.left;
110 dib2fxdev.f = dstRect.bottom();
111 if (pDevMatrix) {
112 dib2fxdev.Concat(*pDevMatrix);
113 }
thestigcfb77cc2016-06-10 12:21:53 -0700114 void* handle = nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400115 m_pDevice->StartDIBits(pDib, 255, 0, (const CFX_Matrix*)&dib2fxdev, 0,
116 handle);
thestigcfb77cc2016-06-10 12:21:53 -0700117 while (m_pDevice->ContinueDIBits(handle, nullptr)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400118 }
119 m_pDevice->CancelDIBits(handle);
thestigcfb77cc2016-06-10 12:21:53 -0700120 return !!handle;
Dan Sinclair1770c022016-03-14 14:14:16 -0400121}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500122
tsepezd19e9122016-11-02 15:43:18 -0700123bool CFDE_RenderDevice::DrawString(CFDE_Brush* pBrush,
tsepeze6477992017-01-05 12:57:00 -0800124 const CFX_RetainPtr<CFGAS_GEFont>& pFont,
tsepezd19e9122016-11-02 15:43:18 -0700125 const FXTEXT_CHARPOS* pCharPos,
126 int32_t iCount,
127 FX_FLOAT fFontSize,
128 const CFX_Matrix* pMatrix) {
tsepez48ddd862016-06-06 10:51:58 -0700129 ASSERT(pBrush && pFont && pCharPos && iCount > 0);
tsepez48ddd862016-06-06 10:51:58 -0700130 CFX_Font* pFxFont = pFont->GetDevFont();
dsinclaira5c13232016-04-12 13:19:36 -0700131 FX_ARGB argb = pBrush->GetColor();
132 if ((pFont->GetFontStyles() & FX_FONTSTYLE_Italic) != 0 &&
133 !pFxFont->IsItalic()) {
134 FXTEXT_CHARPOS* pCP = (FXTEXT_CHARPOS*)pCharPos;
135 FX_FLOAT* pAM;
136 for (int32_t i = 0; i < iCount; ++i) {
137 static const FX_FLOAT mc = 0.267949f;
138 pAM = pCP->m_AdjustMatrix;
139 pAM[2] = mc * pAM[0] + pAM[2];
140 pAM[3] = mc * pAM[1] + pAM[3];
141 pCP++;
142 }
143 }
144 FXTEXT_CHARPOS* pCP = (FXTEXT_CHARPOS*)pCharPos;
tsepeze6477992017-01-05 12:57:00 -0800145 CFX_RetainPtr<CFGAS_GEFont> pCurFont;
146 CFX_RetainPtr<CFGAS_GEFont> pSTFont;
dsinclair85d1f2c2016-06-23 12:40:16 -0700147 FXTEXT_CHARPOS* pCurCP = nullptr;
dsinclaira5c13232016-04-12 13:19:36 -0700148 int32_t iCurCount = 0;
149
Dan Sinclair1770c022016-03-14 14:14:16 -0400150#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
dsinclaira5c13232016-04-12 13:19:36 -0700151 uint32_t dwFontStyle = pFont->GetFontStyles();
152 CFX_Font FxFont;
weili9b671ac2016-07-25 07:40:27 -0700153 CFX_SubstFont* SubstFxFont = new CFX_SubstFont();
154 FxFont.SetSubstFont(std::unique_ptr<CFX_SubstFont>(SubstFxFont));
155 SubstFxFont->m_Weight = dwFontStyle & FX_FONTSTYLE_Bold ? 700 : 400;
156 SubstFxFont->m_ItalicAngle = dwFontStyle & FX_FONTSTYLE_Italic ? -12 : 0;
157 SubstFxFont->m_WeightCJK = SubstFxFont->m_Weight;
158 SubstFxFont->m_bItalicCJK = !!(dwFontStyle & FX_FONTSTYLE_Italic);
Dan Sinclair1770c022016-03-14 14:14:16 -0400159#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
dsinclaira5c13232016-04-12 13:19:36 -0700160
161 for (int32_t i = 0; i < iCount; ++i) {
162 pSTFont = pFont->GetSubstFont((int32_t)pCP->m_GlyphIndex);
163 pCP->m_GlyphIndex &= 0x00FFFFFF;
thestigec51ac32016-06-20 10:38:52 -0700164 pCP->m_bFontStyle = false;
dsinclaira5c13232016-04-12 13:19:36 -0700165 if (pCurFont != pSTFont) {
tsepez48ddd862016-06-06 10:51:58 -0700166 if (pCurFont) {
167 pFxFont = pCurFont->GetDevFont();
Dan Sinclair1770c022016-03-14 14:14:16 -0400168#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
169 FxFont.SetFace(pFxFont->GetFace());
art-snake9972ff92016-09-20 07:46:25 -0700170 m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, -fFontSize,
Dan Sinclair1b08df12017-02-09 09:17:20 -0500171 pMatrix, argb, FXTEXT_CLEARTYPE);
Dan Sinclair1770c022016-03-14 14:14:16 -0400172#else
art-snake9972ff92016-09-20 07:46:25 -0700173 m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, -fFontSize,
Dan Sinclair1b08df12017-02-09 09:17:20 -0500174 pMatrix, argb, FXTEXT_CLEARTYPE);
Dan Sinclair1770c022016-03-14 14:14:16 -0400175#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
176 }
dsinclaira5c13232016-04-12 13:19:36 -0700177 pCurFont = pSTFont;
178 pCurCP = pCP;
179 iCurCount = 1;
180 } else {
181 iCurCount++;
182 }
183 pCP++;
Dan Sinclair1770c022016-03-14 14:14:16 -0400184 }
tsepez48ddd862016-06-06 10:51:58 -0700185 if (pCurFont && iCurCount) {
186 pFxFont = pCurFont->GetDevFont();
dsinclaira5c13232016-04-12 13:19:36 -0700187#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
188 FxFont.SetFace(pFxFont->GetFace());
Dan Sinclair1b08df12017-02-09 09:17:20 -0500189 bool bRet =
190 m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, -fFontSize,
191 pMatrix, argb, FXTEXT_CLEARTYPE);
dsinclaira5c13232016-04-12 13:19:36 -0700192 FxFont.SetFace(nullptr);
193 return bRet;
194#else
art-snake9972ff92016-09-20 07:46:25 -0700195 return m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, -fFontSize,
Dan Sinclair1b08df12017-02-09 09:17:20 -0500196 pMatrix, argb, FXTEXT_CLEARTYPE);
dsinclaira5c13232016-04-12 13:19:36 -0700197#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
198 }
199
200#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
dsinclaira5c13232016-04-12 13:19:36 -0700201 FxFont.SetFace(nullptr);
202#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
203
tsepezd19e9122016-11-02 15:43:18 -0700204 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400205}
dsinclaira5c13232016-04-12 13:19:36 -0700206
tsepezd19e9122016-11-02 15:43:18 -0700207bool CFDE_RenderDevice::DrawBezier(CFDE_Pen* pPen,
208 FX_FLOAT fPenWidth,
209 const CFX_PointF& pt1,
210 const CFX_PointF& pt2,
211 const CFX_PointF& pt3,
212 const CFX_PointF& pt4,
213 const CFX_Matrix* pMatrix) {
tsepez6db6fbc2017-01-20 12:22:16 -0800214 std::vector<CFX_PointF> points;
215 points.push_back(pt1);
216 points.push_back(pt2);
217 points.push_back(pt3);
218 points.push_back(pt4);
Dan Sinclair1770c022016-03-14 14:14:16 -0400219 CFDE_Path path;
220 path.AddBezier(points);
221 return DrawPath(pPen, fPenWidth, &path, pMatrix);
222}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500223
tsepezd19e9122016-11-02 15:43:18 -0700224bool CFDE_RenderDevice::DrawCurve(CFDE_Pen* pPen,
225 FX_FLOAT fPenWidth,
tsepez6db6fbc2017-01-20 12:22:16 -0800226 const std::vector<CFX_PointF>& points,
tsepezd19e9122016-11-02 15:43:18 -0700227 bool bClosed,
228 FX_FLOAT fTension,
229 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400230 CFDE_Path path;
231 path.AddCurve(points, bClosed, fTension);
232 return DrawPath(pPen, fPenWidth, &path, pMatrix);
233}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500234
tsepezd19e9122016-11-02 15:43:18 -0700235bool CFDE_RenderDevice::DrawEllipse(CFDE_Pen* pPen,
236 FX_FLOAT fPenWidth,
237 const CFX_RectF& rect,
238 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400239 CFDE_Path path;
240 path.AddEllipse(rect);
241 return DrawPath(pPen, fPenWidth, &path, pMatrix);
242}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500243
tsepezd19e9122016-11-02 15:43:18 -0700244bool CFDE_RenderDevice::DrawLines(CFDE_Pen* pPen,
245 FX_FLOAT fPenWidth,
tsepez6db6fbc2017-01-20 12:22:16 -0800246 const std::vector<CFX_PointF>& points,
tsepezd19e9122016-11-02 15:43:18 -0700247 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400248 CFDE_Path path;
249 path.AddLines(points);
250 return DrawPath(pPen, fPenWidth, &path, pMatrix);
251}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500252
tsepezd19e9122016-11-02 15:43:18 -0700253bool CFDE_RenderDevice::DrawLine(CFDE_Pen* pPen,
254 FX_FLOAT fPenWidth,
255 const CFX_PointF& pt1,
256 const CFX_PointF& pt2,
257 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400258 CFDE_Path path;
259 path.AddLine(pt1, pt2);
260 return DrawPath(pPen, fPenWidth, &path, pMatrix);
261}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500262
tsepezd19e9122016-11-02 15:43:18 -0700263bool CFDE_RenderDevice::DrawPath(CFDE_Pen* pPen,
264 FX_FLOAT fPenWidth,
265 const CFDE_Path* pPath,
266 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400267 CFDE_Path* pGePath = (CFDE_Path*)pPath;
thestigcfb77cc2016-06-10 12:21:53 -0700268 if (!pGePath)
tsepezd19e9122016-11-02 15:43:18 -0700269 return false;
thestigcfb77cc2016-06-10 12:21:53 -0700270
Dan Sinclair1770c022016-03-14 14:14:16 -0400271 CFX_GraphStateData graphState;
272 if (!CreatePen(pPen, fPenWidth, graphState)) {
tsepezd19e9122016-11-02 15:43:18 -0700273 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400274 }
275 return m_pDevice->DrawPath(&pGePath->m_Path, (const CFX_Matrix*)pMatrix,
276 &graphState, 0, pPen->GetColor(), 0);
277}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500278
tsepezd19e9122016-11-02 15:43:18 -0700279bool CFDE_RenderDevice::DrawPolygon(CFDE_Pen* pPen,
280 FX_FLOAT fPenWidth,
tsepez6db6fbc2017-01-20 12:22:16 -0800281 const std::vector<CFX_PointF>& points,
tsepezd19e9122016-11-02 15:43:18 -0700282 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400283 CFDE_Path path;
284 path.AddPolygon(points);
285 return DrawPath(pPen, fPenWidth, &path, pMatrix);
286}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500287
tsepezd19e9122016-11-02 15:43:18 -0700288bool CFDE_RenderDevice::DrawRectangle(CFDE_Pen* pPen,
289 FX_FLOAT fPenWidth,
290 const CFX_RectF& rect,
291 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400292 CFDE_Path path;
293 path.AddRectangle(rect);
294 return DrawPath(pPen, fPenWidth, &path, pMatrix);
295}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500296
tsepezd19e9122016-11-02 15:43:18 -0700297bool CFDE_RenderDevice::FillClosedCurve(CFDE_Brush* pBrush,
tsepez6db6fbc2017-01-20 12:22:16 -0800298 const std::vector<CFX_PointF>& points,
tsepezd19e9122016-11-02 15:43:18 -0700299 FX_FLOAT fTension,
300 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400301 CFDE_Path path;
tsepezd19e9122016-11-02 15:43:18 -0700302 path.AddCurve(points, true, fTension);
Dan Sinclair1770c022016-03-14 14:14:16 -0400303 return FillPath(pBrush, &path, pMatrix);
304}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500305
tsepezd19e9122016-11-02 15:43:18 -0700306bool CFDE_RenderDevice::FillEllipse(CFDE_Brush* pBrush,
307 const CFX_RectF& rect,
308 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400309 CFDE_Path path;
310 path.AddEllipse(rect);
311 return FillPath(pBrush, &path, pMatrix);
312}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500313
tsepezd19e9122016-11-02 15:43:18 -0700314bool CFDE_RenderDevice::FillPolygon(CFDE_Brush* pBrush,
tsepez6db6fbc2017-01-20 12:22:16 -0800315 const std::vector<CFX_PointF>& points,
tsepezd19e9122016-11-02 15:43:18 -0700316 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400317 CFDE_Path path;
318 path.AddPolygon(points);
319 return FillPath(pBrush, &path, pMatrix);
320}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500321
tsepezd19e9122016-11-02 15:43:18 -0700322bool CFDE_RenderDevice::FillRectangle(CFDE_Brush* pBrush,
323 const CFX_RectF& rect,
324 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400325 CFDE_Path path;
326 path.AddRectangle(rect);
327 return FillPath(pBrush, &path, pMatrix);
328}
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500329
tsepezd19e9122016-11-02 15:43:18 -0700330bool CFDE_RenderDevice::CreatePen(CFDE_Pen* pPen,
331 FX_FLOAT fPenWidth,
332 CFX_GraphStateData& graphState) {
dsinclaira5c13232016-04-12 13:19:36 -0700333 if (!pPen)
tsepezd19e9122016-11-02 15:43:18 -0700334 return false;
dsinclaira5c13232016-04-12 13:19:36 -0700335
336 graphState.m_LineCap = CFX_GraphStateData::LineCapButt;
337 graphState.m_LineJoin = CFX_GraphStateData::LineJoinMiter;
Dan Sinclair1770c022016-03-14 14:14:16 -0400338 graphState.m_LineWidth = fPenWidth;
dsinclaira5c13232016-04-12 13:19:36 -0700339 graphState.m_MiterLimit = 10;
340 graphState.m_DashPhase = 0;
tsepezd19e9122016-11-02 15:43:18 -0700341 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400342}
dsinclair25c223d2016-04-12 09:51:45 -0700343
tsepezd19e9122016-11-02 15:43:18 -0700344bool CFDE_RenderDevice::FillPath(CFDE_Brush* pBrush,
345 const CFDE_Path* pPath,
346 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400347 CFDE_Path* pGePath = (CFDE_Path*)pPath;
dsinclair25c223d2016-04-12 09:51:45 -0700348 if (!pGePath)
tsepezd19e9122016-11-02 15:43:18 -0700349 return false;
dsinclair25c223d2016-04-12 09:51:45 -0700350 if (!pBrush)
tsepezd19e9122016-11-02 15:43:18 -0700351 return false;
dsinclaira5c13232016-04-12 13:19:36 -0700352 return m_pDevice->DrawPath(&pGePath->m_Path, pMatrix, nullptr,
353 pBrush->GetColor(), 0, FXFILL_WINDING);
Dan Sinclair1770c022016-03-14 14:14:16 -0400354}
dsinclair25c223d2016-04-12 09:51:45 -0700355