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 "SkData.h" | 14 #include "SkData.h" |
15 #include "SkDraw.h" | 15 #include "SkDraw.h" |
16 #include "SkGlyphCache.h" | 16 #include "SkGlyphCache.h" |
17 #include "SkPaint.h" | 17 #include "SkPaint.h" |
18 #include "SkPath.h" | 18 #include "SkPath.h" |
19 #include "SkPathOps.h" | 19 #include "SkPathOps.h" |
20 #include "SkPDFBitmap.h" | 20 #include "SkPDFBitmap.h" |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 fShaderResources.unrefAll(); | 750 fShaderResources.unrefAll(); |
751 fLinkToURLs.deleteAll(); | 751 fLinkToURLs.deleteAll(); |
752 fLinkToDestinations.deleteAll(); | 752 fLinkToDestinations.deleteAll(); |
753 fNamedDestinations.deleteAll(); | 753 fNamedDestinations.deleteAll(); |
754 | 754 |
755 if (clearFontUsage) { | 755 if (clearFontUsage) { |
756 fFontGlyphUsage->reset(); | 756 fFontGlyphUsage->reset(); |
757 } | 757 } |
758 } | 758 } |
759 | 759 |
| 760 void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char
key[], |
| 761 SkData* value) { |
| 762 if (0 == rect.width() && 0 == rect.height()) { |
| 763 handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value); |
| 764 } else { |
| 765 SkPath path; |
| 766 path.addRect(rect); |
| 767 handlePathAnnotation(path, d, key, value); |
| 768 } |
| 769 } |
| 770 |
760 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { | 771 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { |
761 SkPaint newPaint = paint; | 772 SkPaint newPaint = paint; |
762 replace_srcmode_on_opaque_paint(&newPaint); | 773 replace_srcmode_on_opaque_paint(&newPaint); |
763 | 774 |
764 newPaint.setStyle(SkPaint::kFill_Style); | 775 newPaint.setStyle(SkPaint::kFill_Style); |
765 ScopedContentEntry content(this, d, newPaint); | 776 ScopedContentEntry content(this, d, newPaint); |
766 internalDrawPaint(newPaint, content.entry()); | 777 internalDrawPaint(newPaint, content.entry()); |
767 } | 778 } |
768 | 779 |
769 void SkPDFDevice::internalDrawPaint(const SkPaint& paint, | 780 void SkPDFDevice::internalDrawPaint(const SkPaint& paint, |
(...skipping 19 matching lines...) Expand all Loading... |
789 size_t count, | 800 size_t count, |
790 const SkPoint* points, | 801 const SkPoint* points, |
791 const SkPaint& srcPaint) { | 802 const SkPaint& srcPaint) { |
792 SkPaint passedPaint = srcPaint; | 803 SkPaint passedPaint = srcPaint; |
793 replace_srcmode_on_opaque_paint(&passedPaint); | 804 replace_srcmode_on_opaque_paint(&passedPaint); |
794 | 805 |
795 if (count == 0) { | 806 if (count == 0) { |
796 return; | 807 return; |
797 } | 808 } |
798 | 809 |
799 if (SkAnnotation* annotation = passedPaint.getAnnotation()) { | |
800 if (handlePointAnnotation(points, count, *d.fMatrix, annotation)) { | |
801 return; | |
802 } | |
803 } | |
804 | |
805 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath. | 810 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath. |
806 // We only use this when there's a path effect because of the overhead | 811 // We only use this when there's a path effect because of the overhead |
807 // of multiple calls to setUpContentEntry it causes. | 812 // of multiple calls to setUpContentEntry it causes. |
808 if (passedPaint.getPathEffect()) { | 813 if (passedPaint.getPathEffect()) { |
809 if (d.fClip->isEmpty()) { | 814 if (d.fClip->isEmpty()) { |
810 return; | 815 return; |
811 } | 816 } |
812 SkDraw pointDraw(d); | 817 SkDraw pointDraw(d); |
813 pointDraw.fDevice = this; | 818 pointDraw.fDevice = this; |
814 pointDraw.drawPoints(mode, count, points, passedPaint, true); | 819 pointDraw.drawPoints(mode, count, points, passedPaint, true); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 if (paint.getPathEffect()) { | 937 if (paint.getPathEffect()) { |
933 if (d.fClip->isEmpty()) { | 938 if (d.fClip->isEmpty()) { |
934 return; | 939 return; |
935 } | 940 } |
936 SkPath path; | 941 SkPath path; |
937 path.addRect(r); | 942 path.addRect(r); |
938 drawPath(d, path, paint, nullptr, true); | 943 drawPath(d, path, paint, nullptr, true); |
939 return; | 944 return; |
940 } | 945 } |
941 | 946 |
942 if (SkAnnotation* annotation = paint.getAnnotation()) { | |
943 SkPath path; | |
944 path.addRect(rect); | |
945 if (handlePathAnnotation(path, d, annotation)) { | |
946 return; | |
947 } | |
948 } | |
949 | |
950 ScopedContentEntry content(this, d, paint); | 947 ScopedContentEntry content(this, d, paint); |
951 if (!content.entry()) { | 948 if (!content.entry()) { |
952 return; | 949 return; |
953 } | 950 } |
954 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent); | 951 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent); |
955 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, | 952 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, |
956 &content.entry()->fContent); | 953 &content.entry()->fContent); |
957 } | 954 } |
958 | 955 |
959 void SkPDFDevice::drawRRect(const SkDraw& draw, | 956 void SkPDFDevice::drawRRect(const SkDraw& draw, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 noEffectPaint.setStrokeWidth(0); | 1015 noEffectPaint.setStrokeWidth(0); |
1019 } | 1016 } |
1020 drawPath(d, *pathPtr, noEffectPaint, nullptr, true); | 1017 drawPath(d, *pathPtr, noEffectPaint, nullptr, true); |
1021 return; | 1018 return; |
1022 } | 1019 } |
1023 | 1020 |
1024 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) { | 1021 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) { |
1025 return; | 1022 return; |
1026 } | 1023 } |
1027 | 1024 |
1028 if (SkAnnotation* annotation = paint.getAnnotation()) { | |
1029 if (handlePathAnnotation(*pathPtr, d, annotation)) { | |
1030 return; | |
1031 } | |
1032 } | |
1033 | |
1034 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); | 1025 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); |
1035 if (!content.entry()) { | 1026 if (!content.entry()) { |
1036 return; | 1027 return; |
1037 } | 1028 } |
1038 bool consumeDegeratePathSegments = | 1029 bool consumeDegeratePathSegments = |
1039 paint.getStyle() == SkPaint::kFill_Style || | 1030 paint.getStyle() == SkPaint::kFill_Style || |
1040 (paint.getStrokeCap() != SkPaint::kRound_Cap && | 1031 (paint.getStrokeCap() != SkPaint::kRound_Cap && |
1041 paint.getStrokeCap() != SkPaint::kSquare_Cap); | 1032 paint.getStrokeCap() != SkPaint::kSquare_Cap); |
1042 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), | 1033 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), |
1043 consumeDegeratePathSegments, | 1034 consumeDegeratePathSegments, |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1677 paint.getStrokeWidth() + SK_Scalar1); | 1668 paint.getStrokeWidth() + SK_Scalar1); |
1678 | 1669 |
1679 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) { | 1670 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) { |
1680 return false; | 1671 return false; |
1681 } | 1672 } |
1682 | 1673 |
1683 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true); | 1674 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true); |
1684 return true; | 1675 return true; |
1685 } | 1676 } |
1686 | 1677 |
1687 bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count, | 1678 void SkPDFDevice::handlePointAnnotation(const SkPoint& point, |
1688 const SkMatrix& matrix, | 1679 const SkMatrix& matrix, |
1689 SkAnnotation* annotationInfo) { | 1680 const char key[], SkData* value) { |
1690 SkData* nameData = annotationInfo->find( | 1681 if (!value) { |
1691 SkAnnotationKeys::Define_Named_Dest_Key()); | 1682 return; |
1692 if (nameData) { | |
1693 for (size_t i = 0; i < count; i++) { | |
1694 SkPoint transformedPoint; | |
1695 matrix.mapXY(points[i].x(), points[i].y(), &transformedPoint); | |
1696 fNamedDestinations.push(new NamedDestination(nameData, transformedPo
int)); | |
1697 } | |
1698 return true; | |
1699 } | 1683 } |
1700 return false; | 1684 |
| 1685 if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) { |
| 1686 SkPoint transformedPoint; |
| 1687 matrix.mapXY(point.x(), point.y(), &transformedPoint); |
| 1688 fNamedDestinations.push(new NamedDestination(value, transformedPoint)); |
| 1689 } |
1701 } | 1690 } |
1702 | 1691 |
1703 bool SkPDFDevice::handlePathAnnotation(const SkPath& path, | 1692 void SkPDFDevice::handlePathAnnotation(const SkPath& path, |
1704 const SkDraw& d, | 1693 const SkDraw& d, |
1705 SkAnnotation* annotation) { | 1694 const char key[], SkData* value) { |
1706 SkASSERT(annotation); | 1695 if (!value) { |
| 1696 return; |
| 1697 } |
1707 | 1698 |
1708 SkPath transformedPath = path; | 1699 SkPath transformedPath = path; |
1709 transformedPath.transform(*d.fMatrix); | 1700 transformedPath.transform(*d.fMatrix); |
1710 SkRasterClip clip = *d.fRC; | 1701 SkRasterClip clip = *d.fRC; |
1711 clip.op(transformedPath, SkIRect::MakeWH(width(), height()), SkRegion::kInte
rsect_Op, | 1702 clip.op(transformedPath, SkIRect::MakeWH(width(), height()), SkRegion::kInte
rsect_Op, |
1712 false); | 1703 false); |
1713 SkRect transformedRect = SkRect::Make(clip.getBounds()); | 1704 SkRect transformedRect = SkRect::Make(clip.getBounds()); |
1714 | 1705 |
1715 SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key()); | 1706 if (!strcmp(SkAnnotationKeys::URL_Key(), key)) { |
1716 if (urlData) { | |
1717 if (!transformedRect.isEmpty()) { | 1707 if (!transformedRect.isEmpty()) { |
1718 fLinkToURLs.push(new RectWithData(transformedRect, urlData)); | 1708 fLinkToURLs.push(new RectWithData(transformedRect, value)); |
1719 } | 1709 } |
1720 return true; | 1710 } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) { |
| 1711 if (!transformedRect.isEmpty()) { |
| 1712 fLinkToDestinations.push(new RectWithData(transformedRect, value)); |
| 1713 } |
1721 } | 1714 } |
1722 | |
1723 SkData* linkToDestination = | |
1724 annotation->find(SkAnnotationKeys::Link_Named_Dest_Key()); | |
1725 if (linkToDestination) { | |
1726 if (!transformedRect.isEmpty()) { | |
1727 fLinkToDestinations.push(new RectWithData(transformedRect, linkToDes
tination)); | |
1728 } | |
1729 return true; | |
1730 } | |
1731 | |
1732 return false; | |
1733 } | 1715 } |
1734 | 1716 |
1735 void SkPDFDevice::appendAnnotations(SkPDFArray* array) const { | 1717 void SkPDFDevice::appendAnnotations(SkPDFArray* array) const { |
1736 array->reserve(fLinkToURLs.count() + fLinkToDestinations.count()); | 1718 array->reserve(fLinkToURLs.count() + fLinkToDestinations.count()); |
1737 for (RectWithData* rectWithURL : fLinkToURLs) { | 1719 for (RectWithData* rectWithURL : fLinkToURLs) { |
1738 SkRect r; | 1720 SkRect r; |
1739 fInitialTransform.mapRect(&r, rectWithURL->rect); | 1721 fInitialTransform.mapRect(&r, rectWithURL->rect); |
1740 array->appendObject(create_link_to_url(rectWithURL->data, r)); | 1722 array->appendObject(create_link_to_url(rectWithURL->data, r)); |
1741 } | 1723 } |
1742 for (RectWithData* linkToDestination : fLinkToDestinations) { | 1724 for (RectWithData* linkToDestination : fLinkToDestinations) { |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2365 pdfimage.reset(SkPDFCreateBitmapObject( | 2347 pdfimage.reset(SkPDFCreateBitmapObject( |
2366 image, fCanon->fPixelSerializer)); | 2348 image, fCanon->fPixelSerializer)); |
2367 if (!pdfimage) { | 2349 if (!pdfimage) { |
2368 return; | 2350 return; |
2369 } | 2351 } |
2370 fCanon->addPDFBitmap(image->uniqueID(), pdfimage); | 2352 fCanon->addPDFBitmap(image->uniqueID(), pdfimage); |
2371 } | 2353 } |
2372 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2354 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2373 &content.entry()->fContent); | 2355 &content.entry()->fContent); |
2374 } | 2356 } |
OLD | NEW |