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 |