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 |