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

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

Issue 1159763004: SkPDF: with opaque draws, treat SRC mode as SRC_OVER (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: unify with blitter code Created 5 years, 6 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
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 14 matching lines...) Expand all
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 "SkRect.h" 28 #include "SkRect.h"
29 #include "SkRRect.h" 29 #include "SkRRect.h"
30 #include "SkString.h" 30 #include "SkString.h"
31 #include "SkSurface.h" 31 #include "SkSurface.h"
32 #include "SkTextFormatParams.h" 32 #include "SkTextFormatParams.h"
33 #include "SkTemplates.h" 33 #include "SkTemplates.h"
34 #include "SkTypefacePriv.h" 34 #include "SkTypefacePriv.h"
35 #include "SkXfermodeInterpretation.h"
35 36
36 #define DPI_FOR_RASTER_SCALE_ONE 72 37 #define DPI_FOR_RASTER_SCALE_ONE 72
37 38
38 // Utility functions 39 // Utility functions
39 40
41 // If the paint will definitely draw opaquely, replace kSrc_Mode with
42 // kSrcOver_Mode. http://crbug.com/473572
43 static void replace_srcmode_on_opaque_paint(SkPaint* paint) {
44 if (kSrcOver_SkXfermodeInterpretation
45 == SkInterpretXfermode(*paint, false)) {
46 paint->setXfermode(NULL);
47 }
48 }
49
40 static void emit_pdf_color(SkColor color, SkWStream* result) { 50 static void emit_pdf_color(SkColor color, SkWStream* result) {
41 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere. 51 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere.
42 SkScalar colorScale = SkScalarInvert(0xFF); 52 SkScalar colorScale = SkScalarInvert(0xFF);
43 SkPDFUtils::AppendScalar(SkColorGetR(color) * colorScale, result); 53 SkPDFUtils::AppendScalar(SkColorGetR(color) * colorScale, result);
44 result->writeText(" "); 54 result->writeText(" ");
45 SkPDFUtils::AppendScalar(SkColorGetG(color) * colorScale, result); 55 SkPDFUtils::AppendScalar(SkColorGetG(color) * colorScale, result);
46 result->writeText(" "); 56 result->writeText(" ");
47 SkPDFUtils::AppendScalar(SkColorGetB(color) * colorScale, result); 57 SkPDFUtils::AppendScalar(SkColorGetB(color) * colorScale, result);
48 result->writeText(" "); 58 result->writeText(" ");
49 } 59 }
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 SkSafeUnref(fAnnotations); 759 SkSafeUnref(fAnnotations);
750 fNamedDestinations.deleteAll(); 760 fNamedDestinations.deleteAll();
751 761
752 if (clearFontUsage) { 762 if (clearFontUsage) {
753 fFontGlyphUsage->reset(); 763 fFontGlyphUsage->reset();
754 } 764 }
755 } 765 }
756 766
757 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { 767 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
758 SkPaint newPaint = paint; 768 SkPaint newPaint = paint;
769 replace_srcmode_on_opaque_paint(&newPaint);
770
759 newPaint.setStyle(SkPaint::kFill_Style); 771 newPaint.setStyle(SkPaint::kFill_Style);
760 ScopedContentEntry content(this, d, newPaint); 772 ScopedContentEntry content(this, d, newPaint);
761 internalDrawPaint(newPaint, content.entry()); 773 internalDrawPaint(newPaint, content.entry());
762 } 774 }
763 775
764 void SkPDFDevice::internalDrawPaint(const SkPaint& paint, 776 void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
765 ContentEntry* contentEntry) { 777 ContentEntry* contentEntry) {
766 if (!contentEntry) { 778 if (!contentEntry) {
767 return; 779 return;
768 } 780 }
769 SkRect bbox = SkRect::MakeWH(SkIntToScalar(this->width()), 781 SkRect bbox = SkRect::MakeWH(SkIntToScalar(this->width()),
770 SkIntToScalar(this->height())); 782 SkIntToScalar(this->height()));
771 SkMatrix inverse; 783 SkMatrix inverse;
772 if (!contentEntry->fState.fMatrix.invert(&inverse)) { 784 if (!contentEntry->fState.fMatrix.invert(&inverse)) {
773 return; 785 return;
774 } 786 }
775 inverse.mapRect(&bbox); 787 inverse.mapRect(&bbox);
776 788
777 SkPDFUtils::AppendRectangle(bbox, &contentEntry->fContent); 789 SkPDFUtils::AppendRectangle(bbox, &contentEntry->fContent);
778 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, 790 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType,
779 &contentEntry->fContent); 791 &contentEntry->fContent);
780 } 792 }
781 793
782 void SkPDFDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode, 794 void SkPDFDevice::drawPoints(const SkDraw& d,
783 size_t count, const SkPoint* points, 795 SkCanvas::PointMode mode,
784 const SkPaint& passedPaint) { 796 size_t count,
797 const SkPoint* points,
798 const SkPaint& srcPaint) {
799 SkPaint passedPaint = srcPaint;
800 replace_srcmode_on_opaque_paint(&passedPaint);
801
785 if (count == 0) { 802 if (count == 0) {
786 return; 803 return;
787 } 804 }
788 805
789 if (handlePointAnnotation(points, count, *d.fMatrix, passedPaint)) { 806 if (handlePointAnnotation(points, count, *d.fMatrix, passedPaint)) {
790 return; 807 return;
791 } 808 }
792 809
793 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath. 810 // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath.
794 // 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
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 &content.entry()->fContent); 876 &content.entry()->fContent);
860 SkPDFUtils::ClosePath(&content.entry()->fContent); 877 SkPDFUtils::ClosePath(&content.entry()->fContent);
861 SkPDFUtils::StrokePath(&content.entry()->fContent); 878 SkPDFUtils::StrokePath(&content.entry()->fContent);
862 } 879 }
863 break; 880 break;
864 default: 881 default:
865 SkASSERT(false); 882 SkASSERT(false);
866 } 883 }
867 } 884 }
868 885
869 void SkPDFDevice::drawRect(const SkDraw& d, const SkRect& rect, 886 void SkPDFDevice::drawRect(const SkDraw& d,
870 const SkPaint& paint) { 887 const SkRect& rect,
888 const SkPaint& srcPaint) {
889 SkPaint paint = srcPaint;
890 replace_srcmode_on_opaque_paint(&paint);
871 SkRect r = rect; 891 SkRect r = rect;
872 r.sort(); 892 r.sort();
873 893
874 if (paint.getPathEffect()) { 894 if (paint.getPathEffect()) {
875 if (d.fClip->isEmpty()) { 895 if (d.fClip->isEmpty()) {
876 return; 896 return;
877 } 897 }
878 SkPath path; 898 SkPath path;
879 path.addRect(r); 899 path.addRect(r);
880 drawPath(d, path, paint, NULL, true); 900 drawPath(d, path, paint, NULL, true);
881 return; 901 return;
882 } 902 }
883 903
884 if (handleRectAnnotation(r, *d.fMatrix, paint)) { 904 if (handleRectAnnotation(r, *d.fMatrix, paint)) {
885 return; 905 return;
886 } 906 }
887 907
888 ScopedContentEntry content(this, d, paint); 908 ScopedContentEntry content(this, d, paint);
889 if (!content.entry()) { 909 if (!content.entry()) {
890 return; 910 return;
891 } 911 }
892 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent); 912 SkPDFUtils::AppendRectangle(r, &content.entry()->fContent);
893 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType, 913 SkPDFUtils::PaintPath(paint.getStyle(), SkPath::kWinding_FillType,
894 &content.entry()->fContent); 914 &content.entry()->fContent);
895 } 915 }
896 916
897 void SkPDFDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPa int& paint) { 917 void SkPDFDevice::drawRRect(const SkDraw& draw,
918 const SkRRect& rrect,
919 const SkPaint& srcPaint) {
920 SkPaint paint = srcPaint;
921 replace_srcmode_on_opaque_paint(&paint);
898 SkPath path; 922 SkPath path;
899 path.addRRect(rrect); 923 path.addRRect(rrect);
900 this->drawPath(draw, path, paint, NULL, true); 924 this->drawPath(draw, path, paint, NULL, true);
901 } 925 }
902 926
903 void SkPDFDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint & paint) { 927 void SkPDFDevice::drawOval(const SkDraw& draw,
928 const SkRect& oval,
929 const SkPaint& srcPaint) {
930 SkPaint paint = srcPaint;
931 replace_srcmode_on_opaque_paint(&paint);
904 SkPath path; 932 SkPath path;
905 path.addOval(oval); 933 path.addOval(oval);
906 this->drawPath(draw, path, paint, NULL, true); 934 this->drawPath(draw, path, paint, NULL, true);
907 } 935 }
908 936
909 void SkPDFDevice::drawPath(const SkDraw& d, const SkPath& origPath, 937 void SkPDFDevice::drawPath(const SkDraw& d,
910 const SkPaint& paint, const SkMatrix* prePathMatrix, 938 const SkPath& origPath,
939 const SkPaint& srcPaint,
940 const SkMatrix* prePathMatrix,
911 bool pathIsMutable) { 941 bool pathIsMutable) {
942 SkPaint paint = srcPaint;
943 replace_srcmode_on_opaque_paint(&paint);
912 SkPath modifiedPath; 944 SkPath modifiedPath;
913 SkPath* pathPtr = const_cast<SkPath*>(&origPath); 945 SkPath* pathPtr = const_cast<SkPath*>(&origPath);
914 946
915 SkMatrix matrix = *d.fMatrix; 947 SkMatrix matrix = *d.fMatrix;
916 if (prePathMatrix) { 948 if (prePathMatrix) {
917 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) { 949 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
918 if (!pathIsMutable) { 950 if (!pathIsMutable) {
919 pathPtr = &modifiedPath; 951 pathPtr = &modifiedPath;
920 pathIsMutable = true; 952 pathIsMutable = true;
921 } 953 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 return; 992 return;
961 } 993 }
962 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), 994 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(),
963 &content.entry()->fContent); 995 &content.entry()->fContent);
964 SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(), 996 SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(),
965 &content.entry()->fContent); 997 &content.entry()->fContent);
966 } 998 }
967 999
968 void SkPDFDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, 1000 void SkPDFDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
969 const SkRect* src, const SkRect& dst, 1001 const SkRect* src, const SkRect& dst,
970 const SkPaint& paint, 1002 const SkPaint& srcPaint,
971 SkCanvas::DrawBitmapRectFlags flags) { 1003 SkCanvas::DrawBitmapRectFlags flags) {
1004 SkPaint paint = srcPaint;
1005 if (bitmap.isOpaque()) {
1006 replace_srcmode_on_opaque_paint(&paint);
1007 }
1008
972 // TODO: this code path must be updated to respect the flags parameter 1009 // TODO: this code path must be updated to respect the flags parameter
973 SkMatrix matrix; 1010 SkMatrix matrix;
974 SkRect bitmapBounds, tmpSrc, tmpDst; 1011 SkRect bitmapBounds, tmpSrc, tmpDst;
975 SkBitmap tmpBitmap; 1012 SkBitmap tmpBitmap;
976 1013
977 bitmapBounds.isetWH(bitmap.width(), bitmap.height()); 1014 bitmapBounds.isetWH(bitmap.width(), bitmap.height());
978 1015
979 // Compute matrix from the two rectangles 1016 // Compute matrix from the two rectangles
980 if (src) { 1017 if (src) {
981 tmpSrc = *src; 1018 tmpSrc = *src;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 dy = SkIntToScalar(srcIR.fTop); 1053 dy = SkIntToScalar(srcIR.fTop);
1017 } 1054 }
1018 if (dx || dy) { 1055 if (dx || dy) {
1019 matrix.preTranslate(dx, dy); 1056 matrix.preTranslate(dx, dy);
1020 } 1057 }
1021 } 1058 }
1022 this->drawBitmap(draw, *bitmapPtr, matrix, paint); 1059 this->drawBitmap(draw, *bitmapPtr, matrix, paint);
1023 } 1060 }
1024 1061
1025 void SkPDFDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap, 1062 void SkPDFDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
1026 const SkMatrix& matrix, const SkPaint& paint) { 1063 const SkMatrix& matrix, const SkPaint& srcPaint) {
1064 SkPaint paint = srcPaint;
1065 if (bitmap.isOpaque()) {
1066 replace_srcmode_on_opaque_paint(&paint);
1067 }
1068
1027 if (d.fClip->isEmpty()) { 1069 if (d.fClip->isEmpty()) {
1028 return; 1070 return;
1029 } 1071 }
1030 1072
1031 SkMatrix transform = matrix; 1073 SkMatrix transform = matrix;
1032 transform.postConcat(*d.fMatrix); 1074 transform.postConcat(*d.fMatrix);
1033 this->internalDrawBitmap(transform, d.fClipStack, *d.fClip, bitmap, NULL, 1075 this->internalDrawBitmap(transform, d.fClipStack, *d.fClip, bitmap, NULL,
1034 paint); 1076 paint);
1035 } 1077 }
1036 1078
1037 void SkPDFDevice::drawSprite(const SkDraw& d, const SkBitmap& bitmap, 1079 void SkPDFDevice::drawSprite(const SkDraw& d, const SkBitmap& bitmap,
1038 int x, int y, const SkPaint& paint) { 1080 int x, int y, const SkPaint& srcPaint) {
1081 SkPaint paint = srcPaint;
1082 if (bitmap.isOpaque()) {
1083 replace_srcmode_on_opaque_paint(&paint);
1084 }
1085
1039 if (d.fClip->isEmpty()) { 1086 if (d.fClip->isEmpty()) {
1040 return; 1087 return;
1041 } 1088 }
1042 1089
1043 SkMatrix matrix; 1090 SkMatrix matrix;
1044 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 1091 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
1045 this->internalDrawBitmap(matrix, d.fClipStack, *d.fClip, bitmap, NULL, 1092 this->internalDrawBitmap(matrix, d.fClipStack, *d.fClip, bitmap, NULL,
1046 paint); 1093 paint);
1047 } 1094 }
1048 1095
(...skipping 26 matching lines...) Expand all
1075 SkString tmp(len); 1122 SkString tmp(len);
1076 for (size_t i = 0; i < len; i++) { 1123 for (size_t i = 0; i < len; i++) {
1077 SkASSERT(0 == input[i] >> 8); 1124 SkASSERT(0 == input[i] >> 8);
1078 tmp[i] = static_cast<uint8_t>(input[i]); 1125 tmp[i] = static_cast<uint8_t>(input[i]);
1079 } 1126 }
1080 return SkPDFUtils::FormatString(tmp.c_str(), tmp.size()); 1127 return SkPDFUtils::FormatString(tmp.c_str(), tmp.size());
1081 } 1128 }
1082 } 1129 }
1083 1130
1084 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, 1131 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
1085 SkScalar x, SkScalar y, const SkPaint& paint) { 1132 SkScalar x, SkScalar y, const SkPaint& srcPaint) {
1133 SkPaint paint = srcPaint;
1134 replace_srcmode_on_opaque_paint(&paint);
1135
1086 NOT_IMPLEMENTED(paint.getMaskFilter() != NULL, false); 1136 NOT_IMPLEMENTED(paint.getMaskFilter() != NULL, false);
1087 if (paint.getMaskFilter() != NULL) { 1137 if (paint.getMaskFilter() != NULL) {
1088 // Don't pretend we support drawing MaskFilters, it makes for artifacts 1138 // Don't pretend we support drawing MaskFilters, it makes for artifacts
1089 // making text unreadable (e.g. same text twice when using CSS shadows). 1139 // making text unreadable (e.g. same text twice when using CSS shadows).
1090 return; 1140 return;
1091 } 1141 }
1092 SkPaint textPaint = calculate_text_paint(paint); 1142 SkPaint textPaint = calculate_text_paint(paint);
1093 ScopedContentEntry content(this, d, textPaint, true); 1143 ScopedContentEntry content(this, d, textPaint, true);
1094 if (!content.entry()) { 1144 if (!content.entry()) {
1095 return; 1145 return;
(...skipping 28 matching lines...) Expand all
1124 availableGlyphs, font->multiByteGlyphs()); 1174 availableGlyphs, font->multiByteGlyphs());
1125 content.entry()->fContent.writeText(encodedString.c_str()); 1175 content.entry()->fContent.writeText(encodedString.c_str());
1126 consumedGlyphCount += availableGlyphs; 1176 consumedGlyphCount += availableGlyphs;
1127 content.entry()->fContent.writeText(" Tj\n"); 1177 content.entry()->fContent.writeText(" Tj\n");
1128 } 1178 }
1129 content.entry()->fContent.writeText("ET\n"); 1179 content.entry()->fContent.writeText("ET\n");
1130 } 1180 }
1131 1181
1132 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, 1182 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
1133 const SkScalar pos[], int scalarsPerPos, 1183 const SkScalar pos[], int scalarsPerPos,
1134 const SkPoint& offset, const SkPaint& paint) { 1184 const SkPoint& offset, const SkPaint& srcPaint) {
1185 SkPaint paint = srcPaint;
1186 replace_srcmode_on_opaque_paint(&paint);
1187
1135 NOT_IMPLEMENTED(paint.getMaskFilter() != NULL, false); 1188 NOT_IMPLEMENTED(paint.getMaskFilter() != NULL, false);
1136 if (paint.getMaskFilter() != NULL) { 1189 if (paint.getMaskFilter() != NULL) {
1137 // Don't pretend we support drawing MaskFilters, it makes for artifacts 1190 // Don't pretend we support drawing MaskFilters, it makes for artifacts
1138 // making text unreadable (e.g. same text twice when using CSS shadows). 1191 // making text unreadable (e.g. same text twice when using CSS shadows).
1139 return; 1192 return;
1140 } 1193 }
1141 SkASSERT(1 == scalarsPerPos || 2 == scalarsPerPos); 1194 SkASSERT(1 == scalarsPerPos || 2 == scalarsPerPos);
1142 SkPaint textPaint = calculate_text_paint(paint); 1195 SkPaint textPaint = calculate_text_paint(paint);
1143 ScopedContentEntry content(this, d, textPaint, true); 1196 ScopedContentEntry content(this, d, textPaint, true);
1144 if (!content.entry()) { 1197 if (!content.entry()) {
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 return; 2194 return;
2142 } 2195 }
2143 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap)); 2196 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap));
2144 if (!image) { 2197 if (!image) {
2145 return; 2198 return;
2146 } 2199 }
2147 2200
2148 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), 2201 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()),
2149 &content.entry()->fContent); 2202 &content.entry()->fContent);
2150 } 2203 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698