Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if defined(_SKIA_SUPPORT_) | 5 #if defined(_SKIA_SUPPORT_) |
| 6 #include <algorithm> | 6 #include <algorithm> |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "core/fxcodec/include/fx_codec.h" | 9 #include "core/fxcodec/include/fx_codec.h" |
| 10 #include "core/fxcrt/include/fx_memory.h" | 10 #include "core/fxcrt/include/fx_memory.h" |
| 11 | 11 |
| 12 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" | 12 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" |
| 13 #include "core/fpdfapi/fpdf_page/pageint.h" | 13 #include "core/fpdfapi/fpdf_page/pageint.h" |
| 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
| 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" | 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
| 17 #include "core/fxge/include/cfx_fxgedevice.h" | 17 #include "core/fxge/include/cfx_fxgedevice.h" |
| 18 #include "core/fxge/include/cfx_gemodule.h" | 18 #include "core/fxge/include/cfx_gemodule.h" |
| 19 #include "core/fxge/include/cfx_graphstatedata.h" | 19 #include "core/fxge/include/cfx_graphstatedata.h" |
| 20 #include "core/fxge/include/cfx_pathdata.h" | 20 #include "core/fxge/include/cfx_pathdata.h" |
| 21 #include "core/fxge/include/cfx_renderdevice.h" | 21 #include "core/fxge/include/cfx_renderdevice.h" |
| 22 #include "core/fxge/skia/fx_skia_device.h" | 22 #include "core/fxge/skia/fx_skia_device.h" |
| 23 | 23 |
| 24 #include "third_party/skia/include/core/SkCanvas.h" | 24 #include "third_party/skia/include/core/SkCanvas.h" |
| 25 #include "third_party/skia/include/core/SkColorFilter.h" | 25 #include "third_party/skia/include/core/SkColorFilter.h" |
| 26 #include "third_party/skia/include/core/SkColorPriv.h" | 26 #include "third_party/skia/include/core/SkColorPriv.h" |
| 27 #include "third_party/skia/include/core/SkMaskFilter.h" | |
| 27 #include "third_party/skia/include/core/SkPaint.h" | 28 #include "third_party/skia/include/core/SkPaint.h" |
| 28 #include "third_party/skia/include/core/SkPath.h" | 29 #include "third_party/skia/include/core/SkPath.h" |
| 29 #include "third_party/skia/include/core/SkPictureRecorder.h" | 30 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 30 #include "third_party/skia/include/core/SkStream.h" | 31 #include "third_party/skia/include/core/SkStream.h" |
| 31 #include "third_party/skia/include/core/SkTypeface.h" | 32 #include "third_party/skia/include/core/SkTypeface.h" |
| 32 #include "third_party/skia/include/effects/SkDashPathEffect.h" | 33 #include "third_party/skia/include/effects/SkDashPathEffect.h" |
| 33 #include "third_party/skia/include/effects/SkGradientShader.h" | 34 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 34 #include "third_party/skia/include/pathops/SkPathOps.h" | 35 #include "third_party/skia/include/pathops/SkPathOps.h" |
| 36 #include "third_party/skia/include/core/SkShader.h" | |
|
dsinclair
2016/08/15 13:33:30
nit: sort includes
caryclark
2016/08/15 16:55:04
Done.
| |
| 35 | 37 |
| 36 #ifdef SK_DEBUG | 38 #ifdef SK_DEBUG |
| 37 #include "third_party/skia/include/core/SkClipStack.h" | 39 #include "third_party/skia/include/core/SkClipStack.h" |
| 38 #endif | 40 #endif |
| 39 | 41 |
| 40 namespace { | 42 namespace { |
| 41 | 43 |
| 42 #define SHOW_SKIA_PATH 0 // set to 1 to print the path contents | 44 #define SHOW_SKIA_PATH 0 // set to 1 to print the path contents |
| 43 #define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip | 45 #define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip |
| 44 | 46 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 return skPath; | 135 return skPath; |
| 134 } | 136 } |
| 135 | 137 |
| 136 SkMatrix ToSkMatrix(const CFX_Matrix& m) { | 138 SkMatrix ToSkMatrix(const CFX_Matrix& m) { |
| 137 SkMatrix skMatrix; | 139 SkMatrix skMatrix; |
| 138 skMatrix.setAll(m.a, m.b, m.e, m.c, m.d, m.f, 0, 0, 1); | 140 skMatrix.setAll(m.a, m.b, m.e, m.c, m.d, m.f, 0, 0, 1); |
| 139 return skMatrix; | 141 return skMatrix; |
| 140 } | 142 } |
| 141 | 143 |
| 142 // use when pdf's y-axis points up insead of down | 144 // use when pdf's y-axis points up insead of down |
| 143 SkMatrix ToFlippedSkMatrix(const CFX_Matrix& m) { | 145 SkMatrix ToFlippedSkMatrix(const CFX_Matrix& m, SkScalar flip) { |
| 144 SkMatrix skMatrix; | 146 SkMatrix skMatrix; |
| 145 skMatrix.setAll(m.a, -m.c, m.e, m.b, -m.d, m.f, 0, 0, 1); | 147 skMatrix.setAll(m.a * flip, -m.c * flip, m.e, m.b * flip, -m.d * flip, m.f, 0, |
| 148 0, 1); | |
| 146 return skMatrix; | 149 return skMatrix; |
| 147 } | 150 } |
| 148 | 151 |
| 149 SkXfermode::Mode GetSkiaBlendMode(int blend_type) { | 152 SkXfermode::Mode GetSkiaBlendMode(int blend_type) { |
| 150 switch (blend_type) { | 153 switch (blend_type) { |
| 151 case FXDIB_BLEND_MULTIPLY: | 154 case FXDIB_BLEND_MULTIPLY: |
| 152 return SkXfermode::kMultiply_Mode; | 155 return SkXfermode::kMultiply_Mode; |
| 153 case FXDIB_BLEND_SCREEN: | 156 case FXDIB_BLEND_SCREEN: |
| 154 return SkXfermode::kScreen_Mode; | 157 return SkXfermode::kScreen_Mode; |
| 155 case FXDIB_BLEND_OVERLAY: | 158 case FXDIB_BLEND_OVERLAY: |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 ASSERT(maxBounds != minBounds && maxBounds >= 0); | 363 ASSERT(maxBounds != minBounds && maxBounds >= 0); |
| 361 // construct a clip parallel to the gradient that goes through | 364 // construct a clip parallel to the gradient that goes through |
| 362 // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the | 365 // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the |
| 363 // gradient that goes through startEdgePt, endEdgePt. | 366 // gradient that goes through startEdgePt, endEdgePt. |
| 364 clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt)); | 367 clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt)); |
| 365 clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt)); | 368 clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt)); |
| 366 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt)); | 369 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt)); |
| 367 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt)); | 370 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt)); |
| 368 } | 371 } |
| 369 | 372 |
| 373 void SetBitmapMatrix(const CFX_Matrix* pMatrix, | |
| 374 int width, | |
| 375 int height, | |
| 376 SkMatrix* skMatrix) { | |
| 377 const CFX_Matrix& m = *pMatrix; | |
| 378 skMatrix->setAll(m.a / width, -m.c / height, m.c + m.e, m.b / width, | |
| 379 -m.d / height, m.d + m.f, 0, 0, 1); | |
| 380 } | |
| 381 | |
| 382 void SetBitmapPaint(bool isAlphaMask, | |
| 383 uint32_t argb, | |
| 384 int bitmap_alpha, | |
| 385 int blend_type, | |
| 386 SkPaint* paint) { | |
| 387 paint->setAntiAlias(true); | |
| 388 if (isAlphaMask) { | |
| 389 paint->setColorFilter( | |
| 390 SkColorFilter::MakeModeFilter(argb, SkXfermode::kSrc_Mode)); | |
| 391 } | |
| 392 // paint->setFilterQuality(kHigh_SkFilterQuality); | |
| 393 paint->setXfermodeMode(GetSkiaBlendMode(blend_type)); | |
| 394 paint->setAlpha(bitmap_alpha); | |
| 395 } | |
| 396 | |
| 397 bool Upsample(const CFX_DIBSource* pSource, | |
| 398 std::unique_ptr<uint8_t, FxFreeDeleter>& dst8Storage, | |
| 399 std::unique_ptr<uint32_t, FxFreeDeleter>& dst32Storage, | |
| 400 SkColorTable** ctPtr, | |
| 401 SkBitmap* skBitmap, | |
| 402 int* widthPtr, | |
| 403 int* heightPtr, | |
| 404 bool forceAlpha) { | |
| 405 void* buffer = pSource->GetBuffer(); | |
| 406 if (!buffer) | |
| 407 return false; | |
| 408 SkColorType colorType = forceAlpha || pSource->IsAlphaMask() | |
| 409 ? SkColorType::kAlpha_8_SkColorType | |
| 410 : SkColorType::kGray_8_SkColorType; | |
| 411 SkAlphaType alphaType = | |
| 412 pSource->IsAlphaMask() ? kPremul_SkAlphaType : kOpaque_SkAlphaType; | |
| 413 int width = pSource->GetWidth(); | |
| 414 int height = pSource->GetHeight(); | |
| 415 int rowBytes = pSource->GetPitch(); | |
| 416 switch (pSource->GetBPP()) { | |
| 417 case 1: { | |
| 418 dst8Storage.reset(FX_Alloc2D(uint8_t, width, height)); | |
| 419 uint8_t* dst8Pixels = dst8Storage.get(); | |
| 420 for (int y = 0; y < height; ++y) { | |
| 421 const uint8_t* srcRow = | |
| 422 static_cast<const uint8_t*>(buffer) + y * rowBytes; | |
| 423 uint8_t* dstRow = dst8Pixels + y * width; | |
| 424 for (int x = 0; x < width; ++x) | |
| 425 dstRow[x] = srcRow[x >> 3] & (1 << (~x & 0x07)) ? 0xFF : 0x00; | |
| 426 } | |
| 427 buffer = dst8Storage.get(); | |
| 428 rowBytes = width; | |
| 429 } break; | |
|
dsinclair
2016/08/15 13:33:30
nit: move break inside the }.
caryclark
2016/08/15 16:55:04
Done.
| |
| 430 case 8: | |
| 431 if (pSource->GetPalette()) { | |
| 432 *ctPtr = | |
| 433 new SkColorTable(pSource->GetPalette(), pSource->GetPaletteSize()); | |
| 434 colorType = SkColorType::kIndex_8_SkColorType; | |
| 435 } | |
| 436 break; | |
| 437 case 24: { | |
| 438 dst32Storage.reset(FX_Alloc2D(uint32_t, width, height)); | |
| 439 uint32_t* dst32Pixels = dst32Storage.get(); | |
| 440 for (int y = 0; y < height; ++y) { | |
| 441 const uint8_t* srcRow = | |
| 442 static_cast<const uint8_t*>(buffer) + y * rowBytes; | |
| 443 uint32_t* dstRow = dst32Pixels + y * width; | |
| 444 for (int x = 0; x < width; ++x) { | |
| 445 dstRow[x] = SkPackARGB32(0xFF, srcRow[x * 3 + 2], srcRow[x * 3 + 1], | |
| 446 srcRow[x * 3 + 0]); | |
| 447 } | |
| 448 } | |
| 449 buffer = dst32Storage.get(); | |
| 450 rowBytes = width * sizeof(uint32_t); | |
| 451 colorType = SkColorType::kN32_SkColorType; | |
| 452 alphaType = kOpaque_SkAlphaType; | |
| 453 } break; | |
| 454 case 32: | |
| 455 colorType = SkColorType::kN32_SkColorType; | |
| 456 alphaType = kPremul_SkAlphaType; | |
| 457 pSource->DebugVerifyBitmapIsPreMultiplied(buffer); | |
| 458 break; | |
| 459 default: | |
| 460 SkASSERT(0); // TODO(caryclark) ensure that all cases are covered | |
| 461 colorType = SkColorType::kUnknown_SkColorType; | |
| 462 } | |
| 463 SkImageInfo imageInfo = | |
| 464 SkImageInfo::Make(width, height, colorType, alphaType); | |
| 465 skBitmap->installPixels(imageInfo, buffer, rowBytes, *ctPtr, nullptr, | |
| 466 nullptr); | |
| 467 *widthPtr = width; | |
| 468 *heightPtr = height; | |
| 469 return true; | |
| 470 } | |
| 471 | |
| 370 } // namespace | 472 } // namespace |
| 371 | 473 |
| 372 // Encapsulate the state used for successive text and path draws so that | 474 // Encapsulate the state used for successive text and path draws so that |
| 373 // they can be combined. | 475 // they can be combined. |
| 374 class SkiaState { | 476 class SkiaState { |
| 375 public: | 477 public: |
| 376 enum class Clip { | 478 enum class Clip { |
| 377 kSave, | 479 kSave, |
| 378 kPath, | 480 kPath, |
| 379 }; | 481 }; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 m_glyphs.setCount(0); | 595 m_glyphs.setCount(0); |
| 494 m_pFont = pFont; | 596 m_pFont = pFont; |
| 495 m_pCache = pCache; | 597 m_pCache = pCache; |
| 496 m_fontSize = font_size; | 598 m_fontSize = font_size; |
| 497 m_fillColor = color; | 599 m_fillColor = color; |
| 498 m_drawMatrix = *pMatrix; | 600 m_drawMatrix = *pMatrix; |
| 499 } | 601 } |
| 500 int count = m_positions.count(); | 602 int count = m_positions.count(); |
| 501 m_positions.setCount(nChars + count); | 603 m_positions.setCount(nChars + count); |
| 502 m_glyphs.setCount(nChars + count); | 604 m_glyphs.setCount(nChars + count); |
| 605 SkScalar flip = m_fontSize < 0 ? -1 : 1; | |
| 503 for (int index = 0; index < nChars; ++index) { | 606 for (int index = 0; index < nChars; ++index) { |
| 504 const FXTEXT_CHARPOS& cp = pCharPos[index]; | 607 const FXTEXT_CHARPOS& cp = pCharPos[index]; |
| 505 m_positions[index + count] = {cp.m_OriginX, cp.m_OriginY}; | 608 m_positions[index + count] = {cp.m_OriginX * flip, cp.m_OriginY * flip}; |
| 506 m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex; | 609 m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex; |
| 507 } | 610 } |
| 508 SkPoint delta; | 611 SkPoint delta; |
| 509 if (MatrixOffset(pMatrix, &delta)) { | 612 if (MatrixOffset(pMatrix, &delta)) { |
| 510 for (int index = 0; index < nChars; ++index) | 613 for (int index = 0; index < nChars; ++index) |
| 511 m_positions[index + count].offset(delta.fX, -delta.fY); | 614 m_positions[index + count].offset(delta.fX * flip, -delta.fY * flip); |
| 512 } | 615 } |
| 513 m_drawText = true; | 616 m_drawText = true; |
| 514 return true; | 617 return true; |
| 515 } | 618 } |
| 516 | 619 |
| 517 void FlushText(CFX_SkiaDeviceDriver* pDriver) { | 620 void FlushText(CFX_SkiaDeviceDriver* pDriver) { |
| 518 SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix); | 621 SkScalar flip = m_fontSize < 0 ? -1 : 1; |
| 622 SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix, flip); | |
| 519 SkPaint skPaint; | 623 SkPaint skPaint; |
| 520 skPaint.setAntiAlias(true); | 624 skPaint.setAntiAlias(true); |
| 521 skPaint.setColor(m_fillColor); | 625 skPaint.setColor(m_fillColor); |
| 522 if (m_pFont->GetFace() && m_pCache) { // exclude placeholder test fonts | 626 if (m_pFont->GetFace() && m_pCache) { // exclude placeholder test fonts |
| 523 sk_sp<SkTypeface> typeface(SkSafeRef(m_pCache->GetDeviceCache(m_pFont))); | 627 sk_sp<SkTypeface> typeface(SkSafeRef(m_pCache->GetDeviceCache(m_pFont))); |
| 524 skPaint.setTypeface(typeface); | 628 skPaint.setTypeface(typeface); |
| 525 } | 629 } |
| 526 skPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 630 skPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 527 skPaint.setTextSize(m_fontSize); | 631 skPaint.setTextSize(m_fontSize); |
| 528 skPaint.setSubpixelText(true); | 632 skPaint.setSubpixelText(true); |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 SkSafeRef(pCache ? pCache->GetDeviceCache(pFont) : nullptr)); | 1016 SkSafeRef(pCache ? pCache->GetDeviceCache(pFont) : nullptr)); |
| 913 SkPaint paint; | 1017 SkPaint paint; |
| 914 paint.setAntiAlias(true); | 1018 paint.setAntiAlias(true); |
| 915 paint.setColor(color); | 1019 paint.setColor(color); |
| 916 paint.setTypeface(typeface); | 1020 paint.setTypeface(typeface); |
| 917 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 1021 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 918 paint.setHinting(SkPaint::kNo_Hinting); | 1022 paint.setHinting(SkPaint::kNo_Hinting); |
| 919 paint.setTextSize(font_size); | 1023 paint.setTextSize(font_size); |
| 920 paint.setSubpixelText(true); | 1024 paint.setSubpixelText(true); |
| 921 m_pCanvas->save(); | 1025 m_pCanvas->save(); |
| 922 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device); | 1026 SkScalar flip = font_size < 0 ? -1 : 1; |
| 1027 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device, flip); | |
| 923 m_pCanvas->concat(skMatrix); | 1028 m_pCanvas->concat(skMatrix); |
| 924 SkTDArray<SkPoint> positions; | 1029 SkTDArray<SkPoint> positions; |
| 925 positions.setCount(nChars); | 1030 positions.setCount(nChars); |
| 926 SkTDArray<uint16_t> glyphs; | 1031 SkTDArray<uint16_t> glyphs; |
| 927 glyphs.setCount(nChars); | 1032 glyphs.setCount(nChars); |
| 928 for (int index = 0; index < nChars; ++index) { | 1033 for (int index = 0; index < nChars; ++index) { |
| 929 const FXTEXT_CHARPOS& cp = pCharPos[index]; | 1034 const FXTEXT_CHARPOS& cp = pCharPos[index]; |
| 930 positions[index] = {cp.m_OriginX, cp.m_OriginY}; | 1035 positions[index] = {cp.m_OriginX * flip, cp.m_OriginY * flip}; |
| 931 glyphs[index] = (uint16_t)cp.m_GlyphIndex; | 1036 glyphs[index] = (uint16_t)cp.m_GlyphIndex; |
| 932 } | 1037 } |
| 933 m_pCanvas->drawPosText(glyphs.begin(), nChars * 2, positions.begin(), paint); | 1038 m_pCanvas->drawPosText(glyphs.begin(), nChars * 2, positions.begin(), paint); |
| 934 m_pCanvas->restore(); | 1039 m_pCanvas->restore(); |
| 935 return TRUE; | 1040 return TRUE; |
| 936 } | 1041 } |
| 937 | 1042 |
| 938 int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) const { | 1043 int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) const { |
| 939 switch (caps_id) { | 1044 switch (caps_id) { |
| 940 case FXDC_DEVICE_CLASS: | 1045 case FXDC_DEVICE_CLASS: |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1332 } | 1437 } |
| 1333 | 1438 |
| 1334 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, | 1439 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, |
| 1335 int bitmap_alpha, | 1440 int bitmap_alpha, |
| 1336 uint32_t argb, | 1441 uint32_t argb, |
| 1337 const CFX_Matrix* pMatrix, | 1442 const CFX_Matrix* pMatrix, |
| 1338 uint32_t render_flags, | 1443 uint32_t render_flags, |
| 1339 void*& handle, | 1444 void*& handle, |
| 1340 int blend_type) { | 1445 int blend_type) { |
| 1341 DebugValidate(m_pBitmap, m_pOriDevice); | 1446 DebugValidate(m_pBitmap, m_pOriDevice); |
| 1342 SkColorType colorType = pSource->IsAlphaMask() | |
| 1343 ? SkColorType::kAlpha_8_SkColorType | |
| 1344 : SkColorType::kGray_8_SkColorType; | |
| 1345 SkAlphaType alphaType = | |
| 1346 pSource->IsAlphaMask() ? kPremul_SkAlphaType : kOpaque_SkAlphaType; | |
| 1347 SkColorTable* ct = nullptr; | 1447 SkColorTable* ct = nullptr; |
| 1348 void* buffer = pSource->GetBuffer(); | |
| 1349 if (!buffer) | |
| 1350 return FALSE; | |
| 1351 std::unique_ptr<uint8_t, FxFreeDeleter> dst8Storage; | 1448 std::unique_ptr<uint8_t, FxFreeDeleter> dst8Storage; |
| 1352 std::unique_ptr<uint32_t, FxFreeDeleter> dst32Storage; | 1449 std::unique_ptr<uint32_t, FxFreeDeleter> dst32Storage; |
| 1353 int width = pSource->GetWidth(); | 1450 SkBitmap skBitmap; |
| 1354 int height = pSource->GetHeight(); | 1451 int width, height; |
| 1355 int rowBytes = pSource->GetPitch(); | 1452 if (!Upsample(pSource, dst8Storage, dst32Storage, &ct, &skBitmap, &width, |
| 1356 switch (pSource->GetBPP()) { | 1453 &height, false)) { |
| 1357 case 1: { | 1454 return FALSE; |
| 1358 dst8Storage.reset(FX_Alloc2D(uint8_t, width, height)); | |
| 1359 uint8_t* dst8Pixels = dst8Storage.get(); | |
| 1360 for (int y = 0; y < height; ++y) { | |
| 1361 const uint8_t* srcRow = | |
| 1362 static_cast<const uint8_t*>(buffer) + y * rowBytes; | |
| 1363 uint8_t* dstRow = dst8Pixels + y * width; | |
| 1364 for (int x = 0; x < width; ++x) | |
| 1365 dstRow[x] = srcRow[x >> 3] & (1 << (~x & 0x07)) ? 0xFF : 0x00; | |
| 1366 } | |
| 1367 buffer = dst8Storage.get(); | |
| 1368 rowBytes = width; | |
| 1369 } break; | |
| 1370 case 8: | |
| 1371 if (pSource->GetPalette()) { | |
| 1372 ct = new SkColorTable(pSource->GetPalette(), pSource->GetPaletteSize()); | |
| 1373 colorType = SkColorType::kIndex_8_SkColorType; | |
| 1374 } | |
| 1375 break; | |
| 1376 case 24: { | |
| 1377 dst32Storage.reset(FX_Alloc2D(uint32_t, width, height)); | |
| 1378 uint32_t* dst32Pixels = dst32Storage.get(); | |
| 1379 for (int y = 0; y < height; ++y) { | |
| 1380 const uint8_t* srcRow = | |
| 1381 static_cast<const uint8_t*>(buffer) + y * rowBytes; | |
| 1382 uint32_t* dstRow = dst32Pixels + y * width; | |
| 1383 for (int x = 0; x < width; ++x) { | |
| 1384 dstRow[x] = SkPackARGB32(0xFF, srcRow[x * 3 + 2], srcRow[x * 3 + 1], | |
| 1385 srcRow[x * 3 + 0]); | |
| 1386 } | |
| 1387 } | |
| 1388 buffer = dst32Storage.get(); | |
| 1389 rowBytes = width * sizeof(uint32_t); | |
| 1390 colorType = SkColorType::kN32_SkColorType; | |
| 1391 alphaType = kOpaque_SkAlphaType; | |
| 1392 } break; | |
| 1393 case 32: | |
| 1394 colorType = SkColorType::kN32_SkColorType; | |
| 1395 alphaType = kPremul_SkAlphaType; | |
| 1396 pSource->DebugVerifyBitmapIsPreMultiplied(buffer); | |
| 1397 break; | |
| 1398 default: | |
| 1399 SkASSERT(0); // TODO(caryclark) ensure that all cases are covered | |
| 1400 colorType = SkColorType::kUnknown_SkColorType; | |
| 1401 } | 1455 } |
| 1402 SkImageInfo imageInfo = | |
| 1403 SkImageInfo::Make(width, height, colorType, alphaType); | |
| 1404 SkBitmap skBitmap; | |
| 1405 skBitmap.installPixels(imageInfo, buffer, rowBytes, ct, nullptr, nullptr); | |
| 1406 m_pCanvas->save(); | 1456 m_pCanvas->save(); |
| 1407 SkMatrix skMatrix; | 1457 SkMatrix skMatrix; |
| 1408 const CFX_Matrix& m = *pMatrix; | 1458 SetBitmapMatrix(pMatrix, width, height, &skMatrix); |
| 1409 skMatrix.setAll(m.a / width, -m.c / height, m.c + m.e, m.b / width, | |
| 1410 -m.d / height, m.d + m.f, 0, 0, 1); | |
| 1411 m_pCanvas->concat(skMatrix); | 1459 m_pCanvas->concat(skMatrix); |
| 1412 SkPaint paint; | 1460 SkPaint paint; |
| 1413 paint.setAntiAlias(true); | 1461 SetBitmapPaint(pSource->IsAlphaMask(), argb, bitmap_alpha, blend_type, |
| 1414 if (pSource->IsAlphaMask()) { | 1462 &paint); |
| 1415 paint.setColorFilter( | 1463 // TODO(caryclark) Once Skia supports 8 bit src to 8 bit dst remove this |
| 1416 SkColorFilter::MakeModeFilter(argb, SkXfermode::kSrc_Mode)); | 1464 if (m_pBitmap->GetBPP() == 8 && pSource->GetBPP() == 8) { |
| 1465 SkMatrix inv; | |
| 1466 SkAssertResult(skMatrix.invert(&inv)); | |
| 1467 for (int y = 0; y < m_pBitmap->GetHeight(); ++y) { | |
| 1468 for (int x = 0; x < m_pBitmap->GetWidth(); ++x) { | |
| 1469 SkPoint src = {x + 0.5f, y + 0.5f}; | |
| 1470 inv.mapPoints(&src, 1); | |
| 1471 // TODO(caryclark) Why does the matrix map require clamping? | |
| 1472 src.fX = SkTMax(0.5f, SkTMin(src.fX, width - 0.5f)); | |
| 1473 src.fY = SkTMax(0.5f, SkTMin(src.fY, height - 0.5f)); | |
| 1474 m_pBitmap->SetPixel(x, y, skBitmap.getColor(src.fX, src.fY)); | |
| 1475 } | |
| 1476 } | |
| 1477 } else { | |
| 1478 m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint); | |
| 1417 } | 1479 } |
| 1418 // paint.setFilterQuality(kHigh_SkFilterQuality); | |
| 1419 paint.setXfermodeMode(GetSkiaBlendMode(blend_type)); | |
| 1420 paint.setAlpha(bitmap_alpha); | |
| 1421 m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint); | |
| 1422 m_pCanvas->restore(); | 1480 m_pCanvas->restore(); |
| 1423 if (ct) | 1481 if (ct) |
| 1424 ct->unref(); | 1482 ct->unref(); |
| 1425 DebugValidate(m_pBitmap, m_pOriDevice); | 1483 DebugValidate(m_pBitmap, m_pOriDevice); |
| 1426 return TRUE; | 1484 return TRUE; |
| 1427 } | 1485 } |
| 1428 | 1486 |
| 1429 FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* handle, IFX_Pause* pPause) { | 1487 FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* handle, IFX_Pause* pPause) { |
| 1430 return FALSE; | 1488 return FALSE; |
| 1431 } | 1489 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1443 SkImageInfo unpremultipliedInfo = | 1501 SkImageInfo unpremultipliedInfo = |
| 1444 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType); | 1502 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType); |
| 1445 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes); | 1503 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes); |
| 1446 SkImageInfo premultipliedInfo = | 1504 SkImageInfo premultipliedInfo = |
| 1447 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); | 1505 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); |
| 1448 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes); | 1506 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes); |
| 1449 unpremultiplied.readPixels(premultiplied); | 1507 unpremultiplied.readPixels(premultiplied); |
| 1450 pDIBitmap->DebugVerifyBitmapIsPreMultiplied(); | 1508 pDIBitmap->DebugVerifyBitmapIsPreMultiplied(); |
| 1451 } | 1509 } |
| 1452 | 1510 |
| 1511 bool CFX_SkiaDeviceDriver::DrawBitsWithMask(const CFX_DIBSource* pSource, | |
| 1512 const CFX_DIBSource* pMask, | |
| 1513 int bitmap_alpha, | |
| 1514 const CFX_Matrix* pMatrix, | |
| 1515 int blend_type) { | |
| 1516 DebugValidate(m_pBitmap, m_pOriDevice); | |
| 1517 SkColorTable* srcCt = nullptr; | |
| 1518 SkColorTable* maskCt = nullptr; | |
| 1519 std::unique_ptr<uint8_t, FxFreeDeleter> src8Storage, mask8Storage; | |
| 1520 std::unique_ptr<uint32_t, FxFreeDeleter> src32Storage, mask32Storage; | |
| 1521 SkBitmap skBitmap, skMask; | |
| 1522 int srcWidth, srcHeight, maskWidth, maskHeight; | |
| 1523 if (!Upsample(pSource, src8Storage, src32Storage, &srcCt, &skBitmap, | |
| 1524 &srcWidth, &srcHeight, false)) { | |
| 1525 return false; | |
| 1526 } | |
| 1527 if (!Upsample(pMask, mask8Storage, mask32Storage, &maskCt, &skMask, | |
| 1528 &maskWidth, &maskHeight, true)) { | |
| 1529 return false; | |
| 1530 } | |
| 1531 m_pCanvas->save(); | |
| 1532 SkMatrix skMatrix; | |
| 1533 SetBitmapMatrix(pMatrix, srcWidth, srcHeight, &skMatrix); | |
| 1534 m_pCanvas->concat(skMatrix); | |
| 1535 SkPaint paint; | |
| 1536 SetBitmapPaint(pSource->IsAlphaMask(), 0xFFFFFFFF, bitmap_alpha, blend_type, | |
| 1537 &paint); | |
| 1538 sk_sp<SkImage> skSrc = SkImage::MakeFromBitmap(skBitmap); | |
| 1539 sk_sp<SkShader> skSrcShader = | |
| 1540 skSrc->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); | |
| 1541 sk_sp<SkImage> skMaskImage = SkImage::MakeFromBitmap(skMask); | |
| 1542 sk_sp<SkShader> skMaskShader = skMaskImage->makeShader( | |
| 1543 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); | |
| 1544 sk_sp<SkXfermode> dstInMode = SkXfermode::Make(SkXfermode::kSrcIn_Mode); | |
| 1545 paint.setShader( | |
| 1546 SkShader::MakeComposeShader(skMaskShader, skSrcShader, dstInMode)); | |
| 1547 SkRect r = {0, 0, SkIntToScalar(srcWidth), SkIntToScalar(srcHeight)}; | |
| 1548 m_pCanvas->drawRect(r, paint); | |
| 1549 m_pCanvas->restore(); | |
| 1550 if (srcCt) | |
| 1551 srcCt->unref(); | |
| 1552 DebugValidate(m_pBitmap, m_pOriDevice); | |
| 1553 return true; | |
| 1554 } | |
| 1555 | |
| 1556 bool CFX_SkiaDeviceDriver::SetBitsWithMask(const CFX_DIBSource* pBitmap, | |
| 1557 const CFX_DIBSource* pMask, | |
| 1558 int dest_left, | |
| 1559 int dest_top, | |
| 1560 int bitmap_alpha, | |
| 1561 int blend_type) { | |
| 1562 if (!m_pBitmap || !m_pBitmap->GetBuffer()) | |
| 1563 return true; | |
| 1564 CFX_Matrix m(pBitmap->GetWidth(), 0, 0, -pBitmap->GetHeight(), dest_left, | |
| 1565 dest_top + pBitmap->GetHeight()); | |
| 1566 return DrawBitsWithMask(pBitmap, pMask, bitmap_alpha, &m, blend_type); | |
| 1567 } | |
| 1568 | |
| 1569 void CFX_SkiaDeviceDriver::Clear(uint32_t color) { | |
| 1570 m_pCanvas->clear(color); | |
| 1571 } | |
| 1572 | |
| 1453 void CFX_SkiaDeviceDriver::Dump() const { | 1573 void CFX_SkiaDeviceDriver::Dump() const { |
| 1454 #ifdef SK_DEBUG | 1574 #ifdef SK_DEBUG |
| 1455 if (m_pCache) | 1575 if (m_pCache) |
| 1456 m_pCache->Dump(this); | 1576 m_pCache->Dump(this); |
| 1457 #endif | 1577 #endif |
| 1458 } | 1578 } |
| 1459 | 1579 |
| 1460 void CFX_SkiaDeviceDriver::DebugVerifyBitmapIsPreMultiplied() const { | 1580 void CFX_SkiaDeviceDriver::DebugVerifyBitmapIsPreMultiplied() const { |
| 1461 if (m_pOriDevice) | 1581 if (m_pOriDevice) |
| 1462 m_pOriDevice->DebugVerifyBitmapIsPreMultiplied(); | 1582 m_pOriDevice->DebugVerifyBitmapIsPreMultiplied(); |
| 1463 } | 1583 } |
| 1464 | 1584 |
| 1465 CFX_FxgeDevice::CFX_FxgeDevice() { | 1585 CFX_FxgeDevice::CFX_FxgeDevice() { |
| 1466 m_bOwnedBitmap = FALSE; | 1586 m_bOwnedBitmap = FALSE; |
| 1467 } | 1587 } |
| 1468 | 1588 |
| 1589 void CFX_FxgeDevice::Clear(uint32_t color) { | |
| 1590 CFX_SkiaDeviceDriver* skDriver = | |
| 1591 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()); | |
| 1592 skDriver->Clear(color); | |
| 1593 } | |
| 1594 | |
| 1469 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) { | 1595 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) { |
| 1470 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); | 1596 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); |
| 1471 SetDeviceDriver(WrapUnique(skDriver)); | 1597 SetDeviceDriver(WrapUnique(skDriver)); |
| 1472 return skDriver->GetRecorder(); | 1598 return skDriver->GetRecorder(); |
| 1473 } | 1599 } |
| 1474 | 1600 |
| 1475 bool CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap, | 1601 bool CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap, |
| 1476 bool bRgbByteOrder, | 1602 bool bRgbByteOrder, |
| 1477 CFX_DIBitmap* pOriDevice, | 1603 CFX_DIBitmap* pOriDevice, |
| 1478 bool bGroupKnockout) { | 1604 bool bGroupKnockout) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1516 | 1642 |
| 1517 void CFX_FxgeDevice::DebugVerifyBitmapIsPreMultiplied() const { | 1643 void CFX_FxgeDevice::DebugVerifyBitmapIsPreMultiplied() const { |
| 1518 #ifdef SK_DEBUG | 1644 #ifdef SK_DEBUG |
| 1519 CFX_SkiaDeviceDriver* skDriver = | 1645 CFX_SkiaDeviceDriver* skDriver = |
| 1520 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()); | 1646 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()); |
| 1521 if (skDriver) | 1647 if (skDriver) |
| 1522 skDriver->DebugVerifyBitmapIsPreMultiplied(); | 1648 skDriver->DebugVerifyBitmapIsPreMultiplied(); |
| 1523 #endif | 1649 #endif |
| 1524 } | 1650 } |
| 1525 | 1651 |
| 1652 bool CFX_FxgeDevice::SetBitsWithMask(const CFX_DIBSource* pBitmap, | |
| 1653 const CFX_DIBSource* pMask, | |
| 1654 int left, | |
| 1655 int top, | |
| 1656 int bitmap_alpha, | |
| 1657 int blend_type) { | |
| 1658 CFX_SkiaDeviceDriver* skDriver = | |
| 1659 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()); | |
| 1660 if (skDriver) | |
| 1661 return skDriver->SetBitsWithMask(pBitmap, pMask, left, top, bitmap_alpha, | |
| 1662 blend_type); | |
| 1663 return false; | |
| 1664 } | |
| 1665 | |
| 1526 void CFX_DIBSource::DebugVerifyBitmapIsPreMultiplied(void* opt) const { | 1666 void CFX_DIBSource::DebugVerifyBitmapIsPreMultiplied(void* opt) const { |
| 1527 #ifdef SK_DEBUG | 1667 #ifdef SK_DEBUG |
| 1528 SkASSERT(32 == GetBPP()); | 1668 SkASSERT(32 == GetBPP()); |
| 1529 const uint32_t* buffer = (const uint32_t*)(opt ? opt : GetBuffer()); | 1669 const uint32_t* buffer = (const uint32_t*)(opt ? opt : GetBuffer()); |
| 1530 int width = GetWidth(); | 1670 int width = GetWidth(); |
| 1531 int height = GetHeight(); | 1671 int height = GetHeight(); |
| 1532 // verify that input is really premultiplied | 1672 // verify that input is really premultiplied |
| 1533 for (int y = 0; y < height; ++y) { | 1673 for (int y = 0; y < height; ++y) { |
| 1534 const uint32_t* srcRow = buffer + y * width; | 1674 const uint32_t* srcRow = buffer + y * width; |
| 1535 for (int x = 0; x < width; ++x) { | 1675 for (int x = 0; x < width; ++x) { |
| 1536 uint8_t a = SkGetPackedA32(srcRow[x]); | 1676 uint8_t a = SkGetPackedA32(srcRow[x]); |
| 1537 uint8_t r = SkGetPackedR32(srcRow[x]); | 1677 uint8_t r = SkGetPackedR32(srcRow[x]); |
| 1538 uint8_t g = SkGetPackedG32(srcRow[x]); | 1678 uint8_t g = SkGetPackedG32(srcRow[x]); |
| 1539 uint8_t b = SkGetPackedB32(srcRow[x]); | 1679 uint8_t b = SkGetPackedB32(srcRow[x]); |
| 1540 SkA32Assert(a); | 1680 SkA32Assert(a); |
| 1541 SkASSERT(r <= a); | 1681 SkASSERT(r <= a); |
| 1542 SkASSERT(g <= a); | 1682 SkASSERT(g <= a); |
| 1543 SkASSERT(b <= a); | 1683 SkASSERT(b <= a); |
| 1544 } | 1684 } |
| 1545 } | 1685 } |
| 1546 #endif | 1686 #endif |
| 1547 } | 1687 } |
| 1548 | 1688 |
| 1549 #endif | 1689 #endif |
| OLD | NEW |