OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |