Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: xfa/src/fde/fde_gedevice.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/src/fde/fde_gedevice.h ('k') | xfa/src/fde/fde_geobject.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // 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/src/fde/fde_gedevice.h"
8
9 #include <algorithm>
10
11 #include "xfa/src/fde/fde_brush.h"
12 #include "xfa/src/fde/fde_devbasic.h"
13 #include "xfa/src/fde/fde_geobject.h"
14 #include "xfa/src/fde/fde_image.h"
15 #include "xfa/src/fde/fde_pen.h"
16
17 FX_BOOL FDE_GetStockHatchMask(int32_t iHatchStyle, CFX_DIBitmap& hatchMask) {
18 FDE_LPCHATCHDATA pData = FDE_DEVGetHatchData(iHatchStyle);
19 if (!pData) {
20 return FALSE;
21 }
22 hatchMask.Create(pData->iWidth, pData->iHeight, FXDIB_1bppMask);
23 FXSYS_memcpy(hatchMask.GetBuffer(), pData->MaskBits,
24 hatchMask.GetPitch() * pData->iHeight);
25 return TRUE;
26 }
27
28 IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_DIBitmap* pBitmap,
29 FX_BOOL bRgbByteOrder) {
30 if (pBitmap == NULL) {
31 return NULL;
32 }
33 CFX_FxgeDevice* pDevice = new CFX_FxgeDevice;
34 pDevice->Attach(pBitmap, 0, bRgbByteOrder);
35 return new CFDE_FxgeDevice(pDevice, TRUE);
36 }
37 IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_RenderDevice* pDevice) {
38 return pDevice ? new CFDE_FxgeDevice(pDevice, FALSE) : nullptr;
39 }
40 CFDE_FxgeDevice::CFDE_FxgeDevice(CFX_RenderDevice* pDevice,
41 FX_BOOL bOwnerDevice)
42 : m_pDevice(pDevice),
43 m_bOwnerDevice(bOwnerDevice),
44 m_pCharPos(NULL),
45 m_iCharCount(0) {
46 FXSYS_assert(pDevice != NULL);
47 FX_RECT rt = m_pDevice->GetClipBox();
48 m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(),
49 (FX_FLOAT)rt.Height());
50 }
51 CFDE_FxgeDevice::~CFDE_FxgeDevice() {
52 FX_Free(m_pCharPos);
53 if (m_bOwnerDevice)
54 delete m_pDevice;
55 }
56 int32_t CFDE_FxgeDevice::GetWidth() const {
57 return m_pDevice->GetWidth();
58 }
59 int32_t CFDE_FxgeDevice::GetHeight() const {
60 return m_pDevice->GetHeight();
61 }
62 FDE_HDEVICESTATE CFDE_FxgeDevice::SaveState() {
63 m_pDevice->SaveState();
64 return NULL;
65 }
66 void CFDE_FxgeDevice::RestoreState(FDE_HDEVICESTATE hState) {
67 m_pDevice->RestoreState();
68 const FX_RECT& rt = m_pDevice->GetClipBox();
69 m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(),
70 (FX_FLOAT)rt.Height());
71 }
72 FX_BOOL CFDE_FxgeDevice::SetClipRect(const CFX_RectF& rtClip) {
73 m_rtClip = rtClip;
74 return m_pDevice->SetClip_Rect(FX_RECT((int32_t)FXSYS_floor(rtClip.left),
75 (int32_t)FXSYS_floor(rtClip.top),
76 (int32_t)FXSYS_ceil(rtClip.right()),
77 (int32_t)FXSYS_ceil(rtClip.bottom())));
78 }
79 const CFX_RectF& CFDE_FxgeDevice::GetClipRect() {
80 return m_rtClip;
81 }
82 FX_BOOL CFDE_FxgeDevice::SetClipPath(const IFDE_Path* pClip) {
83 return FALSE;
84 }
85 IFDE_Path* CFDE_FxgeDevice::GetClipPath() const {
86 return NULL;
87 }
88 FX_FLOAT CFDE_FxgeDevice::GetDpiX() const {
89 return 96;
90 }
91 FX_FLOAT CFDE_FxgeDevice::GetDpiY() const {
92 return 96;
93 }
94 FX_BOOL CFDE_FxgeDevice::DrawImage(CFX_DIBSource* pDib,
95 const CFX_RectF* pSrcRect,
96 const CFX_RectF& dstRect,
97 const CFX_Matrix* pImgMatrix,
98 const CFX_Matrix* pDevMatrix) {
99 FXSYS_assert(pDib != NULL);
100 CFX_RectF srcRect;
101 if (pSrcRect) {
102 srcRect = *pSrcRect;
103 } else {
104 srcRect.Set(0, 0, (FX_FLOAT)pDib->GetWidth(), (FX_FLOAT)pDib->GetHeight());
105 }
106 if (srcRect.IsEmpty()) {
107 return FALSE;
108 }
109 CFX_Matrix dib2fxdev;
110 if (pImgMatrix) {
111 dib2fxdev = *pImgMatrix;
112 } else {
113 dib2fxdev.SetIdentity();
114 }
115 dib2fxdev.a = dstRect.width;
116 dib2fxdev.d = -dstRect.height;
117 dib2fxdev.e = dstRect.left;
118 dib2fxdev.f = dstRect.bottom();
119 if (pDevMatrix) {
120 dib2fxdev.Concat(*pDevMatrix);
121 }
122 void* handle = NULL;
123 m_pDevice->StartDIBits(pDib, 255, 0, (const CFX_Matrix*)&dib2fxdev, 0,
124 handle);
125 while (m_pDevice->ContinueDIBits(handle, NULL)) {
126 }
127 m_pDevice->CancelDIBits(handle);
128 return handle != NULL;
129 }
130 FX_BOOL CFDE_FxgeDevice::DrawString(IFDE_Brush* pBrush,
131 IFX_Font* pFont,
132 const FXTEXT_CHARPOS* pCharPos,
133 int32_t iCount,
134 FX_FLOAT fFontSize,
135 const CFX_Matrix* pMatrix) {
136 FXSYS_assert(pBrush != NULL && pFont != NULL && pCharPos != NULL &&
137 iCount > 0);
138 CFX_FontCache* pCache = CFX_GEModule::Get()->GetFontCache();
139 CFX_Font* pFxFont = (CFX_Font*)pFont->GetDevFont();
140 switch (pBrush->GetType()) {
141 case FDE_BRUSHTYPE_Solid: {
142 FX_ARGB argb = ((IFDE_SolidBrush*)pBrush)->GetColor();
143 if ((pFont->GetFontStyles() & FX_FONTSTYLE_Italic) != 0 &&
144 !pFxFont->IsItalic()) {
145 FXTEXT_CHARPOS* pCP = (FXTEXT_CHARPOS*)pCharPos;
146 FX_FLOAT* pAM;
147 for (int32_t i = 0; i < iCount; ++i) {
148 static const FX_FLOAT mc = 0.267949f;
149 pAM = pCP->m_AdjustMatrix;
150 pAM[2] = mc * pAM[0] + pAM[2];
151 pAM[3] = mc * pAM[1] + pAM[3];
152 pCP++;
153 }
154 }
155 FXTEXT_CHARPOS* pCP = (FXTEXT_CHARPOS*)pCharPos;
156 IFX_Font* pCurFont = NULL;
157 IFX_Font* pSTFont = NULL;
158 FXTEXT_CHARPOS* pCurCP = NULL;
159 int32_t iCurCount = 0;
160 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
161 FX_DWORD dwFontStyle = pFont->GetFontStyles();
162 CFX_Font FxFont;
163 CFX_SubstFont SubstFxFont;
164 FxFont.SetSubstFont(&SubstFxFont);
165 SubstFxFont.m_Weight = dwFontStyle & FX_FONTSTYLE_Bold ? 700 : 400;
166 SubstFxFont.m_WeightCJK = SubstFxFont.m_Weight;
167 SubstFxFont.m_ItalicAngle = dwFontStyle & FX_FONTSTYLE_Italic ? -12 : 0;
168 SubstFxFont.m_bItlicCJK = !!(dwFontStyle & FX_FONTSTYLE_Italic);
169 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
170 for (int32_t i = 0; i < iCount; ++i) {
171 pSTFont = pFont->GetSubstFont((int32_t)pCP->m_GlyphIndex);
172 pCP->m_GlyphIndex &= 0x00FFFFFF;
173 pCP->m_bFontStyle = FALSE;
174 if (pCurFont != pSTFont) {
175 if (pCurFont != NULL) {
176 pFxFont = (CFX_Font*)pCurFont->GetDevFont();
177 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
178 FxFont.SetFace(pFxFont->GetFace());
179 m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, pCache,
180 -fFontSize, (const CFX_Matrix*)pMatrix,
181 argb, FXTEXT_CLEARTYPE);
182 #else
183 m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, pCache,
184 -fFontSize, (const CFX_Matrix*)pMatrix,
185 argb, FXTEXT_CLEARTYPE);
186 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
187 }
188 pCurFont = pSTFont;
189 pCurCP = pCP;
190 iCurCount = 1;
191 } else {
192 iCurCount++;
193 }
194 pCP++;
195 }
196 if (pCurFont != NULL && iCurCount) {
197 pFxFont = (CFX_Font*)pCurFont->GetDevFont();
198 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
199 FxFont.SetFace(pFxFont->GetFace());
200 FX_BOOL bRet = m_pDevice->DrawNormalText(
201 iCurCount, pCurCP, &FxFont, pCache, -fFontSize,
202 (const CFX_Matrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
203 FxFont.SetSubstFont(nullptr);
204 FxFont.SetFace(nullptr);
205 return bRet;
206 #else
207 return m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, pCache,
208 -fFontSize, (const CFX_Matrix*)pMatrix,
209 argb, FXTEXT_CLEARTYPE);
210 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
211 }
212 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
213 FxFont.SetSubstFont(nullptr);
214 FxFont.SetFace(nullptr);
215 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
216 return TRUE;
217 } break;
218 default:
219 return FALSE;
220 }
221 }
222 FX_BOOL CFDE_FxgeDevice::DrawBezier(IFDE_Pen* pPen,
223 FX_FLOAT fPenWidth,
224 const CFX_PointF& pt1,
225 const CFX_PointF& pt2,
226 const CFX_PointF& pt3,
227 const CFX_PointF& pt4,
228 const CFX_Matrix* pMatrix) {
229 CFX_PointsF points;
230 points.Add(pt1);
231 points.Add(pt2);
232 points.Add(pt3);
233 points.Add(pt4);
234 CFDE_Path path;
235 path.AddBezier(points);
236 return DrawPath(pPen, fPenWidth, &path, pMatrix);
237 }
238 FX_BOOL CFDE_FxgeDevice::DrawCurve(IFDE_Pen* pPen,
239 FX_FLOAT fPenWidth,
240 const CFX_PointsF& points,
241 FX_BOOL bClosed,
242 FX_FLOAT fTension,
243 const CFX_Matrix* pMatrix) {
244 CFDE_Path path;
245 path.AddCurve(points, bClosed, fTension);
246 return DrawPath(pPen, fPenWidth, &path, pMatrix);
247 }
248 FX_BOOL CFDE_FxgeDevice::DrawEllipse(IFDE_Pen* pPen,
249 FX_FLOAT fPenWidth,
250 const CFX_RectF& rect,
251 const CFX_Matrix* pMatrix) {
252 CFDE_Path path;
253 path.AddEllipse(rect);
254 return DrawPath(pPen, fPenWidth, &path, pMatrix);
255 }
256 FX_BOOL CFDE_FxgeDevice::DrawLines(IFDE_Pen* pPen,
257 FX_FLOAT fPenWidth,
258 const CFX_PointsF& points,
259 const CFX_Matrix* pMatrix) {
260 CFDE_Path path;
261 path.AddLines(points);
262 return DrawPath(pPen, fPenWidth, &path, pMatrix);
263 }
264 FX_BOOL CFDE_FxgeDevice::DrawLine(IFDE_Pen* pPen,
265 FX_FLOAT fPenWidth,
266 const CFX_PointF& pt1,
267 const CFX_PointF& pt2,
268 const CFX_Matrix* pMatrix) {
269 CFDE_Path path;
270 path.AddLine(pt1, pt2);
271 return DrawPath(pPen, fPenWidth, &path, pMatrix);
272 }
273 FX_BOOL CFDE_FxgeDevice::DrawPath(IFDE_Pen* pPen,
274 FX_FLOAT fPenWidth,
275 const IFDE_Path* pPath,
276 const CFX_Matrix* pMatrix) {
277 CFDE_Path* pGePath = (CFDE_Path*)pPath;
278 if (pGePath == NULL) {
279 return FALSE;
280 }
281 CFX_GraphStateData graphState;
282 if (!CreatePen(pPen, fPenWidth, graphState)) {
283 return FALSE;
284 }
285 return m_pDevice->DrawPath(&pGePath->m_Path, (const CFX_Matrix*)pMatrix,
286 &graphState, 0, pPen->GetColor(), 0);
287 }
288 FX_BOOL CFDE_FxgeDevice::DrawPolygon(IFDE_Pen* pPen,
289 FX_FLOAT fPenWidth,
290 const CFX_PointsF& points,
291 const CFX_Matrix* pMatrix) {
292 CFDE_Path path;
293 path.AddPolygon(points);
294 return DrawPath(pPen, fPenWidth, &path, pMatrix);
295 }
296 FX_BOOL CFDE_FxgeDevice::DrawRectangle(IFDE_Pen* pPen,
297 FX_FLOAT fPenWidth,
298 const CFX_RectF& rect,
299 const CFX_Matrix* pMatrix) {
300 CFDE_Path path;
301 path.AddRectangle(rect);
302 return DrawPath(pPen, fPenWidth, &path, pMatrix);
303 }
304 FX_BOOL CFDE_FxgeDevice::FillClosedCurve(IFDE_Brush* pBrush,
305 const CFX_PointsF& points,
306 FX_FLOAT fTension,
307 const CFX_Matrix* pMatrix) {
308 CFDE_Path path;
309 path.AddCurve(points, TRUE, fTension);
310 return FillPath(pBrush, &path, pMatrix);
311 }
312 FX_BOOL CFDE_FxgeDevice::FillEllipse(IFDE_Brush* pBrush,
313 const CFX_RectF& rect,
314 const CFX_Matrix* pMatrix) {
315 CFDE_Path path;
316 path.AddEllipse(rect);
317 return FillPath(pBrush, &path, pMatrix);
318 }
319 FX_BOOL CFDE_FxgeDevice::FillPolygon(IFDE_Brush* pBrush,
320 const CFX_PointsF& points,
321 const CFX_Matrix* pMatrix) {
322 CFDE_Path path;
323 path.AddPolygon(points);
324 return FillPath(pBrush, &path, pMatrix);
325 }
326 FX_BOOL CFDE_FxgeDevice::FillRectangle(IFDE_Brush* pBrush,
327 const CFX_RectF& rect,
328 const CFX_Matrix* pMatrix) {
329 CFDE_Path path;
330 path.AddRectangle(rect);
331 return FillPath(pBrush, &path, pMatrix);
332 }
333 FX_BOOL CFDE_FxgeDevice::CreatePen(IFDE_Pen* pPen,
334 FX_FLOAT fPenWidth,
335 CFX_GraphStateData& graphState) {
336 if (pPen == NULL) {
337 return FALSE;
338 }
339 graphState.m_LineCap = (CFX_GraphStateData::LineCap)pPen->GetLineCap();
340 graphState.m_LineJoin = (CFX_GraphStateData::LineJoin)pPen->GetLineJoin();
341 graphState.m_LineWidth = fPenWidth;
342 graphState.m_MiterLimit = pPen->GetMiterLimit();
343 graphState.m_DashPhase = pPen->GetDashPhase();
344 CFX_FloatArray dashArray;
345 switch (pPen->GetDashStyle()) {
346 case FDE_DASHSTYLE_Dash:
347 dashArray.Add(3);
348 dashArray.Add(1);
349 break;
350 case FDE_DASHSTYLE_Dot:
351 dashArray.Add(1);
352 dashArray.Add(1);
353 break;
354 case FDE_DASHSTYLE_DashDot:
355 dashArray.Add(3);
356 dashArray.Add(1);
357 dashArray.Add(1);
358 dashArray.Add(1);
359 break;
360 case FDE_DASHSTYLE_DashDotDot:
361 dashArray.Add(3);
362 dashArray.Add(1);
363 dashArray.Add(1);
364 dashArray.Add(1);
365 dashArray.Add(1);
366 dashArray.Add(1);
367 break;
368 case FDE_DASHSTYLE_Customized:
369 pPen->GetDashArray(dashArray);
370 break;
371 }
372 int32_t iDashCount = dashArray.GetSize();
373 if (iDashCount > 0) {
374 graphState.SetDashCount(iDashCount);
375 for (int32_t i = 0; i < iDashCount; ++i) {
376 graphState.m_DashArray[i] = dashArray[i] * fPenWidth;
377 }
378 }
379 return TRUE;
380 }
381 typedef FX_BOOL (CFDE_FxgeDevice::*pfFillPath)(IFDE_Brush* pBrush,
382 const CFX_PathData* pPath,
383 const CFX_Matrix* pMatrix);
384 static const pfFillPath gs_FillPath[] = {
385 &CFDE_FxgeDevice::FillSolidPath, &CFDE_FxgeDevice::FillHatchPath,
386 &CFDE_FxgeDevice::FillTexturePath, &CFDE_FxgeDevice::FillLinearGradientPath,
387 };
388 FX_BOOL CFDE_FxgeDevice::FillPath(IFDE_Brush* pBrush,
389 const IFDE_Path* pPath,
390 const CFX_Matrix* pMatrix) {
391 CFDE_Path* pGePath = (CFDE_Path*)pPath;
392 if (pGePath == NULL) {
393 return FALSE;
394 }
395 if (pBrush == NULL) {
396 return FALSE;
397 }
398 int32_t iType = pBrush->GetType();
399 if (iType < 0 || iType > FDE_BRUSHTYPE_MAX) {
400 return FALSE;
401 }
402 return (this->*gs_FillPath[iType])(pBrush, &pGePath->m_Path, pMatrix);
403 }
404 FX_BOOL CFDE_FxgeDevice::FillSolidPath(IFDE_Brush* pBrush,
405 const CFX_PathData* pPath,
406 const CFX_Matrix* pMatrix) {
407 FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Solid);
408 IFDE_SolidBrush* pSolidBrush = (IFDE_SolidBrush*)pBrush;
409 return m_pDevice->DrawPath(pPath, (const CFX_Matrix*)pMatrix, NULL,
410 pSolidBrush->GetColor(), 0, FXFILL_WINDING);
411 }
412 FX_BOOL CFDE_FxgeDevice::FillHatchPath(IFDE_Brush* pBrush,
413 const CFX_PathData* pPath,
414 const CFX_Matrix* pMatrix) {
415 FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Hatch);
416 IFDE_HatchBrush* pHatchBrush = (IFDE_HatchBrush*)pBrush;
417 int32_t iStyle = pHatchBrush->GetHatchStyle();
418 if (iStyle < FDE_HATCHSTYLE_Min || iStyle > FDE_HATCHSTYLE_Max) {
419 return FALSE;
420 }
421 CFX_DIBitmap mask;
422 if (!FDE_GetStockHatchMask(iStyle, mask)) {
423 return FALSE;
424 }
425 FX_ARGB dwForeColor = pHatchBrush->GetColor(TRUE);
426 FX_ARGB dwBackColor = pHatchBrush->GetColor(FALSE);
427 CFX_FloatRect rectf = pPath->GetBoundingBox();
428 if (pMatrix) {
429 rectf.Transform((const CFX_Matrix*)pMatrix);
430 }
431 FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
432 FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
433 m_pDevice->SaveState();
434 m_pDevice->StartRendering();
435 m_pDevice->SetClip_PathFill(pPath, (const CFX_Matrix*)pMatrix,
436 FXFILL_WINDING);
437 m_pDevice->FillRect(&rect, dwBackColor);
438 for (int32_t j = rect.bottom; j < rect.top; j += mask.GetHeight())
439 for (int32_t i = rect.left; i < rect.right; i += mask.GetWidth()) {
440 m_pDevice->SetBitMask(&mask, i, j, dwForeColor);
441 }
442 m_pDevice->EndRendering();
443 m_pDevice->RestoreState();
444 return TRUE;
445 }
446 FX_BOOL CFDE_FxgeDevice::FillTexturePath(IFDE_Brush* pBrush,
447 const CFX_PathData* pPath,
448 const CFX_Matrix* pMatrix) {
449 FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Texture);
450 IFDE_TextureBrush* pTextureBrush = static_cast<IFDE_TextureBrush*>(pBrush);
451 IFDE_Image* pImage = pTextureBrush->GetImage();
452 if (!pImage)
453 return FALSE;
454
455 CFX_Size size(pImage->GetImageWidth(), pImage->GetImageHeight());
456 CFX_DIBitmap bmp;
457 bmp.Create(size.x, size.y, FXDIB_Argb);
458 if (!pImage->StartLoadImage(&bmp, 0, 0, size.x, size.y, 0, 0, size.x,
459 size.y)) {
460 return FALSE;
461 }
462 if (pImage->DoLoadImage() < 100) {
463 return FALSE;
464 }
465 pImage->StopLoadImage();
466 return WrapTexture(pTextureBrush->GetWrapMode(), &bmp, pPath, pMatrix);
467 }
468 FX_BOOL CFDE_FxgeDevice::WrapTexture(int32_t iWrapMode,
469 const CFX_DIBitmap* pBitmap,
470 const CFX_PathData* pPath,
471 const CFX_Matrix* pMatrix) {
472 CFX_FloatRect rectf = pPath->GetBoundingBox();
473 if (pMatrix) {
474 rectf.Transform((const CFX_Matrix*)pMatrix);
475 }
476 FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
477 FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
478 rect.Normalize();
479 if (rect.IsEmpty()) {
480 return FALSE;
481 }
482 m_pDevice->SaveState();
483 m_pDevice->StartRendering();
484 m_pDevice->SetClip_PathFill(pPath, (const CFX_Matrix*)pMatrix,
485 FXFILL_WINDING);
486 switch (iWrapMode) {
487 case FDE_WRAPMODE_Tile:
488 case FDE_WRAPMODE_TileFlipX:
489 case FDE_WRAPMODE_TileFlipY:
490 case FDE_WRAPMODE_TileFlipXY: {
491 FX_BOOL bFlipX = iWrapMode == FDE_WRAPMODE_TileFlipXY ||
492 iWrapMode == FDE_WRAPMODE_TileFlipX;
493 FX_BOOL bFlipY = iWrapMode == FDE_WRAPMODE_TileFlipXY ||
494 iWrapMode == FDE_WRAPMODE_TileFlipY;
495 const CFX_DIBitmap* pFlip[2][2];
496 pFlip[0][0] = pBitmap;
497 pFlip[0][1] = bFlipX ? pBitmap->FlipImage(TRUE, FALSE) : pBitmap;
498 pFlip[1][0] = bFlipY ? pBitmap->FlipImage(FALSE, TRUE) : pBitmap;
499 pFlip[1][1] =
500 (bFlipX || bFlipY) ? pBitmap->FlipImage(bFlipX, bFlipY) : pBitmap;
501 int32_t iCounterY = 0;
502 for (int32_t j = rect.top; j < rect.bottom; j += pBitmap->GetHeight()) {
503 int32_t indexY = iCounterY++ % 2;
504 int32_t iCounterX = 0;
505 for (int32_t i = rect.left; i < rect.right; i += pBitmap->GetWidth()) {
506 int32_t indexX = iCounterX++ % 2;
507 m_pDevice->SetDIBits(pFlip[indexY][indexX], i, j);
508 }
509 }
510 if (pFlip[0][1] != pFlip[0][0]) {
511 delete pFlip[0][1];
512 }
513 if (pFlip[1][0] != pFlip[0][0]) {
514 delete pFlip[1][0];
515 }
516 if (pFlip[1][1] != pFlip[0][0]) {
517 delete pFlip[1][1];
518 }
519 } break;
520 case FDE_WRAPMODE_Clamp: {
521 m_pDevice->SetDIBits(pBitmap, rect.left, rect.bottom);
522 } break;
523 }
524 m_pDevice->EndRendering();
525 m_pDevice->RestoreState();
526 return TRUE;
527 }
528 FX_BOOL CFDE_FxgeDevice::FillLinearGradientPath(IFDE_Brush* pBrush,
529 const CFX_PathData* pPath,
530 const CFX_Matrix* pMatrix) {
531 FXSYS_assert(pPath && pBrush &&
532 pBrush->GetType() == FDE_BRUSHTYPE_LinearGradient);
533 IFDE_LinearGradientBrush* pLinearBrush = (IFDE_LinearGradientBrush*)pBrush;
534 CFX_PointF pt0, pt1;
535 pLinearBrush->GetLinearPoints(pt0, pt1);
536 CFX_VectorF fDiagonal(pt0, pt1);
537 FX_FLOAT fTheta = FXSYS_atan2(fDiagonal.y, fDiagonal.x);
538 FX_FLOAT fLength = fDiagonal.Length();
539 FX_FLOAT fTotalX = fLength / FXSYS_cos(fTheta);
540 FX_FLOAT fTotalY = fLength / FXSYS_cos(FX_PI / 2 - fTheta);
541 FX_FLOAT fSteps = std::max(fTotalX, fTotalY);
542 FX_FLOAT dx = fTotalX / fSteps;
543 FX_FLOAT dy = fTotalY / fSteps;
544 FX_ARGB cr0, cr1;
545 pLinearBrush->GetLinearColors(cr0, cr1);
546 FX_FLOAT a0 = FXARGB_A(cr0);
547 FX_FLOAT r0 = FXARGB_R(cr0);
548 FX_FLOAT g0 = FXARGB_G(cr0);
549 FX_FLOAT b0 = FXARGB_B(cr0);
550 FX_FLOAT da = (FXARGB_A(cr1) - a0) / fSteps;
551 FX_FLOAT dr = (FXARGB_R(cr1) - r0) / fSteps;
552 FX_FLOAT dg = (FXARGB_G(cr1) - g0) / fSteps;
553 FX_FLOAT db = (FXARGB_B(cr1) - b0) / fSteps;
554 CFX_DIBitmap bmp;
555 bmp.Create(FXSYS_round(FXSYS_fabs(fDiagonal.x)),
556 FXSYS_round(FXSYS_fabs(fDiagonal.y)), FXDIB_Argb);
557 CFX_FxgeDevice dev;
558 dev.Attach(&bmp);
559 pt1 = pt0;
560 int32_t iSteps = FXSYS_round(FXSYS_ceil(fSteps));
561 while (--iSteps >= 0) {
562 cr0 = ArgbEncode(FXSYS_round(a0), FXSYS_round(r0), FXSYS_round(g0),
563 FXSYS_round(b0));
564 dev.DrawCosmeticLine(pt0.x, pt0.y, pt1.x, pt1.y, cr0);
565 pt1.x += dx;
566 pt0.y += dy;
567 a0 += da;
568 r0 += dr;
569 g0 += dg;
570 b0 += db;
571 }
572 return WrapTexture(pLinearBrush->GetWrapMode(), &bmp, pPath, pMatrix);
573 }
OLDNEW
« no previous file with comments | « xfa/src/fde/fde_gedevice.h ('k') | xfa/src/fde/fde_geobject.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698