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" |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 SkAutoFree fColorData; // This provides storage for arrays in fInfo. | 482 SkAutoFree fColorData; // This provides storage for arrays in fInfo. |
483 SkMatrix fCanvasTransform; | 483 SkMatrix fCanvasTransform; |
484 SkMatrix fShaderTransform; | 484 SkMatrix fShaderTransform; |
485 SkIRect fBBox; | 485 SkIRect fBBox; |
486 | 486 |
487 SkBitmap fImage; | 487 SkBitmap fImage; |
488 uint32_t fPixelGeneration; | 488 uint32_t fPixelGeneration; |
489 SkShader::TileMode fImageTileModes[2]; | 489 SkShader::TileMode fImageTileModes[2]; |
490 | 490 |
491 State(const SkShader& shader, const SkMatrix& canvasTransform, | 491 State(const SkShader& shader, const SkMatrix& canvasTransform, |
492 const SkIRect& bbox); | 492 const SkIRect& bbox, SkScalar rasterScale); |
493 | 493 |
494 bool operator==(const State& b) const; | 494 bool operator==(const State& b) const; |
495 | 495 |
496 SkPDFShader::State* CreateAlphaToLuminosityState() const; | 496 SkPDFShader::State* CreateAlphaToLuminosityState() const; |
497 SkPDFShader::State* CreateOpaqueState() const; | 497 SkPDFShader::State* CreateOpaqueState() const; |
498 | 498 |
499 bool GradientHasAlpha() const; | 499 bool GradientHasAlpha() const; |
500 | 500 |
501 private: | 501 private: |
502 State(const State& other); | 502 State(const State& other); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 SkAutoMutexAcquire lock(CanonicalShadersMutex()); | 650 SkAutoMutexAcquire lock(CanonicalShadersMutex()); |
651 ShaderCanonicalEntry entry(shader, NULL); | 651 ShaderCanonicalEntry entry(shader, NULL); |
652 int index = CanonicalShaders().find(entry); | 652 int index = CanonicalShaders().find(entry); |
653 SkASSERT(index >= 0); | 653 SkASSERT(index >= 0); |
654 CanonicalShaders().removeShuffle(index); | 654 CanonicalShaders().removeShuffle(index); |
655 } | 655 } |
656 | 656 |
657 // static | 657 // static |
658 SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader, | 658 SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader, |
659 const SkMatrix& matrix, | 659 const SkMatrix& matrix, |
660 const SkIRect& surfaceBBox) { | 660 const SkIRect& surfaceBBox, |
| 661 SkScalar rasterScale) { |
661 SkAutoMutexAcquire lock(CanonicalShadersMutex()); | 662 SkAutoMutexAcquire lock(CanonicalShadersMutex()); |
662 return GetPDFShaderByState( | 663 return GetPDFShaderByState( |
663 SkNEW_ARGS(State, (shader, matrix, surfaceBBox))); | 664 SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale))); |
664 } | 665 } |
665 | 666 |
666 // static | 667 // static |
667 SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() { | 668 SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() { |
668 SkPDFShader::CanonicalShadersMutex().assertHeld(); | 669 SkPDFShader::CanonicalShadersMutex().assertHeld(); |
669 static SkTDArray<ShaderCanonicalEntry> gCanonicalShaders; | 670 static SkTDArray<ShaderCanonicalEntry> gCanonicalShaders; |
670 return gCanonicalShaders; | 671 return gCanonicalShaders; |
671 } | 672 } |
672 | 673 |
673 SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex); | 674 SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex); |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 break; | 1233 break; |
1233 case SkShader::kSweep_GradientType: | 1234 case SkShader::kSweep_GradientType: |
1234 case SkShader::kNone_GradientType: | 1235 case SkShader::kNone_GradientType: |
1235 case SkShader::kColor_GradientType: | 1236 case SkShader::kColor_GradientType: |
1236 break; | 1237 break; |
1237 } | 1238 } |
1238 } | 1239 } |
1239 return true; | 1240 return true; |
1240 } | 1241 } |
1241 | 1242 |
1242 SkPDFShader::State::State(const SkShader& shader, | 1243 SkPDFShader::State::State(const SkShader& shader, const SkMatrix& canvasTransfor
m, |
1243 const SkMatrix& canvasTransform, const SkIRect& bbox) | 1244 const SkIRect& bbox, SkScalar rasterScale) |
1244 : fCanvasTransform(canvasTransform), | 1245 : fCanvasTransform(canvasTransform), |
1245 fBBox(bbox), | 1246 fBBox(bbox), |
1246 fPixelGeneration(0) { | 1247 fPixelGeneration(0) { |
1247 fInfo.fColorCount = 0; | 1248 fInfo.fColorCount = 0; |
1248 fInfo.fColors = NULL; | 1249 fInfo.fColors = NULL; |
1249 fInfo.fColorOffsets = NULL; | 1250 fInfo.fColorOffsets = NULL; |
1250 fShaderTransform = shader.getLocalMatrix(); | 1251 fShaderTransform = shader.getLocalMatrix(); |
1251 fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode; | 1252 fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode; |
1252 | 1253 |
1253 fType = shader.asAGradient(&fInfo); | 1254 fType = shader.asAGradient(&fInfo); |
1254 | 1255 |
1255 if (fType == SkShader::kNone_GradientType) { | 1256 if (fType == SkShader::kNone_GradientType) { |
1256 SkShader::BitmapType bitmapType; | 1257 SkShader::BitmapType bitmapType; |
1257 SkMatrix matrix; | 1258 SkMatrix matrix; |
1258 bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes); | 1259 bitmapType = shader.asABitmap(&fImage, &matrix, fImageTileModes); |
1259 if (bitmapType != SkShader::kDefault_BitmapType) { | 1260 if (bitmapType != SkShader::kDefault_BitmapType) { |
1260 fImage.reset(); | 1261 // Generic fallback for unsupported shaders: |
1261 return; | 1262 // * allocate a bbox-sized bitmap |
| 1263 // * shade the whole area |
| 1264 // * use the result as a bitmap shader |
| 1265 |
| 1266 // Clamp the bitmap size to about 1M pixels |
| 1267 static const SkScalar kMaxBitmapArea = 1024 * 1024; |
| 1268 SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbo
x.height(); |
| 1269 if (bitmapArea > kMaxBitmapArea) { |
| 1270 rasterScale *= SkScalarSqrt(SkScalarDiv(kMaxBitmapArea, bitmapAr
ea)); |
| 1271 } |
| 1272 |
| 1273 SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.w
idth()), |
| 1274 SkScalarRoundToInt(rasterScale * bbox.h
eight())); |
| 1275 SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / SkIntToSca
lar(bbox.width()), |
| 1276 SkIntToScalar(size.height()) / SkIntToSc
alar(bbox.height())); |
| 1277 |
| 1278 fImage.allocN32Pixels(size.width(), size.height()); |
| 1279 fImage.eraseColor(SK_ColorTRANSPARENT); |
| 1280 |
| 1281 SkPaint p; |
| 1282 p.setShader(const_cast<SkShader*>(&shader)); |
| 1283 |
| 1284 SkCanvas canvas(fImage); |
| 1285 canvas.scale(scale.width(), scale.height()); |
| 1286 canvas.translate(-SkIntToScalar(bbox.x()), -SkIntToScalar(bbox.y()))
; |
| 1287 canvas.drawPaint(p); |
| 1288 |
| 1289 fShaderTransform.setTranslate(SkIntToScalar(bbox.x()), SkIntToScalar
(bbox.y())); |
| 1290 fShaderTransform.preScale(1 / scale.width(), 1 / scale.height()); |
| 1291 } else { |
| 1292 SkASSERT(matrix.isIdentity()); |
1262 } | 1293 } |
1263 SkASSERT(matrix.isIdentity()); | |
1264 fPixelGeneration = fImage.getGenerationID(); | 1294 fPixelGeneration = fImage.getGenerationID(); |
1265 } else { | 1295 } else { |
1266 AllocateGradientInfoStorage(); | 1296 AllocateGradientInfoStorage(); |
1267 shader.asAGradient(&fInfo); | 1297 shader.asAGradient(&fInfo); |
1268 } | 1298 } |
1269 } | 1299 } |
1270 | 1300 |
1271 SkPDFShader::State::State(const SkPDFShader::State& other) | 1301 SkPDFShader::State::State(const SkPDFShader::State& other) |
1272 : fType(other.fType), | 1302 : fType(other.fType), |
1273 fCanvasTransform(other.fCanvasTransform), | 1303 fCanvasTransform(other.fCanvasTransform), |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 return false; | 1369 return false; |
1340 } | 1370 } |
1341 | 1371 |
1342 void SkPDFShader::State::AllocateGradientInfoStorage() { | 1372 void SkPDFShader::State::AllocateGradientInfoStorage() { |
1343 fColorData.set(sk_malloc_throw( | 1373 fColorData.set(sk_malloc_throw( |
1344 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); | 1374 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); |
1345 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); | 1375 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); |
1346 fInfo.fColorOffsets = | 1376 fInfo.fColorOffsets = |
1347 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); | 1377 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); |
1348 } | 1378 } |
OLD | NEW |