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

Side by Side Diff: core/fxge/skia/fx_skia_device.cpp

Issue 2182763002: add native draw bitmap with alpha mask (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: adapt new virtuals 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
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
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
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
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
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
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
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
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
OLDNEW
« core/fpdfapi/fpdf_render/fpdf_render_image.cpp ('K') | « core/fxge/skia/fx_skia_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698