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

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

Issue 944643002: PDF: Now threadsafe! (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: formatting Created 5 years, 10 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
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"
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 bool GradientHasAlpha() const; 500 bool GradientHasAlpha() const;
501 501
502 private: 502 private:
503 State(const State& other); 503 State(const State& other);
504 State operator=(const State& rhs); 504 State operator=(const State& rhs);
505 void AllocateGradientInfoStorage(); 505 void AllocateGradientInfoStorage();
506 }; 506 };
507 507
508 //////////////////////////////////////////////////////////////////////////////// 508 ////////////////////////////////////////////////////////////////////////////////
509 509
510 SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state) 510 SkPDFFunctionShader::SkPDFFunctionShader(SkPDFCanon* canon,
511 : SkPDFDict("Pattern"), fShaderState(state) {} 511 SkPDFShader::State* state)
512 : SkPDFDict("Pattern"), fCanon(canon), fShaderState(state) {}
512 513
513 SkPDFFunctionShader::~SkPDFFunctionShader() { 514 SkPDFFunctionShader::~SkPDFFunctionShader() {
514 SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex()); 515 fCanon->removeFunctionShader(this);
515 SkPDFCanon::GetCanon().removeFunctionShader(this);
516 lock.release();
517 fResources.unrefAll(); 516 fResources.unrefAll();
518 } 517 }
519 518
520 bool SkPDFFunctionShader::equals(const SkPDFShader::State& state) const { 519 bool SkPDFFunctionShader::equals(const SkPDFShader::State& state) const {
521 return state == *fShaderState; 520 return state == *fShaderState;
522 } 521 }
523 522
524 //////////////////////////////////////////////////////////////////////////////// 523 ////////////////////////////////////////////////////////////////////////////////
525 524
526 SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state) 525 SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFCanon* canon,
527 : fShaderState(state) {} 526 SkPDFShader::State* state)
527 : fCanon(canon), fShaderState(state) {}
528 528
529 bool SkPDFAlphaFunctionShader::equals(const SkPDFShader::State& state) const { 529 bool SkPDFAlphaFunctionShader::equals(const SkPDFShader::State& state) const {
530 return state == *fShaderState; 530 return state == *fShaderState;
531 } 531 }
532 532
533 SkPDFAlphaFunctionShader::~SkPDFAlphaFunctionShader() { 533 SkPDFAlphaFunctionShader::~SkPDFAlphaFunctionShader() {
534 SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex()); 534 fCanon->removeAlphaShader(this);
535 SkPDFCanon::GetCanon().removeAlphaShader(this);
536 } 535 }
537 536
538 //////////////////////////////////////////////////////////////////////////////// 537 ////////////////////////////////////////////////////////////////////////////////
539 538
540 SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) 539 SkPDFImageShader::SkPDFImageShader(SkPDFCanon* canon, SkPDFShader::State* state)
541 : fShaderState(state) {} 540 : fCanon(canon), fShaderState(state) {}
542 541
543 bool SkPDFImageShader::equals(const SkPDFShader::State& state) const { 542 bool SkPDFImageShader::equals(const SkPDFShader::State& state) const {
544 return state == *fShaderState; 543 return state == *fShaderState;
545 } 544 }
546 545
547 SkPDFImageShader::~SkPDFImageShader() { 546 SkPDFImageShader::~SkPDFImageShader() {
548 SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex()); 547 fCanon->removeImageShader(this);
549 SkPDFCanon::GetCanon().removeImageShader(this);
550 lock.release();
551 fResources.unrefAll(); 548 fResources.unrefAll();
552 } 549 }
553 550
554 //////////////////////////////////////////////////////////////////////////////// 551 ////////////////////////////////////////////////////////////////////////////////
555 552
556 static SkPDFObject* get_pdf_shader_by_state( 553 static SkPDFObject* get_pdf_shader_by_state(
557 SkAutoTDelete<SkPDFShader::State>* autoState) { 554 SkPDFCanon* canon, SkAutoTDelete<SkPDFShader::State>* autoState) {
558 const SkPDFShader::State& state = **autoState; 555 const SkPDFShader::State& state = **autoState;
559 if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) { 556 if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) {
560 // TODO(vandebo) This drops SKComposeShader on the floor. We could 557 // TODO(vandebo) This drops SKComposeShader on the floor. We could
561 // handle compose shader by pulling things up to a layer, drawing with 558 // handle compose shader by pulling things up to a layer, drawing with
562 // the first shader, applying the xfer mode and drawing again with the 559 // the first shader, applying the xfer mode and drawing again with the
563 // second shader, then applying the layer to the original drawing. 560 // second shader, then applying the layer to the original drawing.
564 return NULL; 561 return NULL;
565 } else if (state.fType == SkShader::kNone_GradientType) { 562 } else if (state.fType == SkShader::kNone_GradientType) {
566 SkPDFObject* shader = SkPDFCanon::GetCanon().findImageShader(state); 563 SkPDFObject* shader = canon->findImageShader(state);
567 return shader ? SkRef(shader) : SkPDFImageShader::Create(autoState); 564 return shader ? SkRef(shader)
565 : SkPDFImageShader::Create(canon, autoState);
568 } else if (state.GradientHasAlpha()) { 566 } else if (state.GradientHasAlpha()) {
569 SkPDFObject* shader = SkPDFCanon::GetCanon().findAlphaShader(state); 567 SkPDFObject* shader = canon->findAlphaShader(state);
570 return shader ? SkRef(shader) 568 return shader ? SkRef(shader)
571 : SkPDFAlphaFunctionShader::Create(autoState); 569 : SkPDFAlphaFunctionShader::Create(canon, autoState);
572 } else { 570 } else {
573 SkPDFObject* shader = SkPDFCanon::GetCanon().findFunctionShader(state); 571 SkPDFObject* shader = canon->findFunctionShader(state);
574 return shader ? SkRef(shader) : SkPDFFunctionShader::Create(autoState); 572 return shader ? SkRef(shader)
573 : SkPDFFunctionShader::Create(canon, autoState);
575 } 574 }
576 } 575 }
577 576
578 // static 577 // static
579 SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader, 578 SkPDFObject* SkPDFShader::GetPDFShader(SkPDFCanon* canon,
579 const SkShader& shader,
580 const SkMatrix& matrix, 580 const SkMatrix& matrix,
581 const SkIRect& surfaceBBox, 581 const SkIRect& surfaceBBox,
582 SkScalar rasterScale) { 582 SkScalar rasterScale) {
583 // There is only one mutex becasue we don't know which one we'll need. 583 // There is only one mutex becasue we don't know which one we'll need.
584 SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
585 SkAutoTDelete<SkPDFShader::State> state( 584 SkAutoTDelete<SkPDFShader::State> state(
586 SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale))); 585 SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale)));
587 return get_pdf_shader_by_state(&state); 586 return get_pdf_shader_by_state(canon, &state);
588 } 587 }
589 588
590 static SkPDFResourceDict* get_gradient_resource_dict( 589 static SkPDFResourceDict* get_gradient_resource_dict(
591 SkPDFObject* functionShader, 590 SkPDFObject* functionShader,
592 SkPDFObject* gState) { 591 SkPDFObject* gState) {
593 SkPDFResourceDict* dict = new SkPDFResourceDict(); 592 SkPDFResourceDict* dict = new SkPDFResourceDict();
594 593
595 if (functionShader != NULL) { 594 if (functionShader != NULL) {
596 dict->insertResourceAsReference( 595 dict->insertResourceAsReference(
597 SkPDFResourceDict::kPattern_ResourceType, 0, functionShader); 596 SkPDFResourceDict::kPattern_ResourceType, 0, functionShader);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 &content); 639 &content);
641 640
642 return content.detachAsStream(); 641 return content.detachAsStream();
643 } 642 }
644 643
645 /** 644 /**
646 * Creates a ExtGState with the SMask set to the luminosityShader in 645 * Creates a ExtGState with the SMask set to the luminosityShader in
647 * luminosity mode. The shader pattern extends to the bbox. 646 * luminosity mode. The shader pattern extends to the bbox.
648 */ 647 */
649 static SkPDFGraphicState* create_smask_graphic_state( 648 static SkPDFGraphicState* create_smask_graphic_state(
650 const SkPDFShader::State& state) { 649 SkPDFCanon* canon, const SkPDFShader::State& state) {
651 SkRect bbox; 650 SkRect bbox;
652 bbox.set(state.fBBox); 651 bbox.set(state.fBBox);
653 652
654 SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState( 653 SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState(
655 state.CreateAlphaToLuminosityState()); 654 state.CreateAlphaToLuminosityState());
656 SkAutoTUnref<SkPDFObject> luminosityShader( 655 SkAutoTUnref<SkPDFObject> luminosityShader(
657 get_pdf_shader_by_state(&alphaToLuminosityState)); 656 get_pdf_shader_by_state(canon, &alphaToLuminosityState));
658 657
659 SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox)); 658 SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
660 659
661 SkAutoTUnref<SkPDFResourceDict> 660 SkAutoTUnref<SkPDFResourceDict>
662 resources(get_gradient_resource_dict(luminosityShader, NULL)); 661 resources(get_gradient_resource_dict(luminosityShader, NULL));
663 662
664 SkAutoTUnref<SkPDFFormXObject> alphaMask( 663 SkAutoTUnref<SkPDFFormXObject> alphaMask(
665 new SkPDFFormXObject(alphaStream.get(), bbox, resources.get())); 664 new SkPDFFormXObject(alphaStream.get(), bbox, resources.get()));
666 665
667 return SkPDFGraphicState::GetSMaskGraphicState( 666 return SkPDFGraphicState::GetSMaskGraphicState(
668 alphaMask.get(), false, 667 alphaMask.get(), false,
669 SkPDFGraphicState::kLuminosity_SMaskMode); 668 SkPDFGraphicState::kLuminosity_SMaskMode);
670 } 669 }
671 670
672 SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( 671 SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create(
673 SkAutoTDelete<SkPDFShader::State>* autoState) { 672 SkPDFCanon* canon, SkAutoTDelete<SkPDFShader::State>* autoState) {
674 const SkPDFShader::State& state = **autoState; 673 const SkPDFShader::State& state = **autoState;
675 SkRect bbox; 674 SkRect bbox;
676 bbox.set(state.fBBox); 675 bbox.set(state.fBBox);
677 676
678 SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState()); 677 SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState());
679 678
680 SkPDFObject* colorShader = get_pdf_shader_by_state(&opaqueState); 679 SkPDFObject* colorShader = get_pdf_shader_by_state(canon, &opaqueState);
681 if (!colorShader) { 680 if (!colorShader) {
682 return NULL; 681 return NULL;
683 } 682 }
684 683
685 // Create resource dict with alpha graphics state as G0 and 684 // Create resource dict with alpha graphics state as G0 and
686 // pattern shader as P0, then write content stream. 685 // pattern shader as P0, then write content stream.
687 SkAutoTUnref<SkPDFGraphicState> alphaGs(create_smask_graphic_state(state)); 686 SkAutoTUnref<SkPDFGraphicState> alphaGs(
687 create_smask_graphic_state(canon, state));
688 688
689 SkPDFAlphaFunctionShader* alphaFunctionShader = 689 SkPDFAlphaFunctionShader* alphaFunctionShader =
690 SkNEW_ARGS(SkPDFAlphaFunctionShader, (autoState->detach())); 690 SkNEW_ARGS(SkPDFAlphaFunctionShader, (canon, autoState->detach()));
691 691
692 alphaFunctionShader->fColorShader.reset(colorShader); 692 alphaFunctionShader->fColorShader.reset(colorShader);
693 693
694 alphaFunctionShader->fResourceDict.reset(get_gradient_resource_dict( 694 alphaFunctionShader->fResourceDict.reset(get_gradient_resource_dict(
695 alphaFunctionShader->fColorShader.get(), alphaGs.get())); 695 alphaFunctionShader->fColorShader.get(), alphaGs.get()));
696 696
697 SkAutoTDelete<SkStream> colorStream( 697 SkAutoTDelete<SkStream> colorStream(
698 create_pattern_fill_content(0, bbox)); 698 create_pattern_fill_content(0, bbox));
699 alphaFunctionShader->setData(colorStream.get()); 699 alphaFunctionShader->setData(colorStream.get());
700 700
701 populate_tiling_pattern_dict(alphaFunctionShader, bbox, 701 populate_tiling_pattern_dict(alphaFunctionShader, bbox,
702 alphaFunctionShader->fResourceDict.get(), 702 alphaFunctionShader->fResourceDict.get(),
703 SkMatrix::I()); 703 SkMatrix::I());
704 SkPDFCanon::GetCanon().addAlphaShader(alphaFunctionShader); 704 canon->addAlphaShader(alphaFunctionShader);
705 return alphaFunctionShader; 705 return alphaFunctionShader;
706 } 706 }
707 707
708 // Finds affine and persp such that in = affine * persp. 708 // Finds affine and persp such that in = affine * persp.
709 // but it returns the inverse of perspective matrix. 709 // but it returns the inverse of perspective matrix.
710 static bool split_perspective(const SkMatrix in, SkMatrix* affine, 710 static bool split_perspective(const SkMatrix in, SkMatrix* affine,
711 SkMatrix* perspectiveInverse) { 711 SkMatrix* perspectiveInverse) {
712 const SkScalar p2 = in[SkMatrix::kMPersp2]; 712 const SkScalar p2 = in[SkMatrix::kMPersp2];
713 713
714 if (SkScalarNearlyZero(p2)) { 714 if (SkScalarNearlyZero(p2)) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 SkAutoDataUnref funcData( 767 SkAutoDataUnref funcData(
768 SkData::NewWithCopy(psCode.c_str(), psCode.size())); 768 SkData::NewWithCopy(psCode.c_str(), psCode.size()));
769 SkPDFStream* result = SkNEW_ARGS(SkPDFStream, (funcData.get())); 769 SkPDFStream* result = SkNEW_ARGS(SkPDFStream, (funcData.get()));
770 result->insertInt("FunctionType", 4); 770 result->insertInt("FunctionType", 4);
771 result->insert("Domain", domain); 771 result->insert("Domain", domain);
772 result->insert("Range", rangeObject.get()); 772 result->insert("Range", rangeObject.get());
773 return result; 773 return result;
774 } 774 }
775 775
776 SkPDFFunctionShader* SkPDFFunctionShader::Create( 776 SkPDFFunctionShader* SkPDFFunctionShader::Create(
777 SkAutoTDelete<SkPDFShader::State>* autoState) { 777 SkPDFCanon* canon, SkAutoTDelete<SkPDFShader::State>* autoState) {
778 const SkPDFShader::State& state = **autoState; 778 const SkPDFShader::State& state = **autoState;
779 779
780 SkString (*codeFunction)(const SkShader::GradientInfo& info, 780 SkString (*codeFunction)(const SkShader::GradientInfo& info,
781 const SkMatrix& perspectiveRemover) = NULL; 781 const SkMatrix& perspectiveRemover) = NULL;
782 SkPoint transformPoints[2]; 782 SkPoint transformPoints[2];
783 783
784 // Depending on the type of the gradient, we want to transform the 784 // Depending on the type of the gradient, we want to transform the
785 // coordinate space in different ways. 785 // coordinate space in different ways.
786 const SkShader::GradientInfo* info = &state.fInfo; 786 const SkShader::GradientInfo* info = &state.fInfo;
787 transformPoints[0] = info->fPoint[0]; 787 transformPoints[0] = info->fPoint[0];
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 pdfShader->insertName("ColorSpace", "DeviceRGB"); 886 pdfShader->insertName("ColorSpace", "DeviceRGB");
887 pdfShader->insert("Domain", domain.get()); 887 pdfShader->insert("Domain", domain.get());
888 888
889 SkPDFStream* function = make_ps_function(functionCode, domain.get()); 889 SkPDFStream* function = make_ps_function(functionCode, domain.get());
890 pdfShader->insert("Function", new SkPDFObjRef(function))->unref(); 890 pdfShader->insert("Function", new SkPDFObjRef(function))->unref();
891 891
892 SkAutoTUnref<SkPDFArray> matrixArray( 892 SkAutoTUnref<SkPDFArray> matrixArray(
893 SkPDFUtils::MatrixToArray(finalMatrix)); 893 SkPDFUtils::MatrixToArray(finalMatrix));
894 894
895 SkPDFFunctionShader* pdfFunctionShader = 895 SkPDFFunctionShader* pdfFunctionShader =
896 SkNEW_ARGS(SkPDFFunctionShader, (autoState->detach())); 896 SkNEW_ARGS(SkPDFFunctionShader, (canon, autoState->detach()));
897 897
898 pdfFunctionShader->fResources.push(function); 898 pdfFunctionShader->fResources.push(function);
899 // Pass ownership to resource list. 899 // Pass ownership to resource list.
900 900
901 pdfFunctionShader->insertInt("PatternType", 2); 901 pdfFunctionShader->insertInt("PatternType", 2);
902 pdfFunctionShader->insert("Matrix", matrixArray.get()); 902 pdfFunctionShader->insert("Matrix", matrixArray.get());
903 pdfFunctionShader->insert("Shading", pdfShader.get()); 903 pdfFunctionShader->insert("Shading", pdfShader.get());
904 904
905 SkPDFCanon::GetCanon().addFunctionShader(pdfFunctionShader); 905 canon->addFunctionShader(pdfFunctionShader);
906 return pdfFunctionShader; 906 return pdfFunctionShader;
907 } 907 }
908 908
909 SkPDFImageShader* SkPDFImageShader::Create( 909 SkPDFImageShader* SkPDFImageShader::Create(
910 SkAutoTDelete<SkPDFShader::State>* autoState) { 910 SkPDFCanon* canon, SkAutoTDelete<SkPDFShader::State>* autoState) {
911 const SkPDFShader::State& state = **autoState; 911 const SkPDFShader::State& state = **autoState;
912 912
913 state.fImage.lockPixels(); 913 state.fImage.lockPixels();
914 914
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.
(...skipping 14 matching lines...) Expand all
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
936 // or not the main bitmap is in it. 936 // or not the main bitmap is in it.
937 SkShader::TileMode tileModes[2]; 937 SkShader::TileMode tileModes[2];
938 tileModes[0] = state.fImageTileModes[0]; 938 tileModes[0] = state.fImageTileModes[0];
939 tileModes[1] = state.fImageTileModes[1]; 939 tileModes[1] = state.fImageTileModes[1];
940 if (tileModes[0] != SkShader::kClamp_TileMode || 940 if (tileModes[0] != SkShader::kClamp_TileMode ||
941 tileModes[1] != SkShader::kClamp_TileMode) { 941 tileModes[1] != SkShader::kClamp_TileMode) {
942 deviceBounds.join(bitmapBounds); 942 deviceBounds.join(bitmapBounds);
943 } 943 }
944 944
945 SkMatrix unflip; 945 SkMatrix unflip;
mtklein 2015/02/19 23:50:38 Now unused?
hal.canary 2015/02/20 01:22:28 Done.
946 unflip.setTranslate(0, SkScalarRoundToScalar(deviceBounds.height())); 946 unflip.setTranslate(0, SkScalarRoundToScalar(deviceBounds.height()));
947 unflip.preScale(SK_Scalar1, -SK_Scalar1); 947 unflip.preScale(SK_Scalar1, -SK_Scalar1);
948 SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()), 948 SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()),
949 SkScalarRoundToInt(deviceBounds.height())); 949 SkScalarRoundToInt(deviceBounds.height()));
950 // TODO(edisonn): should we pass here the DCT encoder of the destination dev ice? 950 // TODO(edisonn): should we pass here the DCT encoder of the destination dev ice?
951 // TODO(edisonn): NYI Perspective, use SkPDFDeviceFlattener. 951 // TODO(edisonn): NYI Perspective, use SkPDFDeviceFlattener.
952 SkPDFDevice pattern(size, size, unflip); 952 const SkScalar dpi = 72.0f; /*TODO: get this right*/
mtklein 2015/02/19 23:50:38 Is that, pull it from the device instead of making
hal.canary 2015/02/20 01:22:28 I meant to do that. Done
953 SkCanvas canvas(&pattern); 953 SkAutoTUnref<SkPDFDevice> patternDevice(
954 SkPDFDevice::CreateUnflipped(size, dpi, canon));
955 SkCanvas canvas(patternDevice.get());
954 956
955 SkRect patternBBox; 957 SkRect patternBBox;
956 image->getBounds(&patternBBox); 958 image->getBounds(&patternBBox);
957 959
958 // Translate the canvas so that the bitmap origin is at (0, 0). 960 // Translate the canvas so that the bitmap origin is at (0, 0).
959 canvas.translate(-deviceBounds.left(), -deviceBounds.top()); 961 canvas.translate(-deviceBounds.left(), -deviceBounds.top());
960 patternBBox.offset(-deviceBounds.left(), -deviceBounds.top()); 962 patternBBox.offset(-deviceBounds.left(), -deviceBounds.top());
961 // Undo the translation in the final matrix 963 // Undo the translation in the final matrix
962 finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top()); 964 finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top());
963 965
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 if (tileModes[0] == SkShader::kMirror_TileMode) { 1103 if (tileModes[0] == SkShader::kMirror_TileMode) {
1102 bottomMatrix.postScale(-1, 1); 1104 bottomMatrix.postScale(-1, 1);
1103 bottomMatrix.postTranslate(2 * width, 0); 1105 bottomMatrix.postTranslate(2 * width, 0);
1104 drawBitmapMatrix(&canvas, bottom, bottomMatrix); 1106 drawBitmapMatrix(&canvas, bottom, bottomMatrix);
1105 } 1107 }
1106 patternBBox.fBottom = deviceBounds.height(); 1108 patternBBox.fBottom = deviceBounds.height();
1107 } 1109 }
1108 } 1110 }
1109 1111
1110 // Put the canvas into the pattern stream (fContent). 1112 // Put the canvas into the pattern stream (fContent).
1111 SkAutoTDelete<SkStream> content(pattern.content()); 1113 SkAutoTDelete<SkStream> content(patternDevice->content());
1112 1114
1113 SkPDFImageShader* imageShader = 1115 SkPDFImageShader* imageShader =
1114 SkNEW_ARGS(SkPDFImageShader, (autoState->detach())); 1116 SkNEW_ARGS(SkPDFImageShader, (canon, autoState->detach()));
1115 imageShader->setData(content.get()); 1117 imageShader->setData(content.get());
1116 1118
1117 populate_tiling_pattern_dict(imageShader, patternBBox, 1119 populate_tiling_pattern_dict(imageShader, patternBBox,
1118 pattern.getResourceDict(), finalMatrix); 1120 patternDevice->getResourceDict(), finalMatrix);
1119 1121
1120 imageShader->fShaderState->fImage.unlockPixels(); 1122 imageShader->fShaderState->fImage.unlockPixels();
1121 1123
1122 SkPDFCanon::GetCanon().addImageShader(imageShader); 1124 canon->addImageShader(imageShader);
1123 return imageShader; 1125 return imageShader;
1124 } 1126 }
1125 1127
1126 bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const { 1128 bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
1127 if (fType != b.fType || 1129 if (fType != b.fType ||
1128 fCanvasTransform != b.fCanvasTransform || 1130 fCanvasTransform != b.fCanvasTransform ||
1129 fShaderTransform != b.fShaderTransform || 1131 fShaderTransform != b.fShaderTransform ||
1130 fBBox != b.fBBox) { 1132 fBBox != b.fBBox) {
1131 return false; 1133 return false;
1132 } 1134 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 return false; 1317 return false;
1316 } 1318 }
1317 1319
1318 void SkPDFShader::State::AllocateGradientInfoStorage() { 1320 void SkPDFShader::State::AllocateGradientInfoStorage() {
1319 fColorData.set(sk_malloc_throw( 1321 fColorData.set(sk_malloc_throw(
1320 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); 1322 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
1321 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); 1323 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
1322 fInfo.fColorOffsets = 1324 fInfo.fColorOffsets =
1323 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); 1325 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount);
1324 } 1326 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698