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

Side by Side Diff: core/fxge/ge/fx_ge_device.cpp

Issue 2223213002: Refactor fx_ge part 3 (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase Created 4 years, 4 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 | « core/fxge/ge/cfx_renderdevice.cpp ('k') | core/fxge/ge/fx_ge_fontmap.cpp » ('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 "core/fxge/include/cfx_pathdata.h"
8 #include "core/fxge/include/fx_ge.h"
9 #include "core/fxge/include/ifx_renderdevicedriver.h"
10
11 #if defined _SKIA_SUPPORT_
12 #include "third_party/skia/include/core/SkTypes.h"
13 #endif
14
15 CFX_RenderDevice::CFX_RenderDevice()
16 : m_pBitmap(nullptr),
17 m_Width(0),
18 m_Height(0),
19 m_bpp(0),
20 m_RenderCaps(0),
21 m_DeviceClass(0) {}
22
23 CFX_RenderDevice::~CFX_RenderDevice() {}
24
25 #ifdef _SKIA_SUPPORT_
26 void CFX_RenderDevice::Flush() {
27 m_pDeviceDriver.reset();
28 }
29 #endif
30
31 void CFX_RenderDevice::SetDeviceDriver(
32 std::unique_ptr<IFX_RenderDeviceDriver> pDriver) {
33 m_pDeviceDriver = std::move(pDriver);
34 InitDeviceInfo();
35 }
36
37 void CFX_RenderDevice::InitDeviceInfo() {
38 m_Width = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_WIDTH);
39 m_Height = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_HEIGHT);
40 m_bpp = m_pDeviceDriver->GetDeviceCaps(FXDC_BITS_PIXEL);
41 m_RenderCaps = m_pDeviceDriver->GetDeviceCaps(FXDC_RENDER_CAPS);
42 m_DeviceClass = m_pDeviceDriver->GetDeviceCaps(FXDC_DEVICE_CLASS);
43 if (!m_pDeviceDriver->GetClipBox(&m_ClipBox)) {
44 m_ClipBox.left = 0;
45 m_ClipBox.top = 0;
46 m_ClipBox.right = m_Width;
47 m_ClipBox.bottom = m_Height;
48 }
49 }
50
51 FX_BOOL CFX_RenderDevice::StartRendering() {
52 return m_pDeviceDriver->StartRendering();
53 }
54
55 void CFX_RenderDevice::EndRendering() {
56 m_pDeviceDriver->EndRendering();
57 }
58
59 void CFX_RenderDevice::SaveState() {
60 m_pDeviceDriver->SaveState();
61 }
62
63 void CFX_RenderDevice::RestoreState(bool bKeepSaved) {
64 m_pDeviceDriver->RestoreState(bKeepSaved);
65 UpdateClipBox();
66 }
67
68 int CFX_RenderDevice::GetDeviceCaps(int caps_id) const {
69 return m_pDeviceDriver->GetDeviceCaps(caps_id);
70 }
71 CFX_Matrix CFX_RenderDevice::GetCTM() const {
72 return m_pDeviceDriver->GetCTM();
73 }
74
75 FX_BOOL CFX_RenderDevice::CreateCompatibleBitmap(CFX_DIBitmap* pDIB,
76 int width,
77 int height) const {
78 if (m_RenderCaps & FXRC_CMYK_OUTPUT) {
79 return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT
80 ? FXDIB_Cmyka
81 : FXDIB_Cmyk);
82 }
83 if (m_RenderCaps & FXRC_BYTEMASK_OUTPUT) {
84 return pDIB->Create(width, height, FXDIB_8bppMask);
85 }
86 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
87 return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT
88 ? FXDIB_Argb
89 : FXDIB_Rgb32);
90 #else
91 return pDIB->Create(
92 width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb);
93 #endif
94 }
95
96 FX_BOOL CFX_RenderDevice::SetClip_PathFill(const CFX_PathData* pPathData,
97 const CFX_Matrix* pObject2Device,
98 int fill_mode) {
99 if (!m_pDeviceDriver->SetClip_PathFill(pPathData, pObject2Device,
100 fill_mode)) {
101 return FALSE;
102 }
103 UpdateClipBox();
104 return TRUE;
105 }
106
107 FX_BOOL CFX_RenderDevice::SetClip_PathStroke(
108 const CFX_PathData* pPathData,
109 const CFX_Matrix* pObject2Device,
110 const CFX_GraphStateData* pGraphState) {
111 if (!m_pDeviceDriver->SetClip_PathStroke(pPathData, pObject2Device,
112 pGraphState)) {
113 return FALSE;
114 }
115 UpdateClipBox();
116 return TRUE;
117 }
118
119 FX_BOOL CFX_RenderDevice::SetClip_Rect(const FX_RECT& rect) {
120 CFX_PathData path;
121 path.AppendRect(rect.left, rect.bottom, rect.right, rect.top);
122 if (!SetClip_PathFill(&path, nullptr, FXFILL_WINDING))
123 return FALSE;
124
125 UpdateClipBox();
126 return TRUE;
127 }
128
129 void CFX_RenderDevice::UpdateClipBox() {
130 if (m_pDeviceDriver->GetClipBox(&m_ClipBox)) {
131 return;
132 }
133 m_ClipBox.left = 0;
134 m_ClipBox.top = 0;
135 m_ClipBox.right = m_Width;
136 m_ClipBox.bottom = m_Height;
137 }
138
139 FX_BOOL CFX_RenderDevice::DrawPathWithBlend(
140 const CFX_PathData* pPathData,
141 const CFX_Matrix* pObject2Device,
142 const CFX_GraphStateData* pGraphState,
143 uint32_t fill_color,
144 uint32_t stroke_color,
145 int fill_mode,
146 int blend_type) {
147 uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0;
148 uint8_t fill_alpha = (fill_mode & 3) ? FXARGB_A(fill_color) : 0;
149 if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) {
150 FX_PATHPOINT* pPoints = pPathData->GetPoints();
151 FX_FLOAT x1, x2, y1, y2;
152 if (pObject2Device) {
153 pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1,
154 y1);
155 pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2,
156 y2);
157 } else {
158 x1 = pPoints[0].m_PointX;
159 y1 = pPoints[0].m_PointY;
160 x2 = pPoints[1].m_PointX;
161 y2 = pPoints[1].m_PointY;
162 }
163 DrawCosmeticLineWithFillModeAndBlend(x1, y1, x2, y2, fill_color, fill_mode,
164 blend_type);
165 return TRUE;
166 }
167 if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
168 stroke_alpha == 0) {
169 CFX_FloatRect rect_f;
170 if (!(fill_mode & FXFILL_RECT_AA) &&
171 pPathData->IsRect(pObject2Device, &rect_f)) {
172 FX_RECT rect_i = rect_f.GetOuterRect();
173
174 // Depending on the top/bottom, left/right values of the rect it's
175 // possible to overflow the Width() and Height() calculations. Check that
176 // the rect will have valid dimension before continuing.
177 if (!rect_i.Valid())
178 return FALSE;
179
180 int width = (int)FXSYS_ceil(rect_f.right - rect_f.left);
181 if (width < 1) {
182 width = 1;
183 if (rect_i.left == rect_i.right) {
184 rect_i.right++;
185 }
186 }
187 int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom);
188 if (height < 1) {
189 height = 1;
190 if (rect_i.bottom == rect_i.top) {
191 rect_i.bottom++;
192 }
193 }
194 if (rect_i.Width() >= width + 1) {
195 if (rect_f.left - (FX_FLOAT)(rect_i.left) >
196 (FX_FLOAT)(rect_i.right) - rect_f.right) {
197 rect_i.left++;
198 } else {
199 rect_i.right--;
200 }
201 }
202 if (rect_i.Height() >= height + 1) {
203 if (rect_f.top - (FX_FLOAT)(rect_i.top) >
204 (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) {
205 rect_i.top++;
206 } else {
207 rect_i.bottom--;
208 }
209 }
210 if (FillRectWithBlend(&rect_i, fill_color, blend_type)) {
211 return TRUE;
212 }
213 }
214 }
215 if ((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) &&
216 !(fill_mode & FX_FILL_TEXT_MODE)) {
217 CFX_PathData newPath;
218 FX_BOOL bThin = FALSE;
219 if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin,
220 m_pDeviceDriver->GetDriverType())) {
221 CFX_GraphStateData graphState;
222 graphState.m_LineWidth = 0.0f;
223 uint32_t strokecolor = fill_color;
224 if (bThin) {
225 strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff));
226 }
227 CFX_Matrix* pMatrix = nullptr;
228 if (pObject2Device && !pObject2Device->IsIdentity()) {
229 pMatrix = (CFX_Matrix*)pObject2Device;
230 }
231 int smooth_path = FX_ZEROAREA_FILL;
232 if (fill_mode & FXFILL_NOPATHSMOOTH) {
233 smooth_path |= FXFILL_NOPATHSMOOTH;
234 }
235 m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor,
236 smooth_path, blend_type);
237 }
238 }
239 if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff &&
240 (fill_mode & FX_FILL_STROKE)) {
241 if (m_RenderCaps & FXRC_FILLSTROKE_PATH) {
242 return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
243 fill_color, stroke_color, fill_mode,
244 blend_type);
245 }
246 return DrawFillStrokePath(pPathData, pObject2Device, pGraphState,
247 fill_color, stroke_color, fill_mode, blend_type);
248 }
249 return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
250 fill_color, stroke_color, fill_mode,
251 blend_type);
252 }
253
254 // This can be removed once PDFium entirely relies on Skia
255 FX_BOOL CFX_RenderDevice::DrawFillStrokePath(
256 const CFX_PathData* pPathData,
257 const CFX_Matrix* pObject2Device,
258 const CFX_GraphStateData* pGraphState,
259 uint32_t fill_color,
260 uint32_t stroke_color,
261 int fill_mode,
262 int blend_type) {
263 if (!(m_RenderCaps & FXRC_GET_BITS)) {
264 return FALSE;
265 }
266 CFX_FloatRect bbox;
267 if (pGraphState) {
268 bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth,
269 pGraphState->m_MiterLimit);
270 } else {
271 bbox = pPathData->GetBoundingBox();
272 }
273 if (pObject2Device) {
274 bbox.Transform(pObject2Device);
275 }
276 CFX_Matrix ctm = GetCTM();
277 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
278 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
279 FX_RECT rect = bbox.GetOuterRect();
280 CFX_DIBitmap bitmap, Backdrop;
281 if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX),
282 FXSYS_round(rect.Height() * fScaleY))) {
283 return FALSE;
284 }
285 if (bitmap.HasAlpha()) {
286 bitmap.Clear(0);
287 Backdrop.Copy(&bitmap);
288 } else {
289 if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top))
290 return FALSE;
291 Backdrop.Copy(&bitmap);
292 }
293 CFX_FxgeDevice bitmap_device;
294 bitmap_device.Attach(&bitmap, false, &Backdrop, true);
295 CFX_Matrix matrix;
296 if (pObject2Device) {
297 matrix = *pObject2Device;
298 }
299 matrix.TranslateI(-rect.left, -rect.top);
300 matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
301 if (!bitmap_device.GetDeviceDriver()->DrawPath(
302 pPathData, &matrix, pGraphState, fill_color, stroke_color,
303 fill_mode, blend_type)) {
304 return FALSE;
305 }
306 FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX),
307 FXSYS_round(rect.Height() * fScaleY));
308 return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left,
309 rect.top, FXDIB_BLEND_NORMAL);
310 }
311
312 FX_BOOL CFX_RenderDevice::SetPixel(int x, int y, uint32_t color) {
313 if (m_pDeviceDriver->SetPixel(x, y, color))
314 return TRUE;
315
316 FX_RECT rect(x, y, x + 1, y + 1);
317 return FillRectWithBlend(&rect, color, FXDIB_BLEND_NORMAL);
318 }
319
320 FX_BOOL CFX_RenderDevice::FillRectWithBlend(const FX_RECT* pRect,
321 uint32_t fill_color,
322 int blend_type) {
323 if (m_pDeviceDriver->FillRectWithBlend(pRect, fill_color, blend_type))
324 return TRUE;
325
326 if (!(m_RenderCaps & FXRC_GET_BITS))
327 return FALSE;
328
329 CFX_DIBitmap bitmap;
330 if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height()))
331 return FALSE;
332
333 if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top))
334 return FALSE;
335
336 if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color,
337 0, nullptr)) {
338 return FALSE;
339 }
340 FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height());
341 m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top,
342 FXDIB_BLEND_NORMAL);
343 return TRUE;
344 }
345
346 FX_BOOL CFX_RenderDevice::DrawCosmeticLineWithFillModeAndBlend(FX_FLOAT x1,
347 FX_FLOAT y1,
348 FX_FLOAT x2,
349 FX_FLOAT y2,
350 uint32_t color,
351 int fill_mode,
352 int blend_type) {
353 if ((color >= 0xff000000) &&
354 m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, blend_type)) {
355 return TRUE;
356 }
357 CFX_GraphStateData graph_state;
358 CFX_PathData path;
359 path.SetPointCount(2);
360 path.SetPoint(0, x1, y1, FXPT_MOVETO);
361 path.SetPoint(1, x2, y2, FXPT_LINETO);
362 return m_pDeviceDriver->DrawPath(&path, nullptr, &graph_state, 0, color,
363 fill_mode, blend_type);
364 }
365
366 FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top) {
367 if (!(m_RenderCaps & FXRC_GET_BITS))
368 return FALSE;
369 return m_pDeviceDriver->GetDIBits(pBitmap, left, top);
370 }
371
372 CFX_DIBitmap* CFX_RenderDevice::GetBackDrop() {
373 return m_pDeviceDriver->GetBackDrop();
374 }
375
376 FX_BOOL CFX_RenderDevice::SetDIBitsWithBlend(const CFX_DIBSource* pBitmap,
377 int left,
378 int top,
379 int blend_mode) {
380 ASSERT(!pBitmap->IsAlphaMask());
381 CFX_Matrix ctm = GetCTM();
382 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
383 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
384 FX_RECT dest_rect(left, top,
385 FXSYS_round(left + pBitmap->GetWidth() / fScaleX),
386 FXSYS_round(top + pBitmap->GetHeight() / fScaleY));
387 dest_rect.Intersect(m_ClipBox);
388 if (dest_rect.IsEmpty()) {
389 return TRUE;
390 }
391 FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top,
392 dest_rect.left - left + dest_rect.Width(),
393 dest_rect.top - top + dest_rect.Height());
394 src_rect.left = FXSYS_round(src_rect.left * fScaleX);
395 src_rect.top = FXSYS_round(src_rect.top * fScaleY);
396 src_rect.right = FXSYS_round(src_rect.right * fScaleX);
397 src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY);
398 if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE)) ||
399 (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) {
400 if (!(m_RenderCaps & FXRC_GET_BITS)) {
401 return FALSE;
402 }
403 int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX);
404 int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY);
405 CFX_DIBitmap background;
406 if (!background.Create(
407 bg_pixel_width, bg_pixel_height,
408 (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk : FXDIB_Rgb32)) {
409 return FALSE;
410 }
411 if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left,
412 dest_rect.top)) {
413 return FALSE;
414 }
415 if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height,
416 pBitmap, src_rect.left, src_rect.top,
417 blend_mode, nullptr, FALSE, nullptr)) {
418 return FALSE;
419 }
420 FX_RECT rect(0, 0, bg_pixel_width, bg_pixel_height);
421 return m_pDeviceDriver->SetDIBits(&background, 0, &rect, dest_rect.left,
422 dest_rect.top, FXDIB_BLEND_NORMAL);
423 }
424 return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left,
425 dest_rect.top, blend_mode);
426 }
427
428 FX_BOOL CFX_RenderDevice::StretchDIBitsWithFlagsAndBlend(
429 const CFX_DIBSource* pBitmap,
430 int left,
431 int top,
432 int dest_width,
433 int dest_height,
434 uint32_t flags,
435 int blend_mode) {
436 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
437 FX_RECT clip_box = m_ClipBox;
438 clip_box.Intersect(dest_rect);
439 if (clip_box.IsEmpty())
440 return TRUE;
441 return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width,
442 dest_height, &clip_box, flags,
443 blend_mode);
444 }
445
446 FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap,
447 int left,
448 int top,
449 uint32_t argb) {
450 FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
451 return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top,
452 FXDIB_BLEND_NORMAL);
453 }
454
455 FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap,
456 int left,
457 int top,
458 int dest_width,
459 int dest_height,
460 uint32_t color) {
461 return StretchBitMaskWithFlags(pBitmap, left, top, dest_width, dest_height,
462 color, 0);
463 }
464
465 FX_BOOL CFX_RenderDevice::StretchBitMaskWithFlags(const CFX_DIBSource* pBitmap,
466 int left,
467 int top,
468 int dest_width,
469 int dest_height,
470 uint32_t argb,
471 uint32_t flags) {
472 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
473 FX_RECT clip_box = m_ClipBox;
474 clip_box.Intersect(dest_rect);
475 return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width,
476 dest_height, &clip_box, flags,
477 FXDIB_BLEND_NORMAL);
478 }
479
480 FX_BOOL CFX_RenderDevice::StartDIBitsWithBlend(const CFX_DIBSource* pBitmap,
481 int bitmap_alpha,
482 uint32_t argb,
483 const CFX_Matrix* pMatrix,
484 uint32_t flags,
485 void*& handle,
486 int blend_mode) {
487 return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix,
488 flags, handle, blend_mode);
489 }
490
491 FX_BOOL CFX_RenderDevice::ContinueDIBits(void* handle, IFX_Pause* pPause) {
492 return m_pDeviceDriver->ContinueDIBits(handle, pPause);
493 }
494
495 void CFX_RenderDevice::CancelDIBits(void* handle) {
496 m_pDeviceDriver->CancelDIBits(handle);
497 }
498
499 #ifdef _SKIA_SUPPORT_
500
501 void CFX_RenderDevice::DebugVerifyBitmapIsPreMultiplied() const {
502 SkASSERT(0);
503 }
504 #endif
OLDNEW
« no previous file with comments | « core/fxge/ge/cfx_renderdevice.cpp ('k') | core/fxge/ge/fx_ge_fontmap.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698