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

Side by Side Diff: src/pdf/SkPDFDevice.cpp

Issue 2396953002: Revert[8] "replace SkXfermode obj with SkBlendMode enum in paints" (Closed)
Patch Set: add tmp virtual to unroll legacy arithmodes Created 4 years, 2 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 | « src/pdf/SkPDFDevice.h ('k') | src/pdf/SkPDFGraphicState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkPDFDevice.h" 8 #include "SkPDFDevice.h"
9 9
10 #include "SkAdvancedTypefaceMetrics.h" 10 #include "SkAdvancedTypefaceMetrics.h"
(...skipping 29 matching lines...) Expand all
40 #include "SkTemplates.h" 40 #include "SkTemplates.h"
41 #include "SkTextBlobRunIterator.h" 41 #include "SkTextBlobRunIterator.h"
42 #include "SkTextFormatParams.h" 42 #include "SkTextFormatParams.h"
43 #include "SkUtils.h" 43 #include "SkUtils.h"
44 #include "SkXfermodeInterpretation.h" 44 #include "SkXfermodeInterpretation.h"
45 45
46 #define DPI_FOR_RASTER_SCALE_ONE 72 46 #define DPI_FOR_RASTER_SCALE_ONE 72
47 47
48 // Utility functions 48 // Utility functions
49 49
50 // If the paint will definitely draw opaquely, replace kSrc_Mode with 50 // If the paint will definitely draw opaquely, replace kSrc with
51 // kSrcOver_Mode. http://crbug.com/473572 51 // kSrcOver. http://crbug.com/473572
52 static void replace_srcmode_on_opaque_paint(SkPaint* paint) { 52 static void replace_srcmode_on_opaque_paint(SkPaint* paint) {
53 if (kSrcOver_SkXfermodeInterpretation 53 if (kSrcOver_SkXfermodeInterpretation == SkInterpretXfermode(*paint, false)) {
54 == SkInterpretXfermode(*paint, false)) { 54 paint->setBlendMode(SkBlendMode::kSrcOver);
55 paint->setXfermode(nullptr);
56 } 55 }
57 } 56 }
58 57
59 static void emit_pdf_color(SkColor color, SkWStream* result) { 58 static void emit_pdf_color(SkColor color, SkWStream* result) {
60 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere. 59 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere.
61 SkPDFUtils::AppendColorComponent(SkColorGetR(color), result); 60 SkPDFUtils::AppendColorComponent(SkColorGetR(color), result);
62 result->writeText(" "); 61 result->writeText(" ");
63 SkPDFUtils::AppendColorComponent(SkColorGetG(color), result); 62 SkPDFUtils::AppendColorComponent(SkColorGetG(color), result);
64 result->writeText(" "); 63 result->writeText(" ");
65 SkPDFUtils::AppendColorComponent(SkColorGetB(color), result); 64 SkPDFUtils::AppendColorComponent(SkColorGetB(color), result);
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 384
386 385
387 // A helper class to automatically finish a ContentEntry at the end of a 386 // A helper class to automatically finish a ContentEntry at the end of a
388 // drawing method and maintain the state needed between set up and finish. 387 // drawing method and maintain the state needed between set up and finish.
389 class ScopedContentEntry { 388 class ScopedContentEntry {
390 public: 389 public:
391 ScopedContentEntry(SkPDFDevice* device, const SkDraw& draw, 390 ScopedContentEntry(SkPDFDevice* device, const SkDraw& draw,
392 const SkPaint& paint, bool hasText = false) 391 const SkPaint& paint, bool hasText = false)
393 : fDevice(device), 392 : fDevice(device),
394 fContentEntry(nullptr), 393 fContentEntry(nullptr),
395 fXfermode(SkXfermode::kSrcOver_Mode), 394 fBlendMode(SkBlendMode::kSrcOver),
396 fDstFormXObject(nullptr) { 395 fDstFormXObject(nullptr) {
397 init(draw.fClipStack, draw.fRC->bwRgn(), *draw.fMatrix, paint, hasText); 396 init(draw.fClipStack, draw.fRC->bwRgn(), *draw.fMatrix, paint, hasText);
398 } 397 }
399 ScopedContentEntry(SkPDFDevice* device, const SkClipStack* clipStack, 398 ScopedContentEntry(SkPDFDevice* device, const SkClipStack* clipStack,
400 const SkRegion& clipRegion, const SkMatrix& matrix, 399 const SkRegion& clipRegion, const SkMatrix& matrix,
401 const SkPaint& paint, bool hasText = false) 400 const SkPaint& paint, bool hasText = false)
402 : fDevice(device), 401 : fDevice(device),
403 fContentEntry(nullptr), 402 fContentEntry(nullptr),
404 fXfermode(SkXfermode::kSrcOver_Mode), 403 fBlendMode(SkBlendMode::kSrcOver),
405 fDstFormXObject(nullptr) { 404 fDstFormXObject(nullptr) {
406 init(clipStack, clipRegion, matrix, paint, hasText); 405 init(clipStack, clipRegion, matrix, paint, hasText);
407 } 406 }
408 407
409 ~ScopedContentEntry() { 408 ~ScopedContentEntry() {
410 if (fContentEntry) { 409 if (fContentEntry) {
411 SkPath* shape = &fShape; 410 SkPath* shape = &fShape;
412 if (shape->isEmpty()) { 411 if (shape->isEmpty()) {
413 shape = nullptr; 412 shape = nullptr;
414 } 413 }
415 fDevice->finishContentEntry(fXfermode, std::move(fDstFormXObject), s hape); 414 fDevice->finishContentEntry(fBlendMode, std::move(fDstFormXObject), shape);
416 } 415 }
417 } 416 }
418 417
419 SkPDFDevice::ContentEntry* entry() { return fContentEntry; } 418 SkPDFDevice::ContentEntry* entry() { return fContentEntry; }
420 419
421 /* Returns true when we explicitly need the shape of the drawing. */ 420 /* Returns true when we explicitly need the shape of the drawing. */
422 bool needShape() { 421 bool needShape() {
423 switch (fXfermode) { 422 switch (fBlendMode) {
424 case SkXfermode::kClear_Mode: 423 case SkBlendMode::kClear:
425 case SkXfermode::kSrc_Mode: 424 case SkBlendMode::kSrc:
426 case SkXfermode::kSrcIn_Mode: 425 case SkBlendMode::kSrcIn:
427 case SkXfermode::kSrcOut_Mode: 426 case SkBlendMode::kSrcOut:
428 case SkXfermode::kDstIn_Mode: 427 case SkBlendMode::kDstIn:
429 case SkXfermode::kDstOut_Mode: 428 case SkBlendMode::kDstOut:
430 case SkXfermode::kSrcATop_Mode: 429 case SkBlendMode::kSrcATop:
431 case SkXfermode::kDstATop_Mode: 430 case SkBlendMode::kDstATop:
432 case SkXfermode::kModulate_Mode: 431 case SkBlendMode::kModulate:
433 return true; 432 return true;
434 default: 433 default:
435 return false; 434 return false;
436 } 435 }
437 } 436 }
438 437
439 /* Returns true unless we only need the shape of the drawing. */ 438 /* Returns true unless we only need the shape of the drawing. */
440 bool needSource() { 439 bool needSource() {
441 if (fXfermode == SkXfermode::kClear_Mode) { 440 if (fBlendMode == SkBlendMode::kClear) {
442 return false; 441 return false;
443 } 442 }
444 return true; 443 return true;
445 } 444 }
446 445
447 /* If the shape is different than the alpha component of the content, then 446 /* If the shape is different than the alpha component of the content, then
448 * setShape should be called with the shape. In particular, images and 447 * setShape should be called with the shape. In particular, images and
449 * devices have rectangular shape. 448 * devices have rectangular shape.
450 */ 449 */
451 void setShape(const SkPath& shape) { 450 void setShape(const SkPath& shape) {
452 fShape = shape; 451 fShape = shape;
453 } 452 }
454 453
455 private: 454 private:
456 SkPDFDevice* fDevice; 455 SkPDFDevice* fDevice;
457 SkPDFDevice::ContentEntry* fContentEntry; 456 SkPDFDevice::ContentEntry* fContentEntry;
458 SkXfermode::Mode fXfermode; 457 SkBlendMode fBlendMode;
459 sk_sp<SkPDFObject> fDstFormXObject; 458 sk_sp<SkPDFObject> fDstFormXObject;
460 SkPath fShape; 459 SkPath fShape;
461 460
462 void init(const SkClipStack* clipStack, const SkRegion& clipRegion, 461 void init(const SkClipStack* clipStack, const SkRegion& clipRegion,
463 const SkMatrix& matrix, const SkPaint& paint, bool hasText) { 462 const SkMatrix& matrix, const SkPaint& paint, bool hasText) {
464 // Shape has to be flatten before we get here. 463 // Shape has to be flatten before we get here.
465 if (matrix.hasPerspective()) { 464 if (matrix.hasPerspective()) {
466 NOT_IMPLEMENTED(!matrix.hasPerspective(), false); 465 NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
467 return; 466 return;
468 } 467 }
469 if (paint.getXfermode()) { 468 fBlendMode = paint.getBlendMode();
470 paint.getXfermode()->asMode(&fXfermode);
471 }
472 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, 469 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion,
473 matrix, paint, hasText, 470 matrix, paint, hasText,
474 &fDstFormXObject); 471 &fDstFormXObject);
475 } 472 }
476 }; 473 };
477 474
478 //////////////////////////////////////////////////////////////////////////////// 475 ////////////////////////////////////////////////////////////////////////////////
479 476
480 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do c, bool flip) 477 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do c, bool flip)
481 : INHERITED(SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()), 478 : INHERITED(SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()),
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 // it back in later. 1697 // it back in later.
1701 this->cleanUp(); // Reset this device to have no content. 1698 this->cleanUp(); // Reset this device to have no content.
1702 this->init(); 1699 this->init();
1703 return xobject; 1700 return xobject;
1704 } 1701 }
1705 1702
1706 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, 1703 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
1707 sk_sp<SkPDFObject> mask, 1704 sk_sp<SkPDFObject> mask,
1708 const SkClipStack* clipStack, 1705 const SkClipStack* clipStack,
1709 const SkRegion& clipRegion, 1706 const SkRegion& clipRegion,
1710 SkXfermode::Mode mode, 1707 SkBlendMode mode,
1711 bool invertClip) { 1708 bool invertClip) {
1712 if (clipRegion.isEmpty() && !invertClip) { 1709 if (clipRegion.isEmpty() && !invertClip) {
1713 return; 1710 return;
1714 } 1711 }
1715 1712
1716 sk_sp<SkPDFDict> sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( 1713 sk_sp<SkPDFDict> sMaskGS = SkPDFGraphicState::GetSMaskGraphicState(
1717 std::move(mask), invertClip, 1714 std::move(mask), invertClip,
1718 SkPDFGraphicState::kAlpha_SMaskMode, fDocument->canon()); 1715 SkPDFGraphicState::kAlpha_SMaskMode, fDocument->canon());
1719 1716
1720 SkMatrix identity; 1717 SkMatrix identity;
1721 identity.reset(); 1718 identity.reset();
1722 SkPaint paint; 1719 SkPaint paint;
1723 paint.setXfermodeMode(mode); 1720 paint.setBlendMode(mode);
1724 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); 1721 ScopedContentEntry content(this, clipStack, clipRegion, identity, paint);
1725 if (!content.entry()) { 1722 if (!content.entry()) {
1726 return; 1723 return;
1727 } 1724 }
1728 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), 1725 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()),
1729 &content.entry()->fContent); 1726 &content.entry()->fContent);
1730 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent); 1727 SkPDFUtils::DrawFormXObject(xObjectIndex, &content.entry()->fContent);
1731 1728
1732 // Call makeNoSmaskGraphicState() instead of 1729 // Call makeNoSmaskGraphicState() instead of
1733 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon 1730 // SkPDFGraphicState::MakeNoSmaskGraphicState so that the canon
(...skipping 24 matching lines...) Expand all
1758 // fExistingClip as a prefix, so start there, then set the clip 1755 // fExistingClip as a prefix, so start there, then set the clip
1759 // to the passed region. 1756 // to the passed region.
1760 synthesizedClipStack = fExistingClipStack; 1757 synthesizedClipStack = fExistingClipStack;
1761 SkPath clipPath; 1758 SkPath clipPath;
1762 clipRegion.getBoundaryPath(&clipPath); 1759 clipRegion.getBoundaryPath(&clipPath);
1763 synthesizedClipStack.clipPath(clipPath, SkMatrix::I(), SkCanvas::kRe place_Op, false); 1760 synthesizedClipStack.clipPath(clipPath, SkMatrix::I(), SkCanvas::kRe place_Op, false);
1764 clipStack = &synthesizedClipStack; 1761 clipStack = &synthesizedClipStack;
1765 } 1762 }
1766 } 1763 }
1767 1764
1768 SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode; 1765 SkBlendMode blendMode = paint.getBlendMode();
1769 if (paint.getXfermode()) {
1770 paint.getXfermode()->asMode(&xfermode);
1771 }
1772 1766
1773 // For the following modes, we want to handle source and destination 1767 // For the following modes, we want to handle source and destination
1774 // separately, so make an object of what's already there. 1768 // separately, so make an object of what's already there.
1775 if (xfermode == SkXfermode::kClear_Mode || 1769 if (blendMode == SkBlendMode::kClear ||
1776 xfermode == SkXfermode::kSrc_Mode || 1770 blendMode == SkBlendMode::kSrc ||
1777 xfermode == SkXfermode::kSrcIn_Mode || 1771 blendMode == SkBlendMode::kSrcIn ||
1778 xfermode == SkXfermode::kDstIn_Mode || 1772 blendMode == SkBlendMode::kDstIn ||
1779 xfermode == SkXfermode::kSrcOut_Mode || 1773 blendMode == SkBlendMode::kSrcOut ||
1780 xfermode == SkXfermode::kDstOut_Mode || 1774 blendMode == SkBlendMode::kDstOut ||
1781 xfermode == SkXfermode::kSrcATop_Mode || 1775 blendMode == SkBlendMode::kSrcATop ||
1782 xfermode == SkXfermode::kDstATop_Mode || 1776 blendMode == SkBlendMode::kDstATop ||
1783 xfermode == SkXfermode::kModulate_Mode) { 1777 blendMode == SkBlendMode::kModulate) {
1784 if (!isContentEmpty()) { 1778 if (!isContentEmpty()) {
1785 *dst = this->makeFormXObjectFromDevice(); 1779 *dst = this->makeFormXObjectFromDevice();
1786 SkASSERT(isContentEmpty()); 1780 SkASSERT(isContentEmpty());
1787 } else if (xfermode != SkXfermode::kSrc_Mode && 1781 } else if (blendMode != SkBlendMode::kSrc &&
1788 xfermode != SkXfermode::kSrcOut_Mode) { 1782 blendMode != SkBlendMode::kSrcOut) {
1789 // Except for Src and SrcOut, if there isn't anything already there, 1783 // Except for Src and SrcOut, if there isn't anything already there,
1790 // then we're done. 1784 // then we're done.
1791 return nullptr; 1785 return nullptr;
1792 } 1786 }
1793 } 1787 }
1794 // TODO(vandebo): Figure out how/if we can handle the following modes: 1788 // TODO(vandebo): Figure out how/if we can handle the following modes:
1795 // Xor, Plus. 1789 // Xor, Plus.
1796 1790
1797 // Dst xfer mode doesn't draw source at all. 1791 // Dst xfer mode doesn't draw source at all.
1798 if (xfermode == SkXfermode::kDst_Mode) { 1792 if (blendMode == SkBlendMode::kDst) {
1799 return nullptr; 1793 return nullptr;
1800 } 1794 }
1801 1795
1802 SkPDFDevice::ContentEntry* entry; 1796 SkPDFDevice::ContentEntry* entry;
1803 if (fContentEntries.back() && fContentEntries.back()->fContent.getOffset() = = 0) { 1797 if (fContentEntries.back() && fContentEntries.back()->fContent.getOffset() = = 0) {
1804 entry = fContentEntries.back(); 1798 entry = fContentEntries.back();
1805 } else if (xfermode != SkXfermode::kDstOver_Mode) { 1799 } else if (blendMode != SkBlendMode::kDstOver) {
1806 entry = fContentEntries.emplace_back(); 1800 entry = fContentEntries.emplace_back();
1807 } else { 1801 } else {
1808 entry = fContentEntries.emplace_front(); 1802 entry = fContentEntries.emplace_front();
1809 } 1803 }
1810 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint, 1804 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint,
1811 hasText, &entry->fState); 1805 hasText, &entry->fState);
1812 return entry; 1806 return entry;
1813 } 1807 }
1814 1808
1815 void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, 1809 void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
1816 sk_sp<SkPDFObject> dst, 1810 sk_sp<SkPDFObject> dst,
1817 SkPath* shape) { 1811 SkPath* shape) {
1818 if (xfermode != SkXfermode::kClear_Mode && 1812 if (blendMode != SkBlendMode::kClear &&
1819 xfermode != SkXfermode::kSrc_Mode && 1813 blendMode != SkBlendMode::kSrc &&
1820 xfermode != SkXfermode::kDstOver_Mode && 1814 blendMode != SkBlendMode::kDstOver &&
1821 xfermode != SkXfermode::kSrcIn_Mode && 1815 blendMode != SkBlendMode::kSrcIn &&
1822 xfermode != SkXfermode::kDstIn_Mode && 1816 blendMode != SkBlendMode::kDstIn &&
1823 xfermode != SkXfermode::kSrcOut_Mode && 1817 blendMode != SkBlendMode::kSrcOut &&
1824 xfermode != SkXfermode::kDstOut_Mode && 1818 blendMode != SkBlendMode::kDstOut &&
1825 xfermode != SkXfermode::kSrcATop_Mode && 1819 blendMode != SkBlendMode::kSrcATop &&
1826 xfermode != SkXfermode::kDstATop_Mode && 1820 blendMode != SkBlendMode::kDstATop &&
1827 xfermode != SkXfermode::kModulate_Mode) { 1821 blendMode != SkBlendMode::kModulate) {
1828 SkASSERT(!dst); 1822 SkASSERT(!dst);
1829 return; 1823 return;
1830 } 1824 }
1831 if (xfermode == SkXfermode::kDstOver_Mode) { 1825 if (blendMode == SkBlendMode::kDstOver) {
1832 SkASSERT(!dst); 1826 SkASSERT(!dst);
1833 if (fContentEntries.front()->fContent.getOffset() == 0) { 1827 if (fContentEntries.front()->fContent.getOffset() == 0) {
1834 // For DstOver, an empty content entry was inserted before the rest 1828 // For DstOver, an empty content entry was inserted before the rest
1835 // of the content entries. If nothing was drawn, it needs to be 1829 // of the content entries. If nothing was drawn, it needs to be
1836 // removed. 1830 // removed.
1837 fContentEntries.pop_front(); 1831 fContentEntries.pop_front();
1838 } 1832 }
1839 return; 1833 return;
1840 } 1834 }
1841 if (!dst) { 1835 if (!dst) {
1842 SkASSERT(xfermode == SkXfermode::kSrc_Mode || 1836 SkASSERT(blendMode == SkBlendMode::kSrc ||
1843 xfermode == SkXfermode::kSrcOut_Mode); 1837 blendMode == SkBlendMode::kSrcOut);
1844 return; 1838 return;
1845 } 1839 }
1846 1840
1847 SkASSERT(dst); 1841 SkASSERT(dst);
1848 SkASSERT(fContentEntries.count() == 1); 1842 SkASSERT(fContentEntries.count() == 1);
1849 // Changing the current content into a form-xobject will destroy the clip 1843 // Changing the current content into a form-xobject will destroy the clip
1850 // objects which is fine since the xobject will already be clipped. However 1844 // objects which is fine since the xobject will already be clipped. However
1851 // if source has shape, we need to clip it too, so a copy of the clip is 1845 // if source has shape, we need to clip it too, so a copy of the clip is
1852 // saved. 1846 // saved.
1853 1847
1854 SkClipStack clipStack = fContentEntries.front()->fState.fClipStack; 1848 SkClipStack clipStack = fContentEntries.front()->fState.fClipStack;
1855 SkRegion clipRegion = fContentEntries.front()->fState.fClipRegion; 1849 SkRegion clipRegion = fContentEntries.front()->fState.fClipRegion;
1856 1850
1857 SkMatrix identity; 1851 SkMatrix identity;
1858 identity.reset(); 1852 identity.reset();
1859 SkPaint stockPaint; 1853 SkPaint stockPaint;
1860 1854
1861 sk_sp<SkPDFObject> srcFormXObject; 1855 sk_sp<SkPDFObject> srcFormXObject;
1862 if (isContentEmpty()) { 1856 if (isContentEmpty()) {
1863 // If nothing was drawn and there's no shape, then the draw was a 1857 // If nothing was drawn and there's no shape, then the draw was a
1864 // no-op, but dst needs to be restored for that to be true. 1858 // no-op, but dst needs to be restored for that to be true.
1865 // If there is shape, then an empty source with Src, SrcIn, SrcOut, 1859 // If there is shape, then an empty source with Src, SrcIn, SrcOut,
1866 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop 1860 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop
1867 // reduces to Dst. 1861 // reduces to Dst.
1868 if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode || 1862 if (shape == nullptr || blendMode == SkBlendMode::kDstOut ||
1869 xfermode == SkXfermode::kSrcATop_Mode) { 1863 blendMode == SkBlendMode::kSrcATop) {
1870 ScopedContentEntry content(this, &fExistingClipStack, 1864 ScopedContentEntry content(this, &fExistingClipStack,
1871 fExistingClipRegion, identity, 1865 fExistingClipRegion, identity,
1872 stockPaint); 1866 stockPaint);
1873 // TODO: addXObjectResource take sk_sp 1867 // TODO: addXObjectResource take sk_sp
1874 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()), 1868 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
1875 &content.entry()->fContent); 1869 &content.entry()->fContent);
1876 return; 1870 return;
1877 } else { 1871 } else {
1878 xfermode = SkXfermode::kClear_Mode; 1872 blendMode = SkBlendMode::kClear;
1879 } 1873 }
1880 } else { 1874 } else {
1881 SkASSERT(fContentEntries.count() == 1); 1875 SkASSERT(fContentEntries.count() == 1);
1882 srcFormXObject = this->makeFormXObjectFromDevice(); 1876 srcFormXObject = this->makeFormXObjectFromDevice();
1883 } 1877 }
1884 1878
1885 // TODO(vandebo) srcFormXObject may contain alpha, but here we want it 1879 // TODO(vandebo) srcFormXObject may contain alpha, but here we want it
1886 // without alpha. 1880 // without alpha.
1887 if (xfermode == SkXfermode::kSrcATop_Mode) { 1881 if (blendMode == SkBlendMode::kSrcATop) {
1888 // TODO(vandebo): In order to properly support SrcATop we have to track 1882 // TODO(vandebo): In order to properly support SrcATop we have to track
1889 // the shape of what's been drawn at all times. It's the intersection of 1883 // the shape of what's been drawn at all times. It's the intersection of
1890 // the non-transparent parts of the device and the outlines (shape) of 1884 // the non-transparent parts of the device and the outlines (shape) of
1891 // all images and devices drawn. 1885 // all images and devices drawn.
1892 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, 1886 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst,
1893 &fExistingClipStack, fExistingClipRegion, 1887 &fExistingClipStack, fExistingClipRegion,
1894 SkXfermode::kSrcOver_Mode, true); 1888 SkBlendMode::kSrcOver, true);
1895 } else { 1889 } else {
1896 if (shape != nullptr) { 1890 if (shape != nullptr) {
1897 // Draw shape into a form-xobject. 1891 // Draw shape into a form-xobject.
1898 SkRasterClip rc(clipRegion); 1892 SkRasterClip rc(clipRegion);
1899 SkDraw d; 1893 SkDraw d;
1900 d.fMatrix = &identity; 1894 d.fMatrix = &identity;
1901 d.fRC = &rc; 1895 d.fRC = &rc;
1902 d.fClipStack = &clipStack; 1896 d.fClipStack = &clipStack;
1903 SkPaint filledPaint; 1897 SkPaint filledPaint;
1904 filledPaint.setColor(SK_ColorBLACK); 1898 filledPaint.setColor(SK_ColorBLACK);
1905 filledPaint.setStyle(SkPaint::kFill_Style); 1899 filledPaint.setStyle(SkPaint::kFill_Style);
1906 this->drawPath(d, *shape, filledPaint, nullptr, true); 1900 this->drawPath(d, *shape, filledPaint, nullptr, true);
1907 drawFormXObjectWithMask(addXObjectResource(dst.get()), 1901 drawFormXObjectWithMask(addXObjectResource(dst.get()),
1908 this->makeFormXObjectFromDevice(), 1902 this->makeFormXObjectFromDevice(),
1909 &fExistingClipStack, fExistingClipRegion, 1903 &fExistingClipStack, fExistingClipRegion,
1910 SkXfermode::kSrcOver_Mode, true); 1904 SkBlendMode::kSrcOver, true);
1911 1905
1912 } else { 1906 } else {
1913 drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObjec t, 1907 drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObjec t,
1914 &fExistingClipStack, fExistingClipRegion, 1908 &fExistingClipStack, fExistingClipRegion,
1915 SkXfermode::kSrcOver_Mode, true); 1909 SkBlendMode::kSrcOver, true);
1916 } 1910 }
1917 } 1911 }
1918 1912
1919 if (xfermode == SkXfermode::kClear_Mode) { 1913 if (blendMode == SkBlendMode::kClear) {
1920 return; 1914 return;
1921 } else if (xfermode == SkXfermode::kSrc_Mode || 1915 } else if (blendMode == SkBlendMode::kSrc ||
1922 xfermode == SkXfermode::kDstATop_Mode) { 1916 blendMode == SkBlendMode::kDstATop) {
1923 ScopedContentEntry content(this, &fExistingClipStack, 1917 ScopedContentEntry content(this, &fExistingClipStack,
1924 fExistingClipRegion, identity, stockPaint); 1918 fExistingClipRegion, identity, stockPaint);
1925 if (content.entry()) { 1919 if (content.entry()) {
1926 SkPDFUtils::DrawFormXObject( 1920 SkPDFUtils::DrawFormXObject(
1927 this->addXObjectResource(srcFormXObject.get()), 1921 this->addXObjectResource(srcFormXObject.get()),
1928 &content.entry()->fContent); 1922 &content.entry()->fContent);
1929 } 1923 }
1930 if (xfermode == SkXfermode::kSrc_Mode) { 1924 if (blendMode == SkBlendMode::kSrc) {
1931 return; 1925 return;
1932 } 1926 }
1933 } else if (xfermode == SkXfermode::kSrcATop_Mode) { 1927 } else if (blendMode == SkBlendMode::kSrcATop) {
1934 ScopedContentEntry content(this, &fExistingClipStack, 1928 ScopedContentEntry content(this, &fExistingClipStack,
1935 fExistingClipRegion, identity, stockPaint); 1929 fExistingClipRegion, identity, stockPaint);
1936 if (content.entry()) { 1930 if (content.entry()) {
1937 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()), 1931 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
1938 &content.entry()->fContent); 1932 &content.entry()->fContent);
1939 } 1933 }
1940 } 1934 }
1941 1935
1942 SkASSERT(xfermode == SkXfermode::kSrcIn_Mode || 1936 SkASSERT(blendMode == SkBlendMode::kSrcIn ||
1943 xfermode == SkXfermode::kDstIn_Mode || 1937 blendMode == SkBlendMode::kDstIn ||
1944 xfermode == SkXfermode::kSrcOut_Mode || 1938 blendMode == SkBlendMode::kSrcOut ||
1945 xfermode == SkXfermode::kDstOut_Mode || 1939 blendMode == SkBlendMode::kDstOut ||
1946 xfermode == SkXfermode::kSrcATop_Mode || 1940 blendMode == SkBlendMode::kSrcATop ||
1947 xfermode == SkXfermode::kDstATop_Mode || 1941 blendMode == SkBlendMode::kDstATop ||
1948 xfermode == SkXfermode::kModulate_Mode); 1942 blendMode == SkBlendMode::kModulate);
1949 1943
1950 if (xfermode == SkXfermode::kSrcIn_Mode || 1944 if (blendMode == SkBlendMode::kSrcIn ||
1951 xfermode == SkXfermode::kSrcOut_Mode || 1945 blendMode == SkBlendMode::kSrcOut ||
1952 xfermode == SkXfermode::kSrcATop_Mode) { 1946 blendMode == SkBlendMode::kSrcATop) {
1953 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), 1947 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
1954 std::move(dst), 1948 std::move(dst),
1955 &fExistingClipStack, fExistingClipRegion, 1949 &fExistingClipStack, fExistingClipRegion,
1956 SkXfermode::kSrcOver_Mode, 1950 SkBlendMode::kSrcOver,
1957 xfermode == SkXfermode::kSrcOut_Mode); 1951 blendMode == SkBlendMode::kSrcOut);
1958 return; 1952 return;
1959 } else { 1953 } else {
1960 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode; 1954 SkBlendMode mode = SkBlendMode::kSrcOver;
1961 int resourceID = addXObjectResource(dst.get()); 1955 int resourceID = addXObjectResource(dst.get());
1962 if (xfermode == SkXfermode::kModulate_Mode) { 1956 if (blendMode == SkBlendMode::kModulate) {
1963 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), 1957 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
1964 std::move(dst), &fExistingClipStack, 1958 std::move(dst), &fExistingClipStack,
1965 fExistingClipRegion, 1959 fExistingClipRegion,
1966 SkXfermode::kSrcOver_Mode, false); 1960 SkBlendMode::kSrcOver, false);
1967 mode = SkXfermode::kMultiply_Mode; 1961 mode = SkBlendMode::kMultiply;
1968 } 1962 }
1969 drawFormXObjectWithMask(resourceID, std::move(srcFormXObject), 1963 drawFormXObjectWithMask(resourceID, std::move(srcFormXObject),
1970 &fExistingClipStack, fExistingClipRegion, mode, 1964 &fExistingClipStack, fExistingClipRegion, mode,
1971 xfermode == SkXfermode::kDstOut_Mode); 1965 blendMode == SkBlendMode::kDstOut);
1972 return; 1966 return;
1973 } 1967 }
1974 } 1968 }
1975 1969
1976 bool SkPDFDevice::isContentEmpty() { 1970 bool SkPDFDevice::isContentEmpty() {
1977 if (!fContentEntries.front() || fContentEntries.front()->fContent.getOffset( ) == 0) { 1971 if (!fContentEntries.front() || fContentEntries.front()->fContent.getOffset( ) == 0) {
1978 SkASSERT(fContentEntries.count() <= 1); 1972 SkASSERT(fContentEntries.count() <= 1);
1979 return true; 1973 return true;
1980 } 1974 }
1981 return false; 1975 return false;
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 2316
2323 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { 2317 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() {
2324 return nullptr; 2318 return nullptr;
2325 } 2319 }
2326 2320
2327 SkImageFilterCache* SkPDFDevice::getImageFilterCache() { 2321 SkImageFilterCache* SkPDFDevice::getImageFilterCache() {
2328 // We always return a transient cache, so it is freed after each 2322 // We always return a transient cache, so it is freed after each
2329 // filter traversal. 2323 // filter traversal.
2330 return SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize) ; 2324 return SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize) ;
2331 } 2325 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | src/pdf/SkPDFGraphicState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698