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

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: Fix warnings Created 5 years, 4 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
« src/doc/SkDocument_PDF.cpp ('K') | « 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 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 //////////////////////////////////////////////////////////////////////////////// 706 ////////////////////////////////////////////////////////////////////////////////
706 707
707 SkPDFDevice::SkPDFDevice(SkISize pageSize, 708 SkPDFDevice::SkPDFDevice(SkISize pageSize,
708 SkScalar rasterDpi, 709 SkScalar rasterDpi,
709 SkPDFCanon* canon, 710 SkPDFCanon* canon,
710 bool flip) 711 bool flip)
711 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry)) 712 : INHERITED(SkSurfaceProps(0, kUnknown_SkPixelGeometry))
712 , fPageSize(pageSize) 713 , fPageSize(pageSize)
713 , fContentSize(pageSize) 714 , fContentSize(pageSize)
714 , fExistingClipRegion(SkIRect::MakeSize(pageSize)) 715 , fExistingClipRegion(SkIRect::MakeSize(pageSize))
715 , fAnnotations(NULL)
716 , fLastContentEntry(NULL) 716 , fLastContentEntry(NULL)
717 , fLastMarginContentEntry(NULL) 717 , fLastMarginContentEntry(NULL)
718 , fDrawingArea(kContent_DrawingArea) 718 , fDrawingArea(kContent_DrawingArea)
719 , fClipStack(NULL) 719 , fClipStack(NULL)
720 , fFontGlyphUsage(SkNEW(SkPDFGlyphSetMap)) 720 , fFontGlyphUsage(SkNEW(SkPDFGlyphSetMap))
721 , fRasterDpi(rasterDpi) 721 , fRasterDpi(rasterDpi)
722 , fCanon(canon) { 722 , fCanon(canon) {
723 SkASSERT(pageSize.width() > 0); 723 SkASSERT(pageSize.width() > 0);
724 SkASSERT(pageSize.height() > 0); 724 SkASSERT(pageSize.height() > 0);
725 fLegacyBitmap.setInfo( 725 fLegacyBitmap.setInfo(
726 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height())); 726 SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()));
727 if (flip) { 727 if (flip) {
728 // Skia generally uses the top left as the origin but PDF 728 // Skia generally uses the top left as the origin but PDF
729 // natively has the origin at the bottom left. This matrix 729 // natively has the origin at the bottom left. This matrix
730 // corrects for that. But that only needs to be done once, we 730 // corrects for that. But that only needs to be done once, we
731 // don't do it when layering. 731 // don't do it when layering.
732 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); 732 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight));
733 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); 733 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
734 } else { 734 } else {
735 fInitialTransform.setIdentity(); 735 fInitialTransform.setIdentity();
736 } 736 }
737 } 737 }
738 738
739 SkPDFDevice::~SkPDFDevice() { 739 SkPDFDevice::~SkPDFDevice() {
740 this->cleanUp(true); 740 this->cleanUp(true);
741 } 741 }
742 742
743 void SkPDFDevice::init() { 743 void SkPDFDevice::init() {
744 fAnnotations = NULL;
745 fContentEntries.free(); 744 fContentEntries.free();
746 fLastContentEntry = NULL; 745 fLastContentEntry = NULL;
747 fMarginContentEntries.free(); 746 fMarginContentEntries.free();
748 fLastMarginContentEntry = NULL; 747 fLastMarginContentEntry = NULL;
749 fDrawingArea = kContent_DrawingArea; 748 fDrawingArea = kContent_DrawingArea;
750 if (fFontGlyphUsage.get() == NULL) { 749 if (fFontGlyphUsage.get() == NULL) {
751 fFontGlyphUsage.reset(SkNEW(SkPDFGlyphSetMap)); 750 fFontGlyphUsage.reset(SkNEW(SkPDFGlyphSetMap));
752 } 751 }
753 } 752 }
754 753
755 void SkPDFDevice::cleanUp(bool clearFontUsage) { 754 void SkPDFDevice::cleanUp(bool clearFontUsage) {
756 fGraphicStateResources.unrefAll(); 755 fGraphicStateResources.unrefAll();
757 fXObjectResources.unrefAll(); 756 fXObjectResources.unrefAll();
758 fFontResources.unrefAll(); 757 fFontResources.unrefAll();
759 fShaderResources.unrefAll(); 758 fShaderResources.unrefAll();
760 SkSafeUnref(fAnnotations); 759 fLinkToURLs.deleteAll();
760 fLinkToDestinations.deleteAll();
761 fNamedDestinations.deleteAll(); 761 fNamedDestinations.deleteAll();
762 762
763 if (clearFontUsage) { 763 if (clearFontUsage) {
764 fFontGlyphUsage->reset(); 764 fFontGlyphUsage->reset();
765 } 765 }
766 } 766 }
767 767
768 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { 768 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
769 SkPaint newPaint = paint; 769 SkPaint newPaint = paint;
770 replace_srcmode_on_opaque_paint(&newPaint); 770 replace_srcmode_on_opaque_paint(&newPaint);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 &content.entry()->fContent); 879 &content.entry()->fContent);
880 SkPDFUtils::ClosePath(&content.entry()->fContent); 880 SkPDFUtils::ClosePath(&content.entry()->fContent);
881 SkPDFUtils::StrokePath(&content.entry()->fContent); 881 SkPDFUtils::StrokePath(&content.entry()->fContent);
882 } 882 }
883 break; 883 break;
884 default: 884 default:
885 SkASSERT(false); 885 SkASSERT(false);
886 } 886 }
887 } 887 }
888 888
889 static SkPath transform_and_clip_path(const SkDraw& d,
890 const SkPath& region,
891 const SkMatrix& initialTransform) {
892 SkPath path = region;
893 SkMatrix transform = *d.fMatrix;
894 transform.postConcat(initialTransform);
895 path.transform(transform);
896 if (const SkClipStack* clipStack = d.fClipStack) {
897 SkPath clip;
898 (void)clipStack->asPath(&clip);
899 clip.transform(initialTransform);
900 Op(clip, path, SkPathOp::kIntersect_SkPathOp, &path);
901 }
902 return path;
903 }
904
905 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) { 889 static SkPDFDict* create_link_annotation(const SkRect& translatedRect) {
906 SkAutoTUnref<SkPDFDict> annotation(SkNEW_ARGS(SkPDFDict, ("Annot"))); 890 SkAutoTUnref<SkPDFDict> annotation(SkNEW_ARGS(SkPDFDict, ("Annot")));
907 annotation->insertName("Subtype", "Link"); 891 annotation->insertName("Subtype", "Link");
908 892
909 SkAutoTUnref<SkPDFArray> border(SkNEW(SkPDFArray)); 893 SkAutoTUnref<SkPDFArray> border(SkNEW(SkPDFArray));
910 border->reserve(3); 894 border->reserve(3);
911 border->appendInt(0); // Horizontal corner radius. 895 border->appendInt(0); // Horizontal corner radius.
912 border->appendInt(0); // Vertical corner radius. 896 border->appendInt(0); // Vertical corner radius.
913 border->appendInt(0); // Width, 0 = no border. 897 border->appendInt(0); // Width, 0 = no border.
914 annotation->insertObject("Border", border.detach()); 898 annotation->insertObject("Border", border.detach());
915 899
916 SkAutoTUnref<SkPDFArray> rect(SkNEW(SkPDFArray)); 900 SkAutoTUnref<SkPDFArray> rect(SkNEW(SkPDFArray));
917 rect->reserve(4); 901 rect->reserve(4);
918 rect->appendScalar(translatedRect.fLeft); 902 rect->appendScalar(translatedRect.fLeft);
919 rect->appendScalar(translatedRect.fTop); 903 rect->appendScalar(translatedRect.fTop);
920 rect->appendScalar(translatedRect.fRight); 904 rect->appendScalar(translatedRect.fRight);
921 rect->appendScalar(translatedRect.fBottom); 905 rect->appendScalar(translatedRect.fBottom);
922 annotation->insertObject("Rect", rect.detach()); 906 annotation->insertObject("Rect", rect.detach());
923 907
924 return annotation.detach(); 908 return annotation.detach();
925 } 909 }
926 910
927 static SkPDFDict* create_link_to_url(SkData* urlData, const SkRect& r) { 911 static SkPDFDict* create_link_to_url(const SkData* urlData, const SkRect& r) {
928 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); 912 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
929 913
930 SkString url(static_cast<const char *>(urlData->data()), 914 SkString url(static_cast<const char *>(urlData->data()),
931 urlData->size() - 1); 915 urlData->size() - 1);
932 SkAutoTUnref<SkPDFDict> action(SkNEW_ARGS(SkPDFDict, ("Action"))); 916 SkAutoTUnref<SkPDFDict> action(SkNEW_ARGS(SkPDFDict, ("Action")));
933 action->insertName("S", "URI"); 917 action->insertName("S", "URI");
934 action->insertString("URI", url); 918 action->insertString("URI", url);
935 annotation->insertObject("A", action.detach()); 919 annotation->insertObject("A", action.detach());
936 return annotation.detach(); 920 return annotation.detach();
937 } 921 }
938 922
939 static SkPDFDict* create_link_named_dest(SkData* nameData, const SkRect& r) { 923 static SkPDFDict* create_link_named_dest(const SkData* nameData,
924 const SkRect& r) {
940 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); 925 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
941 SkString name(static_cast<const char *>(nameData->data()), 926 SkString name(static_cast<const char *>(nameData->data()),
942 nameData->size() - 1); 927 nameData->size() - 1);
943 annotation->insertName("Dest", name); 928 annotation->insertName("Dest", name);
944 return annotation.detach(); 929 return annotation.detach();
945 } 930 }
946 931
947 static SkPDFDict* create_rect_annotation(const SkRect& r,
948 SkAnnotation* annotation) {
949 SkASSERT(annotation);
950 SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key());
951 if (urlData) {
952 return create_link_to_url(urlData, r);
953 }
954 SkData* linkToName =
955 annotation->find(SkAnnotationKeys::Link_Named_Dest_Key());
956 if (linkToName) {
957 return create_link_named_dest(linkToName, r);
958 }
959 return NULL;
960 }
961
962 void SkPDFDevice::drawRect(const SkDraw& d, 932 void SkPDFDevice::drawRect(const SkDraw& d,
963 const SkRect& rect, 933 const SkRect& rect,
964 const SkPaint& srcPaint) { 934 const SkPaint& srcPaint) {
965 SkPaint paint = srcPaint; 935 SkPaint paint = srcPaint;
966 replace_srcmode_on_opaque_paint(&paint); 936 replace_srcmode_on_opaque_paint(&paint);
967 SkRect r = rect; 937 SkRect r = rect;
968 r.sort(); 938 r.sort();
969 939
970 if (paint.getPathEffect()) { 940 if (paint.getPathEffect()) {
971 if (d.fClip->isEmpty()) { 941 if (d.fClip->isEmpty()) {
972 return; 942 return;
973 } 943 }
974 SkPath path; 944 SkPath path;
975 path.addRect(r); 945 path.addRect(r);
976 drawPath(d, path, paint, NULL, true); 946 drawPath(d, path, paint, NULL, true);
977 return; 947 return;
978 } 948 }
979 949
980 if (SkAnnotation* annotation = paint.getAnnotation()) { 950 if (SkAnnotation* annotation = paint.getAnnotation()) {
981 SkPath path; 951 SkPath path;
982 path.addRect(rect); 952 path.addRect(rect);
983 SkRect transformedRect = 953 if (handlePathAnnotation(path, d, annotation)) {
984 transform_and_clip_path(d, path, fInitialTransform).getBounds();
985 SkAutoTUnref<SkPDFDict> annot(
986 create_rect_annotation(transformedRect, annotation));
987 if (annot) {
988 this->addAnnotation(annot.detach());
989 return; 954 return;
990 } 955 }
991 } 956 }
992 957
993 ScopedContentEntry content(this, d, paint); 958 ScopedContentEntry content(this, d, paint);
994 if (!content.entry()) { 959 if (!content.entry()) {
995 return; 960 return;
996 } 961 }
997 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent); 962 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent);
998 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, 963 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 } 1027 }
1063 drawPath(d, *pathPtr, noEffectPaint, NULL, true); 1028 drawPath(d, *pathPtr, noEffectPaint, NULL, true);
1064 return; 1029 return;
1065 } 1030 }
1066 1031
1067 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) { 1032 if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) {
1068 return; 1033 return;
1069 } 1034 }
1070 1035
1071 if (SkAnnotation* annotation = paint.getAnnotation()) { 1036 if (SkAnnotation* annotation = paint.getAnnotation()) {
1072 SkRect transformedRect = 1037 if (handlePathAnnotation(*pathPtr, d, annotation)) {
1073 transform_and_clip_path(d, *pathPtr, fInitialTransform)
1074 .getBounds();
1075 SkAutoTUnref<SkPDFDict> annot(
1076 create_rect_annotation(transformedRect, annotation));
1077 if (annot) {
1078 this->addAnnotation(annot.detach());
1079 return; 1038 return;
1080 } 1039 }
1081 } 1040 }
1082 1041
1083 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); 1042 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
1084 if (!content.entry()) { 1043 if (!content.entry()) {
1085 return; 1044 return;
1086 } 1045 }
1087 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), 1046 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(),
1088 &content.entry()->fContent); 1047 &content.entry()->fContent);
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 int vertexCount, const SkPoint verts[], 1289 int vertexCount, const SkPoint verts[],
1331 const SkPoint texs[], const SkColor colors[], 1290 const SkPoint texs[], const SkColor colors[],
1332 SkXfermode* xmode, const uint16_t indices[], 1291 SkXfermode* xmode, const uint16_t indices[],
1333 int indexCount, const SkPaint& paint) { 1292 int indexCount, const SkPaint& paint) {
1334 if (d.fClip->isEmpty()) { 1293 if (d.fClip->isEmpty()) {
1335 return; 1294 return;
1336 } 1295 }
1337 // TODO: implement drawVertices 1296 // TODO: implement drawVertices
1338 } 1297 }
1339 1298
1299 struct RectWithData {
1300 SkRect rect;
1301 SkAutoTUnref<const SkData> data;
1302
1303 RectWithData(const SkRect& rect, const SkData* data)
1304 : rect(rect), data(SkRef(data)) {}
1305 };
1306
1307 struct NamedDestination {
1308 SkAutoTUnref<const SkData> nameData;
1309 SkPoint point;
1310
1311 NamedDestination(const SkData* nameData, const SkPoint& point)
1312 : nameData(SkRef(nameData)), point(point) {}
1313 };
1314
1340 void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device, 1315 void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
1341 int x, int y, const SkPaint& paint) { 1316 int x, int y, const SkPaint& paint) {
1342 // our onCreateCompatibleDevice() always creates SkPDFDevice subclasses. 1317 // our onCreateCompatibleDevice() always creates SkPDFDevice subclasses.
1343 SkPDFDevice* pdfDevice = static_cast<SkPDFDevice*>(device); 1318 SkPDFDevice* pdfDevice = static_cast<SkPDFDevice*>(device);
1319
1320 SkScalar scalarX = SkIntToScalar(x);
1321 SkScalar scalarY = SkIntToScalar(y);
1322 for (RectWithData* link : pdfDevice->fLinkToURLs) {
1323 fLinkToURLs.push(SkNEW_ARGS(
1324 RectWithData,
1325 (link->rect.makeOffset(scalarX, scalarY), link->data)));
1326 }
1327 for (RectWithData* link : pdfDevice->fLinkToDestinations) {
1328 fLinkToDestinations.push(SkNEW_ARGS(
1329 RectWithData,
1330 (link->rect.makeOffset(scalarX, scalarY), link->data)));
1331 }
1332 for (NamedDestination* d : pdfDevice->fNamedDestinations) {
1333 fNamedDestinations.push(SkNEW_ARGS(
1334 NamedDestination,
1335 (d->nameData, d->point + SkPoint::Make(scalarX, scalarY))));
1336 }
1337
1344 if (pdfDevice->isContentEmpty()) { 1338 if (pdfDevice->isContentEmpty()) {
1345 return; 1339 return;
1346 } 1340 }
1347 1341
1348 SkMatrix matrix; 1342 SkMatrix matrix;
1349 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 1343 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
1350 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); 1344 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
1351 if (!content.entry()) { 1345 if (!content.entry()) {
1352 return; 1346 return;
1353 } 1347 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 paint.getStrokeWidth() + SK_Scalar1); 1554 paint.getStrokeWidth() + SK_Scalar1);
1561 1555
1562 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) { 1556 if (!calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) {
1563 return false; 1557 return false;
1564 } 1558 }
1565 1559
1566 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true); 1560 drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true);
1567 return true; 1561 return true;
1568 } 1562 }
1569 1563
1570 struct NamedDestination {
1571 SkAutoTUnref<const SkData> nameData;
1572 SkPoint point;
1573
1574 NamedDestination(const SkData* nameData, const SkPoint& point)
1575 : nameData(SkRef(nameData)), point(point) {}
1576 };
1577
1578 bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count, 1564 bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count,
1579 const SkMatrix& matrix, 1565 const SkMatrix& matrix,
1580 SkAnnotation* annotationInfo) { 1566 SkAnnotation* annotationInfo) {
1581 SkData* nameData = annotationInfo->find( 1567 SkData* nameData = annotationInfo->find(
1582 SkAnnotationKeys::Define_Named_Dest_Key()); 1568 SkAnnotationKeys::Define_Named_Dest_Key());
1583 if (nameData) { 1569 if (nameData) {
1584 SkMatrix transform = matrix;
1585 transform.postConcat(fInitialTransform);
1586 for (size_t i = 0; i < count; i++) { 1570 for (size_t i = 0; i < count; i++) {
1587 SkPoint translatedPoint; 1571 SkPoint transformedPoint;
1588 transform.mapXY(points[i].x(), points[i].y(), &translatedPoint); 1572 matrix.mapXY(points[i].x(), points[i].y(), &transformedPoint);
1589 fNamedDestinations.push( 1573 fNamedDestinations.push(
1590 SkNEW_ARGS(NamedDestination, (nameData, translatedPoint))); 1574 SkNEW_ARGS(NamedDestination, (nameData, transformedPoint)));
1591
1592 } 1575 }
1593 return true; 1576 return true;
1594 } 1577 }
1595 return false; 1578 return false;
1596 } 1579 }
1597 1580
1598 void SkPDFDevice::addAnnotation(SkPDFDict* annotation) { 1581 bool SkPDFDevice::handlePathAnnotation(const SkPath& path,
1599 if (NULL == fAnnotations) { 1582 const SkDraw& d,
1600 fAnnotations = SkNEW(SkPDFArray); 1583 SkAnnotation* annotation) {
1584 SkASSERT(annotation);
1585
1586 SkPath transformedPath = path;
1587 transformedPath.transform(*d.fMatrix);
1588 SkRasterClip clip = *d.fRC;
1589 clip.op(transformedPath, SkISize::Make(width(), height()), SkRegion::kInters ect_Op, false);
1590 SkRect transformedRect = SkRect::Make(clip.getBounds());
1591
1592 SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key());
1593 if (urlData) {
1594 if (!transformedRect.isEmpty()) {
1595 fLinkToURLs.push(SkNEW_ARGS(
1596 RectWithData, (transformedRect, urlData)));
1597 }
1598 return true;
1601 } 1599 }
1602 fAnnotations->appendObject(annotation); 1600
1601 SkData* linkToDestination =
1602 annotation->find(SkAnnotationKeys::Link_Named_Dest_Key());
1603 if (linkToDestination) {
1604 if (!transformedRect.isEmpty()) {
1605 fLinkToDestinations.push(SkNEW_ARGS(
1606 RectWithData, (transformedRect, linkToDestination)));
1607 }
1608 return true;
1609 }
1610
1611 return false;
1603 } 1612 }
1604 1613
1614 void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
1615 array->reserve(fLinkToURLs.count() + fLinkToDestinations.count());
1616 for (RectWithData* rectWithURL : fLinkToURLs) {
1617 SkRect r;
1618 fInitialTransform.mapRect(&r, rectWithURL->rect);
1619 array->appendObject(create_link_to_url(rectWithURL->data, r));
1620 }
1621 for (RectWithData* linkToDestination : fLinkToDestinations) {
1622 SkRect r;
1623 fInitialTransform.mapRect(&r, linkToDestination->rect);
1624 array->appendObject(create_link_named_dest(linkToDestination->data, r));
1625 }
1626 }
1605 1627
1606 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const { 1628 void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const {
1607 int nDest = fNamedDestinations.count(); 1629 for (NamedDestination* dest : fNamedDestinations) {
1608 for (int i = 0; i < nDest; i++) {
1609 NamedDestination* dest = fNamedDestinations[i];
1610 SkAutoTUnref<SkPDFArray> pdfDest(SkNEW(SkPDFArray)); 1630 SkAutoTUnref<SkPDFArray> pdfDest(SkNEW(SkPDFArray));
1611 pdfDest->reserve(5); 1631 pdfDest->reserve(5);
1612 pdfDest->appendObjRef(SkRef(page)); 1632 pdfDest->appendObjRef(SkRef(page));
1613 pdfDest->appendName("XYZ"); 1633 pdfDest->appendName("XYZ");
1614 pdfDest->appendScalar(dest->point.x()); 1634 SkPoint p = fInitialTransform.mapXY(dest->point.x(), dest->point.y());
1615 pdfDest->appendScalar(dest->point.y()); 1635 pdfDest->appendScalar(p.x());
1636 pdfDest->appendScalar(p.y());
1616 pdfDest->appendInt(0); // Leave zoom unchanged 1637 pdfDest->appendInt(0); // Leave zoom unchanged
1617 SkString name(static_cast<const char*>(dest->nameData->data())); 1638 SkString name(static_cast<const char*>(dest->nameData->data()));
1618 dict->insertObject(name, pdfDest.detach()); 1639 dict->insertObject(name, pdfDest.detach());
1619 } 1640 }
1620 } 1641 }
1621 1642
1622 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() { 1643 SkPDFFormXObject* SkPDFDevice::createFormXObjectFromDevice() {
1623 SkPDFFormXObject* xobject = SkNEW_ARGS(SkPDFFormXObject, (this)); 1644 SkPDFFormXObject* xobject = SkNEW_ARGS(SkPDFFormXObject, (this));
1624 // We always draw the form xobjects that we create back into the device, so 1645 // We always draw the form xobjects that we create back into the device, so
1625 // we simply preserve the font usage instead of pulling it out and merging 1646 // 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
2202 return; 2223 return;
2203 } 2224 }
2204 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap)); 2225 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap));
2205 if (!image) { 2226 if (!image) {
2206 return; 2227 return;
2207 } 2228 }
2208 2229
2209 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), 2230 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()),
2210 &content.entry()->fContent); 2231 &content.entry()->fContent);
2211 } 2232 }
OLDNEW
« src/doc/SkDocument_PDF.cpp ('K') | « src/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698