Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/pdf/SkPDFDevice.cpp

Issue 1257533004: Merge sub-device annotations in SkPDFDevice::drawDevice() (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase and address comment Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "SkColor.h" 11 #include "SkColor.h"
12 #include "SkClipStack.h" 12 #include "SkClipStack.h"
13 #include "SkData.h" 13 #include "SkData.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 "SkPDFFont.h" 20 #include "SkPDFFont.h"
21 #include "SkPDFFormXObject.h" 21 #include "SkPDFFormXObject.h"
22 #include "SkPDFGraphicState.h" 22 #include "SkPDFGraphicState.h"
23 #include "SkPDFResourceDict.h" 23 #include "SkPDFResourceDict.h"
24 #include "SkPDFShader.h" 24 #include "SkPDFShader.h"
25 #include "SkPDFStream.h" 25 #include "SkPDFStream.h"
26 #include "SkPDFTypes.h" 26 #include "SkPDFTypes.h"
27 #include "SkPDFUtils.h" 27 #include "SkPDFUtils.h"
28 #include "SkRasterClip.h"
28 #include "SkRect.h" 29 #include "SkRect.h"
29 #include "SkRRect.h" 30 #include "SkRRect.h"
30 #include "SkString.h" 31 #include "SkString.h"
31 #include "SkSurface.h" 32 #include "SkSurface.h"
32 #include "SkTextFormatParams.h" 33 #include "SkTextFormatParams.h"
33 #include "SkTemplates.h" 34 #include "SkTemplates.h"
34 #include "SkTypefacePriv.h" 35 #include "SkTypefacePriv.h"
35 #include "SkXfermodeInterpretation.h" 36 #include "SkXfermodeInterpretation.h"
36 37
37 #define DPI_FOR_RASTER_SCALE_ONE 72 38 #define DPI_FOR_RASTER_SCALE_ONE 72
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 } 696 }
696 }; 697 };
697 698
698 //////////////////////////////////////////////////////////////////////////////// 699 ////////////////////////////////////////////////////////////////////////////////
699 700
700 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon , bool flip) 701 SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon , bool flip)
701 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) 702 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry))
702 , fPageSize(pageSize) 703 , fPageSize(pageSize)
703 , fContentSize(pageSize) 704 , fContentSize(pageSize)
704 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) 705 , fExistingClipRegion(SkIRect::MakeSize(pageSize))
705 , fAnnotations(nullptr)
706 , fLastContentEntry(nullptr) 706 , fLastContentEntry(nullptr)
707 , fLastMarginContentEntry(nullptr) 707 , fLastMarginContentEntry(nullptr)
708 , fDrawingArea(kContent_DrawingArea) 708 , fDrawingArea(kContent_DrawingArea)
709 , fClipStack(nullptr) 709 , fClipStack(nullptr)
710 , fFontGlyphUsage(new SkPDFGlyphSetMap) 710 , fFontGlyphUsage(new SkPDFGlyphSetMap)
711 , fRasterDpi(rasterDpi) 711 , fRasterDpi(rasterDpi)
712 , fCanon(canon) { 712 , fCanon(canon) {
713 SkASSERT(pageSize.width() > 0); 713 SkASSERT(pageSize.width() > 0);
714 SkASSERT(pageSize.height() > 0); 714 SkASSERT(pageSize.height() > 0);
715 fLegacyBitmap.setInfo( 715 fLegacyBitmap.setInfo(
716 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); 716 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()));
717 if (flip) { 717 if (flip) {
718 // Skia generally uses the top left as the origin but PDF 718 // Skia generally uses the top left as the origin but PDF
719 // natively has the origin at the bottom left. This matrix 719 // natively has the origin at the bottom left. This matrix
720 // 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
721 // don't do it when layering. 721 // don't do it when layering.
722 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); 722 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight));
723 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); 723 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
724 } else { 724 } else {
725 fInitialTransform.setIdentity(); 725 fInitialTransform.setIdentity();
726 } 726 }
727 } 727 }
728 728
729 SkPDFDevice::~SkPDFDevice() { 729 SkPDFDevice::~SkPDFDevice() {
730 this->cleanUp(true); 730 this->cleanUp(true);
731 } 731 }
732 732
733 void SkPDFDevice::init() { 733 void SkPDFDevice::init() {
734 fAnnotations = nullptr;
735 fContentEntries.free(); 734 fContentEntries.free();
736 fLastContentEntry = nullptr; 735 fLastContentEntry = nullptr;
737 fMarginContentEntries.free(); 736 fMarginContentEntries.free();
738 fLastMarginContentEntry = nullptr; 737 fLastMarginContentEntry = nullptr;
739 fDrawingArea = kContent_DrawingArea; 738 fDrawingArea = kContent_DrawingArea;
740 if (fFontGlyphUsage.get() == nullptr) { 739 if (fFontGlyphUsage.get() == nullptr) {
741 fFontGlyphUsage.reset(new SkPDFGlyphSetMap); 740 fFontGlyphUsage.reset(new SkPDFGlyphSetMap);
742 } 741 }
743 } 742 }
744 743
745 void SkPDFDevice::cleanUp(bool clearFontUsage) { 744 void SkPDFDevice::cleanUp(bool clearFontUsage) {
746 fGraphicStateResources.unrefAll(); 745 fGraphicStateResources.unrefAll();
747 fXObjectResources.unrefAll(); 746 fXObjectResources.unrefAll();
748 fFontResources.unrefAll(); 747 fFontResources.unrefAll();
749 fShaderResources.unrefAll(); 748 fShaderResources.unrefAll();
750 SkSafeUnref(fAnnotations); 749 fLinkToURLs.deleteAll();
750 fLinkToDestinations.deleteAll();
751 fNamedDestinations.deleteAll(); 751 fNamedDestinations.deleteAll();
752 752
753 if (clearFontUsage) { 753 if (clearFontUsage) {
754 fFontGlyphUsage->reset(); 754 fFontGlyphUsage->reset();
755 } 755 }
756 } 756 }
757 757
758 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { 758 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
759 SkPaint newPaint = paint; 759 SkPaint newPaint = paint;
760 replace_srcmode_on_opaque_paint(&newPaint); 760 replace_srcmode_on_opaque_paint(&newPaint);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 &content.entry()->fContent); 869 &content.entry()->fContent);
870 SkPDFUtils::ClosePath(&content.entry()->fContent); 870 SkPDFUtils::ClosePath(&content.entry()->fContent);
871 SkPDFUtils::StrokePath(&content.entry()->fContent); 871 SkPDFUtils::StrokePath(&content.entry()->fContent);
872 } 872 }
873 break; 873 break;
874 default: 874 default:
875 SkASSERT(false); 875 SkASSERT(false);
876 } 876 }
877 } 877 }
878 878
879 static SkPath transform_and_clip_path(const SkDraw& d,
880 const SkPath& region,
881 const SkMatrix& initialTransform) {
882 SkPath path = region;
883 SkMatrix transform = *d.fMatrix;
884 transform.postConcat(initialTransform);
885 path.transform(transform);
886 if (const SkClipStack* clipStack = d.fClipStack) {
887 SkPath clip;
888 (void)clipStack->asPath(&clip);
889 clip.transform(initialTransform);
890 Op(clip, path, SkPathOp::kIntersect_SkPathOp, &path);
891 }
892 return path;
893 }
894
895 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) { 879 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) {
896 SkAutoTUnref<SkPDFDict> annotation(new SkPDFDict("Annot")); 880 SkAutoTUnref<SkPDFDict> annotation(new SkPDFDict("Annot"));
897 annotation->insertName("Subtype", "Link"); 881 annotation->insertName("Subtype", "Link");
898 882
899 SkAutoTUnref<SkPDFArray> border(new SkPDFArray); 883 SkAutoTUnref<SkPDFArray> border(new SkPDFArray);
900 border->reserve(3); 884 border->reserve(3);
901 border->appendInt(0); // Horizontal corner radius. 885 border->appendInt(0); // Horizontal corner radius.
902 border->appendInt(0); // Vertical corner radius. 886 border->appendInt(0); // Vertical corner radius.
903 border->appendInt(0); // Width, 0 = no border. 887 border->appendInt(0); // Width, 0 = no border.
904 annotation->insertObject("Border", border.detach()); 888 annotation->insertObject("Border", border.detach());
905 889
906 SkAutoTUnref<SkPDFArray> rect(new SkPDFArray); 890 SkAutoTUnref<SkPDFArray> rect(new SkPDFArray);
907 rect->reserve(4); 891 rect->reserve(4);
908 rect->appendScalar(translatedRect.fLeft); 892 rect->appendScalar(translatedRect.fLeft);
909 rect->appendScalar(translatedRect.fTop); 893 rect->appendScalar(translatedRect.fTop);
910 rect->appendScalar(translatedRect.fRight); 894 rect->appendScalar(translatedRect.fRight);
911 rect->appendScalar(translatedRect.fBottom); 895 rect->appendScalar(translatedRect.fBottom);
912 annotation->insertObject("Rect", rect.detach()); 896 annotation->insertObject("Rect", rect.detach());
913 897
914 return annotation.detach(); 898 return annotation.detach();
915 } 899 }
916 900
917 static SkPDFDict* create_link_to_url(SkData* urlData, const SkRect& r) { 901 static SkPDFDict* create_link_to_url(const SkData* urlData, const SkRect& r) {
918 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); 902 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
919 903
920 SkString url(static_cast<const char *>(urlData->data()), 904 SkString url(static_cast<const char *>(urlData->data()),
921 urlData->size() - 1); 905 urlData->size() - 1);
922 SkAutoTUnref<SkPDFDict> action(new SkPDFDict("Action")); 906 SkAutoTUnref<SkPDFDict> action(new SkPDFDict("Action"));
923 action->insertName("S", "URI"); 907 action->insertName("S", "URI");
924 action->insertString("URI", url); 908 action->insertString("URI", url);
925 annotation->insertObject("A", action.detach()); 909 annotation->insertObject("A", action.detach());
926 return annotation.detach(); 910 return annotation.detach();
927 } 911 }
928 912
929 static SkPDFDict* create_link_named_dest(SkData* nameData, const SkRect& r) { 913 static SkPDFDict* create_link_named_dest(const SkData* nameData,
914 const SkRect& r) {
930 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); 915 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
931 SkString name(static_cast<const char *>(nameData->data()), 916 SkString name(static_cast<const char *>(nameData->data()),
932 nameData->size() - 1); 917 nameData->size() - 1);
933 annotation->insertName("Dest", name); 918 annotation->insertName("Dest", name);
934 return annotation.detach(); 919 return annotation.detach();
935 } 920 }
936 921
937 static SkPDFDict* create_rect_annotation(const SkRect& r,
938 SkAnnotation* annotation) {
939 SkASSERT(annotation);
940 SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key());
941 if (urlData) {
942 return create_link_to_url(urlData, r);
943 }
944 SkData* linkToName =
945 annotation->find(SkAnnotationKeys::Link_Named_Dest_Key());
946 if (linkToName) {
947 return create_link_named_dest(linkToName, r);
948 }
949 return nullptr;
950 }
951
952 void SkPDFDevice::drawRect(const SkDraw& d, 922 void SkPDFDevice::drawRect(const SkDraw& d,
953 const SkRect& rect, 923 const SkRect& rect,
954 const SkPaint& srcPaint) { 924 const SkPaint& srcPaint) {
955 SkPaint paint = srcPaint; 925 SkPaint paint = srcPaint;
956 replace_srcmode_on_opaque_paint(&paint); 926 replace_srcmode_on_opaque_paint(&paint);
957 SkRect r = rect; 927 SkRect r = rect;
958 r.sort(); 928 r.sort();
959 929
960 if (paint.getPathEffect()) { 930 if (paint.getPathEffect()) {
961 if (d.fClip->isEmpty()) { 931 if (d.fClip->isEmpty()) {
962 return; 932 return;
963 } 933 }
964 SkPath path; 934 SkPath path;
965 path.addRect(r); 935 path.addRect(r);
966 drawPath(d, path, paint, nullptr, true); 936 drawPath(d, path, paint, nullptr, true);
967 return; 937 return;
968 } 938 }
969 939
970 if (SkAnnotation* annotation = paint.getAnnotation()) { 940 if (SkAnnotation* annotation = paint.getAnnotation()) {
971 SkPath path; 941 SkPath path;
972 path.addRect(rect); 942 path.addRect(rect);
973 SkRect transformedRect = 943 if (handlePathAnnotation(path, d, annotation)) {
974 transform_and_clip_path(d, path, fInitialTransform).getBounds();
975 SkAutoTUnref<SkPDFDict> annot(
976 create_rect_annotation(transformedRect, annotation));
977 if (annot) {
978 this->addAnnotation(annot.detach());
979 return; 944 return;
980 } 945 }
981 } 946 }
982 947
983 ScopedContentEntry content(this, d, paint); 948 ScopedContentEntry content(this, d, paint);
984 if (!content.entry()) { 949 if (!content.entry()) {
985 return; 950 return;
986 } 951 }
987 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent); 952 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent);
988 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, 953 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 } 1017 }
1053 drawPath(d, *pathPtr, noEffectPaint, nullptr, true); 1018 drawPath(d, *pathPtr, noEffectPaint, nullptr, true);
1054 return; 1019 return;
1055 } 1020 }
1056 1021
1057 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) { 1022 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) {
1058 return; 1023 return;
1059 } 1024 }
1060 1025
1061 if (SkAnnotation* annotation = paint.getAnnotation()) { 1026 if (SkAnnotation* annotation = paint.getAnnotation()) {
1062 SkRect transformedRect = 1027 if (handlePathAnnotation(*pathPtr, d, annotation)) {
1063 transform_and_clip_path(d, *pathPtr, fInitialTransform)
1064 .getBounds();
1065 SkAutoTUnref<SkPDFDict> annot(
1066 create_rect_annotation(transformedRect, annotation));
1067 if (annot) {
1068 this->addAnnotation(annot.detach());
1069 return; 1028 return;
1070 } 1029 }
1071 } 1030 }
1072 1031
1073 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); 1032 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
1074 if (!content.entry()) { 1033 if (!content.entry()) {
1075 return; 1034 return;
1076 } 1035 }
1077 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), 1036 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(),
1078 &content.entry()->fContent); 1037 &content.entry()->fContent);
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 int vertexCount, const SkPoint verts[], 1279 int vertexCount, const SkPoint verts[],
1321 const SkPoint texs[], const SkColor colors[], 1280 const SkPoint texs[], const SkColor colors[],
1322 SkXfermode* xmode, const uint16_t indices[], 1281 SkXfermode* xmode, const uint16_t indices[],
1323 int indexCount, const SkPaint& paint) { 1282 int indexCount, const SkPaint& paint) {
1324 if (d.fClip->isEmpty()) { 1283 if (d.fClip->isEmpty()) {
1325 return; 1284 return;
1326 } 1285 }
1327 // TODO: implement drawVertices 1286 // TODO: implement drawVertices
1328 } 1287 }
1329 1288
1289 struct RectWithData {
1290 SkRect rect;
1291 SkAutoTUnref<const SkData> data;
1292
1293 RectWithData(const SkRect& rect, const SkData* data)
1294 : rect(rect), data(SkRef(data)) {}
1295 };
1296
1297 struct NamedDestination {
1298 SkAutoTUnref<const SkData> nameData;
1299 SkPoint point;
1300
1301 NamedDestination(const SkData* nameData, const SkPoint& point)
1302 : nameData(SkRef(nameData)), point(point) {}
1303 };
1304
1330 void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device, 1305 void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
1331 int x, int y, const SkPaint& paint) { 1306 int x, int y, const SkPaint& paint) {
1332 // our onCreateCompatibleDevice() always creates SkPDFDevice subclasses. 1307 // our onCreateCompatibleDevice() always creates SkPDFDevice subclasses.
1333 SkPDFDevice* pdfDevice = static_cast<SkPDFDevice*>(device); 1308 SkPDFDevice* pdfDevice = static_cast<SkPDFDevice*>(device);
1309
1310 SkScalar scalarX = SkIntToScalar(x);
1311 SkScalar scalarY = SkIntToScalar(y);
1312 for (RectWithData* link : pdfDevice->fLinkToURLs) {
1313 fLinkToURLs.push(new RectWithData(
1314 link->rect.makeOffset(scalarX, scalarY), link->data));
1315 }
1316 for (RectWithData* link : pdfDevice->fLinkToDestinations) {
1317 fLinkToDestinations.push(new RectWithData(
1318 link->rect.makeOffset(scalarX, scalarY), link->data));
1319 }
1320 for (NamedDestination* d : pdfDevice->fNamedDestinations) {
1321 fNamedDestinations.push(new NamedDestination(
1322 d->nameData, d->point + SkPoint::Make(scalarX, scalarY)));
1323 }
1324
1334 if (pdfDevice->isContentEmpty()) { 1325 if (pdfDevice->isContentEmpty()) {
1335 return; 1326 return;
1336 } 1327 }
1337 1328
1338 SkMatrix matrix; 1329 SkMatrix matrix;
1339 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 1330 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
1340 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); 1331 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
1341 if (!content.entry()) { 1332 if (!content.entry()) {
1342 return; 1333 return;
1343 } 1334 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 paint.getStrokeWidth() + SK_Scalar1); 1541 paint.getStrokeWidth() + SK_Scalar1);
1551 1542
1552 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) { 1543 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) {
1553 return false; 1544 return false;
1554 } 1545 }
1555 1546
1556 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true); 1547 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true);
1557 return true; 1548 return true;
1558 } 1549 }
1559 1550
1560 struct NamedDestination {
1561 SkAutoTUnref<const SkData> nameData;
1562 SkPoint point;
1563
1564 NamedDestination(const SkData* nameData, const SkPoint& point)
1565 : nameData(SkRef(nameData)), point(point) {}
1566 };
1567
1568 bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count, 1551 bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count,
1569 const SkMatrix& matrix, 1552 const SkMatrix& matrix,
1570 SkAnnotation* annotationInfo) { 1553 SkAnnotation* annotationInfo) {
1571 SkData* nameData = annotationInfo->find( 1554 SkData* nameData = annotationInfo->find(
1572 SkAnnotationKeys::Define_Named_Dest_Key()); 1555 SkAnnotationKeys::Define_Named_Dest_Key());
1573 if (nameData) { 1556 if (nameData) {
1574 SkMatrix transform = matrix;
1575 transform.postConcat(fInitialTransform);
1576 for (size_t i = 0; i < count; i++) { 1557 for (size_t i = 0; i < count; i++) {
1577 SkPoint translatedPoint; 1558 SkPoint transformedPoint;
1578 transform.mapXY(points[i].x(), points[i].y(), &translatedPoint); 1559 matrix.mapXY(points[i].x(), points[i].y(), &transformedPoint);
1579 fNamedDestinations.push(new NamedDestination(nameData, translatedPoi nt)); 1560 fNamedDestinations.push(new NamedDestination(nameData, transformedPo int));
1580 } 1561 }
1581 return true; 1562 return true;
1582 } 1563 }
1583 return false; 1564 return false;
1584 } 1565 }
1585 1566
1586 void SkPDFDevice::addAnnotation(SkPDFDict* annotation) { 1567 bool SkPDFDevice::handlePathAnnotation(const SkPath& path,
1587 if (nullptr == fAnnotations) { 1568 const SkDraw& d,
1588 fAnnotations = new SkPDFArray; 1569 SkAnnotation* annotation) {
1570 SkASSERT(annotation);
1571
1572 SkPath transformedPath = path;
1573 transformedPath.transform(*d.fMatrix);
1574 SkRasterClip clip = *d.fRC;
1575 clip.op(transformedPath, SkISize::Make(width(), height()), SkRegion::kInters ect_Op, false);
1576 SkRect transformedRect = SkRect::Make(clip.getBounds());
1577
1578 SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key());
1579 if (urlData) {
1580 if (!transformedRect.isEmpty()) {
1581 fLinkToURLs.push(new RectWithData(transformedRect, urlData));
1582 }
1583 return true;
1589 } 1584 }
1590 fAnnotations->appendObject(annotation); 1585
1586 SkData* linkToDestination =
1587 annotation->find(SkAnnotationKeys::Link_Named_Dest_Key());
1588 if (linkToDestination) {
1589 if (!transformedRect.isEmpty()) {
1590 fLinkToDestinations.push(new RectWithData(transformedRect, linkToDes tination));
1591 }
1592 return true;
1593 }
1594
1595 return false;
1591 } 1596 }
1592 1597
1598 void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
1599 array->reserve(fLinkToURLs.count() + fLinkToDestinations.count());
1600 for (RectWithData* rectWithURL : fLinkToURLs) {
1601 SkRect r;
1602 fInitialTransform.mapRect(&r, rectWithURL->rect);
1603 array->appendObject(create_link_to_url(rectWithURL->data, r));
1604 }
1605 for (RectWithData* linkToDestination : fLinkToDestinations) {
1606 SkRect r;
1607 fInitialTransform.mapRect(&r, linkToDestination->rect);
1608 array->appendObject(create_link_named_dest(linkToDestination->data, r));
1609 }
1610 }
1593 1611
1594 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { 1612 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const {
1595 int nDest = fNamedDestinations.count(); 1613 for (NamedDestination* dest : fNamedDestinations) {
1596 for (int i = 0; i < nDest; i++) {
1597 NamedDestination* dest = fNamedDestinations[i];
1598 SkAutoTUnref<SkPDFArray> pdfDest(new SkPDFArray); 1614 SkAutoTUnref<SkPDFArray> pdfDest(new SkPDFArray);
1599 pdfDest->reserve(5); 1615 pdfDest->reserve(5);
1600 pdfDest->appendObjRef(SkRef(page)); 1616 pdfDest->appendObjRef(SkRef(page));
1601 pdfDest->appendName("XYZ"); 1617 pdfDest->appendName("XYZ");
1602 pdfDest->appendScalar(dest->point.x()); 1618 SkPoint p = fInitialTransform.mapXY(dest->point.x(), dest->point.y());
1603 pdfDest->appendScalar(dest->point.y()); 1619 pdfDest->appendScalar(p.x());
1620 pdfDest->appendScalar(p.y());
1604 pdfDest->appendInt(0); // Leave zoom unchanged 1621 pdfDest->appendInt(0); // Leave zoom unchanged
1605 SkString name(static_cast<const char*>(dest->nameData->data())); 1622 SkString name(static_cast<const char*>(dest->nameData->data()));
1606 dict->insertObject(name, pdfDest.detach()); 1623 dict->insertObject(name, pdfDest.detach());
1607 } 1624 }
1608 } 1625 }
1609 1626
1610 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { 1627 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() {
1611 SkPDFFormXObject* xobject = new SkPDFFormXObject(this); 1628 SkPDFFormXObject* xobject = new SkPDFFormXObject(this);
1612 // We always draw the form xobjects that we create back into the device, so 1629 // We always draw the form xobjects that we create back into the device, so
1613 // we simply preserve the font usage instead of pulling it out and merging 1630 // we simply preserve the font usage instead of pulling it out and merging
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 return; 2207 return;
2191 } 2208 }
2192 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap)); 2209 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap));
2193 if (!image) { 2210 if (!image) {
2194 return; 2211 return;
2195 } 2212 }
2196 2213
2197 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), 2214 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()),
2198 &content.entry()->fContent); 2215 &content.entry()->fContent);
2199 } 2216 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698