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

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

Issue 842253003: SkPDFCanon (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: did you mean struct here? Created 5 years, 11 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 | « src/pdf/SkPDFShader.h ('k') | 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 "SkPDFCatalog.h" 14 #include "SkPDFCatalog.h"
14 #include "SkPDFDevice.h" 15 #include "SkPDFDevice.h"
15 #include "SkPDFFormXObject.h" 16 #include "SkPDFFormXObject.h"
16 #include "SkPDFGraphicState.h" 17 #include "SkPDFGraphicState.h"
17 #include "SkPDFResourceDict.h" 18 #include "SkPDFResourceDict.h"
18 #include "SkPDFUtils.h" 19 #include "SkPDFUtils.h"
19 #include "SkScalar.h" 20 #include "SkScalar.h"
20 #include "SkStream.h" 21 #include "SkStream.h"
21 #include "SkTemplates.h" 22 #include "SkTemplates.h"
22 #include "SkThread.h" 23 #include "SkThread.h"
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 State(const State& other); 503 State(const State& other);
503 State operator=(const State& rhs); 504 State operator=(const State& rhs);
504 void AllocateGradientInfoStorage(); 505 void AllocateGradientInfoStorage();
505 }; 506 };
506 507
507 class SkPDFFunctionShader : public SkPDFDict, public SkPDFShader { 508 class SkPDFFunctionShader : public SkPDFDict, public SkPDFShader {
508 SK_DECLARE_INST_COUNT(SkPDFFunctionShader) 509 SK_DECLARE_INST_COUNT(SkPDFFunctionShader)
509 public: 510 public:
510 explicit SkPDFFunctionShader(SkPDFShader::State* state); 511 explicit SkPDFFunctionShader(SkPDFShader::State* state);
511 virtual ~SkPDFFunctionShader() { 512 virtual ~SkPDFFunctionShader() {
512 if (isValid()) { 513 SkPDFShader::RemoveFromCanonIfValid(this);
513 RemoveShader(this);
514 }
515 fResources.unrefAll(); 514 fResources.unrefAll();
516 } 515 }
517 516
518 bool isValid() SK_OVERRIDE { return fResources.count() > 0; } 517 bool isValid() SK_OVERRIDE { return fResources.count() > 0; }
518 SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
519 519
520 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, 520 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
521 SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE { 521 SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
522 GetResourcesHelper(&fResources, 522 GetResourcesHelper(&fResources,
523 knownResourceObjects, 523 knownResourceObjects,
524 newResourceObjects); 524 newResourceObjects);
525 } 525 }
526 526
527 private: 527 private:
528 static SkPDFObject* RangeObject(); 528 static SkPDFObject* RangeObject();
529 529
530 SkTDArray<SkPDFObject*> fResources; 530 SkTDArray<SkPDFObject*> fResources;
531 SkAutoTDelete<const SkPDFShader::State> fState;
532 531
533 SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain); 532 SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
534 typedef SkPDFDict INHERITED; 533 typedef SkPDFDict INHERITED;
535 }; 534 };
536 535
537 /** 536 /**
538 * A shader for PDF gradients. This encapsulates the function shader 537 * A shader for PDF gradients. This encapsulates the function shader
539 * inside a tiling pattern while providing a common pattern interface. 538 * inside a tiling pattern while providing a common pattern interface.
540 * The encapsulation allows the use of a SMask for transparency gradients. 539 * The encapsulation allows the use of a SMask for transparency gradients.
541 */ 540 */
542 class SkPDFAlphaFunctionShader : public SkPDFStream, public SkPDFShader { 541 class SkPDFAlphaFunctionShader : public SkPDFStream, public SkPDFShader {
543 public: 542 public:
544 explicit SkPDFAlphaFunctionShader(SkPDFShader::State* state); 543 explicit SkPDFAlphaFunctionShader(SkPDFShader::State* state);
545 virtual ~SkPDFAlphaFunctionShader() { 544 virtual ~SkPDFAlphaFunctionShader() {
546 if (isValid()) { 545 SkPDFShader::RemoveFromCanonIfValid(this);
547 RemoveShader(this);
548 }
549 } 546 }
550 547
551 bool isValid() SK_OVERRIDE { 548 bool isValid() SK_OVERRIDE {
552 return fColorShader.get() != NULL; 549 return fColorShader.get() != NULL;
553 } 550 }
551 SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
554 552
555 private: 553 private:
556 SkAutoTDelete<const SkPDFShader::State> fState;
557
558 SkPDFGraphicState* CreateSMaskGraphicState(); 554 SkPDFGraphicState* CreateSMaskGraphicState();
559 555
560 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, 556 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
561 SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE { 557 SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
562 fResourceDict->getReferencedResources(knownResourceObjects, 558 fResourceDict->getReferencedResources(knownResourceObjects,
563 newResourceObjects, 559 newResourceObjects,
564 true); 560 true);
565 } 561 }
566 562
567 SkAutoTUnref<SkPDFObject> fColorShader; 563 SkAutoTUnref<SkPDFObject> fColorShader;
568 SkAutoTUnref<SkPDFResourceDict> fResourceDict; 564 SkAutoTUnref<SkPDFResourceDict> fResourceDict;
569 }; 565 };
570 566
571 class SkPDFImageShader : public SkPDFStream, public SkPDFShader { 567 class SkPDFImageShader : public SkPDFStream, public SkPDFShader {
572 public: 568 public:
573 explicit SkPDFImageShader(SkPDFShader::State* state); 569 explicit SkPDFImageShader(SkPDFShader::State* state);
574 virtual ~SkPDFImageShader() { 570 virtual ~SkPDFImageShader() {
575 if (isValid()) { 571 SkPDFShader::RemoveFromCanonIfValid(this);
576 RemoveShader(this);
577 }
578 fResources.unrefAll(); 572 fResources.unrefAll();
579 } 573 }
580 574
581 bool isValid() SK_OVERRIDE { return size() > 0; } 575 bool isValid() SK_OVERRIDE { return size() > 0; }
576 SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
582 577
583 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, 578 void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
584 SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE { 579 SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
585 GetResourcesHelper(&fResources.toArray(), 580 GetResourcesHelper(&fResources.toArray(),
586 knownResourceObjects, 581 knownResourceObjects,
587 newResourceObjects); 582 newResourceObjects);
588 } 583 }
589 584
590 private: 585 private:
591 SkTSet<SkPDFObject*> fResources; 586 SkTSet<SkPDFObject*> fResources;
592 SkAutoTDelete<const SkPDFShader::State> fState;
593 }; 587 };
594 588
595 SkPDFShader::SkPDFShader() {} 589 SkPDFShader::SkPDFShader(SkPDFShader::State* s) : fShaderState(s) {}
590
591 SkPDFShader::~SkPDFShader() {}
592
593 void SkPDFShader::RemoveFromCanonIfValid(SkPDFShader* shader) {
594 if (shader->isValid()) {
595 SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
596 SkPDFCanon::GetCanon().removeShader(shader);
597 }
598 }
599
600 bool SkPDFShader::equals(const SkPDFShader::State& state) const {
601 return state == *fShaderState.get();
602 }
603
604 SkPDFObject* SkPDFShader::AddToCanonIfValid(SkPDFShader* shader) {
605 if (!shader->isValid()) {
606 SkDELETE(shader);
607 return NULL;
608 }
609 SkPDFCanon::GetCanon().addShader(shader);
610 return shader->toPDFObject();
611 }
596 612
597 // static 613 // static
598 SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) { 614 SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) {
599 SkPDFObject* result; 615 SkAutoTDelete<State> state(inState);
600 616 if (state->fType == SkShader::kNone_GradientType &&
601 SkAutoTDelete<State> shaderState(inState); 617 state->fImage.isNull()) {
602 if (shaderState.get()->fType == SkShader::kNone_GradientType &&
603 shaderState.get()->fImage.isNull()) {
604 // TODO(vandebo) This drops SKComposeShader on the floor. We could 618 // TODO(vandebo) This drops SKComposeShader on the floor. We could
605 // handle compose shader by pulling things up to a layer, drawing with 619 // handle compose shader by pulling things up to a layer, drawing with
606 // the first shader, applying the xfer mode and drawing again with the 620 // the first shader, applying the xfer mode and drawing again with the
607 // second shader, then applying the layer to the original drawing. 621 // second shader, then applying the layer to the original drawing.
608 return NULL; 622 return NULL;
609 } 623 }
610 624
611 ShaderCanonicalEntry entry(NULL, shaderState.get()); 625 SkPDFShader* pdfShader = SkPDFCanon::GetCanon().findShader(*state);
612 int index = CanonicalShaders().find(entry); 626 if (pdfShader) {
613 if (index >= 0) { 627 SkASSERT(pdfShader->isValid());
614 result = CanonicalShaders()[index].fPDFShader; 628 return SkRef(pdfShader->toPDFObject());
615 result->ref();
616 return result;
617 } 629 }
618 630
619 bool valid = false;
620 // The PDFShader takes ownership of the shaderSate. 631 // The PDFShader takes ownership of the shaderSate.
621 if (shaderState.get()->fType == SkShader::kNone_GradientType) { 632 if (state->fType == SkShader::kNone_GradientType) {
622 SkPDFImageShader* imageShader = 633 return SkPDFShader::AddToCanonIfValid(
623 new SkPDFImageShader(shaderState.detach()); 634 SkNEW_ARGS(SkPDFImageShader, (state.detach())));
624 valid = imageShader->isValid(); 635 } else if (state->GradientHasAlpha()) {
625 result = imageShader; 636 return SkPDFShader::AddToCanonIfValid(
637 SkNEW_ARGS(SkPDFAlphaFunctionShader, (state.detach())));
626 } else { 638 } else {
627 if (shaderState.get()->GradientHasAlpha()) { 639 return SkPDFShader::AddToCanonIfValid(
628 SkPDFAlphaFunctionShader* gradientShader = 640 SkNEW_ARGS(SkPDFFunctionShader, (state.detach())));
629 SkNEW_ARGS(SkPDFAlphaFunctionShader, (shaderState.detach()));
630 valid = gradientShader->isValid();
631 result = gradientShader;
632 } else {
633 SkPDFFunctionShader* functionShader =
634 SkNEW_ARGS(SkPDFFunctionShader, (shaderState.detach()));
635 valid = functionShader->isValid();
636 result = functionShader;
637 }
638 } 641 }
639 if (!valid) {
640 delete result;
641 return NULL;
642 }
643 entry.fPDFShader = result;
644 CanonicalShaders().push(entry);
645 return result; // return the reference that came from new.
646 } 642 }
647 643
648 // static 644 // static
649 void SkPDFShader::RemoveShader(SkPDFObject* shader) {
650 SkAutoMutexAcquire lock(CanonicalShadersMutex());
651 ShaderCanonicalEntry entry(shader, NULL);
652 int index = CanonicalShaders().find(entry);
653 SkASSERT(index >= 0);
654 CanonicalShaders().removeShuffle(index);
655 }
656
657 // static
658 SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader, 645 SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader,
659 const SkMatrix& matrix, 646 const SkMatrix& matrix,
660 const SkIRect& surfaceBBox, 647 const SkIRect& surfaceBBox,
661 SkScalar rasterScale) { 648 SkScalar rasterScale) {
662 SkAutoMutexAcquire lock(CanonicalShadersMutex()); 649 SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
663 return GetPDFShaderByState( 650 return GetPDFShaderByState(
664 SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale))); 651 SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale)));
665 } 652 }
666 653
667 // static
668 SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() {
669 SkPDFShader::CanonicalShadersMutex().assertHeld();
670 static SkTDArray<ShaderCanonicalEntry> gCanonicalShaders;
671 return gCanonicalShaders;
672 }
673
674 SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
675 // static
676 SkBaseMutex& SkPDFShader::CanonicalShadersMutex() {
677 return gCanonicalShadersMutex;
678 }
679 654
680 // static 655 // static
681 SkPDFObject* SkPDFFunctionShader::RangeObject() { 656 SkPDFObject* SkPDFFunctionShader::RangeObject() {
682 SkPDFShader::CanonicalShadersMutex().assertHeld(); 657 SkPDFCanon::GetShaderMutex().assertHeld();
683 static SkPDFArray* range = NULL; 658 static SkPDFArray* range = NULL;
684 // This method is only used with CanonicalShadersMutex, so it's safe to 659 // This method is only used with CanonicalShadersMutex, so it's safe to
685 // populate domain. 660 // populate domain.
686 if (range == NULL) { 661 if (range == NULL) {
687 range = new SkPDFArray; 662 range = new SkPDFArray;
688 range->reserve(6); 663 range->reserve(6);
689 range->appendInt(0); 664 range->appendInt(0);
690 range->appendInt(1); 665 range->appendInt(1);
691 range->appendInt(0); 666 range->appendInt(0);
692 range->appendInt(1); 667 range->appendInt(1);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 725
751 return content.detachAsStream(); 726 return content.detachAsStream();
752 } 727 }
753 728
754 /** 729 /**
755 * Creates a ExtGState with the SMask set to the luminosityShader in 730 * Creates a ExtGState with the SMask set to the luminosityShader in
756 * luminosity mode. The shader pattern extends to the bbox. 731 * luminosity mode. The shader pattern extends to the bbox.
757 */ 732 */
758 SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() { 733 SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() {
759 SkRect bbox; 734 SkRect bbox;
760 bbox.set(fState.get()->fBBox); 735 bbox.set(fShaderState->fBBox);
761 736
762 SkAutoTUnref<SkPDFObject> luminosityShader( 737 SkAutoTUnref<SkPDFObject> luminosityShader(SkPDFShader::GetPDFShaderByState(
763 SkPDFShader::GetPDFShaderByState( 738 fShaderState->CreateAlphaToLuminosityState()));
764 fState->CreateAlphaToLuminosityState()));
765 739
766 SkAutoTUnref<SkStream> alphaStream(create_pattern_fill_content(-1, bbox)); 740 SkAutoTUnref<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
767 741
768 SkAutoTUnref<SkPDFResourceDict> 742 SkAutoTUnref<SkPDFResourceDict>
769 resources(get_gradient_resource_dict(luminosityShader, NULL)); 743 resources(get_gradient_resource_dict(luminosityShader, NULL));
770 744
771 SkAutoTUnref<SkPDFFormXObject> alphaMask( 745 SkAutoTUnref<SkPDFFormXObject> alphaMask(
772 new SkPDFFormXObject(alphaStream.get(), bbox, resources.get())); 746 new SkPDFFormXObject(alphaStream.get(), bbox, resources.get()));
773 747
774 return SkPDFGraphicState::GetSMaskGraphicState( 748 return SkPDFGraphicState::GetSMaskGraphicState(
775 alphaMask.get(), false, 749 alphaMask.get(), false,
776 SkPDFGraphicState::kLuminosity_SMaskMode); 750 SkPDFGraphicState::kLuminosity_SMaskMode);
777 } 751 }
778 752
779 SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state) 753 SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state)
780 : fState(state) { 754 : SkPDFShader(state) {
781 SkRect bbox; 755 SkRect bbox;
782 bbox.set(fState.get()->fBBox); 756 bbox.set(fShaderState->fBBox);
783 757
784 fColorShader.reset( 758 fColorShader.reset(
785 SkPDFShader::GetPDFShaderByState(state->CreateOpaqueState())); 759 SkPDFShader::GetPDFShaderByState(state->CreateOpaqueState()));
786 760
787 // Create resource dict with alpha graphics state as G0 and 761 // Create resource dict with alpha graphics state as G0 and
788 // pattern shader as P0, then write content stream. 762 // pattern shader as P0, then write content stream.
789 SkAutoTUnref<SkPDFGraphicState> alphaGs(CreateSMaskGraphicState()); 763 SkAutoTUnref<SkPDFGraphicState> alphaGs(CreateSMaskGraphicState());
790 fResourceDict.reset( 764 fResourceDict.reset(
791 get_gradient_resource_dict(fColorShader.get(), alphaGs.get())); 765 get_gradient_resource_dict(fColorShader.get(), alphaGs.get()));
792 766
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 -p0/p2, -p1/p2, 1/p2); 804 -p0/p2, -p1/p2, 1/p2);
831 805
832 affine->setAll(sx - p0 * tx / p2, kx - p1 * tx / p2, tx / p2, 806 affine->setAll(sx - p0 * tx / p2, kx - p1 * tx / p2, tx / p2,
833 ky - p0 * ty / p2, sy - p1 * ty / p2, ty / p2, 807 ky - p0 * ty / p2, sy - p1 * ty / p2, ty / p2,
834 zero, zero, one); 808 zero, zero, one);
835 809
836 return true; 810 return true;
837 } 811 }
838 812
839 SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state) 813 SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
840 : SkPDFDict("Pattern"), 814 : SkPDFDict("Pattern"), SkPDFShader(state) {
841 fState(state) {
842 SkString (*codeFunction)(const SkShader::GradientInfo& info, 815 SkString (*codeFunction)(const SkShader::GradientInfo& info,
843 const SkMatrix& perspectiveRemover) = NULL; 816 const SkMatrix& perspectiveRemover) = NULL;
844 SkPoint transformPoints[2]; 817 SkPoint transformPoints[2];
845 818
846 // Depending on the type of the gradient, we want to transform the 819 // Depending on the type of the gradient, we want to transform the
847 // coordinate space in different ways. 820 // coordinate space in different ways.
848 const SkShader::GradientInfo* info = &fState.get()->fInfo; 821 const SkShader::GradientInfo* info = &fShaderState->fInfo;
849 transformPoints[0] = info->fPoint[0]; 822 transformPoints[0] = info->fPoint[0];
850 transformPoints[1] = info->fPoint[1]; 823 transformPoints[1] = info->fPoint[1];
851 switch (fState.get()->fType) { 824 switch (fShaderState->fType) {
852 case SkShader::kLinear_GradientType: 825 case SkShader::kLinear_GradientType:
853 codeFunction = &linearCode; 826 codeFunction = &linearCode;
854 break; 827 break;
855 case SkShader::kRadial_GradientType: 828 case SkShader::kRadial_GradientType:
856 transformPoints[1] = transformPoints[0]; 829 transformPoints[1] = transformPoints[0];
857 transformPoints[1].fX += info->fRadius[0]; 830 transformPoints[1].fX += info->fRadius[0];
858 codeFunction = &radialCode; 831 codeFunction = &radialCode;
859 break; 832 break;
860 case SkShader::kRadial2_GradientType: { 833 case SkShader::kRadial2_GradientType: {
861 // Bail out if the radii are the same. Empty fResources signals 834 // Bail out if the radii are the same. Empty fResources signals
(...skipping 24 matching lines...) Expand all
886 return; 859 return;
887 } 860 }
888 861
889 // Move any scaling (assuming a unit gradient) or translation 862 // Move any scaling (assuming a unit gradient) or translation
890 // (and rotation for linear gradient), of the final gradient from 863 // (and rotation for linear gradient), of the final gradient from
891 // info->fPoints to the matrix (updating bbox appropriately). Now 864 // info->fPoints to the matrix (updating bbox appropriately). Now
892 // the gradient can be drawn on on the unit segment. 865 // the gradient can be drawn on on the unit segment.
893 SkMatrix mapperMatrix; 866 SkMatrix mapperMatrix;
894 unitToPointsMatrix(transformPoints, &mapperMatrix); 867 unitToPointsMatrix(transformPoints, &mapperMatrix);
895 868
896 SkMatrix finalMatrix = fState.get()->fCanvasTransform; 869 SkMatrix finalMatrix = fShaderState->fCanvasTransform;
897 finalMatrix.preConcat(fState.get()->fShaderTransform); 870 finalMatrix.preConcat(fShaderState->fShaderTransform);
898 finalMatrix.preConcat(mapperMatrix); 871 finalMatrix.preConcat(mapperMatrix);
899 872
900 // Preserves as much as posible in the final matrix, and only removes 873 // Preserves as much as posible in the final matrix, and only removes
901 // the perspective. The inverse of the perspective is stored in 874 // the perspective. The inverse of the perspective is stored in
902 // perspectiveInverseOnly matrix and has 3 useful numbers 875 // perspectiveInverseOnly matrix and has 3 useful numbers
903 // (p0, p1, p2), while everything else is either 0 or 1. 876 // (p0, p1, p2), while everything else is either 0 or 1.
904 // In this way the shader will handle it eficiently, with minimal code. 877 // In this way the shader will handle it eficiently, with minimal code.
905 SkMatrix perspectiveInverseOnly = SkMatrix::I(); 878 SkMatrix perspectiveInverseOnly = SkMatrix::I();
906 if (finalMatrix.hasPerspective()) { 879 if (finalMatrix.hasPerspective()) {
907 if (!split_perspective(finalMatrix, 880 if (!split_perspective(finalMatrix,
908 &finalMatrix, &perspectiveInverseOnly)) { 881 &finalMatrix, &perspectiveInverseOnly)) {
909 return; 882 return;
910 } 883 }
911 } 884 }
912 885
913 SkRect bbox; 886 SkRect bbox;
914 bbox.set(fState.get()->fBBox); 887 bbox.set(fShaderState->fBBox);
915 if (!inverseTransformBBox(finalMatrix, &bbox)) { 888 if (!inverseTransformBBox(finalMatrix, &bbox)) {
916 return; 889 return;
917 } 890 }
918 891
919 SkAutoTUnref<SkPDFArray> domain(new SkPDFArray); 892 SkAutoTUnref<SkPDFArray> domain(new SkPDFArray);
920 domain->reserve(4); 893 domain->reserve(4);
921 domain->appendScalar(bbox.fLeft); 894 domain->appendScalar(bbox.fLeft);
922 domain->appendScalar(bbox.fRight); 895 domain->appendScalar(bbox.fRight);
923 domain->appendScalar(bbox.fTop); 896 domain->appendScalar(bbox.fTop);
924 domain->appendScalar(bbox.fBottom); 897 domain->appendScalar(bbox.fBottom);
925 898
926 SkString functionCode; 899 SkString functionCode;
927 // The two point radial gradient further references fState.get()->fInfo 900 // The two point radial gradient further references
901 // fShaderState->fInfo
928 // in translating from x, y coordinates to the t parameter. So, we have 902 // in translating from x, y coordinates to the t parameter. So, we have
929 // to transform the points and radii according to the calculated matrix. 903 // to transform the points and radii according to the calculated matrix.
930 if (fState.get()->fType == SkShader::kRadial2_GradientType) { 904 if (fShaderState->fType == SkShader::kRadial2_GradientType) {
931 SkShader::GradientInfo twoPointRadialInfo = *info; 905 SkShader::GradientInfo twoPointRadialInfo = *info;
932 SkMatrix inverseMapperMatrix; 906 SkMatrix inverseMapperMatrix;
933 if (!mapperMatrix.invert(&inverseMapperMatrix)) { 907 if (!mapperMatrix.invert(&inverseMapperMatrix)) {
934 return; 908 return;
935 } 909 }
936 inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2); 910 inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2);
937 twoPointRadialInfo.fRadius[0] = 911 twoPointRadialInfo.fRadius[0] =
938 inverseMapperMatrix.mapRadius(info->fRadius[0]); 912 inverseMapperMatrix.mapRadius(info->fRadius[0]);
939 twoPointRadialInfo.fRadius[1] = 913 twoPointRadialInfo.fRadius[1] =
940 inverseMapperMatrix.mapRadius(info->fRadius[1]); 914 inverseMapperMatrix.mapRadius(info->fRadius[1]);
941 functionCode = codeFunction(twoPointRadialInfo, perspectiveInverseOnly); 915 functionCode = codeFunction(twoPointRadialInfo, perspectiveInverseOnly);
942 } else { 916 } else {
943 functionCode = codeFunction(*info, perspectiveInverseOnly); 917 functionCode = codeFunction(*info, perspectiveInverseOnly);
944 } 918 }
945 919
946 SkAutoTUnref<SkPDFDict> pdfShader(new SkPDFDict); 920 SkAutoTUnref<SkPDFDict> pdfShader(new SkPDFDict);
947 pdfShader->insertInt("ShadingType", 1); 921 pdfShader->insertInt("ShadingType", 1);
948 pdfShader->insertName("ColorSpace", "DeviceRGB"); 922 pdfShader->insertName("ColorSpace", "DeviceRGB");
949 pdfShader->insert("Domain", domain.get()); 923 pdfShader->insert("Domain", domain.get());
950 924
951 SkPDFStream* function = makePSFunction(functionCode, domain.get()); 925 SkPDFStream* function = makePSFunction(functionCode, domain.get());
952 pdfShader->insert("Function", new SkPDFObjRef(function))->unref(); 926 pdfShader->insert("Function", new SkPDFObjRef(function))->unref();
953 fResources.push(function); // Pass ownership to resource list. 927 fResources.push(function); // Pass ownership to resource list.
954 928
955 insertInt("PatternType", 2); 929 insertInt("PatternType", 2);
956 insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref(); 930 insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref();
957 insert("Shading", pdfShader.get()); 931 insert("Shading", pdfShader.get());
958 } 932 }
959 933
960 SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) { 934 SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state)
961 fState.get()->fImage.lockPixels(); 935 : SkPDFShader(state) {
936 fShaderState->fImage.lockPixels();
962 937
963 // The image shader pattern cell will be drawn into a separate device 938 // The image shader pattern cell will be drawn into a separate device
964 // in pattern cell space (no scaling on the bitmap, though there may be 939 // in pattern cell space (no scaling on the bitmap, though there may be
965 // translations so that all content is in the device, coordinates > 0). 940 // translations so that all content is in the device, coordinates > 0).
966 941
967 // Map clip bounds to shader space to ensure the device is large enough 942 // Map clip bounds to shader space to ensure the device is large enough
968 // to handle fake clamping. 943 // to handle fake clamping.
969 SkMatrix finalMatrix = fState.get()->fCanvasTransform; 944 SkMatrix finalMatrix = fShaderState->fCanvasTransform;
970 finalMatrix.preConcat(fState.get()->fShaderTransform); 945 finalMatrix.preConcat(fShaderState->fShaderTransform);
971 SkRect deviceBounds; 946 SkRect deviceBounds;
972 deviceBounds.set(fState.get()->fBBox); 947 deviceBounds.set(fShaderState->fBBox);
973 if (!inverseTransformBBox(finalMatrix, &deviceBounds)) { 948 if (!inverseTransformBBox(finalMatrix, &deviceBounds)) {
974 return; 949 return;
975 } 950 }
976 951
977 const SkBitmap* image = &fState.get()->fImage; 952 const SkBitmap* image = &fShaderState->fImage;
978 SkRect bitmapBounds; 953 SkRect bitmapBounds;
979 image->getBounds(&bitmapBounds); 954 image->getBounds(&bitmapBounds);
980 955
981 // For tiling modes, the bounds should be extended to include the bitmap, 956 // For tiling modes, the bounds should be extended to include the bitmap,
982 // otherwise the bitmap gets clipped out and the shader is empty and awful. 957 // otherwise the bitmap gets clipped out and the shader is empty and awful.
983 // For clamp modes, we're only interested in the clip region, whether 958 // For clamp modes, we're only interested in the clip region, whether
984 // or not the main bitmap is in it. 959 // or not the main bitmap is in it.
985 SkShader::TileMode tileModes[2]; 960 SkShader::TileMode tileModes[2];
986 tileModes[0] = fState.get()->fImageTileModes[0]; 961 tileModes[0] = fShaderState->fImageTileModes[0];
987 tileModes[1] = fState.get()->fImageTileModes[1]; 962 tileModes[1] = fShaderState->fImageTileModes[1];
988 if (tileModes[0] != SkShader::kClamp_TileMode || 963 if (tileModes[0] != SkShader::kClamp_TileMode ||
989 tileModes[1] != SkShader::kClamp_TileMode) { 964 tileModes[1] != SkShader::kClamp_TileMode) {
990 deviceBounds.join(bitmapBounds); 965 deviceBounds.join(bitmapBounds);
991 } 966 }
992 967
993 SkMatrix unflip; 968 SkMatrix unflip;
994 unflip.setTranslate(0, SkScalarRoundToScalar(deviceBounds.height())); 969 unflip.setTranslate(0, SkScalarRoundToScalar(deviceBounds.height()));
995 unflip.preScale(SK_Scalar1, -SK_Scalar1); 970 unflip.preScale(SK_Scalar1, -SK_Scalar1);
996 SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()), 971 SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()),
997 SkScalarRoundToInt(deviceBounds.height())); 972 SkScalarRoundToInt(deviceBounds.height()));
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 1132
1158 // Put the canvas into the pattern stream (fContent). 1133 // Put the canvas into the pattern stream (fContent).
1159 SkAutoTUnref<SkStream> content(pattern.content()); 1134 SkAutoTUnref<SkStream> content(pattern.content());
1160 setData(content.get()); 1135 setData(content.get());
1161 SkPDFResourceDict* resourceDict = pattern.getResourceDict(); 1136 SkPDFResourceDict* resourceDict = pattern.getResourceDict();
1162 resourceDict->getReferencedResources(fResources, &fResources, false); 1137 resourceDict->getReferencedResources(fResources, &fResources, false);
1163 1138
1164 populate_tiling_pattern_dict(this, patternBBox, 1139 populate_tiling_pattern_dict(this, patternBBox,
1165 pattern.getResourceDict(), finalMatrix); 1140 pattern.getResourceDict(), finalMatrix);
1166 1141
1167 fState.get()->fImage.unlockPixels(); 1142 fShaderState->fImage.unlockPixels();
1168 } 1143 }
1169 1144
1170 SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode, SkPDFAr ray* domain) { 1145 SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode, SkPDFAr ray* domain) {
1171 SkAutoDataUnref funcData(SkData::NewWithCopy(psCode.c_str(), psCode.size())) ; 1146 SkAutoDataUnref funcData(SkData::NewWithCopy(psCode.c_str(), psCode.size())) ;
1172 SkPDFStream* result = new SkPDFStream(funcData.get()); 1147 SkPDFStream* result = new SkPDFStream(funcData.get());
1173 result->insertInt("FunctionType", 4); 1148 result->insertInt("FunctionType", 4);
1174 result->insert("Domain", domain); 1149 result->insert("Domain", domain);
1175 result->insert("Range", RangeObject()); 1150 result->insert("Range", RangeObject());
1176 return result; 1151 return result;
1177 } 1152 }
1178 1153
1179 SkPDFShader::ShaderCanonicalEntry::ShaderCanonicalEntry(SkPDFObject* pdfShader, const State* state)
1180 : fPDFShader(pdfShader)
1181 , fState(state)
1182 {}
1183
1184 bool SkPDFShader::ShaderCanonicalEntry::operator==(const ShaderCanonicalEntry& b ) const {
1185 return fPDFShader == b.fPDFShader ||
1186 (fState != NULL && b.fState != NULL && *fState == *b.fState);
1187 }
1188
1189 bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const { 1154 bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
1190 if (fType != b.fType || 1155 if (fType != b.fType ||
1191 fCanvasTransform != b.fCanvasTransform || 1156 fCanvasTransform != b.fCanvasTransform ||
1192 fShaderTransform != b.fShaderTransform || 1157 fShaderTransform != b.fShaderTransform ||
1193 fBBox != b.fBBox) { 1158 fBBox != b.fBBox) {
1194 return false; 1159 return false;
1195 } 1160 }
1196 1161
1197 if (fType == SkShader::kNone_GradientType) { 1162 if (fType == SkShader::kNone_GradientType) {
1198 if (fPixelGeneration != b.fPixelGeneration || 1163 if (fPixelGeneration != b.fPixelGeneration ||
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 return false; 1334 return false;
1370 } 1335 }
1371 1336
1372 void SkPDFShader::State::AllocateGradientInfoStorage() { 1337 void SkPDFShader::State::AllocateGradientInfoStorage() {
1373 fColorData.set(sk_malloc_throw( 1338 fColorData.set(sk_malloc_throw(
1374 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); 1339 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
1375 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); 1340 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
1376 fInfo.fColorOffsets = 1341 fInfo.fColorOffsets =
1377 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); 1342 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount);
1378 } 1343 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698