| 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 "SkTSet.h" | |
| 24 #include "SkTypes.h" | 23 #include "SkTypes.h" |
| 25 | 24 |
| 26 static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) { | 25 static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) { |
| 27 SkMatrix inverse; | 26 SkMatrix inverse; |
| 28 if (!matrix.invert(&inverse)) { | 27 if (!matrix.invert(&inverse)) { |
| 29 return false; | 28 return false; |
| 30 } | 29 } |
| 31 inverse.mapRect(bbox); | 30 inverse.mapRect(bbox); |
| 32 return true; | 31 return true; |
| 33 } | 32 } |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 State(const State& other); | 501 State(const State& other); |
| 503 State operator=(const State& rhs); | 502 State operator=(const State& rhs); |
| 504 void AllocateGradientInfoStorage(); | 503 void AllocateGradientInfoStorage(); |
| 505 }; | 504 }; |
| 506 | 505 |
| 507 //////////////////////////////////////////////////////////////////////////////// | 506 //////////////////////////////////////////////////////////////////////////////// |
| 508 | 507 |
| 509 SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state) | 508 SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state) |
| 510 : SkPDFDict("Pattern"), fShaderState(state) {} | 509 : SkPDFDict("Pattern"), fShaderState(state) {} |
| 511 | 510 |
| 512 SkPDFFunctionShader::~SkPDFFunctionShader() { | 511 SkPDFFunctionShader::~SkPDFFunctionShader() {} |
| 513 fResources.unrefAll(); | |
| 514 } | |
| 515 | 512 |
| 516 bool SkPDFFunctionShader::equals(const SkPDFShader::State& state) const { | 513 bool SkPDFFunctionShader::equals(const SkPDFShader::State& state) const { |
| 517 return state == *fShaderState; | 514 return state == *fShaderState; |
| 518 } | 515 } |
| 519 | 516 |
| 520 //////////////////////////////////////////////////////////////////////////////// | 517 //////////////////////////////////////////////////////////////////////////////// |
| 521 | 518 |
| 522 SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state) | 519 SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state) |
| 523 : fShaderState(state) {} | 520 : fShaderState(state) {} |
| 524 | 521 |
| 525 bool SkPDFAlphaFunctionShader::equals(const SkPDFShader::State& state) const { | 522 bool SkPDFAlphaFunctionShader::equals(const SkPDFShader::State& state) const { |
| 526 return state == *fShaderState; | 523 return state == *fShaderState; |
| 527 } | 524 } |
| 528 | 525 |
| 529 SkPDFAlphaFunctionShader::~SkPDFAlphaFunctionShader() {} | 526 SkPDFAlphaFunctionShader::~SkPDFAlphaFunctionShader() {} |
| 530 | 527 |
| 531 //////////////////////////////////////////////////////////////////////////////// | 528 //////////////////////////////////////////////////////////////////////////////// |
| 532 | 529 |
| 533 SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) | 530 SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) |
| 534 : fShaderState(state) {} | 531 : fShaderState(state) {} |
| 535 | 532 |
| 536 bool SkPDFImageShader::equals(const SkPDFShader::State& state) const { | 533 bool SkPDFImageShader::equals(const SkPDFShader::State& state) const { |
| 537 return state == *fShaderState; | 534 return state == *fShaderState; |
| 538 } | 535 } |
| 539 | 536 |
| 540 SkPDFImageShader::~SkPDFImageShader() { | 537 SkPDFImageShader::~SkPDFImageShader() {} |
| 541 fResources.unrefAll(); | |
| 542 } | |
| 543 | 538 |
| 544 //////////////////////////////////////////////////////////////////////////////// | 539 //////////////////////////////////////////////////////////////////////////////// |
| 545 | 540 |
| 546 static SkPDFObject* get_pdf_shader_by_state( | 541 static SkPDFObject* get_pdf_shader_by_state( |
| 547 SkPDFCanon* canon, | 542 SkPDFCanon* canon, |
| 548 SkScalar dpi, | 543 SkScalar dpi, |
| 549 SkAutoTDelete<SkPDFShader::State>* autoState) { | 544 SkAutoTDelete<SkPDFShader::State>* autoState) { |
| 550 const SkPDFShader::State& state = **autoState; | 545 const SkPDFShader::State& state = **autoState; |
| 551 if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) { | 546 if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) { |
| 552 // TODO(vandebo) This drops SKComposeShader on the floor. We could | 547 // TODO(vandebo) This drops SKComposeShader on the floor. We could |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 } | 587 } |
| 593 if (gState != NULL) { | 588 if (gState != NULL) { |
| 594 dict->insertResourceAsReference( | 589 dict->insertResourceAsReference( |
| 595 SkPDFResourceDict::kExtGState_ResourceType, 0, gState); | 590 SkPDFResourceDict::kExtGState_ResourceType, 0, gState); |
| 596 } | 591 } |
| 597 | 592 |
| 598 return dict; | 593 return dict; |
| 599 } | 594 } |
| 600 | 595 |
| 601 static void populate_tiling_pattern_dict(SkPDFDict* pattern, | 596 static void populate_tiling_pattern_dict(SkPDFDict* pattern, |
| 602 SkRect& bbox, SkPDFDict* resources, | 597 SkRect& bbox, |
| 603 const SkMatrix& matrix) { | 598 SkPDFDict* resources, |
| 599 const SkMatrix& matrix) { |
| 604 const int kTiling_PatternType = 1; | 600 const int kTiling_PatternType = 1; |
| 605 const int kColoredTilingPattern_PaintType = 1; | 601 const int kColoredTilingPattern_PaintType = 1; |
| 606 const int kConstantSpacing_TilingType = 1; | 602 const int kConstantSpacing_TilingType = 1; |
| 607 | 603 |
| 608 pattern->insertName("Type", "Pattern"); | 604 pattern->insertName("Type", "Pattern"); |
| 609 pattern->insertInt("PatternType", kTiling_PatternType); | 605 pattern->insertInt("PatternType", kTiling_PatternType); |
| 610 pattern->insertInt("PaintType", kColoredTilingPattern_PaintType); | 606 pattern->insertInt("PaintType", kColoredTilingPattern_PaintType); |
| 611 pattern->insertInt("TilingType", kConstantSpacing_TilingType); | 607 pattern->insertInt("TilingType", kConstantSpacing_TilingType); |
| 612 pattern->insert("BBox", SkPDFUtils::RectToArray(bbox))->unref(); | 608 pattern->insert("BBox", SkPDFUtils::RectToArray(bbox))->unref(); |
| 613 pattern->insertScalar("XStep", bbox.width()); | 609 pattern->insertScalar("XStep", bbox.width()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( | 662 SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( |
| 667 SkPDFCanon* canon, | 663 SkPDFCanon* canon, |
| 668 SkScalar dpi, | 664 SkScalar dpi, |
| 669 SkAutoTDelete<SkPDFShader::State>* autoState) { | 665 SkAutoTDelete<SkPDFShader::State>* autoState) { |
| 670 const SkPDFShader::State& state = **autoState; | 666 const SkPDFShader::State& state = **autoState; |
| 671 SkRect bbox; | 667 SkRect bbox; |
| 672 bbox.set(state.fBBox); | 668 bbox.set(state.fBBox); |
| 673 | 669 |
| 674 SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState()); | 670 SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState()); |
| 675 | 671 |
| 676 SkPDFObject* colorShader = | 672 SkAutoTUnref<SkPDFObject> colorShader( |
| 677 get_pdf_shader_by_state(canon, dpi, &opaqueState); | 673 get_pdf_shader_by_state(canon, dpi, &opaqueState)); |
| 678 if (!colorShader) { | 674 if (!colorShader) { |
| 679 return NULL; | 675 return NULL; |
| 680 } | 676 } |
| 681 | 677 |
| 682 // Create resource dict with alpha graphics state as G0 and | 678 // Create resource dict with alpha graphics state as G0 and |
| 683 // pattern shader as P0, then write content stream. | 679 // pattern shader as P0, then write content stream. |
| 684 SkAutoTUnref<SkPDFGraphicState> alphaGs( | 680 SkAutoTUnref<SkPDFGraphicState> alphaGs( |
| 685 create_smask_graphic_state(canon, dpi, state)); | 681 create_smask_graphic_state(canon, dpi, state)); |
| 686 | 682 |
| 687 SkPDFAlphaFunctionShader* alphaFunctionShader = | 683 SkPDFAlphaFunctionShader* alphaFunctionShader = |
| 688 SkNEW_ARGS(SkPDFAlphaFunctionShader, (autoState->detach())); | 684 SkNEW_ARGS(SkPDFAlphaFunctionShader, (autoState->detach())); |
| 689 | 685 |
| 690 alphaFunctionShader->fColorShader.reset(colorShader); | 686 SkAutoTUnref<SkPDFResourceDict> resourceDict( |
| 691 | 687 get_gradient_resource_dict(colorShader.get(), alphaGs.get())); |
| 692 alphaFunctionShader->fResourceDict.reset(get_gradient_resource_dict( | |
| 693 alphaFunctionShader->fColorShader.get(), alphaGs.get())); | |
| 694 | 688 |
| 695 SkAutoTDelete<SkStream> colorStream( | 689 SkAutoTDelete<SkStream> colorStream( |
| 696 create_pattern_fill_content(0, bbox)); | 690 create_pattern_fill_content(0, bbox)); |
| 697 alphaFunctionShader->setData(colorStream.get()); | 691 alphaFunctionShader->setData(colorStream.get()); |
| 698 | 692 |
| 699 populate_tiling_pattern_dict(alphaFunctionShader, bbox, | 693 populate_tiling_pattern_dict(alphaFunctionShader, bbox, resourceDict.get(), |
| 700 alphaFunctionShader->fResourceDict.get(), | |
| 701 SkMatrix::I()); | 694 SkMatrix::I()); |
| 702 canon->addAlphaShader(alphaFunctionShader); | 695 canon->addAlphaShader(alphaFunctionShader); |
| 703 return alphaFunctionShader; | 696 return alphaFunctionShader; |
| 704 } | 697 } |
| 705 | 698 |
| 706 // Finds affine and persp such that in = affine * persp. | 699 // Finds affine and persp such that in = affine * persp. |
| 707 // but it returns the inverse of perspective matrix. | 700 // but it returns the inverse of perspective matrix. |
| 708 static bool split_perspective(const SkMatrix in, SkMatrix* affine, | 701 static bool split_perspective(const SkMatrix in, SkMatrix* affine, |
| 709 SkMatrix* perspectiveInverse) { | 702 SkMatrix* perspectiveInverse) { |
| 710 const SkScalar p2 = in[SkMatrix::kMPersp2]; | 703 const SkScalar p2 = in[SkMatrix::kMPersp2]; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 | 879 |
| 887 SkPDFStream* function = make_ps_function(functionCode, domain.get()); | 880 SkPDFStream* function = make_ps_function(functionCode, domain.get()); |
| 888 pdfShader->insert("Function", new SkPDFObjRef(function))->unref(); | 881 pdfShader->insert("Function", new SkPDFObjRef(function))->unref(); |
| 889 | 882 |
| 890 SkAutoTUnref<SkPDFArray> matrixArray( | 883 SkAutoTUnref<SkPDFArray> matrixArray( |
| 891 SkPDFUtils::MatrixToArray(finalMatrix)); | 884 SkPDFUtils::MatrixToArray(finalMatrix)); |
| 892 | 885 |
| 893 SkPDFFunctionShader* pdfFunctionShader = | 886 SkPDFFunctionShader* pdfFunctionShader = |
| 894 SkNEW_ARGS(SkPDFFunctionShader, (autoState->detach())); | 887 SkNEW_ARGS(SkPDFFunctionShader, (autoState->detach())); |
| 895 | 888 |
| 896 pdfFunctionShader->fResources.push(function); | |
| 897 // Pass ownership to resource list. | |
| 898 | |
| 899 pdfFunctionShader->insertInt("PatternType", 2); | 889 pdfFunctionShader->insertInt("PatternType", 2); |
| 900 pdfFunctionShader->insert("Matrix", matrixArray.get()); | 890 pdfFunctionShader->insert("Matrix", matrixArray.get()); |
| 901 pdfFunctionShader->insert("Shading", pdfShader.get()); | 891 pdfFunctionShader->insert("Shading", pdfShader.get()); |
| 902 | 892 |
| 903 canon->addFunctionShader(pdfFunctionShader); | 893 canon->addFunctionShader(pdfFunctionShader); |
| 904 return pdfFunctionShader; | 894 return pdfFunctionShader; |
| 905 } | 895 } |
| 906 | 896 |
| 907 SkPDFImageShader* SkPDFImageShader::Create( | 897 SkPDFImageShader* SkPDFImageShader::Create( |
| 908 SkPDFCanon* canon, | 898 SkPDFCanon* canon, |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 return false; | 1301 return false; |
| 1312 } | 1302 } |
| 1313 | 1303 |
| 1314 void SkPDFShader::State::AllocateGradientInfoStorage() { | 1304 void SkPDFShader::State::AllocateGradientInfoStorage() { |
| 1315 fColorData.set(sk_malloc_throw( | 1305 fColorData.set(sk_malloc_throw( |
| 1316 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); | 1306 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); |
| 1317 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); | 1307 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); |
| 1318 fInfo.fColorOffsets = | 1308 fInfo.fColorOffsets = |
| 1319 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); | 1309 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); |
| 1320 } | 1310 } |
| OLD | NEW |