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 "SkAnnotation.h" | 10 #include "SkAnnotation.h" |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 paint.getXfermode()->asMode(&fXfermode); | 690 paint.getXfermode()->asMode(&fXfermode); |
691 } | 691 } |
692 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, | 692 fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, |
693 matrix, paint, hasText, | 693 matrix, paint, hasText, |
694 &fDstFormXObject); | 694 &fDstFormXObject); |
695 } | 695 } |
696 }; | 696 }; |
697 | 697 |
698 //////////////////////////////////////////////////////////////////////////////// | 698 //////////////////////////////////////////////////////////////////////////////// |
699 | 699 |
700 SkPDFDevice::SkPDFDevice(SkISize pageSize, | 700 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon
, bool flip) |
701 SkScalar rasterDpi, | |
702 SkPDFCanon* canon, | |
703 bool flip) | |
704 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) | 701 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) |
705 , fPageSize(pageSize) | 702 , fPageSize(pageSize) |
706 , fContentSize(pageSize) | 703 , fContentSize(pageSize) |
707 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) | 704 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) |
708 , fAnnotations(NULL) | 705 , fAnnotations(NULL) |
709 , fLastContentEntry(NULL) | 706 , fLastContentEntry(NULL) |
710 , fLastMarginContentEntry(NULL) | 707 , fLastMarginContentEntry(NULL) |
711 , fDrawingArea(kContent_DrawingArea) | 708 , fDrawingArea(kContent_DrawingArea) |
712 , fClipStack(NULL) | 709 , fClipStack(NULL) |
713 , fFontGlyphUsage(SkNEW(SkPDFGlyphSetMap)) | 710 , fFontGlyphUsage(new SkPDFGlyphSetMap) |
714 , fRasterDpi(rasterDpi) | 711 , fRasterDpi(rasterDpi) |
715 , fCanon(canon) { | 712 , fCanon(canon) { |
716 SkASSERT(pageSize.width() > 0); | 713 SkASSERT(pageSize.width() > 0); |
717 SkASSERT(pageSize.height() > 0); | 714 SkASSERT(pageSize.height() > 0); |
718 fLegacyBitmap.setInfo( | 715 fLegacyBitmap.setInfo( |
719 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); | 716 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); |
720 if (flip) { | 717 if (flip) { |
721 // Skia generally uses the top left as the origin but PDF | 718 // Skia generally uses the top left as the origin but PDF |
722 // natively has the origin at the bottom left. This matrix | 719 // natively has the origin at the bottom left. This matrix |
723 // corrects for that. But that only needs to be done once, we | 720 // corrects for that. But that only needs to be done once, we |
(...skipping 10 matching lines...) Expand all Loading... |
734 } | 731 } |
735 | 732 |
736 void SkPDFDevice::init() { | 733 void SkPDFDevice::init() { |
737 fAnnotations = NULL; | 734 fAnnotations = NULL; |
738 fContentEntries.free(); | 735 fContentEntries.free(); |
739 fLastContentEntry = NULL; | 736 fLastContentEntry = NULL; |
740 fMarginContentEntries.free(); | 737 fMarginContentEntries.free(); |
741 fLastMarginContentEntry = NULL; | 738 fLastMarginContentEntry = NULL; |
742 fDrawingArea = kContent_DrawingArea; | 739 fDrawingArea = kContent_DrawingArea; |
743 if (fFontGlyphUsage.get() == NULL) { | 740 if (fFontGlyphUsage.get() == NULL) { |
744 fFontGlyphUsage.reset(SkNEW(SkPDFGlyphSetMap)); | 741 fFontGlyphUsage.reset(new SkPDFGlyphSetMap); |
745 } | 742 } |
746 } | 743 } |
747 | 744 |
748 void SkPDFDevice::cleanUp(bool clearFontUsage) { | 745 void SkPDFDevice::cleanUp(bool clearFontUsage) { |
749 fGraphicStateResources.unrefAll(); | 746 fGraphicStateResources.unrefAll(); |
750 fXObjectResources.unrefAll(); | 747 fXObjectResources.unrefAll(); |
751 fFontResources.unrefAll(); | 748 fFontResources.unrefAll(); |
752 fShaderResources.unrefAll(); | 749 fShaderResources.unrefAll(); |
753 SkSafeUnref(fAnnotations); | 750 SkSafeUnref(fAnnotations); |
754 fNamedDestinations.deleteAll(); | 751 fNamedDestinations.deleteAll(); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 if (const SkClipStack* clipStack = d.fClipStack) { | 886 if (const SkClipStack* clipStack = d.fClipStack) { |
890 SkPath clip; | 887 SkPath clip; |
891 (void)clipStack->asPath(&clip); | 888 (void)clipStack->asPath(&clip); |
892 clip.transform(initialTransform); | 889 clip.transform(initialTransform); |
893 Op(clip, path, SkPathOp::kIntersect_SkPathOp, &path); | 890 Op(clip, path, SkPathOp::kIntersect_SkPathOp, &path); |
894 } | 891 } |
895 return path; | 892 return path; |
896 } | 893 } |
897 | 894 |
898 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) { | 895 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) { |
899 SkAutoTUnref<SkPDFDict> annotation(SkNEW_ARGS(SkPDFDict, ("Annot"))); | 896 SkAutoTUnref<SkPDFDict> annotation(new SkPDFDict("Annot")); |
900 annotation->insertName("Subtype", "Link"); | 897 annotation->insertName("Subtype", "Link"); |
901 | 898 |
902 SkAutoTUnref<SkPDFArray> border(SkNEW(SkPDFArray)); | 899 SkAutoTUnref<SkPDFArray> border(new SkPDFArray); |
903 border->reserve(3); | 900 border->reserve(3); |
904 border->appendInt(0); // Horizontal corner radius. | 901 border->appendInt(0); // Horizontal corner radius. |
905 border->appendInt(0); // Vertical corner radius. | 902 border->appendInt(0); // Vertical corner radius. |
906 border->appendInt(0); // Width, 0 = no border. | 903 border->appendInt(0); // Width, 0 = no border. |
907 annotation->insertObject("Border", border.detach()); | 904 annotation->insertObject("Border", border.detach()); |
908 | 905 |
909 SkAutoTUnref<SkPDFArray> rect(SkNEW(SkPDFArray)); | 906 SkAutoTUnref<SkPDFArray> rect(new SkPDFArray); |
910 rect->reserve(4); | 907 rect->reserve(4); |
911 rect->appendScalar(translatedRect.fLeft); | 908 rect->appendScalar(translatedRect.fLeft); |
912 rect->appendScalar(translatedRect.fTop); | 909 rect->appendScalar(translatedRect.fTop); |
913 rect->appendScalar(translatedRect.fRight); | 910 rect->appendScalar(translatedRect.fRight); |
914 rect->appendScalar(translatedRect.fBottom); | 911 rect->appendScalar(translatedRect.fBottom); |
915 annotation->insertObject("Rect", rect.detach()); | 912 annotation->insertObject("Rect", rect.detach()); |
916 | 913 |
917 return annotation.detach(); | 914 return annotation.detach(); |
918 } | 915 } |
919 | 916 |
920 static SkPDFDict* create_link_to_url(SkData* urlData, const SkRect& r) { | 917 static SkPDFDict* create_link_to_url(SkData* urlData, const SkRect& r) { |
921 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); | 918 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); |
922 | 919 |
923 SkString url(static_cast<const char *>(urlData->data()), | 920 SkString url(static_cast<const char *>(urlData->data()), |
924 urlData->size() - 1); | 921 urlData->size() - 1); |
925 SkAutoTUnref<SkPDFDict> action(SkNEW_ARGS(SkPDFDict, ("Action"))); | 922 SkAutoTUnref<SkPDFDict> action(new SkPDFDict("Action")); |
926 action->insertName("S", "URI"); | 923 action->insertName("S", "URI"); |
927 action->insertString("URI", url); | 924 action->insertString("URI", url); |
928 annotation->insertObject("A", action.detach()); | 925 annotation->insertObject("A", action.detach()); |
929 return annotation.detach(); | 926 return annotation.detach(); |
930 } | 927 } |
931 | 928 |
932 static SkPDFDict* create_link_named_dest(SkData* nameData, const SkRect& r) { | 929 static SkPDFDict* create_link_named_dest(SkData* nameData, const SkRect& r) { |
933 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); | 930 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); |
934 SkString name(static_cast<const char *>(nameData->data()), | 931 SkString name(static_cast<const char *>(nameData->data()), |
935 nameData->size() - 1); | 932 nameData->size() - 1); |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 &fonts); | 1424 &fonts); |
1428 } | 1425 } |
1429 | 1426 |
1430 const SkTDArray<SkPDFFont*>& SkPDFDevice::getFontResources() const { | 1427 const SkTDArray<SkPDFFont*>& SkPDFDevice::getFontResources() const { |
1431 return fFontResources; | 1428 return fFontResources; |
1432 } | 1429 } |
1433 | 1430 |
1434 SkPDFArray* SkPDFDevice::copyMediaBox() const { | 1431 SkPDFArray* SkPDFDevice::copyMediaBox() const { |
1435 // should this be a singleton? | 1432 // should this be a singleton? |
1436 | 1433 |
1437 SkAutoTUnref<SkPDFArray> mediaBox(SkNEW(SkPDFArray)); | 1434 SkAutoTUnref<SkPDFArray> mediaBox(new SkPDFArray); |
1438 mediaBox->reserve(4); | 1435 mediaBox->reserve(4); |
1439 mediaBox->appendInt(0); | 1436 mediaBox->appendInt(0); |
1440 mediaBox->appendInt(0); | 1437 mediaBox->appendInt(0); |
1441 mediaBox->appendInt(fPageSize.fWidth); | 1438 mediaBox->appendInt(fPageSize.fWidth); |
1442 mediaBox->appendInt(fPageSize.fHeight); | 1439 mediaBox->appendInt(fPageSize.fHeight); |
1443 return mediaBox.detach(); | 1440 return mediaBox.detach(); |
1444 } | 1441 } |
1445 | 1442 |
1446 SkStreamAsset* SkPDFDevice::content() const { | 1443 SkStreamAsset* SkPDFDevice::content() const { |
1447 SkDynamicMemoryWStream buffer; | 1444 SkDynamicMemoryWStream buffer; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 const SkMatrix& matrix, | 1569 const SkMatrix& matrix, |
1573 SkAnnotation* annotationInfo) { | 1570 SkAnnotation* annotationInfo) { |
1574 SkData* nameData = annotationInfo->find( | 1571 SkData* nameData = annotationInfo->find( |
1575 SkAnnotationKeys::Define_Named_Dest_Key()); | 1572 SkAnnotationKeys::Define_Named_Dest_Key()); |
1576 if (nameData) { | 1573 if (nameData) { |
1577 SkMatrix transform = matrix; | 1574 SkMatrix transform = matrix; |
1578 transform.postConcat(fInitialTransform); | 1575 transform.postConcat(fInitialTransform); |
1579 for (size_t i = 0; i < count; i++) { | 1576 for (size_t i = 0; i < count; i++) { |
1580 SkPoint translatedPoint; | 1577 SkPoint translatedPoint; |
1581 transform.mapXY(points[i].x(), points[i].y(), &translatedPoint); | 1578 transform.mapXY(points[i].x(), points[i].y(), &translatedPoint); |
1582 fNamedDestinations.push( | 1579 fNamedDestinations.push(new NamedDestination(nameData, translatedPoi
nt)); |
1583 SkNEW_ARGS(NamedDestination, (nameData, translatedPoint))); | |
1584 | |
1585 } | 1580 } |
1586 return true; | 1581 return true; |
1587 } | 1582 } |
1588 return false; | 1583 return false; |
1589 } | 1584 } |
1590 | 1585 |
1591 void SkPDFDevice::addAnnotation(SkPDFDict* annotation) { | 1586 void SkPDFDevice::addAnnotation(SkPDFDict* annotation) { |
1592 if (NULL == fAnnotations) { | 1587 if (NULL == fAnnotations) { |
1593 fAnnotations = SkNEW(SkPDFArray); | 1588 fAnnotations = new SkPDFArray; |
1594 } | 1589 } |
1595 fAnnotations->appendObject(annotation); | 1590 fAnnotations->appendObject(annotation); |
1596 } | 1591 } |
1597 | 1592 |
1598 | 1593 |
1599 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { | 1594 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { |
1600 int nDest = fNamedDestinations.count(); | 1595 int nDest = fNamedDestinations.count(); |
1601 for (int i = 0; i < nDest; i++) { | 1596 for (int i = 0; i < nDest; i++) { |
1602 NamedDestination* dest = fNamedDestinations[i]; | 1597 NamedDestination* dest = fNamedDestinations[i]; |
1603 SkAutoTUnref<SkPDFArray> pdfDest(SkNEW(SkPDFArray)); | 1598 SkAutoTUnref<SkPDFArray> pdfDest(new SkPDFArray); |
1604 pdfDest->reserve(5); | 1599 pdfDest->reserve(5); |
1605 pdfDest->appendObjRef(SkRef(page)); | 1600 pdfDest->appendObjRef(SkRef(page)); |
1606 pdfDest->appendName("XYZ"); | 1601 pdfDest->appendName("XYZ"); |
1607 pdfDest->appendScalar(dest->point.x()); | 1602 pdfDest->appendScalar(dest->point.x()); |
1608 pdfDest->appendScalar(dest->point.y()); | 1603 pdfDest->appendScalar(dest->point.y()); |
1609 pdfDest->appendInt(0); // Leave zoom unchanged | 1604 pdfDest->appendInt(0); // Leave zoom unchanged |
1610 SkString name(static_cast<const char*>(dest->nameData->data())); | 1605 SkString name(static_cast<const char*>(dest->nameData->data())); |
1611 dict->insertObject(name, pdfDest.detach()); | 1606 dict->insertObject(name, pdfDest.detach()); |
1612 } | 1607 } |
1613 } | 1608 } |
1614 | 1609 |
1615 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { | 1610 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { |
1616 SkPDFFormXObject* xobject = SkNEW_ARGS(SkPDFFormXObject, (this)); | 1611 SkPDFFormXObject* xobject = new SkPDFFormXObject(this); |
1617 // We always draw the form xobjects that we create back into the device, so | 1612 // We always draw the form xobjects that we create back into the device, so |
1618 // we simply preserve the font usage instead of pulling it out and merging | 1613 // we simply preserve the font usage instead of pulling it out and merging |
1619 // it back in later. | 1614 // it back in later. |
1620 cleanUp(false); // Reset this device to have no content. | 1615 cleanUp(false); // Reset this device to have no content. |
1621 init(); | 1616 init(); |
1622 return xobject; | 1617 return xobject; |
1623 } | 1618 } |
1624 | 1619 |
1625 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, | 1620 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, |
1626 SkPDFFormXObject* mask, | 1621 SkPDFFormXObject* mask, |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 return; | 2190 return; |
2196 } | 2191 } |
2197 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap)); | 2192 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap)); |
2198 if (!image) { | 2193 if (!image) { |
2199 return; | 2194 return; |
2200 } | 2195 } |
2201 | 2196 |
2202 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), | 2197 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), |
2203 &content.entry()->fContent); | 2198 &content.entry()->fContent); |
2204 } | 2199 } |
OLD | NEW |