| OLD | NEW |
| (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 | |
| OLD | NEW |