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

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

Issue 1837453003: SkPDF: remove margin foolishness (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 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') | 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 /* 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 "SkAnnotationKeys.h" 10 #include "SkAnnotationKeys.h"
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 }; 700 };
701 701
702 //////////////////////////////////////////////////////////////////////////////// 702 ////////////////////////////////////////////////////////////////////////////////
703 703
704 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do c, bool flip) 704 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* do c, bool flip)
705 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) 705 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry))
706 , fPageSize(pageSize) 706 , fPageSize(pageSize)
707 , fContentSize(pageSize) 707 , fContentSize(pageSize)
708 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) 708 , fExistingClipRegion(SkIRect::MakeSize(pageSize))
709 , fLastContentEntry(nullptr) 709 , fLastContentEntry(nullptr)
710 , fLastMarginContentEntry(nullptr)
711 , fDrawingArea(kContent_DrawingArea)
712 , fClipStack(nullptr) 710 , fClipStack(nullptr)
713 , fFontGlyphUsage(new SkPDFGlyphSetMap) 711 , fFontGlyphUsage(new SkPDFGlyphSetMap)
714 , fRasterDpi(rasterDpi) 712 , fRasterDpi(rasterDpi)
715 , fDocument(doc) { 713 , fDocument(doc) {
716 SkASSERT(pageSize.width() > 0); 714 SkASSERT(pageSize.width() > 0);
717 SkASSERT(pageSize.height() > 0); 715 SkASSERT(pageSize.height() > 0);
718 fLegacyBitmap.setInfo( 716 fLegacyBitmap.setInfo(
719 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); 717 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()));
720 if (flip) { 718 if (flip) {
721 // Skia generally uses the top left as the origin but PDF 719 // Skia generally uses the top left as the origin but PDF
722 // natively has the origin at the bottom left. This matrix 720 // natively has the origin at the bottom left. This matrix
723 // corrects for that. But that only needs to be done once, we 721 // corrects for that. But that only needs to be done once, we
724 // don't do it when layering. 722 // don't do it when layering.
725 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); 723 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight));
726 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); 724 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
727 } else { 725 } else {
728 fInitialTransform.setIdentity(); 726 fInitialTransform.setIdentity();
729 } 727 }
730 } 728 }
731 729
732 SkPDFDevice::~SkPDFDevice() { 730 SkPDFDevice::~SkPDFDevice() {
733 this->cleanUp(true); 731 this->cleanUp(true);
734 } 732 }
735 733
736 void SkPDFDevice::init() { 734 void SkPDFDevice::init() {
737 fContentEntries.reset(); 735 fContentEntries.reset();
738 fLastContentEntry = nullptr; 736 fLastContentEntry = nullptr;
739 fMarginContentEntries.reset();
740 fLastMarginContentEntry = nullptr;
741 fDrawingArea = kContent_DrawingArea;
742 if (fFontGlyphUsage.get() == nullptr) { 737 if (fFontGlyphUsage.get() == nullptr) {
743 fFontGlyphUsage.reset(new SkPDFGlyphSetMap); 738 fFontGlyphUsage.reset(new SkPDFGlyphSetMap);
744 } 739 }
745 } 740 }
746 741
747 void SkPDFDevice::cleanUp(bool clearFontUsage) { 742 void SkPDFDevice::cleanUp(bool clearFontUsage) {
748 fGraphicStateResources.unrefAll(); 743 fGraphicStateResources.unrefAll();
749 fXObjectResources.unrefAll(); 744 fXObjectResources.unrefAll();
750 fFontResources.unrefAll(); 745 fFontResources.unrefAll();
751 fShaderResources.unrefAll(); 746 fShaderResources.unrefAll();
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 void SkPDFDevice::onDetachFromCanvas() { 1397 void SkPDFDevice::onDetachFromCanvas() {
1403 INHERITED::onDetachFromCanvas(); 1398 INHERITED::onDetachFromCanvas();
1404 1399
1405 fClipStack = nullptr; 1400 fClipStack = nullptr;
1406 } 1401 }
1407 1402
1408 sk_sp<SkSurface> SkPDFDevice::makeSurface(const SkImageInfo& info, const SkSurfa ceProps& props) { 1403 sk_sp<SkSurface> SkPDFDevice::makeSurface(const SkImageInfo& info, const SkSurfa ceProps& props) {
1409 return SkSurface::MakeRaster(info, &props); 1404 return SkSurface::MakeRaster(info, &props);
1410 } 1405 }
1411 1406
1412 ContentEntry* SkPDFDevice::getLastContentEntry() {
1413 if (fDrawingArea == kContent_DrawingArea) {
1414 return fLastContentEntry;
1415 } else {
1416 return fLastMarginContentEntry;
1417 }
1418 }
1419
1420 SkAutoTDelete<ContentEntry>* SkPDFDevice::getContentEntries() {
1421 if (fDrawingArea == kContent_DrawingArea) {
1422 return &fContentEntries;
1423 } else {
1424 return &fMarginContentEntries;
1425 }
1426 }
1427
1428 void SkPDFDevice::setLastContentEntry(ContentEntry* contentEntry) {
1429 if (fDrawingArea == kContent_DrawingArea) {
1430 fLastContentEntry = contentEntry;
1431 } else {
1432 fLastMarginContentEntry = contentEntry;
1433 }
1434 }
1435
1436 void SkPDFDevice::setDrawingArea(DrawingArea drawingArea) {
1437 // A ScopedContentEntry only exists during the course of a draw call, so
1438 // this can't be called while a ScopedContentEntry exists.
1439 fDrawingArea = drawingArea;
1440 }
1441 1407
1442 sk_sp<SkPDFDict> SkPDFDevice::makeResourceDict() const { 1408 sk_sp<SkPDFDict> SkPDFDevice::makeResourceDict() const {
1443 SkTDArray<SkPDFObject*> fonts; 1409 SkTDArray<SkPDFObject*> fonts;
1444 fonts.setReserve(fFontResources.count()); 1410 fonts.setReserve(fFontResources.count());
1445 for (SkPDFFont* font : fFontResources) { 1411 for (SkPDFFont* font : fFontResources) {
1446 fonts.push(font); 1412 fonts.push(font);
1447 } 1413 }
1448 return SkPDFResourceDict::Make( 1414 return SkPDFResourceDict::Make(
1449 &fGraphicStateResources, 1415 &fGraphicStateResources,
1450 &fShaderResources, 1416 &fShaderResources,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 entry = entry->fNext.get(); 1459 entry = entry->fNext.get();
1494 } 1460 }
1495 gsState.drainStack(); 1461 gsState.drainStack();
1496 } 1462 }
1497 1463
1498 void SkPDFDevice::writeContent(SkWStream* out) const { 1464 void SkPDFDevice::writeContent(SkWStream* out) const {
1499 if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) { 1465 if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) {
1500 SkPDFUtils::AppendTransform(fInitialTransform, out); 1466 SkPDFUtils::AppendTransform(fInitialTransform, out);
1501 } 1467 }
1502 1468
1503 // TODO(aayushkumar): Apply clip along the margins. Currently, webkit
1504 // colors the contentArea white before it starts drawing into it and
1505 // that currently acts as our clip.
1506 // Also, think about adding a transform here (or assume that the values
1507 // sent across account for that)
1508 SkPDFDevice::copyContentEntriesToData(fMarginContentEntries.get(), out);
1509
1510 // If the content area is the entire page, then we don't need to clip 1469 // If the content area is the entire page, then we don't need to clip
1511 // the content area (PDF area clips to the page size). Otherwise, 1470 // the content area (PDF area clips to the page size). Otherwise,
1512 // we have to clip to the content area; we've already applied the 1471 // we have to clip to the content area; we've already applied the
1513 // initial transform, so just clip to the device size. 1472 // initial transform, so just clip to the device size.
1514 if (fPageSize != fContentSize) { 1473 if (fPageSize != fContentSize) {
1515 SkRect r = SkRect::MakeWH(SkIntToScalar(this->width()), 1474 SkRect r = SkRect::MakeWH(SkIntToScalar(this->width()),
1516 SkIntToScalar(this->height())); 1475 SkIntToScalar(this->height()));
1517 emit_clip(nullptr, &r, out); 1476 emit_clip(nullptr, &r, out);
1518 } 1477 }
1519 1478
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 // Xor, Plus. 1716 // Xor, Plus.
1758 1717
1759 // Dst xfer mode doesn't draw source at all. 1718 // Dst xfer mode doesn't draw source at all.
1760 if (xfermode == SkXfermode::kDst_Mode) { 1719 if (xfermode == SkXfermode::kDst_Mode) {
1761 return nullptr; 1720 return nullptr;
1762 } 1721 }
1763 1722
1764 ContentEntry* entry; 1723 ContentEntry* entry;
1765 SkAutoTDelete<ContentEntry> newEntry; 1724 SkAutoTDelete<ContentEntry> newEntry;
1766 1725
1767 ContentEntry* lastContentEntry = getLastContentEntry(); 1726 if (fLastContentEntry && fLastContentEntry->fContent.getOffset() == 0) {
1768 if (lastContentEntry && lastContentEntry->fContent.getOffset() == 0) { 1727 entry = fLastContentEntry;
1769 entry = lastContentEntry;
1770 } else { 1728 } else {
1771 newEntry.reset(new ContentEntry); 1729 newEntry.reset(new ContentEntry);
1772 entry = newEntry.get(); 1730 entry = newEntry.get();
1773 } 1731 }
1774 1732
1775 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint, 1733 populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint,
1776 hasText, &entry->fState); 1734 hasText, &entry->fState);
1777 if (lastContentEntry && xfermode != SkXfermode::kDstOver_Mode && 1735 if (fLastContentEntry && xfermode != SkXfermode::kDstOver_Mode &&
1778 entry->fState.compareInitialState(lastContentEntry->fState)) { 1736 entry->fState.compareInitialState(fLastContentEntry->fState)) {
1779 return lastContentEntry; 1737 return fLastContentEntry;
1780 } 1738 }
1781 1739
1782 SkAutoTDelete<ContentEntry>* contentEntries = getContentEntries(); 1740 if (!fLastContentEntry) {
1783 if (!lastContentEntry) { 1741 fContentEntries.reset(entry);
1784 contentEntries->reset(entry); 1742 fLastContentEntry = entry;
1785 setLastContentEntry(entry);
1786 } else if (xfermode == SkXfermode::kDstOver_Mode) { 1743 } else if (xfermode == SkXfermode::kDstOver_Mode) {
1787 entry->fNext.reset(contentEntries->release()); 1744 entry->fNext.reset(fContentEntries.release());
1788 contentEntries->reset(entry); 1745 fContentEntries.reset(entry);
1789 } else { 1746 } else {
1790 lastContentEntry->fNext.reset(entry); 1747 fLastContentEntry->fNext.reset(entry);
1791 setLastContentEntry(entry); 1748 fLastContentEntry = entry;
1792 } 1749 }
1793 newEntry.release(); 1750 newEntry.release();
1794 return entry; 1751 return entry;
1795 } 1752 }
1796 1753
1797 void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, 1754 void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
1798 SkPDFFormXObject* dst, 1755 SkPDFFormXObject* dst,
1799 SkPath* shape) { 1756 SkPath* shape) {
1800 if (xfermode != SkXfermode::kClear_Mode && 1757 if (xfermode != SkXfermode::kClear_Mode &&
1801 xfermode != SkXfermode::kSrc_Mode && 1758 xfermode != SkXfermode::kSrc_Mode &&
1802 xfermode != SkXfermode::kDstOver_Mode && 1759 xfermode != SkXfermode::kDstOver_Mode &&
1803 xfermode != SkXfermode::kSrcIn_Mode && 1760 xfermode != SkXfermode::kSrcIn_Mode &&
1804 xfermode != SkXfermode::kDstIn_Mode && 1761 xfermode != SkXfermode::kDstIn_Mode &&
1805 xfermode != SkXfermode::kSrcOut_Mode && 1762 xfermode != SkXfermode::kSrcOut_Mode &&
1806 xfermode != SkXfermode::kDstOut_Mode && 1763 xfermode != SkXfermode::kDstOut_Mode &&
1807 xfermode != SkXfermode::kSrcATop_Mode && 1764 xfermode != SkXfermode::kSrcATop_Mode &&
1808 xfermode != SkXfermode::kDstATop_Mode && 1765 xfermode != SkXfermode::kDstATop_Mode &&
1809 xfermode != SkXfermode::kModulate_Mode) { 1766 xfermode != SkXfermode::kModulate_Mode) {
1810 SkASSERT(!dst); 1767 SkASSERT(!dst);
1811 return; 1768 return;
1812 } 1769 }
1813 if (xfermode == SkXfermode::kDstOver_Mode) { 1770 if (xfermode == SkXfermode::kDstOver_Mode) {
1814 SkASSERT(!dst); 1771 SkASSERT(!dst);
1815 ContentEntry* firstContentEntry = getContentEntries()->get(); 1772 if (fContentEntries->fContent.getOffset() == 0) {
1816 if (firstContentEntry->fContent.getOffset() == 0) {
1817 // For DstOver, an empty content entry was inserted before the rest 1773 // For DstOver, an empty content entry was inserted before the rest
1818 // of the content entries. If nothing was drawn, it needs to be 1774 // of the content entries. If nothing was drawn, it needs to be
1819 // removed. 1775 // removed.
1820 SkAutoTDelete<ContentEntry>* contentEntries = getContentEntries(); 1776 fContentEntries.reset(fContentEntries->fNext.release());
1821 contentEntries->reset(firstContentEntry->fNext.release());
1822 } 1777 }
1823 return; 1778 return;
1824 } 1779 }
1825 if (!dst) { 1780 if (!dst) {
1826 SkASSERT(xfermode == SkXfermode::kSrc_Mode || 1781 SkASSERT(xfermode == SkXfermode::kSrc_Mode ||
1827 xfermode == SkXfermode::kSrcOut_Mode); 1782 xfermode == SkXfermode::kSrcOut_Mode);
1828 return; 1783 return;
1829 } 1784 }
1830 1785
1831 ContentEntry* contentEntries = getContentEntries()->get();
1832 SkASSERT(dst); 1786 SkASSERT(dst);
1833 SkASSERT(!contentEntries->fNext.get()); 1787 SkASSERT(!fContentEntries->fNext.get());
1834 // Changing the current content into a form-xobject will destroy the clip 1788 // Changing the current content into a form-xobject will destroy the clip
1835 // objects which is fine since the xobject will already be clipped. However 1789 // objects which is fine since the xobject will already be clipped. However
1836 // if source has shape, we need to clip it too, so a copy of the clip is 1790 // if source has shape, we need to clip it too, so a copy of the clip is
1837 // saved. 1791 // saved.
1838 SkClipStack clipStack = contentEntries->fState.fClipStack; 1792 SkClipStack clipStack = fContentEntries->fState.fClipStack;
1839 SkRegion clipRegion = contentEntries->fState.fClipRegion; 1793 SkRegion clipRegion = fContentEntries->fState.fClipRegion;
1840 1794
1841 SkMatrix identity; 1795 SkMatrix identity;
1842 identity.reset(); 1796 identity.reset();
1843 SkPaint stockPaint; 1797 SkPaint stockPaint;
1844 1798
1845 sk_sp<SkPDFFormXObject> srcFormXObject; 1799 sk_sp<SkPDFFormXObject> srcFormXObject;
1846 if (isContentEmpty()) { 1800 if (isContentEmpty()) {
1847 // If nothing was drawn and there's no shape, then the draw was a 1801 // If nothing was drawn and there's no shape, then the draw was a
1848 // no-op, but dst needs to be restored for that to be true. 1802 // no-op, but dst needs to be restored for that to be true.
1849 // If there is shape, then an empty source with Src, SrcIn, SrcOut, 1803 // If there is shape, then an empty source with Src, SrcIn, SrcOut,
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 SkXfermode::kSrcOver_Mode, false); 1898 SkXfermode::kSrcOver_Mode, false);
1945 mode = SkXfermode::kMultiply_Mode; 1899 mode = SkXfermode::kMultiply_Mode;
1946 } 1900 }
1947 drawFormXObjectWithMask(addXObjectResource(dst), srcFormXObject.get(), 1901 drawFormXObjectWithMask(addXObjectResource(dst), srcFormXObject.get(),
1948 &fExistingClipStack, fExistingClipRegion, mode, 1902 &fExistingClipStack, fExistingClipRegion, mode,
1949 xfermode == SkXfermode::kDstOut_Mode); 1903 xfermode == SkXfermode::kDstOut_Mode);
1950 } 1904 }
1951 } 1905 }
1952 1906
1953 bool SkPDFDevice::isContentEmpty() { 1907 bool SkPDFDevice::isContentEmpty() {
1954 ContentEntry* contentEntries = getContentEntries()->get(); 1908 if (!fContentEntries || fContentEntries->fContent.getOffset() == 0) {
1955 if (!contentEntries || contentEntries->fContent.getOffset() == 0) { 1909 SkASSERT(!fContentEntries || !fContentEntries->fNext.get());
1956 SkASSERT(!contentEntries || !contentEntries->fNext.get());
1957 return true; 1910 return true;
1958 } 1911 }
1959 return false; 1912 return false;
1960 } 1913 }
1961 1914
1962 void SkPDFDevice::populateGraphicStateEntryFromPaint( 1915 void SkPDFDevice::populateGraphicStateEntryFromPaint(
1963 const SkMatrix& matrix, 1916 const SkMatrix& matrix,
1964 const SkClipStack& clipStack, 1917 const SkClipStack& clipStack,
1965 const SkRegion& clipRegion, 1918 const SkRegion& clipRegion,
1966 const SkPaint& paint, 1919 const SkPaint& paint,
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 if (!pdfimage) { 2213 if (!pdfimage) {
2261 return; 2214 return;
2262 } 2215 }
2263 fDocument->serialize(pdfimage); // serialize images early. 2216 fDocument->serialize(pdfimage); // serialize images early.
2264 fDocument->canon()->addPDFBitmap(key, pdfimage); 2217 fDocument->canon()->addPDFBitmap(key, pdfimage);
2265 } 2218 }
2266 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> 2219 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject>
2267 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), 2220 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()),
2268 &content.entry()->fContent); 2221 &content.entry()->fContent);
2269 } 2222 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698