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

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

Issue 1802963002: SkPDF: SkPDFDevice has ptr to SkPDFDocument (Closed) Base URL: https://skia.googlesource.com/skia.git@SkPdfBigSerializeRefactor
Patch Set: better explanation Created 4 years, 9 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 "SkPDFCanon.h"
14 #include "SkPDFDevice.h" 14 #include "SkPDFDevice.h"
15 #include "SkPDFDocument.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 23
23 static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) { 24 static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) {
24 SkMatrix inverse; 25 SkMatrix inverse;
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 479
479 bool SkPDFImageShader::equals(const SkPDFShader::State& state) const { 480 bool SkPDFImageShader::equals(const SkPDFShader::State& state) const {
480 return state == *fShaderState; 481 return state == *fShaderState;
481 } 482 }
482 483
483 SkPDFImageShader::~SkPDFImageShader() {} 484 SkPDFImageShader::~SkPDFImageShader() {}
484 485
485 //////////////////////////////////////////////////////////////////////////////// 486 ////////////////////////////////////////////////////////////////////////////////
486 487
487 static SkPDFObject* get_pdf_shader_by_state( 488 static SkPDFObject* get_pdf_shader_by_state(
488 SkPDFCanon* canon, 489 SkPDFDocument* doc,
489 SkScalar dpi, 490 SkScalar dpi,
490 SkAutoTDelete<SkPDFShader::State>* autoState) { 491 SkAutoTDelete<SkPDFShader::State>* autoState) {
491 const SkPDFShader::State& state = **autoState; 492 const SkPDFShader::State& state = **autoState;
493 SkPDFCanon* canon = doc->canon();
492 if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) { 494 if (state.fType == SkShader::kNone_GradientType && state.fImage.isNull()) {
493 // TODO(vandebo) This drops SKComposeShader on the floor. We could 495 // TODO(vandebo) This drops SKComposeShader on the floor. We could
494 // handle compose shader by pulling things up to a layer, drawing with 496 // handle compose shader by pulling things up to a layer, drawing with
495 // the first shader, applying the xfer mode and drawing again with the 497 // the first shader, applying the xfer mode and drawing again with the
496 // second shader, then applying the layer to the original drawing. 498 // second shader, then applying the layer to the original drawing.
497 return nullptr; 499 return nullptr;
498 } else if (state.fType == SkShader::kNone_GradientType) { 500 } else if (state.fType == SkShader::kNone_GradientType) {
499 SkPDFObject* shader = canon->findImageShader(state); 501 SkPDFObject* shader = canon->findImageShader(state);
500 return shader ? SkRef(shader) 502 return shader ? SkRef(shader)
501 : SkPDFImageShader::Create(canon, dpi, autoState); 503 : SkPDFImageShader::Create(doc, dpi, autoState);
502 } else if (state.GradientHasAlpha()) { 504 } else if (state.GradientHasAlpha()) {
503 SkPDFObject* shader = canon->findAlphaShader(state); 505 SkPDFObject* shader = canon->findAlphaShader(state);
504 return shader ? SkRef(shader) 506 return shader ? SkRef(shader)
505 : SkPDFAlphaFunctionShader::Create(canon, dpi, autoState); 507 : SkPDFAlphaFunctionShader::Create(doc, dpi, autoState);
506 } else { 508 } else {
507 SkPDFObject* shader = canon->findFunctionShader(state); 509 SkPDFObject* shader = canon->findFunctionShader(state);
508 return shader ? SkRef(shader) 510 return shader ? SkRef(shader)
509 : SkPDFFunctionShader::Create(canon, autoState); 511 : SkPDFFunctionShader::Create(canon, autoState);
510 } 512 }
511 } 513 }
512 514
513 // static 515 // static
514 SkPDFObject* SkPDFShader::GetPDFShader(SkPDFCanon* canon, 516 SkPDFObject* SkPDFShader::GetPDFShader(SkPDFDocument* doc,
515 SkScalar dpi, 517 SkScalar dpi,
516 const SkShader& shader, 518 const SkShader& shader,
517 const SkMatrix& matrix, 519 const SkMatrix& matrix,
518 const SkIRect& surfaceBBox, 520 const SkIRect& surfaceBBox,
519 SkScalar rasterScale) { 521 SkScalar rasterScale) {
520 SkAutoTDelete<SkPDFShader::State> state(new State(shader, matrix, surfaceBBo x, rasterScale)); 522 SkAutoTDelete<SkPDFShader::State> state(new State(shader, matrix, surfaceBBo x, rasterScale));
521 return get_pdf_shader_by_state(canon, dpi, &state); 523 return get_pdf_shader_by_state(doc, dpi, &state);
522 } 524 }
523 525
524 static sk_sp<SkPDFDict> get_gradient_resource_dict( 526 static sk_sp<SkPDFDict> get_gradient_resource_dict(
525 SkPDFObject* functionShader, 527 SkPDFObject* functionShader,
526 SkPDFObject* gState) { 528 SkPDFObject* gState) {
527 SkTDArray<SkPDFObject*> patterns; 529 SkTDArray<SkPDFObject*> patterns;
528 if (functionShader) { 530 if (functionShader) {
529 patterns.push(functionShader); 531 patterns.push(functionShader);
530 } 532 }
531 SkTDArray<SkPDFObject*> graphicStates; 533 SkTDArray<SkPDFObject*> graphicStates;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 &content); 574 &content);
573 575
574 return content.detachAsStream(); 576 return content.detachAsStream();
575 } 577 }
576 578
577 /** 579 /**
578 * Creates a ExtGState with the SMask set to the luminosityShader in 580 * Creates a ExtGState with the SMask set to the luminosityShader in
579 * luminosity mode. The shader pattern extends to the bbox. 581 * luminosity mode. The shader pattern extends to the bbox.
580 */ 582 */
581 static sk_sp<SkPDFObject> create_smask_graphic_state( 583 static sk_sp<SkPDFObject> create_smask_graphic_state(
582 SkPDFCanon* canon, SkScalar dpi, const SkPDFShader::State& state) { 584 SkPDFDocument* doc, SkScalar dpi, const SkPDFShader::State& state) {
583 SkRect bbox; 585 SkRect bbox;
584 bbox.set(state.fBBox); 586 bbox.set(state.fBBox);
585 587
586 SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState( 588 SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState(
587 state.CreateAlphaToLuminosityState()); 589 state.CreateAlphaToLuminosityState());
588 sk_sp<SkPDFObject> luminosityShader( 590 sk_sp<SkPDFObject> luminosityShader(
589 get_pdf_shader_by_state(canon, dpi, &alphaToLuminosityState)); 591 get_pdf_shader_by_state(doc, dpi, &alphaToLuminosityState));
590 592
591 SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox)); 593 SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
592 594
593 auto resources = 595 auto resources =
594 get_gradient_resource_dict(luminosityShader.get(), nullptr); 596 get_gradient_resource_dict(luminosityShader.get(), nullptr);
595 597
596 sk_sp<SkPDFFormXObject> alphaMask( 598 sk_sp<SkPDFFormXObject> alphaMask(
597 new SkPDFFormXObject(alphaStream.get(), bbox, resources.get())); 599 new SkPDFFormXObject(alphaStream.get(), bbox, resources.get()));
598 600
599 return SkPDFGraphicState::GetSMaskGraphicState( 601 return SkPDFGraphicState::GetSMaskGraphicState(
600 alphaMask.get(), false, 602 alphaMask.get(), false,
601 SkPDFGraphicState::kLuminosity_SMaskMode, canon); 603 SkPDFGraphicState::kLuminosity_SMaskMode, doc->canon());
602 } 604 }
603 605
604 SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( 606 SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create(
605 SkPDFCanon* canon, 607 SkPDFDocument* doc,
606 SkScalar dpi, 608 SkScalar dpi,
607 SkAutoTDelete<SkPDFShader::State>* autoState) { 609 SkAutoTDelete<SkPDFShader::State>* autoState) {
608 const SkPDFShader::State& state = **autoState; 610 const SkPDFShader::State& state = **autoState;
609 SkRect bbox; 611 SkRect bbox;
610 bbox.set(state.fBBox); 612 bbox.set(state.fBBox);
611 613
612 SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState()); 614 SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState());
613 615
614 sk_sp<SkPDFObject> colorShader( 616 sk_sp<SkPDFObject> colorShader(
615 get_pdf_shader_by_state(canon, dpi, &opaqueState)); 617 get_pdf_shader_by_state(doc, dpi, &opaqueState));
616 if (!colorShader) { 618 if (!colorShader) {
617 return nullptr; 619 return nullptr;
618 } 620 }
619 621
620 // Create resource dict with alpha graphics state as G0 and 622 // Create resource dict with alpha graphics state as G0 and
621 // pattern shader as P0, then write content stream. 623 // pattern shader as P0, then write content stream.
622 auto alphaGs = create_smask_graphic_state(canon, dpi, state); 624 auto alphaGs = create_smask_graphic_state(doc, dpi, state);
623 625
624 SkPDFAlphaFunctionShader* alphaFunctionShader = 626 SkPDFAlphaFunctionShader* alphaFunctionShader =
625 new SkPDFAlphaFunctionShader(autoState->release()); 627 new SkPDFAlphaFunctionShader(autoState->release());
626 628
627 auto resourceDict = 629 auto resourceDict =
628 get_gradient_resource_dict(colorShader.get(), alphaGs.get()); 630 get_gradient_resource_dict(colorShader.get(), alphaGs.get());
629 631
630 SkAutoTDelete<SkStream> colorStream( 632 SkAutoTDelete<SkStream> colorStream(
631 create_pattern_fill_content(0, bbox)); 633 create_pattern_fill_content(0, bbox));
632 alphaFunctionShader->setData(colorStream.get()); 634 alphaFunctionShader->setData(colorStream.get());
633 635
634 populate_tiling_pattern_dict(alphaFunctionShader, bbox, resourceDict.get(), 636 populate_tiling_pattern_dict(alphaFunctionShader, bbox, resourceDict.get(),
635 SkMatrix::I()); 637 SkMatrix::I());
636 canon->addAlphaShader(alphaFunctionShader); 638 doc->canon()->addAlphaShader(alphaFunctionShader);
637 return alphaFunctionShader; 639 return alphaFunctionShader;
638 } 640 }
639 641
640 // Finds affine and persp such that in = affine * persp. 642 // Finds affine and persp such that in = affine * persp.
641 // but it returns the inverse of perspective matrix. 643 // but it returns the inverse of perspective matrix.
642 static bool split_perspective(const SkMatrix in, SkMatrix* affine, 644 static bool split_perspective(const SkMatrix in, SkMatrix* affine,
643 SkMatrix* perspectiveInverse) { 645 SkMatrix* perspectiveInverse) {
644 const SkScalar p2 = in[SkMatrix::kMPersp2]; 646 const SkScalar p2 = in[SkMatrix::kMPersp2];
645 647
646 if (SkScalarNearlyZero(p2)) { 648 if (SkScalarNearlyZero(p2)) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 pdfFunctionShader->insertInt("PatternType", 2); 815 pdfFunctionShader->insertInt("PatternType", 2);
814 pdfFunctionShader->insertObject("Matrix", 816 pdfFunctionShader->insertObject("Matrix",
815 SkPDFUtils::MatrixToArray(finalMatrix)); 817 SkPDFUtils::MatrixToArray(finalMatrix));
816 pdfFunctionShader->insertObject("Shading", std::move(pdfShader)); 818 pdfFunctionShader->insertObject("Shading", std::move(pdfShader));
817 819
818 canon->addFunctionShader(pdfFunctionShader.get()); 820 canon->addFunctionShader(pdfFunctionShader.get());
819 return pdfFunctionShader.release(); 821 return pdfFunctionShader.release();
820 } 822 }
821 823
822 SkPDFImageShader* SkPDFImageShader::Create( 824 SkPDFImageShader* SkPDFImageShader::Create(
823 SkPDFCanon* canon, 825 SkPDFDocument* doc,
824 SkScalar dpi, 826 SkScalar dpi,
825 SkAutoTDelete<SkPDFShader::State>* autoState) { 827 SkAutoTDelete<SkPDFShader::State>* autoState) {
826 const SkPDFShader::State& state = **autoState; 828 const SkPDFShader::State& state = **autoState;
827 829
828 state.fImage.lockPixels(); 830 state.fImage.lockPixels();
829 831
830 // The image shader pattern cell will be drawn into a separate device 832 // The image shader pattern cell will be drawn into a separate device
831 // in pattern cell space (no scaling on the bitmap, though there may be 833 // in pattern cell space (no scaling on the bitmap, though there may be
832 // translations so that all content is in the device, coordinates > 0). 834 // translations so that all content is in the device, coordinates > 0).
833 835
(...skipping 19 matching lines...) Expand all
853 tileModes[0] = state.fImageTileModes[0]; 855 tileModes[0] = state.fImageTileModes[0];
854 tileModes[1] = state.fImageTileModes[1]; 856 tileModes[1] = state.fImageTileModes[1];
855 if (tileModes[0] != SkShader::kClamp_TileMode || 857 if (tileModes[0] != SkShader::kClamp_TileMode ||
856 tileModes[1] != SkShader::kClamp_TileMode) { 858 tileModes[1] != SkShader::kClamp_TileMode) {
857 deviceBounds.join(bitmapBounds); 859 deviceBounds.join(bitmapBounds);
858 } 860 }
859 861
860 SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()), 862 SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()),
861 SkScalarRoundToInt(deviceBounds.height())); 863 SkScalarRoundToInt(deviceBounds.height()));
862 sk_sp<SkPDFDevice> patternDevice( 864 sk_sp<SkPDFDevice> patternDevice(
863 SkPDFDevice::CreateUnflipped(size, dpi, canon)); 865 SkPDFDevice::CreateUnflipped(size, dpi, doc));
864 SkCanvas canvas(patternDevice.get()); 866 SkCanvas canvas(patternDevice.get());
865 867
866 SkRect patternBBox; 868 SkRect patternBBox;
867 image->getBounds(&patternBBox); 869 image->getBounds(&patternBBox);
868 870
869 // Translate the canvas so that the bitmap origin is at (0, 0). 871 // Translate the canvas so that the bitmap origin is at (0, 0).
870 canvas.translate(-deviceBounds.left(), -deviceBounds.top()); 872 canvas.translate(-deviceBounds.left(), -deviceBounds.top());
871 patternBBox.offset(-deviceBounds.left(), -deviceBounds.top()); 873 patternBBox.offset(-deviceBounds.left(), -deviceBounds.top());
872 // Undo the translation in the final matrix 874 // Undo the translation in the final matrix
873 finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top()); 875 finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top());
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 1025
1024 SkPDFImageShader* imageShader = new SkPDFImageShader(autoState->release()); 1026 SkPDFImageShader* imageShader = new SkPDFImageShader(autoState->release());
1025 imageShader->setData(content.get()); 1027 imageShader->setData(content.get());
1026 1028
1027 auto resourceDict = patternDevice->makeResourceDict(); 1029 auto resourceDict = patternDevice->makeResourceDict();
1028 populate_tiling_pattern_dict(imageShader, patternBBox, 1030 populate_tiling_pattern_dict(imageShader, patternBBox,
1029 resourceDict.get(), finalMatrix); 1031 resourceDict.get(), finalMatrix);
1030 1032
1031 imageShader->fShaderState->fImage.unlockPixels(); 1033 imageShader->fShaderState->fImage.unlockPixels();
1032 1034
1033 canon->addImageShader(imageShader); 1035 doc->canon()->addImageShader(imageShader);
1034 return imageShader; 1036 return imageShader;
1035 } 1037 }
1036 1038
1037 bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const { 1039 bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
1038 if (fType != b.fType || 1040 if (fType != b.fType ||
1039 fCanvasTransform != b.fCanvasTransform || 1041 fCanvasTransform != b.fCanvasTransform ||
1040 fShaderTransform != b.fShaderTransform || 1042 fShaderTransform != b.fShaderTransform ||
1041 fBBox != b.fBBox) { 1043 fBBox != b.fBBox) {
1042 return false; 1044 return false;
1043 } 1045 }
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 return false; 1225 return false;
1224 } 1226 }
1225 1227
1226 void SkPDFShader::State::AllocateGradientInfoStorage() { 1228 void SkPDFShader::State::AllocateGradientInfoStorage() {
1227 fColorData.set(sk_malloc_throw( 1229 fColorData.set(sk_malloc_throw(
1228 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar)))); 1230 fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
1229 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get()); 1231 fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
1230 fInfo.fColorOffsets = 1232 fInfo.fColorOffsets =
1231 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount); 1233 reinterpret_cast<SkScalar*>(fInfo.fColors + fInfo.fColorCount);
1232 } 1234 }
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