Chromium Code Reviews| 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 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |