OLD | NEW |
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 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 &content.entry()->fContent); | 872 &content.entry()->fContent); |
873 SkPDFUtils::ClosePath(&content.entry()->fContent); | 873 SkPDFUtils::ClosePath(&content.entry()->fContent); |
874 SkPDFUtils::StrokePath(&content.entry()->fContent); | 874 SkPDFUtils::StrokePath(&content.entry()->fContent); |
875 } | 875 } |
876 break; | 876 break; |
877 default: | 877 default: |
878 SkASSERT(false); | 878 SkASSERT(false); |
879 } | 879 } |
880 } | 880 } |
881 | 881 |
882 static sk_sp<SkPDFDict> create_link_annotation(const SkRect& translatedRect) { | 882 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) { |
883 auto annotation = sk_make_sp<SkPDFDict>("Annot"); | 883 auto annotation = sk_make_sp<SkPDFDict>("Annot"); |
884 annotation->insertName("Subtype", "Link"); | 884 annotation->insertName("Subtype", "Link"); |
885 | 885 |
886 auto border = sk_make_sp<SkPDFArray>(); | 886 auto border = sk_make_sp<SkPDFArray>(); |
887 border->reserve(3); | 887 border->reserve(3); |
888 border->appendInt(0); // Horizontal corner radius. | 888 border->appendInt(0); // Horizontal corner radius. |
889 border->appendInt(0); // Vertical corner radius. | 889 border->appendInt(0); // Vertical corner radius. |
890 border->appendInt(0); // Width, 0 = no border. | 890 border->appendInt(0); // Width, 0 = no border. |
891 annotation->insertObject("Border", std::move(border)); | 891 annotation->insertObject("Border", border.release()); |
892 | 892 |
893 auto rect = sk_make_sp<SkPDFArray>(); | 893 auto rect = sk_make_sp<SkPDFArray>(); |
894 rect->reserve(4); | 894 rect->reserve(4); |
895 rect->appendScalar(translatedRect.fLeft); | 895 rect->appendScalar(translatedRect.fLeft); |
896 rect->appendScalar(translatedRect.fTop); | 896 rect->appendScalar(translatedRect.fTop); |
897 rect->appendScalar(translatedRect.fRight); | 897 rect->appendScalar(translatedRect.fRight); |
898 rect->appendScalar(translatedRect.fBottom); | 898 rect->appendScalar(translatedRect.fBottom); |
899 annotation->insertObject("Rect", std::move(rect)); | 899 annotation->insertObject("Rect", rect.release()); |
900 | 900 |
901 return std::move(annotation); | 901 return annotation.release(); |
902 } | 902 } |
903 | 903 |
904 static sk_sp<SkPDFDict> create_link_to_url(const SkData* urlData, const SkRect&
r) { | 904 static SkPDFDict* create_link_to_url(const SkData* urlData, const SkRect& r) { |
905 auto annotation = create_link_annotation(r); | 905 sk_sp<SkPDFDict> annotation(create_link_annotation(r)); |
| 906 |
906 SkString url(static_cast<const char *>(urlData->data()), | 907 SkString url(static_cast<const char *>(urlData->data()), |
907 urlData->size() - 1); | 908 urlData->size() - 1); |
908 auto action = sk_make_sp<SkPDFDict>("Action"); | 909 auto action = sk_make_sp<SkPDFDict>("Action"); |
909 action->insertName("S", "URI"); | 910 action->insertName("S", "URI"); |
910 action->insertString("URI", url); | 911 action->insertString("URI", url); |
911 annotation->insertObject("A", std::move(action)); | 912 annotation->insertObject("A", action.release()); |
912 return std::move(annotation); | 913 return annotation.release(); |
913 } | 914 } |
914 | 915 |
915 static sk_sp<SkPDFDict> create_link_named_dest(const SkData* nameData, | 916 static SkPDFDict* create_link_named_dest(const SkData* nameData, |
916 const SkRect& r) { | 917 const SkRect& r) { |
917 auto annotation = create_link_annotation(r); | 918 sk_sp<SkPDFDict> annotation(create_link_annotation(r)); |
918 SkString name(static_cast<const char *>(nameData->data()), | 919 SkString name(static_cast<const char *>(nameData->data()), |
919 nameData->size() - 1); | 920 nameData->size() - 1); |
920 annotation->insertName("Dest", name); | 921 annotation->insertName("Dest", name); |
921 return std::move(annotation); | 922 return annotation.release(); |
922 } | 923 } |
923 | 924 |
924 void SkPDFDevice::drawRect(const SkDraw& d, | 925 void SkPDFDevice::drawRect(const SkDraw& d, |
925 const SkRect& rect, | 926 const SkRect& rect, |
926 const SkPaint& srcPaint) { | 927 const SkPaint& srcPaint) { |
927 SkPaint paint = srcPaint; | 928 SkPaint paint = srcPaint; |
928 replace_srcmode_on_opaque_paint(&paint); | 929 replace_srcmode_on_opaque_paint(&paint); |
929 SkRect r = rect; | 930 SkRect r = rect; |
930 r.sort(); | 931 r.sort(); |
931 | 932 |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 fLastMarginContentEntry = contentEntry; | 1500 fLastMarginContentEntry = contentEntry; |
1500 } | 1501 } |
1501 } | 1502 } |
1502 | 1503 |
1503 void SkPDFDevice::setDrawingArea(DrawingArea drawingArea) { | 1504 void SkPDFDevice::setDrawingArea(DrawingArea drawingArea) { |
1504 // A ScopedContentEntry only exists during the course of a draw call, so | 1505 // A ScopedContentEntry only exists during the course of a draw call, so |
1505 // this can't be called while a ScopedContentEntry exists. | 1506 // this can't be called while a ScopedContentEntry exists. |
1506 fDrawingArea = drawingArea; | 1507 fDrawingArea = drawingArea; |
1507 } | 1508 } |
1508 | 1509 |
1509 sk_sp<SkPDFDict> SkPDFDevice::makeResourceDict() const { | 1510 SkPDFDict* SkPDFDevice::createResourceDict() const { |
1510 SkTDArray<SkPDFObject*> fonts; | 1511 SkTDArray<SkPDFObject*> fonts; |
1511 fonts.setReserve(fFontResources.count()); | 1512 fonts.setReserve(fFontResources.count()); |
1512 for (SkPDFFont* font : fFontResources) { | 1513 for (SkPDFFont* font : fFontResources) { |
1513 fonts.push(font); | 1514 fonts.push(font); |
1514 } | 1515 } |
1515 return SkPDFResourceDict::Make( | 1516 return SkPDFResourceDict::Create( |
1516 &fGraphicStateResources, | 1517 &fGraphicStateResources, |
1517 &fShaderResources, | 1518 &fShaderResources, |
1518 &fXObjectResources, | 1519 &fXObjectResources, |
1519 &fonts); | 1520 &fonts); |
1520 } | 1521 } |
1521 | 1522 |
1522 const SkTDArray<SkPDFFont*>& SkPDFDevice::getFontResources() const { | 1523 const SkTDArray<SkPDFFont*>& SkPDFDevice::getFontResources() const { |
1523 return fFontResources; | 1524 return fFontResources; |
1524 } | 1525 } |
1525 | 1526 |
1526 sk_sp<SkPDFArray> SkPDFDevice::copyMediaBox() const { | 1527 SkPDFArray* SkPDFDevice::copyMediaBox() const { |
| 1528 // should this be a singleton? |
| 1529 |
1527 auto mediaBox = sk_make_sp<SkPDFArray>(); | 1530 auto mediaBox = sk_make_sp<SkPDFArray>(); |
1528 mediaBox->reserve(4); | 1531 mediaBox->reserve(4); |
1529 mediaBox->appendInt(0); | 1532 mediaBox->appendInt(0); |
1530 mediaBox->appendInt(0); | 1533 mediaBox->appendInt(0); |
1531 mediaBox->appendInt(fPageSize.width()); | 1534 mediaBox->appendInt(fPageSize.fWidth); |
1532 mediaBox->appendInt(fPageSize.height()); | 1535 mediaBox->appendInt(fPageSize.fHeight); |
1533 return std::move(mediaBox); | 1536 return mediaBox.release(); |
1534 } | 1537 } |
1535 | 1538 |
1536 skstd::unique_ptr<SkStreamAsset> SkPDFDevice::content() const { | 1539 SkStreamAsset* SkPDFDevice::content() const { |
1537 SkDynamicMemoryWStream buffer; | 1540 SkDynamicMemoryWStream buffer; |
1538 this->writeContent(&buffer); | 1541 this->writeContent(&buffer); |
1539 return skstd::unique_ptr<SkStreamAsset>( | 1542 return buffer.bytesWritten() > 0 |
1540 buffer.bytesWritten() > 0 | 1543 ? buffer.detachAsStream() |
1541 ? buffer.detachAsStream() | 1544 : new SkMemoryStream; |
1542 : new SkMemoryStream); | |
1543 } | 1545 } |
1544 | 1546 |
1545 void SkPDFDevice::copyContentEntriesToData(ContentEntry* entry, | 1547 void SkPDFDevice::copyContentEntriesToData(ContentEntry* entry, |
1546 SkWStream* data) const { | 1548 SkWStream* data) const { |
1547 // TODO(ctguil): For margins, I'm not sure fExistingClipStack/Region is the | 1549 // TODO(ctguil): For margins, I'm not sure fExistingClipStack/Region is the |
1548 // right thing to pass here. | 1550 // right thing to pass here. |
1549 GraphicStackState gsState(fExistingClipStack, fExistingClipRegion, data); | 1551 GraphicStackState gsState(fExistingClipStack, fExistingClipRegion, data); |
1550 while (entry != nullptr) { | 1552 while (entry != nullptr) { |
1551 SkPoint translation; | 1553 SkPoint translation; |
1552 translation.iset(this->getOrigin()); | 1554 translation.iset(this->getOrigin()); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1704 fInitialTransform.mapRect(&r, linkToDestination.rect); | 1706 fInitialTransform.mapRect(&r, linkToDestination.rect); |
1705 array->appendObject( | 1707 array->appendObject( |
1706 create_link_named_dest(linkToDestination.data.get(), r)); | 1708 create_link_named_dest(linkToDestination.data.get(), r)); |
1707 } | 1709 } |
1708 } | 1710 } |
1709 | 1711 |
1710 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { | 1712 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { |
1711 for (const NamedDestination& dest : fNamedDestinations) { | 1713 for (const NamedDestination& dest : fNamedDestinations) { |
1712 auto pdfDest = sk_make_sp<SkPDFArray>(); | 1714 auto pdfDest = sk_make_sp<SkPDFArray>(); |
1713 pdfDest->reserve(5); | 1715 pdfDest->reserve(5); |
1714 pdfDest->appendObjRef(sk_sp<SkPDFObject>(SkRef(page))); | 1716 pdfDest->appendObjRef(SkRef(page)); |
1715 pdfDest->appendName("XYZ"); | 1717 pdfDest->appendName("XYZ"); |
1716 SkPoint p = fInitialTransform.mapXY(dest.point.x(), dest.point.y()); | 1718 SkPoint p = fInitialTransform.mapXY(dest.point.x(), dest.point.y()); |
1717 pdfDest->appendScalar(p.x()); | 1719 pdfDest->appendScalar(p.x()); |
1718 pdfDest->appendScalar(p.y()); | 1720 pdfDest->appendScalar(p.y()); |
1719 pdfDest->appendInt(0); // Leave zoom unchanged | 1721 pdfDest->appendInt(0); // Leave zoom unchanged |
1720 SkString name(static_cast<const char*>(dest.nameData->data())); | 1722 SkString name(static_cast<const char*>(dest.nameData->data())); |
1721 dict->insertObject(name, std::move(pdfDest)); | 1723 dict->insertObject(name, pdfDest.release()); |
1722 } | 1724 } |
1723 } | 1725 } |
1724 | 1726 |
1725 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { | 1727 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { |
1726 SkPDFFormXObject* xobject = new SkPDFFormXObject(this); | 1728 SkPDFFormXObject* xobject = new SkPDFFormXObject(this); |
1727 // We always draw the form xobjects that we create back into the device, so | 1729 // We always draw the form xobjects that we create back into the device, so |
1728 // we simply preserve the font usage instead of pulling it out and merging | 1730 // we simply preserve the font usage instead of pulling it out and merging |
1729 // it back in later. | 1731 // it back in later. |
1730 cleanUp(false); // Reset this device to have no content. | 1732 cleanUp(false); // Reset this device to have no content. |
1731 init(); | 1733 init(); |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2326 pdfimage.reset(SkPDFCreateBitmapObject( | 2328 pdfimage.reset(SkPDFCreateBitmapObject( |
2327 image, fCanon->getPixelSerializer())); | 2329 image, fCanon->getPixelSerializer())); |
2328 if (!pdfimage) { | 2330 if (!pdfimage) { |
2329 return; | 2331 return; |
2330 } | 2332 } |
2331 fCanon->addPDFBitmap(image->uniqueID(), pdfimage.get()); | 2333 fCanon->addPDFBitmap(image->uniqueID(), pdfimage.get()); |
2332 } | 2334 } |
2333 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2335 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2334 &content.entry()->fContent); | 2336 &content.entry()->fContent); |
2335 } | 2337 } |
OLD | NEW |