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