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

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

Issue 1752913002: SkPDF: roll back 53b1c09 and 05b48e2 (Closed) Base URL: https://skia.googlesource.com/skia.git@m49
Patch Set: Created 4 years, 9 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 | « no previous file | 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"
(...skipping 23 matching lines...) Expand all
34 #include "SkSurface.h" 34 #include "SkSurface.h"
35 #include "SkTextFormatParams.h" 35 #include "SkTextFormatParams.h"
36 #include "SkTemplates.h" 36 #include "SkTemplates.h"
37 #include "SkTypefacePriv.h" 37 #include "SkTypefacePriv.h"
38 #include "SkXfermodeInterpretation.h" 38 #include "SkXfermodeInterpretation.h"
39 39
40 #define DPI_FOR_RASTER_SCALE_ONE 72 40 #define DPI_FOR_RASTER_SCALE_ONE 72
41 41
42 // Utility functions 42 // Utility functions
43 43
44 static bool excessive_translation(const SkMatrix& m) {
45 const SkScalar kExcessiveTranslation = 8192.0f;
46 return SkScalarAbs(m.getTranslateX()) > kExcessiveTranslation
47 || SkScalarAbs(m.getTranslateY()) > kExcessiveTranslation;
48 }
49
50 static SkMatrix untranslate(const SkMatrix& matrix, SkScalar x, SkScalar y) {
51 // https://bug.skia.org/257 If the translation is too large,
52 // PDF can't exactly represent the float values as numbers.
53 SkMatrix result(matrix);
54 result.preTranslate(x, y);
55 return result;
56 }
57
58 // If the paint will definitely draw opaquely, replace kSrc_Mode with 44 // If the paint will definitely draw opaquely, replace kSrc_Mode with
59 // kSrcOver_Mode. http://crbug.com/473572 45 // kSrcOver_Mode. http://crbug.com/473572
60 static void replace_srcmode_on_opaque_paint(SkPaint* paint) { 46 static void replace_srcmode_on_opaque_paint(SkPaint* paint) {
61 if (kSrcOver_SkXfermodeInterpretation 47 if (kSrcOver_SkXfermodeInterpretation
62 == SkInterpretXfermode(*paint, false)) { 48 == SkInterpretXfermode(*paint, false)) {
63 paint->setXfermode(nullptr); 49 paint->setXfermode(nullptr);
64 } 50 }
65 } 51 }
66 52
67 static void emit_pdf_color(SkColor color, SkWStream* result) { 53 static void emit_pdf_color(SkColor color, SkWStream* result) {
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 if (!contentEntry->fState.fMatrix.invert(&inverse)) { 777 if (!contentEntry->fState.fMatrix.invert(&inverse)) {
792 return; 778 return;
793 } 779 }
794 inverse.mapRect(&bbox); 780 inverse.mapRect(&bbox);
795 781
796 SkPDFUtils::AppendRectangle(bbox, &contentEntry->fContent); 782 SkPDFUtils::AppendRectangle(bbox, &contentEntry->fContent);
797 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, 783 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType,
798 &contentEntry->fContent); 784 &contentEntry->fContent);
799 } 785 }
800 786
801 void SkPDFDevice::drawPoints(const SkDraw& srcDraw, 787 void SkPDFDevice::drawPoints(const SkDraw& d,
802 SkCanvas::PointMode mode, 788 SkCanvas::PointMode mode,
803 size_t count, 789 size_t count,
804 const SkPoint* points, 790 const SkPoint* points,
805 const SkPaint& srcPaint) { 791 const SkPaint& srcPaint) {
806 SkPaint passedPaint = srcPaint; 792 SkPaint passedPaint = srcPaint;
807 replace_srcmode_on_opaque_paint(&passedPaint); 793 replace_srcmode_on_opaque_paint(&passedPaint);
808 794
809 if (count == 0) { 795 if (count == 0) {
810 return; 796 return;
811 } 797 }
812 798
813 if (SkAnnotation* annotation = passedPaint.getAnnotation()) { 799 if (SkAnnotation* annotation = passedPaint.getAnnotation()) {
814 if (handlePointAnnotation(points, count, *srcDraw.fMatrix, annotation)) { 800 if (handlePointAnnotation(points, count, *d.fMatrix, annotation)) {
815 return; 801 return;
816 } 802 }
817 } 803 }
818 SkMatrix newMatrix;
819 SkDraw d(srcDraw);
820 SkTArray<SkPoint> pointsCopy;
821 if (excessive_translation(*d.fMatrix)) {
822 newMatrix = untranslate(*d.fMatrix, points[0].x(), points[0].y());
823 d.fMatrix = &newMatrix;
824 pointsCopy.reset(points, SkToInt(count));
825 SkPoint::Offset(&pointsCopy[0], SkToInt(count),
826 -points[0].x(), -points[0].y());
827 points = &pointsCopy[0];
828 }
829 804
830 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath. 805 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath.
831 // 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
832 // of multiple calls to setUpContentEntry it causes. 807 // of multiple calls to setUpContentEntry it causes.
833 if (passedPaint.getPathEffect()) { 808 if (passedPaint.getPathEffect()) {
834 if (d.fClip->isEmpty()) { 809 if (d.fClip->isEmpty()) {
835 return; 810 return;
836 } 811 }
837 SkDraw pointDraw(d); 812 SkDraw pointDraw(d);
838 pointDraw.fDevice = this; 813 pointDraw.fDevice = this;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 914
940 static SkPDFDict* create_link_named_dest(const SkData* nameData, 915 static SkPDFDict* create_link_named_dest(const SkData* nameData,
941 const SkRect& r) { 916 const SkRect& r) {
942 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r)); 917 SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
943 SkString name(static_cast<const char *>(nameData->data()), 918 SkString name(static_cast<const char *>(nameData->data()),
944 nameData->size() - 1); 919 nameData->size() - 1);
945 annotation->insertName("Dest", name); 920 annotation->insertName("Dest", name);
946 return annotation.detach(); 921 return annotation.detach();
947 } 922 }
948 923
949 void SkPDFDevice::drawRect(const SkDraw& srcDraw, 924 void SkPDFDevice::drawRect(const SkDraw& d,
950 const SkRect& rect, 925 const SkRect& rect,
951 const SkPaint& srcPaint) { 926 const SkPaint& srcPaint) {
952 SkPaint paint = srcPaint; 927 SkPaint paint = srcPaint;
953 replace_srcmode_on_opaque_paint(&paint); 928 replace_srcmode_on_opaque_paint(&paint);
954 SkRect r = rect; 929 SkRect r = rect;
955 r.sort(); 930 r.sort();
956 931
957 SkMatrix newMatrix;
958 SkDraw d(srcDraw);
959 if (excessive_translation(*d.fMatrix)) {
960 newMatrix = untranslate(*d.fMatrix, r.x(), r.y());
961 d.fMatrix = &newMatrix;
962 r.offsetTo(0, 0);
963 }
964
965 if (paint.getPathEffect()) { 932 if (paint.getPathEffect()) {
966 if (d.fClip->isEmpty()) { 933 if (d.fClip->isEmpty()) {
967 return; 934 return;
968 } 935 }
969 SkPath path; 936 SkPath path;
970 path.addRect(r); 937 path.addRect(r);
971 drawPath(d, path, paint, nullptr, true); 938 drawPath(d, path, paint, nullptr, true);
972 return; 939 return;
973 } 940 }
974 941
(...skipping 27 matching lines...) Expand all
1002 void SkPDFDevice::drawOval(const SkDraw& draw, 969 void SkPDFDevice::drawOval(const SkDraw& draw,
1003 const SkRect& oval, 970 const SkRect& oval,
1004 const SkPaint& srcPaint) { 971 const SkPaint& srcPaint) {
1005 SkPaint paint = srcPaint; 972 SkPaint paint = srcPaint;
1006 replace_srcmode_on_opaque_paint(&paint); 973 replace_srcmode_on_opaque_paint(&paint);
1007 SkPath path; 974 SkPath path;
1008 path.addOval(oval); 975 path.addOval(oval);
1009 this->drawPath(draw, path, paint, nullptr, true); 976 this->drawPath(draw, path, paint, nullptr, true);
1010 } 977 }
1011 978
1012 void SkPDFDevice::drawPath(const SkDraw& srcDraw, 979 void SkPDFDevice::drawPath(const SkDraw& d,
1013 const SkPath& origPath, 980 const SkPath& origPath,
1014 const SkPaint& srcPaint, 981 const SkPaint& srcPaint,
1015 const SkMatrix* prePathMatrix, 982 const SkMatrix* prePathMatrix,
1016 bool pathIsMutable) { 983 bool pathIsMutable) {
1017 SkMatrix newMatrix; 984 SkPaint paint = srcPaint;
1018 SkDraw d(srcDraw); 985 replace_srcmode_on_opaque_paint(&paint);
1019 SkPath modifiedPath; 986 SkPath modifiedPath;
1020 SkPath* pathPtr = const_cast<SkPath*>(&origPath); 987 SkPath* pathPtr = const_cast<SkPath*>(&origPath);
1021 if (excessive_translation(*d.fMatrix)) {
1022 SkPoint firstPt;
1023 if (origPath.getPoints(&firstPt, 1) > 0) {
1024 newMatrix = untranslate(*d.fMatrix, firstPt.x(), firstPt.y());
1025 d.fMatrix = &newMatrix;
1026 modifiedPath = origPath;
1027 modifiedPath.offset(-firstPt.x(), -firstPt.y());
1028 pathPtr = &modifiedPath; // NOTE: shader behavior will be off.
1029 pathIsMutable = true;
1030 }
1031 }
1032
1033 SkPaint paint = srcPaint;
1034 replace_srcmode_on_opaque_paint(&paint);
1035 988
1036 SkMatrix matrix = *d.fMatrix; 989 SkMatrix matrix = *d.fMatrix;
1037 if (prePathMatrix) { 990 if (prePathMatrix) {
1038 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) { 991 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
1039 if (pathIsMutable) { 992 if (!pathIsMutable) {
1040 pathPtr->transform(*prePathMatrix);
1041 } else {
1042 pathPtr->transform(*prePathMatrix, &modifiedPath);
1043 pathPtr = &modifiedPath; 993 pathPtr = &modifiedPath;
1044 pathIsMutable = true; 994 pathIsMutable = true;
1045 } 995 }
996 origPath.transform(*prePathMatrix, pathPtr);
1046 } else { 997 } else {
1047 matrix.preConcat(*prePathMatrix); 998 matrix.preConcat(*prePathMatrix);
1048 } 999 }
1049 } 1000 }
1050 1001
1051 if (paint.getPathEffect()) { 1002 if (paint.getPathEffect()) {
1052 if (d.fClip->isEmpty()) { 1003 if (d.fClip->isEmpty()) {
1053 return; 1004 return;
1054 } 1005 }
1055 bool fill; 1006 if (!pathIsMutable) {
1056 if (pathIsMutable) {
1057 fill = paint.getFillPath(*pathPtr, pathPtr);
1058 } else {
1059 fill = paint.getFillPath(*pathPtr, &modifiedPath);
1060 pathPtr = &modifiedPath; 1007 pathPtr = &modifiedPath;
1061 pathIsMutable = true; 1008 pathIsMutable = true;
1062 } 1009 }
1010 bool fill = paint.getFillPath(origPath, pathPtr);
1063 1011
1064 SkPaint noEffectPaint(paint); 1012 SkPaint noEffectPaint(paint);
1065 noEffectPaint.setPathEffect(nullptr); 1013 noEffectPaint.setPathEffect(nullptr);
1066 if (fill) { 1014 if (fill) {
1067 noEffectPaint.setStyle(SkPaint::kFill_Style); 1015 noEffectPaint.setStyle(SkPaint::kFill_Style);
1068 } else { 1016 } else {
1069 noEffectPaint.setStyle(SkPaint::kStroke_Style); 1017 noEffectPaint.setStyle(SkPaint::kStroke_Style);
1070 noEffectPaint.setStrokeWidth(0); 1018 noEffectPaint.setStrokeWidth(0);
1071 } 1019 }
1072 drawPath(d, *pathPtr, noEffectPaint, nullptr, true); 1020 drawPath(d, *pathPtr, noEffectPaint, nullptr, true);
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 case SkPaint::kUTF32_TextEncoding: 1264 case SkPaint::kUTF32_TextEncoding:
1317 transparent.setTextEncoding(srcPaint.getTextEncoding()); 1265 transparent.setTextEncoding(srcPaint.getTextEncoding());
1318 device->drawText(d, text, len, x, y, transparent); 1266 device->drawText(d, text, len, x, y, transparent);
1319 break; 1267 break;
1320 default: 1268 default:
1321 SkFAIL("unknown text encoding"); 1269 SkFAIL("unknown text encoding");
1322 } 1270 }
1323 } 1271 }
1324 1272
1325 1273
1326 void SkPDFDevice::drawText(const SkDraw& srcDraw, const void* text, size_t len, 1274 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
1327 SkScalar x, SkScalar y, const SkPaint& srcPaint) { 1275 SkScalar x, SkScalar y, const SkPaint& srcPaint) {
1328 SkMatrix newMatrix;
1329 SkDraw d(srcDraw);
1330 if (excessive_translation(*d.fMatrix)) {
1331 newMatrix = untranslate(*d.fMatrix, x, y);
1332 d.fMatrix = &newMatrix;
1333 x = 0;
1334 y = 0;
1335 }
1336
1337 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { 1276 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) {
1338 // https://bug.skia.org/3866 1277 // https://bug.skia.org/3866
1339 SkPath path; 1278 SkPath path;
1340 srcPaint.getTextPath(text, len, x, y, &path); 1279 srcPaint.getTextPath(text, len, x, y, &path);
1341 this->drawPath(d, path, srcPaint, &SkMatrix::I(), true); 1280 this->drawPath(d, path, srcPaint, &SkMatrix::I(), true);
1342 // Draw text transparently to make it copyable/searchable/accessable. 1281 // Draw text transparently to make it copyable/searchable/accessable.
1343 draw_transparent_text(this, d, text, len, x, y, srcPaint); 1282 draw_transparent_text(this, d, text, len, x, y, srcPaint);
1344 return; 1283 return;
1345 } 1284 }
1346 SkPaint paint = srcPaint; 1285 SkPaint paint = srcPaint;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 SkString encodedString = 1324 SkString encodedString =
1386 format_wide_string(glyphIDsCopy.begin() + consumedGlyphCount, 1325 format_wide_string(glyphIDsCopy.begin() + consumedGlyphCount,
1387 availableGlyphs, font->multiByteGlyphs()); 1326 availableGlyphs, font->multiByteGlyphs());
1388 content.entry()->fContent.writeText(encodedString.c_str()); 1327 content.entry()->fContent.writeText(encodedString.c_str());
1389 consumedGlyphCount += availableGlyphs; 1328 consumedGlyphCount += availableGlyphs;
1390 content.entry()->fContent.writeText(" Tj\n"); 1329 content.entry()->fContent.writeText(" Tj\n");
1391 } 1330 }
1392 content.entry()->fContent.writeText("ET\n"); 1331 content.entry()->fContent.writeText("ET\n");
1393 } 1332 }
1394 1333
1395 void SkPDFDevice::drawPosText(const SkDraw& srcDraw, const void* text, size_t le n, 1334 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
1396 const SkScalar pos[], int scalarsPerPos, 1335 const SkScalar pos[], int scalarsPerPos,
1397 const SkPoint& srcOffset, const SkPaint& srcPaint) { 1336 const SkPoint& offset, const SkPaint& srcPaint) {
1398 if (len == 0) {
1399 return;
1400 }
1401 SkMatrix newMatrix;
1402 SkDraw d(srcDraw);
1403 SkPoint offset(srcOffset);
1404 SkAutoTMalloc<SkScalar> scalarsBuffer;
1405 if (excessive_translation(*d.fMatrix)) {
1406 SkPoint first;
1407 if (scalarsPerPos != 2) {
1408 first.set(pos[0], 0);
1409 } else {
1410 first.set(pos[0], pos[1]);
1411 }
1412 newMatrix = untranslate(*d.fMatrix,
1413 first.x() + offset.x(),
1414 first.y() + offset.y());
1415 d.fMatrix = &newMatrix;
1416 offset.set(0, 0); // offset -= offset;
1417 if (first.x() != 0 || first.y() != 0) {
1418 int glyphCount = srcPaint.textToGlyphs(text, len, NULL);
1419 if (scalarsPerPos != 2) {
1420 scalarsBuffer.reset(glyphCount);
1421 for (int i = 0; i < glyphCount; ++i) {
1422 scalarsBuffer[i] = pos[i] - first.x();
1423 }
1424 } else {
1425 scalarsBuffer.reset(2 * glyphCount);
1426 for (int i = 0; i < glyphCount; ++i) {
1427 scalarsBuffer[2 * i] = pos[2 * i] - first.x();
1428 scalarsBuffer[2 * i + 1] = pos[2 * i + 1] - first.y();
1429 }
1430 }
1431 pos = &scalarsBuffer[0];
1432 }
1433 }
1434
1435 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) { 1337 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fCanon)) {
1436 const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos); 1338 const SkPoint* positions = reinterpret_cast<const SkPoint*>(pos);
1437 SkAutoTMalloc<SkPoint> positionsBuffer; 1339 SkAutoTMalloc<SkPoint> positionsBuffer;
1438 if (2 != scalarsPerPos) { 1340 if (2 != scalarsPerPos) {
1439 int glyphCount = srcPaint.textToGlyphs(text, len, NULL); 1341 int glyphCount = srcPaint.textToGlyphs(text, len, NULL);
1440 positionsBuffer.reset(glyphCount); 1342 positionsBuffer.reset(glyphCount);
1441 for (int i = 0; i < glyphCount; ++i) { 1343 for (int i = 0; i < glyphCount; ++i) {
1442 positionsBuffer[i].set(pos[i], 0.0f); 1344 positionsBuffer[i].set(pos[i], 0.0f);
1443 } 1345 }
1444 positions = &positionsBuffer[0]; 1346 positions = &positionsBuffer[0];
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after
2462 pdfimage.reset(SkPDFCreateBitmapObject( 2364 pdfimage.reset(SkPDFCreateBitmapObject(
2463 image, fCanon->fPixelSerializer)); 2365 image, fCanon->fPixelSerializer));
2464 if (!pdfimage) { 2366 if (!pdfimage) {
2465 return; 2367 return;
2466 } 2368 }
2467 fCanon->addPDFBitmap(image->uniqueID(), pdfimage); 2369 fCanon->addPDFBitmap(image->uniqueID(), pdfimage);
2468 } 2370 }
2469 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), 2371 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()),
2470 &content.entry()->fContent); 2372 &content.entry()->fContent);
2471 } 2373 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698