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

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

Issue 2185803003: SkPdf: SkPDFFormXObject de-class-ified. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2016-07-27 (Wednesday) 15:31:16 EDT 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 /* 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 #include "SkAnnotationKeys.h" 9 #include "SkAnnotationKeys.h"
10 #include "SkBitmapDevice.h" 10 #include "SkBitmapDevice.h"
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 * devices have rectangular shape. 620 * devices have rectangular shape.
621 */ 621 */
622 void setShape(const SkPath& shape) { 622 void setShape(const SkPath& shape) {
623 fShape = shape; 623 fShape = shape;
624 } 624 }
625 625
626 private: 626 private:
627 SkPDFDevice* fDevice; 627 SkPDFDevice* fDevice;
628 SkPDFDevice::ContentEntry* fContentEntry; 628 SkPDFDevice::ContentEntry* fContentEntry;
629 SkXfermode::Mode fXfermode; 629 SkXfermode::Mode fXfermode;
630 SkPDFFormXObject* fDstFormXObject; 630 SkPDFObject* fDstFormXObject;
631 SkPath fShape; 631 SkPath fShape;
632 632
633 void init(const SkClipStack* clipStack, const SkRegion& clipRegion, 633 void init(const SkClipStack* clipStack, const SkRegion& clipRegion,
634 const SkMatrix& matrix, const SkPaint& paint, bool hasText) { 634 const SkMatrix& matrix, const SkPaint& paint, bool hasText) {
635 // Shape has to be flatten before we get here. 635 // Shape has to be flatten before we get here.
636 if (matrix.hasPerspective()) { 636 if (matrix.hasPerspective()) {
637 NOT_IMPLEMENTED(!matrix.hasPerspective(), false); 637 NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
638 return; 638 return;
639 } 639 }
640 if (paint.getXfermode()) { 640 if (paint.getXfermode()) {
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 SkPath shape; 1387 SkPath shape;
1388 shape.addRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), 1388 shape.addRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
1389 SkIntToScalar(device->width()), 1389 SkIntToScalar(device->width()),
1390 SkIntToScalar(device->height()))); 1390 SkIntToScalar(device->height())));
1391 content.setShape(shape); 1391 content.setShape(shape);
1392 } 1392 }
1393 if (!content.needSource()) { 1393 if (!content.needSource()) {
1394 return; 1394 return;
1395 } 1395 }
1396 1396
1397 auto xObject = sk_make_sp<SkPDFFormXObject>(pdfDevice); 1397 auto xObject = pdfDevice->makeFormXObjectFromDevice();
1398 SkPDFUtils::DrawFormXObject(this->addXObjectResource(xObject.get()), 1398 SkPDFUtils::DrawFormXObject(this->addXObjectResource(xObject.get()),
1399 &content.entry()->fContent); 1399 &content.entry()->fContent);
1400 } 1400 }
1401 1401
1402 SkImageInfo SkPDFDevice::imageInfo() const { 1402 SkImageInfo SkPDFDevice::imageInfo() const {
1403 SkImageInfo info = SkImageInfo::MakeUnknown(fPageSize.width(), fPageSize.hei ght()); 1403 SkImageInfo info = SkImageInfo::MakeUnknown(fPageSize.width(), fPageSize.hei ght());
1404 return info; 1404 return info;
1405 } 1405 }
1406 1406
1407 sk_sp<SkSurface> SkPDFDevice::makeSurface(const SkImageInfo& info, const SkSurfa ceProps& props) { 1407 sk_sp<SkSurface> SkPDFDevice::makeSurface(const SkImageInfo& info, const SkSurfa ceProps& props) {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 pdfDest->appendName("XYZ"); 1603 pdfDest->appendName("XYZ");
1604 SkPoint p = fInitialTransform.mapXY(dest.point.x(), dest.point.y()); 1604 SkPoint p = fInitialTransform.mapXY(dest.point.x(), dest.point.y());
1605 pdfDest->appendScalar(p.x()); 1605 pdfDest->appendScalar(p.x());
1606 pdfDest->appendScalar(p.y()); 1606 pdfDest->appendScalar(p.y());
1607 pdfDest->appendInt(0); // Leave zoom unchanged 1607 pdfDest->appendInt(0); // Leave zoom unchanged
1608 SkString name(static_cast<const char*>(dest.nameData->data())); 1608 SkString name(static_cast<const char*>(dest.nameData->data()));
1609 dict->insertObject(name, std::move(pdfDest)); 1609 dict->insertObject(name, std::move(pdfDest));
1610 } 1610 }
1611 } 1611 }
1612 1612
1613 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { 1613 sk_sp<SkPDFObject> SkPDFDevice::makeFormXObjectFromDevice() {
1614 SkPDFFormXObject* xobject = new SkPDFFormXObject(this); 1614 auto xobject = SkPDFMakeFormXObject(this->content(),
1615 this->copyMediaBox(),
1616 this->makeResourceDict(),
1617 nullptr);
tomhudson 2016/07/27 20:30:58 I don't like this because I have to read both forw
hal.canary 2016/07/27 20:41:11 Done.
1615 // We always draw the form xobjects that we create back into the device, so 1618 // We always draw the form xobjects that we create back into the device, so
1616 // we simply preserve the font usage instead of pulling it out and merging 1619 // we simply preserve the font usage instead of pulling it out and merging
1617 // it back in later. 1620 // it back in later.
1618 cleanUp(); // Reset this device to have no content. 1621 cleanUp(); // Reset this device to have no content.
1619 init(); 1622 init();
1620 return xobject; 1623 return xobject;
1621 } 1624 }
1622 1625
1623 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, 1626 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
1624 SkPDFFormXObject* mask, 1627 SkPDFObject* mask,
1625 const SkClipStack* clipStack, 1628 const SkClipStack* clipStack,
1626 const SkRegion& clipRegion, 1629 const SkRegion& clipRegion,
1627 SkXfermode::Mode mode, 1630 SkXfermode::Mode mode,
1628 bool invertClip) { 1631 bool invertClip) {
1629 if (clipRegion.isEmpty() && !invertClip) { 1632 if (clipRegion.isEmpty() && !invertClip) {
1630 return; 1633 return;
1631 } 1634 }
1632 1635
1633 auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState( 1636 auto sMaskGS = SkPDFGraphicState::GetSMaskGraphicState(
1634 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fDocument->ca non()); 1637 mask, invertClip, SkPDFGraphicState::kAlpha_SMaskMode, fDocument->ca non());
(...skipping 16 matching lines...) Expand all
1651 sMaskGS = fDocument->canon()->makeNoSmaskGraphicState(); 1654 sMaskGS = fDocument->canon()->makeNoSmaskGraphicState();
1652 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()), 1655 SkPDFUtils::ApplyGraphicState(addGraphicStateResource(sMaskGS.get()),
1653 &content.entry()->fContent); 1656 &content.entry()->fContent);
1654 } 1657 }
1655 1658
1656 SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli pStack, 1659 SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli pStack,
1657 const SkRegion& clipRegion, 1660 const SkRegion& clipRegion,
1658 const SkMatrix& matrix, 1661 const SkMatrix& matrix,
1659 const SkPaint& paint, 1662 const SkPaint& paint,
1660 bool hasText, 1663 bool hasText,
1661 SkPDFFormXObject** dst) { 1664 SkPDFObject** dst) {
1662 *dst = nullptr; 1665 *dst = nullptr;
1663 if (clipRegion.isEmpty()) { 1666 if (clipRegion.isEmpty()) {
1664 return nullptr; 1667 return nullptr;
1665 } 1668 }
1666 1669
1667 // The clip stack can come from an SkDraw where it is technically optional. 1670 // The clip stack can come from an SkDraw where it is technically optional.
1668 SkClipStack synthesizedClipStack; 1671 SkClipStack synthesizedClipStack;
1669 if (clipStack == nullptr) { 1672 if (clipStack == nullptr) {
1670 if (clipRegion == fExistingClipRegion) { 1673 if (clipRegion == fExistingClipRegion) {
1671 clipStack = &fExistingClipStack; 1674 clipStack = &fExistingClipStack;
(...skipping 20 matching lines...) Expand all
1692 if (xfermode == SkXfermode::kClear_Mode || 1695 if (xfermode == SkXfermode::kClear_Mode ||
1693 xfermode == SkXfermode::kSrc_Mode || 1696 xfermode == SkXfermode::kSrc_Mode ||
1694 xfermode == SkXfermode::kSrcIn_Mode || 1697 xfermode == SkXfermode::kSrcIn_Mode ||
1695 xfermode == SkXfermode::kDstIn_Mode || 1698 xfermode == SkXfermode::kDstIn_Mode ||
1696 xfermode == SkXfermode::kSrcOut_Mode || 1699 xfermode == SkXfermode::kSrcOut_Mode ||
1697 xfermode == SkXfermode::kDstOut_Mode || 1700 xfermode == SkXfermode::kDstOut_Mode ||
1698 xfermode == SkXfermode::kSrcATop_Mode || 1701 xfermode == SkXfermode::kSrcATop_Mode ||
1699 xfermode == SkXfermode::kDstATop_Mode || 1702 xfermode == SkXfermode::kDstATop_Mode ||
1700 xfermode == SkXfermode::kModulate_Mode) { 1703 xfermode == SkXfermode::kModulate_Mode) {
1701 if (!isContentEmpty()) { 1704 if (!isContentEmpty()) {
1702 *dst = createFormXObjectFromDevice(); 1705 // TODO(halcanary): make this safer.
1706 *dst = this->makeFormXObjectFromDevice().release();
tomhudson 2016/07/27 20:30:58 Note TODO
hal.canary 2016/07/27 20:41:11 Acknowledged.
1703 SkASSERT(isContentEmpty()); 1707 SkASSERT(isContentEmpty());
1704 } else if (xfermode != SkXfermode::kSrc_Mode && 1708 } else if (xfermode != SkXfermode::kSrc_Mode &&
1705 xfermode != SkXfermode::kSrcOut_Mode) { 1709 xfermode != SkXfermode::kSrcOut_Mode) {
1706 // Except for Src and SrcOut, if there isn't anything already there, 1710 // Except for Src and SrcOut, if there isn't anything already there,
1707 // then we're done. 1711 // then we're done.
1708 return nullptr; 1712 return nullptr;
1709 } 1713 }
1710 } 1714 }
1711 // TODO(vandebo): Figure out how/if we can handle the following modes: 1715 // TODO(vandebo): Figure out how/if we can handle the following modes:
1712 // Xor, Plus. 1716 // Xor, Plus.
(...skipping 10 matching lines...) Expand all
1723 entry = fContentEntries.emplace_back(); 1727 entry = fContentEntries.emplace_back();
1724 } else { 1728 } else {
1725 entry = fContentEntries.emplace_front(); 1729 entry = fContentEntries.emplace_front();
1726 } 1730 }
1727 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint, 1731 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint,
1728 hasText, &entry->fState); 1732 hasText, &entry->fState);
1729 return entry; 1733 return entry;
1730 } 1734 }
1731 1735
1732 void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, 1736 void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
1733 SkPDFFormXObject* dst, 1737 SkPDFObject* dst,
1734 SkPath* shape) { 1738 SkPath* shape) {
1735 if (xfermode != SkXfermode::kClear_Mode && 1739 if (xfermode != SkXfermode::kClear_Mode &&
1736 xfermode != SkXfermode::kSrc_Mode && 1740 xfermode != SkXfermode::kSrc_Mode &&
1737 xfermode != SkXfermode::kDstOver_Mode && 1741 xfermode != SkXfermode::kDstOver_Mode &&
1738 xfermode != SkXfermode::kSrcIn_Mode && 1742 xfermode != SkXfermode::kSrcIn_Mode &&
1739 xfermode != SkXfermode::kDstIn_Mode && 1743 xfermode != SkXfermode::kDstIn_Mode &&
1740 xfermode != SkXfermode::kSrcOut_Mode && 1744 xfermode != SkXfermode::kSrcOut_Mode &&
1741 xfermode != SkXfermode::kDstOut_Mode && 1745 xfermode != SkXfermode::kDstOut_Mode &&
1742 xfermode != SkXfermode::kSrcATop_Mode && 1746 xfermode != SkXfermode::kSrcATop_Mode &&
1743 xfermode != SkXfermode::kDstATop_Mode && 1747 xfermode != SkXfermode::kDstATop_Mode &&
(...skipping 24 matching lines...) Expand all
1768 // if source has shape, we need to clip it too, so a copy of the clip is 1772 // if source has shape, we need to clip it too, so a copy of the clip is
1769 // saved. 1773 // saved.
1770 1774
1771 SkClipStack clipStack = fContentEntries.front()->fState.fClipStack; 1775 SkClipStack clipStack = fContentEntries.front()->fState.fClipStack;
1772 SkRegion clipRegion = fContentEntries.front()->fState.fClipRegion; 1776 SkRegion clipRegion = fContentEntries.front()->fState.fClipRegion;
1773 1777
1774 SkMatrix identity; 1778 SkMatrix identity;
1775 identity.reset(); 1779 identity.reset();
1776 SkPaint stockPaint; 1780 SkPaint stockPaint;
1777 1781
1778 sk_sp<SkPDFFormXObject> srcFormXObject; 1782 sk_sp<SkPDFObject> srcFormXObject;
1779 if (isContentEmpty()) { 1783 if (isContentEmpty()) {
1780 // If nothing was drawn and there's no shape, then the draw was a 1784 // If nothing was drawn and there's no shape, then the draw was a
1781 // no-op, but dst needs to be restored for that to be true. 1785 // no-op, but dst needs to be restored for that to be true.
1782 // If there is shape, then an empty source with Src, SrcIn, SrcOut, 1786 // If there is shape, then an empty source with Src, SrcIn, SrcOut,
1783 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop 1787 // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop
1784 // reduces to Dst. 1788 // reduces to Dst.
1785 if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode || 1789 if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode ||
1786 xfermode == SkXfermode::kSrcATop_Mode) { 1790 xfermode == SkXfermode::kSrcATop_Mode) {
1787 ScopedContentEntry content(this, &fExistingClipStack, 1791 ScopedContentEntry content(this, &fExistingClipStack,
1788 fExistingClipRegion, identity, 1792 fExistingClipRegion, identity,
1789 stockPaint); 1793 stockPaint);
1790 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst), 1794 SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst),
1791 &content.entry()->fContent); 1795 &content.entry()->fContent);
1792 return; 1796 return;
1793 } else { 1797 } else {
1794 xfermode = SkXfermode::kClear_Mode; 1798 xfermode = SkXfermode::kClear_Mode;
1795 } 1799 }
1796 } else { 1800 } else {
1797 SkASSERT(fContentEntries.count() == 1); 1801 SkASSERT(fContentEntries.count() == 1);
1798 srcFormXObject.reset(createFormXObjectFromDevice()); 1802 srcFormXObject = this->makeFormXObjectFromDevice();
1799 } 1803 }
1800 1804
1801 // TODO(vandebo) srcFormXObject may contain alpha, but here we want it 1805 // TODO(vandebo) srcFormXObject may contain alpha, but here we want it
1802 // without alpha. 1806 // without alpha.
1803 if (xfermode == SkXfermode::kSrcATop_Mode) { 1807 if (xfermode == SkXfermode::kSrcATop_Mode) {
1804 // TODO(vandebo): In order to properly support SrcATop we have to track 1808 // TODO(vandebo): In order to properly support SrcATop we have to track
1805 // the shape of what's been drawn at all times. It's the intersection of 1809 // the shape of what's been drawn at all times. It's the intersection of
1806 // the non-transparent parts of the device and the outlines (shape) of 1810 // the non-transparent parts of the device and the outlines (shape) of
1807 // all images and devices drawn. 1811 // all images and devices drawn.
1808 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, 1812 drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst,
1809 &fExistingClipStack, fExistingClipRegion, 1813 &fExistingClipStack, fExistingClipRegion,
1810 SkXfermode::kSrcOver_Mode, true); 1814 SkXfermode::kSrcOver_Mode, true);
1811 } else { 1815 } else {
1812 sk_sp<SkPDFFormXObject> dstMaskStorage; 1816 sk_sp<SkPDFObject> dstMaskStorage;
1813 SkPDFFormXObject* dstMask = srcFormXObject.get(); 1817 SkPDFObject* dstMask = srcFormXObject.get();
1814 if (shape != nullptr) { 1818 if (shape != nullptr) {
1815 // Draw shape into a form-xobject. 1819 // Draw shape into a form-xobject.
1816 SkRasterClip rc(clipRegion); 1820 SkRasterClip rc(clipRegion);
1817 SkDraw d; 1821 SkDraw d;
1818 d.fMatrix = &identity; 1822 d.fMatrix = &identity;
1819 d.fRC = &rc; 1823 d.fRC = &rc;
1820 d.fClipStack = &clipStack; 1824 d.fClipStack = &clipStack;
1821 SkPaint filledPaint; 1825 SkPaint filledPaint;
1822 filledPaint.setColor(SK_ColorBLACK); 1826 filledPaint.setColor(SK_ColorBLACK);
1823 filledPaint.setStyle(SkPaint::kFill_Style); 1827 filledPaint.setStyle(SkPaint::kFill_Style);
1824 this->drawPath(d, *shape, filledPaint, nullptr, true); 1828 this->drawPath(d, *shape, filledPaint, nullptr, true);
1825 1829
1826 dstMaskStorage.reset(createFormXObjectFromDevice()); 1830 dstMaskStorage = this->makeFormXObjectFromDevice();
1827 dstMask = dstMaskStorage.get(); 1831 dstMask = dstMaskStorage.get();
1828 } 1832 }
1829 drawFormXObjectWithMask(addXObjectResource(dst), dstMask, 1833 drawFormXObjectWithMask(addXObjectResource(dst), dstMask,
1830 &fExistingClipStack, fExistingClipRegion, 1834 &fExistingClipStack, fExistingClipRegion,
1831 SkXfermode::kSrcOver_Mode, true); 1835 SkXfermode::kSrcOver_Mode, true);
1832 } 1836 }
1833 1837
1834 if (xfermode == SkXfermode::kClear_Mode) { 1838 if (xfermode == SkXfermode::kClear_Mode) {
1835 return; 1839 return;
1836 } else if (xfermode == SkXfermode::kSrc_Mode || 1840 } else if (xfermode == SkXfermode::kSrc_Mode ||
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 } 2245 }
2242 2246
2243 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) { 2247 sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) {
2244 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image-> height()), 2248 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(image->width(), image-> height()),
2245 image->makeNonTextureImage()); 2249 image->makeNonTextureImage());
2246 } 2250 }
2247 2251
2248 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() { 2252 sk_sp<SkSpecialImage> SkPDFDevice::snapSpecial() {
2249 return nullptr; 2253 return nullptr;
2250 } 2254 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | src/pdf/SkPDFFormXObject.h » ('j') | src/pdf/SkPDFFormXObject.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698