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

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

Issue 901303003: [PDF] Fix shader fallback mapping when clipped (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: actual review comments Created 5 years, 10 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 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkPDFShader.h" 10 #include "SkPDFShader.h"
11 11
12 #include "SkData.h" 12 #include "SkData.h"
13 #include "SkPDFCanon.h" 13 #include "SkPDFCanon.h"
14 #include "SkPDFCatalog.h" 14 #include "SkPDFCatalog.h"
15 #include "SkPDFDevice.h" 15 #include "SkPDFDevice.h"
16 #include "SkPDFFormXObject.h" 16 #include "SkPDFFormXObject.h"
17 #include "SkPDFGraphicState.h" 17 #include "SkPDFGraphicState.h"
18 #include "SkPDFResourceDict.h" 18 #include "SkPDFResourceDict.h"
19 #include "SkPDFUtils.h" 19 #include "SkPDFUtils.h"
20 #include "SkScalar.h" 20 #include "SkScalar.h"
21 #include "SkStream.h" 21 #include "SkStream.h"
22 #include "SkTemplates.h" 22 #include "SkTemplates.h"
23 #include "SkThread.h" 23 #include "SkThread.h"
24 #include "SkTSet.h" 24 #include "SkTSet.h"
25 #include "SkTypes.h" 25 #include "SkTypes.h"
26 26
27 static bool inverseTransformBBox(const SkMatrix& matrix, SkRect* bbox) { 27 static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) {
28 SkMatrix inverse; 28 SkMatrix inverse;
29 if (!matrix.invert(&inverse)) { 29 if (!matrix.invert(&inverse)) {
30 return false; 30 return false;
31 } 31 }
32 inverse.mapRect(bbox); 32 inverse.mapRect(bbox);
33 return true; 33 return true;
34 } 34 }
35 35
36 static void unitToPointsMatrix(const SkPoint pts[2], SkMatrix* matrix) { 36 static void unitToPointsMatrix(const SkPoint pts[2], SkMatrix* matrix) {
37 SkVector vec = pts[1] - pts[0]; 37 SkVector vec = pts[1] - pts[0];
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 SkMatrix perspectiveInverseOnly = SkMatrix::I(); 842 SkMatrix perspectiveInverseOnly = SkMatrix::I();
843 if (finalMatrix.hasPerspective()) { 843 if (finalMatrix.hasPerspective()) {
844 if (!split_perspective(finalMatrix, 844 if (!split_perspective(finalMatrix,
845 &finalMatrix, &perspectiveInverseOnly)) { 845 &finalMatrix, &perspectiveInverseOnly)) {
846 return NULL; 846 return NULL;
847 } 847 }
848 } 848 }
849 849
850 SkRect bbox; 850 SkRect bbox;
851 bbox.set(state.fBBox); 851 bbox.set(state.fBBox);
852 if (!inverseTransformBBox(finalMatrix, &bbox)) { 852 if (!inverse_transform_bbox(finalMatrix, &bbox)) {
853 return NULL; 853 return NULL;
854 } 854 }
855 855
856 SkAutoTUnref<SkPDFArray> domain(new SkPDFArray); 856 SkAutoTUnref<SkPDFArray> domain(new SkPDFArray);
857 domain->reserve(4); 857 domain->reserve(4);
858 domain->appendScalar(bbox.fLeft); 858 domain->appendScalar(bbox.fLeft);
859 domain->appendScalar(bbox.fRight); 859 domain->appendScalar(bbox.fRight);
860 domain->appendScalar(bbox.fTop); 860 domain->appendScalar(bbox.fTop);
861 domain->appendScalar(bbox.fBottom); 861 domain->appendScalar(bbox.fBottom);
862 862
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 // The image shader pattern cell will be drawn into a separate device 915 // The image shader pattern cell will be drawn into a separate device
916 // in pattern cell space (no scaling on the bitmap, though there may be 916 // in pattern cell space (no scaling on the bitmap, though there may be
917 // translations so that all content is in the device, coordinates > 0). 917 // translations so that all content is in the device, coordinates > 0).
918 918
919 // Map clip bounds to shader space to ensure the device is large enough 919 // Map clip bounds to shader space to ensure the device is large enough
920 // to handle fake clamping. 920 // to handle fake clamping.
921 SkMatrix finalMatrix = state.fCanvasTransform; 921 SkMatrix finalMatrix = state.fCanvasTransform;
922 finalMatrix.preConcat(state.fShaderTransform); 922 finalMatrix.preConcat(state.fShaderTransform);
923 SkRect deviceBounds; 923 SkRect deviceBounds;
924 deviceBounds.set(state.fBBox); 924 deviceBounds.set(state.fBBox);
925 if (!inverseTransformBBox(finalMatrix, &deviceBounds)) { 925 if (!inverse_transform_bbox(finalMatrix, &deviceBounds)) {
926 return NULL; 926 return NULL;
927 } 927 }
928 928
929 const SkBitmap* image = &state.fImage; 929 const SkBitmap* image = &state.fImage;
930 SkRect bitmapBounds; 930 SkRect bitmapBounds;
931 image->getBounds(&bitmapBounds); 931 image->getBounds(&bitmapBounds);
932 932
933 // For tiling modes, the bounds should be extended to include the bitmap, 933 // For tiling modes, the bounds should be extended to include the bitmap,
934 // otherwise the bitmap gets clipped out and the shader is empty and awful. 934 // otherwise the bitmap gets clipped out and the shader is empty and awful.
935 // For clamp modes, we're only interested in the clip region, whether 935 // For clamp modes, we're only interested in the clip region, whether
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 if (fType == SkShader::kNone_GradientType) { 1193 if (fType == SkShader::kNone_GradientType) {
1194 SkShader::BitmapType bitmapType; 1194 SkShader::BitmapType bitmapType;
1195 SkMatrix matrix; 1195 SkMatrix matrix;
1196 bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes); 1196 bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes);
1197 if (bitmapType != SkShader::kDefault_BitmapType) { 1197 if (bitmapType != SkShader::kDefault_BitmapType) {
1198 // Generic fallback for unsupported shaders: 1198 // Generic fallback for unsupported shaders:
1199 // * allocate a bbox-sized bitmap 1199 // * allocate a bbox-sized bitmap
1200 // * shade the whole area 1200 // * shade the whole area
1201 // * use the result as a bitmap shader 1201 // * use the result as a bitmap shader
1202 1202
1203 // bbox is in device space. While that's exactly what we want for si zing our bitmap,
1204 // we need to map it into shader space for adjustments (to match
1205 // SkPDFImageShader::Create's behavior).
1206 SkRect shaderRect = SkRect::Make(bbox);
1207 if (!inverse_transform_bbox(canvasTransform, &shaderRect)) {
1208 fImage.reset();
1209 return;
1210 }
1211
1203 // Clamp the bitmap size to about 1M pixels 1212 // Clamp the bitmap size to about 1M pixels
1204 static const SkScalar kMaxBitmapArea = 1024 * 1024; 1213 static const SkScalar kMaxBitmapArea = 1024 * 1024;
1205 SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbo x.height(); 1214 SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbo x.height();
1206 if (bitmapArea > kMaxBitmapArea) { 1215 if (bitmapArea > kMaxBitmapArea) {
1207 rasterScale *= SkScalarSqrt(SkScalarDiv(kMaxBitmapArea, bitmapAr ea)); 1216 rasterScale *= SkScalarSqrt(SkScalarDiv(kMaxBitmapArea, bitmapAr ea));
1208 } 1217 }
1209 1218
1210 SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.w idth()), 1219 SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.w idth()),
1211 SkScalarRoundToInt(rasterScale * bbox.h eight())); 1220 SkScalarRoundToInt(rasterScale * bbox.h eight()));
1212 SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / SkIntToSca lar(bbox.width()), 1221 SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / shaderRect .width(),
1213 SkIntToScalar(size.height()) / SkIntToSc alar(bbox.height())); 1222 SkIntToScalar(size.height()) / shaderRec t.height());
1214 1223
1215 fImage.allocN32Pixels(size.width(), size.height()); 1224 fImage.allocN32Pixels(size.width(), size.height());
1216 fImage.eraseColor(SK_ColorTRANSPARENT); 1225 fImage.eraseColor(SK_ColorTRANSPARENT);
1217 1226
1218 SkPaint p; 1227 SkPaint p;
1219 p.setShader(const_cast<SkShader*>(&shader)); 1228 p.setShader(const_cast<SkShader*>(&shader));
1220 1229
1221 SkCanvas canvas(fImage); 1230 SkCanvas canvas(fImage);
1222 canvas.scale(scale.width(), scale.height()); 1231 canvas.scale(scale.width(), scale.height());
1223 canvas.translate(-SkIntToScalar(bbox.x()), -SkIntToScalar(bbox.y())) ; 1232 canvas.translate(-shaderRect.x(), -shaderRect.y());
1224 canvas.drawPaint(p); 1233 canvas.drawPaint(p);
1225 1234
1226 fShaderTransform.setTranslate(SkIntToScalar(bbox.x()), SkIntToScalar (bbox.y())); 1235 fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
1227 fShaderTransform.preScale(1 / scale.width(), 1 / scale.height()); 1236 fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
1228 } else { 1237 } else {
1229 SkASSERT(matrix.isIdentity()); 1238 SkASSERT(matrix.isIdentity());
1230 } 1239 }
1231 fPixelGeneration = fImage.getGenerationID(); 1240 fPixelGeneration = fImage.getGenerationID();
1232 } else { 1241 } else {
1233 AllocateGradientInfoStorage(); 1242 AllocateGradientInfoStorage();
1234 shader.asAGradient(&fInfo); 1243 shader.asAGradient(&fInfo);
1235 } 1244 }
1236 } 1245 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 return false; 1315 return false;
1307 } 1316 }
1308 1317
1309 void SkPDFShader::State::AllocateGradientInfoStorage() { 1318 void SkPDFShader::State::AllocateGradientInfoStorage() {
1310 fColorData.set(sk_malloc_throw( 1319 fColorData.set(sk_malloc_throw(
1311 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); 1320 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
1312 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); 1321 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
1313 fInfo.fColorOffsets = 1322 fInfo.fColorOffsets =
1314 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); 1323 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount);
1315 } 1324 }
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