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 "SkAnnotationKeys.h" |
11 #include "SkColor.h" | 11 #include "SkColor.h" |
12 #include "SkColorFilter.h" | 12 #include "SkColorFilter.h" |
13 #include "SkClipStack.h" | 13 #include "SkClipStack.h" |
14 #include "SkDraw.h" | 14 #include "SkDraw.h" |
15 #include "SkGlyphCache.h" | 15 #include "SkGlyphCache.h" |
16 #include "SkPaint.h" | 16 #include "SkPaint.h" |
17 #include "SkPath.h" | 17 #include "SkPath.h" |
18 #include "SkPathOps.h" | 18 #include "SkPathOps.h" |
19 #include "SkPDFBitmap.h" | 19 #include "SkPDFBitmap.h" |
20 #include "SkPDFCanon.h" | 20 #include "SkPDFCanon.h" |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 fGraphicStateResources.unrefAll(); | 746 fGraphicStateResources.unrefAll(); |
747 fXObjectResources.unrefAll(); | 747 fXObjectResources.unrefAll(); |
748 fFontResources.unrefAll(); | 748 fFontResources.unrefAll(); |
749 fShaderResources.unrefAll(); | 749 fShaderResources.unrefAll(); |
750 | 750 |
751 if (clearFontUsage) { | 751 if (clearFontUsage) { |
752 fFontGlyphUsage->reset(); | 752 fFontGlyphUsage->reset(); |
753 } | 753 } |
754 } | 754 } |
755 | 755 |
| 756 void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char
key[], |
| 757 SkData* value) { |
| 758 if (0 == rect.width() && 0 == rect.height()) { |
| 759 handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value); |
| 760 } else { |
| 761 SkPath path; |
| 762 path.addRect(rect); |
| 763 handlePathAnnotation(path, d, key, value); |
| 764 } |
| 765 } |
| 766 |
756 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { | 767 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { |
757 SkPaint newPaint = paint; | 768 SkPaint newPaint = paint; |
758 replace_srcmode_on_opaque_paint(&newPaint); | 769 replace_srcmode_on_opaque_paint(&newPaint); |
759 | 770 |
760 newPaint.setStyle(SkPaint::kFill_Style); | 771 newPaint.setStyle(SkPaint::kFill_Style); |
761 ScopedContentEntry content(this, d, newPaint); | 772 ScopedContentEntry content(this, d, newPaint); |
762 internalDrawPaint(newPaint, content.entry()); | 773 internalDrawPaint(newPaint, content.entry()); |
763 } | 774 } |
764 | 775 |
765 void SkPDFDevice::internalDrawPaint(const SkPaint& paint, | 776 void SkPDFDevice::internalDrawPaint(const SkPaint& paint, |
(...skipping 19 matching lines...) Expand all Loading... |
785 size_t count, | 796 size_t count, |
786 const SkPoint* points, | 797 const SkPoint* points, |
787 const SkPaint& srcPaint) { | 798 const SkPaint& srcPaint) { |
788 SkPaint passedPaint = srcPaint; | 799 SkPaint passedPaint = srcPaint; |
789 replace_srcmode_on_opaque_paint(&passedPaint); | 800 replace_srcmode_on_opaque_paint(&passedPaint); |
790 | 801 |
791 if (count == 0) { | 802 if (count == 0) { |
792 return; | 803 return; |
793 } | 804 } |
794 | 805 |
795 if (SkAnnotation* annotation = passedPaint.getAnnotation()) { | |
796 if (handlePointAnnotation(points, count, *d.fMatrix, annotation)) { | |
797 return; | |
798 } | |
799 } | |
800 | |
801 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath. | 806 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath. |
802 // We only use this when there's a path effect because of the overhead | 807 // We only use this when there's a path effect because of the overhead |
803 // of multiple calls to setUpContentEntry it causes. | 808 // of multiple calls to setUpContentEntry it causes. |
804 if (passedPaint.getPathEffect()) { | 809 if (passedPaint.getPathEffect()) { |
805 if (d.fClip->isEmpty()) { | 810 if (d.fClip->isEmpty()) { |
806 return; | 811 return; |
807 } | 812 } |
808 SkDraw pointDraw(d); | 813 SkDraw pointDraw(d); |
809 pointDraw.fDevice = this; | 814 pointDraw.fDevice = this; |
810 pointDraw.drawPoints(mode, count, points, passedPaint, true); | 815 pointDraw.drawPoints(mode, count, points, passedPaint, true); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 if (paint.getPathEffect()) { | 933 if (paint.getPathEffect()) { |
929 if (d.fClip->isEmpty()) { | 934 if (d.fClip->isEmpty()) { |
930 return; | 935 return; |
931 } | 936 } |
932 SkPath path; | 937 SkPath path; |
933 path.addRect(r); | 938 path.addRect(r); |
934 drawPath(d, path, paint, nullptr, true); | 939 drawPath(d, path, paint, nullptr, true); |
935 return; | 940 return; |
936 } | 941 } |
937 | 942 |
938 if (SkAnnotation* annotation = paint.getAnnotation()) { | |
939 SkPath path; | |
940 path.addRect(rect); | |
941 if (handlePathAnnotation(path, d, annotation)) { | |
942 return; | |
943 } | |
944 } | |
945 | |
946 ScopedContentEntry content(this, d, paint); | 943 ScopedContentEntry content(this, d, paint); |
947 if (!content.entry()) { | 944 if (!content.entry()) { |
948 return; | 945 return; |
949 } | 946 } |
950 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent); | 947 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent); |
951 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, | 948 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, |
952 &content.entry()->fContent); | 949 &content.entry()->fContent); |
953 } | 950 } |
954 | 951 |
955 void SkPDFDevice::drawRRect(const SkDraw& draw, | 952 void SkPDFDevice::drawRRect(const SkDraw& draw, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 noEffectPaint.setStrokeWidth(0); | 1011 noEffectPaint.setStrokeWidth(0); |
1015 } | 1012 } |
1016 drawPath(d, *pathPtr, noEffectPaint, nullptr, true); | 1013 drawPath(d, *pathPtr, noEffectPaint, nullptr, true); |
1017 return; | 1014 return; |
1018 } | 1015 } |
1019 | 1016 |
1020 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) { | 1017 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) { |
1021 return; | 1018 return; |
1022 } | 1019 } |
1023 | 1020 |
1024 if (SkAnnotation* annotation = paint.getAnnotation()) { | |
1025 if (handlePathAnnotation(*pathPtr, d, annotation)) { | |
1026 return; | |
1027 } | |
1028 } | |
1029 | |
1030 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); | 1021 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); |
1031 if (!content.entry()) { | 1022 if (!content.entry()) { |
1032 return; | 1023 return; |
1033 } | 1024 } |
1034 bool consumeDegeratePathSegments = | 1025 bool consumeDegeratePathSegments = |
1035 paint.getStyle() == SkPaint::kFill_Style || | 1026 paint.getStyle() == SkPaint::kFill_Style || |
1036 (paint.getStrokeCap() != SkPaint::kRound_Cap && | 1027 (paint.getStrokeCap() != SkPaint::kRound_Cap && |
1037 paint.getStrokeCap() != SkPaint::kSquare_Cap); | 1028 paint.getStrokeCap() != SkPaint::kSquare_Cap); |
1038 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), | 1029 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), |
1039 consumeDegeratePathSegments, | 1030 consumeDegeratePathSegments, |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1657 paint.getStrokeWidth() + SK_Scalar1); | 1648 paint.getStrokeWidth() + SK_Scalar1); |
1658 | 1649 |
1659 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) { | 1650 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) { |
1660 return false; | 1651 return false; |
1661 } | 1652 } |
1662 | 1653 |
1663 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true); | 1654 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true); |
1664 return true; | 1655 return true; |
1665 } | 1656 } |
1666 | 1657 |
1667 bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count, | 1658 void SkPDFDevice::handlePointAnnotation(const SkPoint& point, |
1668 const SkMatrix& matrix, | 1659 const SkMatrix& matrix, |
1669 SkAnnotation* annotationInfo) { | 1660 const char key[], SkData* value) { |
1670 SkData* nameData = annotationInfo->find( | 1661 if (!value) { |
1671 SkAnnotationKeys::Define_Named_Dest_Key()); | 1662 return; |
1672 if (nameData) { | |
1673 for (size_t i = 0; i < count; i++) { | |
1674 SkPoint transformedPoint; | |
1675 matrix.mapXY(points[i].x(), points[i].y(), &transformedPoint); | |
1676 fNamedDestinations.emplace_back(nameData, transformedPoint); | |
1677 } | |
1678 return true; | |
1679 } | 1663 } |
1680 return false; | 1664 |
| 1665 if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) { |
| 1666 SkPoint transformedPoint; |
| 1667 matrix.mapXY(point.x(), point.y(), &transformedPoint); |
| 1668 fNamedDestinations.emplace_back(value, transformedPoint); |
| 1669 } |
1681 } | 1670 } |
1682 | 1671 |
1683 bool SkPDFDevice::handlePathAnnotation(const SkPath& path, | 1672 void SkPDFDevice::handlePathAnnotation(const SkPath& path, |
1684 const SkDraw& d, | 1673 const SkDraw& d, |
1685 SkAnnotation* annotation) { | 1674 const char key[], SkData* value) { |
1686 SkASSERT(annotation); | 1675 if (!value) { |
| 1676 return; |
| 1677 } |
1687 | 1678 |
1688 SkPath transformedPath = path; | 1679 SkPath transformedPath = path; |
1689 transformedPath.transform(*d.fMatrix); | 1680 transformedPath.transform(*d.fMatrix); |
1690 SkRasterClip clip = *d.fRC; | 1681 SkRasterClip clip = *d.fRC; |
1691 clip.op(transformedPath, SkIRect::MakeWH(width(), height()), SkRegion::kInte
rsect_Op, | 1682 clip.op(transformedPath, SkIRect::MakeWH(width(), height()), SkRegion::kInte
rsect_Op, |
1692 false); | 1683 false); |
1693 SkRect transformedRect = SkRect::Make(clip.getBounds()); | 1684 SkRect transformedRect = SkRect::Make(clip.getBounds()); |
1694 | 1685 |
1695 SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key()); | 1686 if (!strcmp(SkAnnotationKeys::URL_Key(), key)) { |
1696 if (urlData) { | |
1697 if (!transformedRect.isEmpty()) { | 1687 if (!transformedRect.isEmpty()) { |
1698 fLinkToURLs.emplace_back(transformedRect, urlData); | 1688 fLinkToURLs.emplace_back(transformedRect, value); |
1699 } | 1689 } |
1700 return true; | 1690 } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) { |
| 1691 if (!transformedRect.isEmpty()) { |
| 1692 fLinkToDestinations.emplace_back(transformedRect, value); |
| 1693 } |
1701 } | 1694 } |
1702 | |
1703 SkData* linkToDestination = | |
1704 annotation->find(SkAnnotationKeys::Link_Named_Dest_Key()); | |
1705 if (linkToDestination) { | |
1706 if (!transformedRect.isEmpty()) { | |
1707 fLinkToDestinations.emplace_back(transformedRect, linkToDestination)
; | |
1708 } | |
1709 return true; | |
1710 } | |
1711 | |
1712 return false; | |
1713 } | 1695 } |
1714 | 1696 |
1715 void SkPDFDevice::appendAnnotations(SkPDFArray* array) const { | 1697 void SkPDFDevice::appendAnnotations(SkPDFArray* array) const { |
1716 array->reserve(fLinkToURLs.count() + fLinkToDestinations.count()); | 1698 array->reserve(fLinkToURLs.count() + fLinkToDestinations.count()); |
1717 for (const RectWithData& rectWithURL : fLinkToURLs) { | 1699 for (const RectWithData& rectWithURL : fLinkToURLs) { |
1718 SkRect r; | 1700 SkRect r; |
1719 fInitialTransform.mapRect(&r, rectWithURL.rect); | 1701 fInitialTransform.mapRect(&r, rectWithURL.rect); |
1720 array->appendObject(create_link_to_url(rectWithURL.data, r)); | 1702 array->appendObject(create_link_to_url(rectWithURL.data, r)); |
1721 } | 1703 } |
1722 for (const RectWithData& linkToDestination : fLinkToDestinations) { | 1704 for (const RectWithData& linkToDestination : fLinkToDestinations) { |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2345 pdfimage.reset(SkPDFCreateBitmapObject( | 2327 pdfimage.reset(SkPDFCreateBitmapObject( |
2346 image, fCanon->fPixelSerializer)); | 2328 image, fCanon->fPixelSerializer)); |
2347 if (!pdfimage) { | 2329 if (!pdfimage) { |
2348 return; | 2330 return; |
2349 } | 2331 } |
2350 fCanon->addPDFBitmap(image->uniqueID(), pdfimage); | 2332 fCanon->addPDFBitmap(image->uniqueID(), pdfimage); |
2351 } | 2333 } |
2352 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2334 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2353 &content.entry()->fContent); | 2335 &content.entry()->fContent); |
2354 } | 2336 } |
OLD | NEW |