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

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: 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
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.GetOutterRect();
173 int width = (int)FXSYS_ceil(rect_f.right - rect_f.left);
174 if (width < 1) {
175 width = 1;
176 if (rect_i.left == rect_i.right) {
177 rect_i.right++;
178 }
179 }
180 int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom);
181 if (height < 1) {
182 height = 1;
183 if (rect_i.bottom == rect_i.top) {
184 rect_i.bottom++;
185 }
186 }
187 if (rect_i.Width() >= width + 1) {
188 if (rect_f.left - (FX_FLOAT)(rect_i.left) >
189 (FX_FLOAT)(rect_i.right) - rect_f.right) {
190 rect_i.left++;
191 } else {
192 rect_i.right--;
193 }
194 }
195 if (rect_i.Height() >= height + 1) {
196 if (rect_f.top - (FX_FLOAT)(rect_i.top) >
197 (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) {
198 rect_i.top++;
199 } else {
200 rect_i.bottom--;
201 }
202 }
203 if (FillRectWithBlend(&rect_i, fill_color, blend_type)) {
204 return TRUE;
205 }
206 }
207 }
208 if ((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) &&
209 !(fill_mode & FX_FILL_TEXT_MODE)) {
210 CFX_PathData newPath;
211 FX_BOOL bThin = FALSE;
212 if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin,
213 m_pDeviceDriver->GetDriverType())) {
214 CFX_GraphStateData graphState;
215 graphState.m_LineWidth = 0.0f;
216 uint32_t strokecolor = fill_color;
217 if (bThin) {
218 strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff));
219 }
220 CFX_Matrix* pMatrix = nullptr;
221 if (pObject2Device && !pObject2Device->IsIdentity()) {
222 pMatrix = (CFX_Matrix*)pObject2Device;
223 }
224 int smooth_path = FX_ZEROAREA_FILL;
225 if (fill_mode & FXFILL_NOPATHSMOOTH) {
226 smooth_path |= FXFILL_NOPATHSMOOTH;
227 }
228 m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor,
229 smooth_path, blend_type);
230 }
231 }
232 if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff &&
233 (fill_mode & FX_FILL_STROKE)) {
234 if (m_RenderCaps & FXRC_FILLSTROKE_PATH) {
235 return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
236 fill_color, stroke_color, fill_mode,
237 blend_type);
238 }
239 return DrawFillStrokePath(pPathData, pObject2Device, pGraphState,
240 fill_color, stroke_color, fill_mode, blend_type);
241 }
242 return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
243 fill_color, stroke_color, fill_mode,
244 blend_type);
245 }
246
247 // This can be removed once PDFium entirely relies on Skia
248 FX_BOOL CFX_RenderDevice::DrawFillStrokePath(
249 const CFX_PathData* pPathData,
250 const CFX_Matrix* pObject2Device,
251 const CFX_GraphStateData* pGraphState,
252 uint32_t fill_color,
253 uint32_t stroke_color,
254 int fill_mode,
255 int blend_type) {
256 if (!(m_RenderCaps & FXRC_GET_BITS)) {
257 return FALSE;
258 }
259 CFX_FloatRect bbox;
260 if (pGraphState) {
261 bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth,
262 pGraphState->m_MiterLimit);
263 } else {
264 bbox = pPathData->GetBoundingBox();
265 }
266 if (pObject2Device) {
267 bbox.Transform(pObject2Device);
268 }
269 CFX_Matrix ctm = GetCTM();
270 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
271 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
272 FX_RECT rect = bbox.GetOutterRect();
273 CFX_DIBitmap bitmap, Backdrop;
274 if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX),
275 FXSYS_round(rect.Height() * fScaleY))) {
276 return FALSE;
277 }
278 if (bitmap.HasAlpha()) {
279 bitmap.Clear(0);
280 Backdrop.Copy(&bitmap);
281 } else {
282 if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top))
283 return FALSE;
284 Backdrop.Copy(&bitmap);
285 }
286 CFX_FxgeDevice bitmap_device;
287 bitmap_device.Attach(&bitmap, false, &Backdrop, true);
288 CFX_Matrix matrix;
289 if (pObject2Device) {
290 matrix = *pObject2Device;
291 }
292 matrix.TranslateI(-rect.left, -rect.top);
293 matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
294 if (!bitmap_device.GetDeviceDriver()->DrawPath(
295 pPathData, &matrix, pGraphState, fill_color, stroke_color,
296 fill_mode, blend_type)) {
297 return FALSE;
298 }
299 FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX),
300 FXSYS_round(rect.Height() * fScaleY));
301 return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left,
302 rect.top, FXDIB_BLEND_NORMAL);
303 }
304
305 FX_BOOL CFX_RenderDevice::SetPixel(int x, int y, uint32_t color) {
306 if (m_pDeviceDriver->SetPixel(x, y, color))
307 return TRUE;
308
309 FX_RECT rect(x, y, x + 1, y + 1);
310 return FillRectWithBlend(&rect, color, FXDIB_BLEND_NORMAL);
311 }
312
313 FX_BOOL CFX_RenderDevice::FillRectWithBlend(const FX_RECT* pRect,
314 uint32_t fill_color,
315 int blend_type) {
316 if (m_pDeviceDriver->FillRectWithBlend(pRect, fill_color, blend_type))
317 return TRUE;
318
319 if (!(m_RenderCaps & FXRC_GET_BITS))
320 return FALSE;
321
322 CFX_DIBitmap bitmap;
323 if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height()))
324 return FALSE;
325
326 if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top))
327 return FALSE;
328
329 if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color,
330 0, nullptr)) {
331 return FALSE;
332 }
333 FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height());
334 m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top,
335 FXDIB_BLEND_NORMAL);
336 return TRUE;
337 }
338
339 FX_BOOL CFX_RenderDevice::DrawCosmeticLineWithFillModeAndBlend(FX_FLOAT x1,
340 FX_FLOAT y1,
341 FX_FLOAT x2,
342 FX_FLOAT y2,
343 uint32_t color,
344 int fill_mode,
345 int blend_type) {
346 if ((color >= 0xff000000) &&
347 m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, blend_type)) {
348 return TRUE;
349 }
350 CFX_GraphStateData graph_state;
351 CFX_PathData path;
352 path.SetPointCount(2);
353 path.SetPoint(0, x1, y1, FXPT_MOVETO);
354 path.SetPoint(1, x2, y2, FXPT_LINETO);
355 return m_pDeviceDriver->DrawPath(&path, nullptr, &graph_state, 0, color,
356 fill_mode, blend_type);
357 }
358
359 FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top) {
360 if (!(m_RenderCaps & FXRC_GET_BITS))
361 return FALSE;
362 return m_pDeviceDriver->GetDIBits(pBitmap, left, top);
363 }
364
365 CFX_DIBitmap* CFX_RenderDevice::GetBackDrop() {
366 return m_pDeviceDriver->GetBackDrop();
367 }
368
369 FX_BOOL CFX_RenderDevice::SetDIBitsWithBlend(const CFX_DIBSource* pBitmap,
370 int left,
371 int top,
372 int blend_mode) {
373 ASSERT(!pBitmap->IsAlphaMask());
374 CFX_Matrix ctm = GetCTM();
375 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
376 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
377 FX_RECT dest_rect(left, top,
378 FXSYS_round(left + pBitmap->GetWidth() / fScaleX),
379 FXSYS_round(top + pBitmap->GetHeight() / fScaleY));
380 dest_rect.Intersect(m_ClipBox);
381 if (dest_rect.IsEmpty()) {
382 return TRUE;
383 }
384 FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top,
385 dest_rect.left - left + dest_rect.Width(),
386 dest_rect.top - top + dest_rect.Height());
387 src_rect.left = FXSYS_round(src_rect.left * fScaleX);
388 src_rect.top = FXSYS_round(src_rect.top * fScaleY);
389 src_rect.right = FXSYS_round(src_rect.right * fScaleX);
390 src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY);
391 if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE)) ||
392 (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) {
393 if (!(m_RenderCaps & FXRC_GET_BITS)) {
394 return FALSE;
395 }
396 int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX);
397 int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY);
398 CFX_DIBitmap background;
399 if (!background.Create(
400 bg_pixel_width, bg_pixel_height,
401 (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk : FXDIB_Rgb32)) {
402 return FALSE;
403 }
404 if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left,
405 dest_rect.top)) {
406 return FALSE;
407 }
408 if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height,
409 pBitmap, src_rect.left, src_rect.top,
410 blend_mode, nullptr, FALSE, nullptr)) {
411 return FALSE;
412 }
413 FX_RECT rect(0, 0, bg_pixel_width, bg_pixel_height);
414 return m_pDeviceDriver->SetDIBits(&background, 0, &rect, dest_rect.left,
415 dest_rect.top, FXDIB_BLEND_NORMAL);
416 }
417 return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left,
418 dest_rect.top, blend_mode);
419 }
420
421 FX_BOOL CFX_RenderDevice::StretchDIBitsWithFlagsAndBlend(
422 const CFX_DIBSource* pBitmap,
423 int left,
424 int top,
425 int dest_width,
426 int dest_height,
427 uint32_t flags,
428 int blend_mode) {
429 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
430 FX_RECT clip_box = m_ClipBox;
431 clip_box.Intersect(dest_rect);
432 if (clip_box.IsEmpty())
433 return TRUE;
434 return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width,
435 dest_height, &clip_box, flags,
436 blend_mode);
437 }
438
439 FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap,
440 int left,
441 int top,
442 uint32_t argb) {
443 FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
444 return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top,
445 FXDIB_BLEND_NORMAL);
446 }
447
448 FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap,
449 int left,
450 int top,
451 int dest_width,
452 int dest_height,
453 uint32_t color) {
454 return StretchBitMaskWithFlags(pBitmap, left, top, dest_width, dest_height,
455 color, 0);
456 }
457
458 FX_BOOL CFX_RenderDevice::StretchBitMaskWithFlags(const CFX_DIBSource* pBitmap,
459 int left,
460 int top,
461 int dest_width,
462 int dest_height,
463 uint32_t argb,
464 uint32_t flags) {
465 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
466 FX_RECT clip_box = m_ClipBox;
467 clip_box.Intersect(dest_rect);
468 return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width,
469 dest_height, &clip_box, flags,
470 FXDIB_BLEND_NORMAL);
471 }
472
473 FX_BOOL CFX_RenderDevice::StartDIBitsWithBlend(const CFX_DIBSource* pBitmap,
474 int bitmap_alpha,
475 uint32_t argb,
476 const CFX_Matrix* pMatrix,
477 uint32_t flags,
478 void*& handle,
479 int blend_mode) {
480 return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix,
481 flags, handle, blend_mode);
482 }
483
484 FX_BOOL CFX_RenderDevice::ContinueDIBits(void* handle, IFX_Pause* pPause) {
485 return m_pDeviceDriver->ContinueDIBits(handle, pPause);
486 }
487
488 void CFX_RenderDevice::CancelDIBits(void* handle) {
489 m_pDeviceDriver->CancelDIBits(handle);
490 }
491
492 #ifdef _SKIA_SUPPORT_
493
494 void CFX_RenderDevice::DebugVerifyBitmapIsPreMultiplied() const {
495 SkASSERT(0);
496 }
497 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698