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

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: address comments 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
« no previous file with comments | « core/fxge/skia/fx_skia_device.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
31 #include "third_party/skia/include/core/SkShader.h"
30 #include "third_party/skia/include/core/SkStream.h" 32 #include "third_party/skia/include/core/SkStream.h"
31 #include "third_party/skia/include/core/SkTypeface.h" 33 #include "third_party/skia/include/core/SkTypeface.h"
32 #include "third_party/skia/include/effects/SkDashPathEffect.h" 34 #include "third_party/skia/include/effects/SkDashPathEffect.h"
33 #include "third_party/skia/include/effects/SkGradientShader.h" 35 #include "third_party/skia/include/effects/SkGradientShader.h"
34 #include "third_party/skia/include/pathops/SkPathOps.h" 36 #include "third_party/skia/include/pathops/SkPathOps.h"
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
(...skipping 93 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;
430 }
431 case 8:
432 if (pSource->GetPalette()) {
433 *ctPtr =
434 new SkColorTable(pSource->GetPalette(), pSource->GetPaletteSize());
435 colorType = SkColorType::kIndex_8_SkColorType;
436 }
437 break;
438 case 24: {
439 dst32Storage.reset(FX_Alloc2D(uint32_t, width, height));
440 uint32_t* dst32Pixels = dst32Storage.get();
441 for (int y = 0; y < height; ++y) {
442 const uint8_t* srcRow =
443 static_cast<const uint8_t*>(buffer) + y * rowBytes;
444 uint32_t* dstRow = dst32Pixels + y * width;
445 for (int x = 0; x < width; ++x) {
446 dstRow[x] = SkPackARGB32(0xFF, srcRow[x * 3 + 2], srcRow[x * 3 + 1],
447 srcRow[x * 3 + 0]);
448 }
449 }
450 buffer = dst32Storage.get();
451 rowBytes = width * sizeof(uint32_t);
452 colorType = SkColorType::kN32_SkColorType;
453 alphaType = kOpaque_SkAlphaType;
454 break;
455 }
456 case 32:
457 colorType = SkColorType::kN32_SkColorType;
458 alphaType = kPremul_SkAlphaType;
459 pSource->DebugVerifyBitmapIsPreMultiplied(buffer);
460 break;
461 default:
462 SkASSERT(0); // TODO(caryclark) ensure that all cases are covered
463 colorType = SkColorType::kUnknown_SkColorType;
464 }
465 SkImageInfo imageInfo =
466 SkImageInfo::Make(width, height, colorType, alphaType);
467 skBitmap->installPixels(imageInfo, buffer, rowBytes, *ctPtr, nullptr,
468 nullptr);
469 *widthPtr = width;
470 *heightPtr = height;
471 return true;
472 }
473
370 } // namespace 474 } // namespace
371 475
372 // Encapsulate the state used for successive text and path draws so that 476 // Encapsulate the state used for successive text and path draws so that
373 // they can be combined. 477 // they can be combined.
374 class SkiaState { 478 class SkiaState {
375 public: 479 public:
376 enum class Clip { 480 enum class Clip {
377 kSave, 481 kSave,
378 kPath, 482 kPath,
379 }; 483 };
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 m_glyphs.setCount(0); 597 m_glyphs.setCount(0);
494 m_pFont = pFont; 598 m_pFont = pFont;
495 m_pCache = pCache; 599 m_pCache = pCache;
496 m_fontSize = font_size; 600 m_fontSize = font_size;
497 m_fillColor = color; 601 m_fillColor = color;
498 m_drawMatrix = *pMatrix; 602 m_drawMatrix = *pMatrix;
499 } 603 }
500 int count = m_positions.count(); 604 int count = m_positions.count();
501 m_positions.setCount(nChars + count); 605 m_positions.setCount(nChars + count);
502 m_glyphs.setCount(nChars + count); 606 m_glyphs.setCount(nChars + count);
607 SkScalar flip = m_fontSize < 0 ? -1 : 1;
503 for (int index = 0; index < nChars; ++index) { 608 for (int index = 0; index < nChars; ++index) {
504 const FXTEXT_CHARPOS& cp = pCharPos[index]; 609 const FXTEXT_CHARPOS& cp = pCharPos[index];
505 m_positions[index + count] = {cp.m_OriginX, cp.m_OriginY}; 610 m_positions[index + count] = {cp.m_OriginX * flip, cp.m_OriginY * flip};
506 m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex; 611 m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex;
507 } 612 }
508 SkPoint delta; 613 SkPoint delta;
509 if (MatrixOffset(pMatrix, &delta)) { 614 if (MatrixOffset(pMatrix, &delta)) {
510 for (int index = 0; index < nChars; ++index) 615 for (int index = 0; index < nChars; ++index)
511 m_positions[index + count].offset(delta.fX, -delta.fY); 616 m_positions[index + count].offset(delta.fX * flip, -delta.fY * flip);
512 } 617 }
513 m_drawText = true; 618 m_drawText = true;
514 return true; 619 return true;
515 } 620 }
516 621
517 void FlushText(CFX_SkiaDeviceDriver* pDriver) { 622 void FlushText(CFX_SkiaDeviceDriver* pDriver) {
518 SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix); 623 SkScalar flip = m_fontSize < 0 ? -1 : 1;
624 SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix, flip);
519 SkPaint skPaint; 625 SkPaint skPaint;
520 skPaint.setAntiAlias(true); 626 skPaint.setAntiAlias(true);
521 skPaint.setColor(m_fillColor); 627 skPaint.setColor(m_fillColor);
522 if (m_pFont->GetFace() && m_pCache) { // exclude placeholder test fonts 628 if (m_pFont->GetFace() && m_pCache) { // exclude placeholder test fonts
523 sk_sp<SkTypeface> typeface(SkSafeRef(m_pCache->GetDeviceCache(m_pFont))); 629 sk_sp<SkTypeface> typeface(SkSafeRef(m_pCache->GetDeviceCache(m_pFont)));
524 skPaint.setTypeface(typeface); 630 skPaint.setTypeface(typeface);
525 } 631 }
526 skPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 632 skPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
527 skPaint.setTextSize(m_fontSize); 633 skPaint.setTextSize(m_fontSize);
528 skPaint.setSubpixelText(true); 634 skPaint.setSubpixelText(true);
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 SkSafeRef(pCache ? pCache->GetDeviceCache(pFont) : nullptr)); 1018 SkSafeRef(pCache ? pCache->GetDeviceCache(pFont) : nullptr));
913 SkPaint paint; 1019 SkPaint paint;
914 paint.setAntiAlias(true); 1020 paint.setAntiAlias(true);
915 paint.setColor(color); 1021 paint.setColor(color);
916 paint.setTypeface(typeface); 1022 paint.setTypeface(typeface);
917 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1023 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
918 paint.setHinting(SkPaint::kNo_Hinting); 1024 paint.setHinting(SkPaint::kNo_Hinting);
919 paint.setTextSize(font_size); 1025 paint.setTextSize(font_size);
920 paint.setSubpixelText(true); 1026 paint.setSubpixelText(true);
921 m_pCanvas->save(); 1027 m_pCanvas->save();
922 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device); 1028 SkScalar flip = font_size < 0 ? -1 : 1;
1029 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device, flip);
923 m_pCanvas->concat(skMatrix); 1030 m_pCanvas->concat(skMatrix);
924 SkTDArray<SkPoint> positions; 1031 SkTDArray<SkPoint> positions;
925 positions.setCount(nChars); 1032 positions.setCount(nChars);
926 SkTDArray<uint16_t> glyphs; 1033 SkTDArray<uint16_t> glyphs;
927 glyphs.setCount(nChars); 1034 glyphs.setCount(nChars);
928 for (int index = 0; index < nChars; ++index) { 1035 for (int index = 0; index < nChars; ++index) {
929 const FXTEXT_CHARPOS& cp = pCharPos[index]; 1036 const FXTEXT_CHARPOS& cp = pCharPos[index];
930 positions[index] = {cp.m_OriginX, cp.m_OriginY}; 1037 positions[index] = {cp.m_OriginX * flip, cp.m_OriginY * flip};
931 glyphs[index] = (uint16_t)cp.m_GlyphIndex; 1038 glyphs[index] = (uint16_t)cp.m_GlyphIndex;
932 } 1039 }
933 m_pCanvas->drawPosText(glyphs.begin(), nChars * 2, positions.begin(), paint); 1040 m_pCanvas->drawPosText(glyphs.begin(), nChars * 2, positions.begin(), paint);
934 m_pCanvas->restore(); 1041 m_pCanvas->restore();
935 return TRUE; 1042 return TRUE;
936 } 1043 }
937 1044
938 int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) const { 1045 int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) const {
939 switch (caps_id) { 1046 switch (caps_id) {
940 case FXDC_DEVICE_CLASS: 1047 case FXDC_DEVICE_CLASS:
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 } 1439 }
1333 1440
1334 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, 1441 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
1335 int bitmap_alpha, 1442 int bitmap_alpha,
1336 uint32_t argb, 1443 uint32_t argb,
1337 const CFX_Matrix* pMatrix, 1444 const CFX_Matrix* pMatrix,
1338 uint32_t render_flags, 1445 uint32_t render_flags,
1339 void*& handle, 1446 void*& handle,
1340 int blend_type) { 1447 int blend_type) {
1341 DebugValidate(m_pBitmap, m_pOriDevice); 1448 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; 1449 SkColorTable* ct = nullptr;
1348 void* buffer = pSource->GetBuffer();
1349 if (!buffer)
1350 return FALSE;
1351 std::unique_ptr<uint8_t, FxFreeDeleter> dst8Storage; 1450 std::unique_ptr<uint8_t, FxFreeDeleter> dst8Storage;
1352 std::unique_ptr<uint32_t, FxFreeDeleter> dst32Storage; 1451 std::unique_ptr<uint32_t, FxFreeDeleter> dst32Storage;
1353 int width = pSource->GetWidth(); 1452 SkBitmap skBitmap;
1354 int height = pSource->GetHeight(); 1453 int width, height;
1355 int rowBytes = pSource->GetPitch(); 1454 if (!Upsample(pSource, dst8Storage, dst32Storage, &ct, &skBitmap, &width,
1356 switch (pSource->GetBPP()) { 1455 &height, false)) {
1357 case 1: { 1456 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 } 1457 }
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(); 1458 m_pCanvas->save();
1407 SkMatrix skMatrix; 1459 SkMatrix skMatrix;
1408 const CFX_Matrix& m = *pMatrix; 1460 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); 1461 m_pCanvas->concat(skMatrix);
1412 SkPaint paint; 1462 SkPaint paint;
1413 paint.setAntiAlias(true); 1463 SetBitmapPaint(pSource->IsAlphaMask(), argb, bitmap_alpha, blend_type,
1414 if (pSource->IsAlphaMask()) { 1464 &paint);
1415 paint.setColorFilter( 1465 // TODO(caryclark) Once Skia supports 8 bit src to 8 bit dst remove this
1416 SkColorFilter::MakeModeFilter(argb, SkXfermode::kSrc_Mode)); 1466 if (m_pBitmap->GetBPP() == 8 && pSource->GetBPP() == 8) {
1467 SkMatrix inv;
1468 SkAssertResult(skMatrix.invert(&inv));
1469 for (int y = 0; y < m_pBitmap->GetHeight(); ++y) {
1470 for (int x = 0; x < m_pBitmap->GetWidth(); ++x) {
1471 SkPoint src = {x + 0.5f, y + 0.5f};
1472 inv.mapPoints(&src, 1);
1473 // TODO(caryclark) Why does the matrix map require clamping?
1474 src.fX = SkTMax(0.5f, SkTMin(src.fX, width - 0.5f));
1475 src.fY = SkTMax(0.5f, SkTMin(src.fY, height - 0.5f));
1476 m_pBitmap->SetPixel(x, y, skBitmap.getColor(src.fX, src.fY));
1477 }
1478 }
1479 } else {
1480 m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint);
1417 } 1481 }
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(); 1482 m_pCanvas->restore();
1423 if (ct) 1483 if (ct)
1424 ct->unref(); 1484 ct->unref();
1425 DebugValidate(m_pBitmap, m_pOriDevice); 1485 DebugValidate(m_pBitmap, m_pOriDevice);
1426 return TRUE; 1486 return TRUE;
1427 } 1487 }
1428 1488
1429 FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* handle, IFX_Pause* pPause) { 1489 FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* handle, IFX_Pause* pPause) {
1430 return FALSE; 1490 return FALSE;
1431 } 1491 }
(...skipping 11 matching lines...) Expand all
1443 SkImageInfo unpremultipliedInfo = 1503 SkImageInfo unpremultipliedInfo =
1444 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType); 1504 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType);
1445 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes); 1505 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes);
1446 SkImageInfo premultipliedInfo = 1506 SkImageInfo premultipliedInfo =
1447 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); 1507 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
1448 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes); 1508 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes);
1449 unpremultiplied.readPixels(premultiplied); 1509 unpremultiplied.readPixels(premultiplied);
1450 pDIBitmap->DebugVerifyBitmapIsPreMultiplied(); 1510 pDIBitmap->DebugVerifyBitmapIsPreMultiplied();
1451 } 1511 }
1452 1512
1513 bool CFX_SkiaDeviceDriver::DrawBitsWithMask(const CFX_DIBSource* pSource,
1514 const CFX_DIBSource* pMask,
1515 int bitmap_alpha,
1516 const CFX_Matrix* pMatrix,
1517 int blend_type) {
1518 DebugValidate(m_pBitmap, m_pOriDevice);
1519 SkColorTable* srcCt = nullptr;
1520 SkColorTable* maskCt = nullptr;
1521 std::unique_ptr<uint8_t, FxFreeDeleter> src8Storage, mask8Storage;
1522 std::unique_ptr<uint32_t, FxFreeDeleter> src32Storage, mask32Storage;
1523 SkBitmap skBitmap, skMask;
1524 int srcWidth, srcHeight, maskWidth, maskHeight;
1525 if (!Upsample(pSource, src8Storage, src32Storage, &srcCt, &skBitmap,
1526 &srcWidth, &srcHeight, false)) {
1527 return false;
1528 }
1529 if (!Upsample(pMask, mask8Storage, mask32Storage, &maskCt, &skMask,
1530 &maskWidth, &maskHeight, true)) {
1531 return false;
1532 }
1533 m_pCanvas->save();
1534 SkMatrix skMatrix;
1535 SetBitmapMatrix(pMatrix, srcWidth, srcHeight, &skMatrix);
1536 m_pCanvas->concat(skMatrix);
1537 SkPaint paint;
1538 SetBitmapPaint(pSource->IsAlphaMask(), 0xFFFFFFFF, bitmap_alpha, blend_type,
1539 &paint);
1540 sk_sp<SkImage> skSrc = SkImage::MakeFromBitmap(skBitmap);
1541 sk_sp<SkShader> skSrcShader =
1542 skSrc->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
1543 sk_sp<SkImage> skMaskImage = SkImage::MakeFromBitmap(skMask);
1544 sk_sp<SkShader> skMaskShader = skMaskImage->makeShader(
1545 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
1546 sk_sp<SkXfermode> dstInMode = SkXfermode::Make(SkXfermode::kSrcIn_Mode);
1547 paint.setShader(
1548 SkShader::MakeComposeShader(skMaskShader, skSrcShader, dstInMode));
1549 SkRect r = {0, 0, SkIntToScalar(srcWidth), SkIntToScalar(srcHeight)};
1550 m_pCanvas->drawRect(r, paint);
1551 m_pCanvas->restore();
1552 if (srcCt)
1553 srcCt->unref();
1554 DebugValidate(m_pBitmap, m_pOriDevice);
1555 return true;
1556 }
1557
1558 bool CFX_SkiaDeviceDriver::SetBitsWithMask(const CFX_DIBSource* pBitmap,
1559 const CFX_DIBSource* pMask,
1560 int dest_left,
1561 int dest_top,
1562 int bitmap_alpha,
1563 int blend_type) {
1564 if (!m_pBitmap || !m_pBitmap->GetBuffer())
1565 return true;
1566 CFX_Matrix m(pBitmap->GetWidth(), 0, 0, -pBitmap->GetHeight(), dest_left,
1567 dest_top + pBitmap->GetHeight());
1568 return DrawBitsWithMask(pBitmap, pMask, bitmap_alpha, &m, blend_type);
1569 }
1570
1571 void CFX_SkiaDeviceDriver::Clear(uint32_t color) {
1572 m_pCanvas->clear(color);
1573 }
1574
1453 void CFX_SkiaDeviceDriver::Dump() const { 1575 void CFX_SkiaDeviceDriver::Dump() const {
1454 #ifdef SK_DEBUG 1576 #ifdef SK_DEBUG
1455 if (m_pCache) 1577 if (m_pCache)
1456 m_pCache->Dump(this); 1578 m_pCache->Dump(this);
1457 #endif 1579 #endif
1458 } 1580 }
1459 1581
1460 void CFX_SkiaDeviceDriver::DebugVerifyBitmapIsPreMultiplied() const { 1582 void CFX_SkiaDeviceDriver::DebugVerifyBitmapIsPreMultiplied() const {
1461 if (m_pOriDevice) 1583 if (m_pOriDevice)
1462 m_pOriDevice->DebugVerifyBitmapIsPreMultiplied(); 1584 m_pOriDevice->DebugVerifyBitmapIsPreMultiplied();
1463 } 1585 }
1464 1586
1465 CFX_FxgeDevice::CFX_FxgeDevice() { 1587 CFX_FxgeDevice::CFX_FxgeDevice() {
1466 m_bOwnedBitmap = FALSE; 1588 m_bOwnedBitmap = FALSE;
1467 } 1589 }
1468 1590
1591 void CFX_FxgeDevice::Clear(uint32_t color) {
1592 CFX_SkiaDeviceDriver* skDriver =
1593 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver());
1594 skDriver->Clear(color);
1595 }
1596
1469 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) { 1597 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) {
1470 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); 1598 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y);
1471 SetDeviceDriver(WrapUnique(skDriver)); 1599 SetDeviceDriver(WrapUnique(skDriver));
1472 return skDriver->GetRecorder(); 1600 return skDriver->GetRecorder();
1473 } 1601 }
1474 1602
1475 bool CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap, 1603 bool CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap,
1476 bool bRgbByteOrder, 1604 bool bRgbByteOrder,
1477 CFX_DIBitmap* pOriDevice, 1605 CFX_DIBitmap* pOriDevice,
1478 bool bGroupKnockout) { 1606 bool bGroupKnockout) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 1644
1517 void CFX_FxgeDevice::DebugVerifyBitmapIsPreMultiplied() const { 1645 void CFX_FxgeDevice::DebugVerifyBitmapIsPreMultiplied() const {
1518 #ifdef SK_DEBUG 1646 #ifdef SK_DEBUG
1519 CFX_SkiaDeviceDriver* skDriver = 1647 CFX_SkiaDeviceDriver* skDriver =
1520 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()); 1648 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver());
1521 if (skDriver) 1649 if (skDriver)
1522 skDriver->DebugVerifyBitmapIsPreMultiplied(); 1650 skDriver->DebugVerifyBitmapIsPreMultiplied();
1523 #endif 1651 #endif
1524 } 1652 }
1525 1653
1654 bool CFX_FxgeDevice::SetBitsWithMask(const CFX_DIBSource* pBitmap,
1655 const CFX_DIBSource* pMask,
1656 int left,
1657 int top,
1658 int bitmap_alpha,
1659 int blend_type) {
1660 CFX_SkiaDeviceDriver* skDriver =
1661 static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver());
1662 if (skDriver)
1663 return skDriver->SetBitsWithMask(pBitmap, pMask, left, top, bitmap_alpha,
1664 blend_type);
1665 return false;
1666 }
1667
1526 void CFX_DIBSource::DebugVerifyBitmapIsPreMultiplied(void* opt) const { 1668 void CFX_DIBSource::DebugVerifyBitmapIsPreMultiplied(void* opt) const {
1527 #ifdef SK_DEBUG 1669 #ifdef SK_DEBUG
1528 SkASSERT(32 == GetBPP()); 1670 SkASSERT(32 == GetBPP());
1529 const uint32_t* buffer = (const uint32_t*)(opt ? opt : GetBuffer()); 1671 const uint32_t* buffer = (const uint32_t*)(opt ? opt : GetBuffer());
1530 int width = GetWidth(); 1672 int width = GetWidth();
1531 int height = GetHeight(); 1673 int height = GetHeight();
1532 // verify that input is really premultiplied 1674 // verify that input is really premultiplied
1533 for (int y = 0; y < height; ++y) { 1675 for (int y = 0; y < height; ++y) {
1534 const uint32_t* srcRow = buffer + y * width; 1676 const uint32_t* srcRow = buffer + y * width;
1535 for (int x = 0; x < width; ++x) { 1677 for (int x = 0; x < width; ++x) {
1536 uint8_t a = SkGetPackedA32(srcRow[x]); 1678 uint8_t a = SkGetPackedA32(srcRow[x]);
1537 uint8_t r = SkGetPackedR32(srcRow[x]); 1679 uint8_t r = SkGetPackedR32(srcRow[x]);
1538 uint8_t g = SkGetPackedG32(srcRow[x]); 1680 uint8_t g = SkGetPackedG32(srcRow[x]);
1539 uint8_t b = SkGetPackedB32(srcRow[x]); 1681 uint8_t b = SkGetPackedB32(srcRow[x]);
1540 SkA32Assert(a); 1682 SkA32Assert(a);
1541 SkASSERT(r <= a); 1683 SkASSERT(r <= a);
1542 SkASSERT(g <= a); 1684 SkASSERT(g <= a);
1543 SkASSERT(b <= a); 1685 SkASSERT(b <= a);
1544 } 1686 }
1545 } 1687 }
1546 #endif 1688 #endif
1547 } 1689 }
1548 1690
1549 #endif 1691 #endif
OLDNEW
« no previous file with comments | « 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