| 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 |