blob: 0d7f685a6343af6ca29376e384700349dfbaa1b1 [file] [log] [blame]
vandebo@chromium.orgda912d62011-03-08 18:31:02 +00001/*
2 * Copyright (C) 2011 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkPDFShader_DEFINED
18#define SkPDFShader_DEFINED
19
20#include "SkPDFStream.h"
21#include "SkPDFTypes.h"
22#include "SkMatrix.h"
23#include "SkRefCnt.h"
24#include "SkShader.h"
25
26class SkObjRef;
27class SkPDFCatalog;
28
29/** \class SkPDFShader
30
31 In PDF parlance, this is a pattern, used in place of a color when the
32 pattern color space is selected.
33*/
34
35class SkPDFShader : public SkPDFObject {
36public:
37 virtual ~SkPDFShader();
38
39 // The SkPDFObject interface.
40 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
41 bool indirect);
42 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
43 virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
44
45 /** Get the PDF shader for the passed SkShader. If the SkShader is
46 * invalid in some way, returns NULL. The reference count of
47 * the object is incremented and it is the caller's responsibility to
48 * unreference it when done. This is needed to accommodate the weak
49 * reference pattern used when the returned object is new and has no
50 * other references.
51 * @param shader The SkShader to emulate.
52 * @param matrix The current transform. (PDF shaders are absolutely
53 * positioned, relative to where the page is drawn.)
54 * @param surfceBBox The bounding box of the drawing surface (with matrix
55 * already applied).
56 */
57 static SkPDFShader* getPDFShader(const SkShader& shader,
58 const SkMatrix& matrix,
59 const SkIRect& surfaceBBox);
60
61private:
62 class State {
63 public:
64 SkShader::GradientType fType;
65 SkShader::GradientInfo fInfo;
66 SkAutoFree fColorData;
67 SkMatrix fCanvasTransform;
68 SkMatrix fShaderTransform;
69 SkIRect fBBox;
70
71 SkBitmap fImage;
72 uint32_t fPixelGeneration;
73 SkShader::TileMode fImageTileModes[2];
74
75 explicit State(const SkShader& shader, const SkMatrix& canvasTransform,
76 const SkIRect& bbox);
77 bool operator==(const State& b) const;
78 };
79
80 SkRefPtr<SkPDFDict> fContent;
81 SkTDArray<SkPDFObject*> fResources;
82 SkAutoTDelete<const State> fState;
83
84 class ShaderCanonicalEntry {
85 public:
86 SkPDFShader* fPDFShader;
87 const State* fState;
88
89 bool operator==(const ShaderCanonicalEntry& b) const {
90 return fPDFShader == b.fPDFShader || *fState == *b.fState;
91 }
92 ShaderCanonicalEntry(SkPDFShader* pdfShader, const State* state)
93 : fPDFShader(pdfShader),
94 fState(state) {
95 }
96 };
97 // This should be made a hash table if performance is a problem.
vandebo@chromium.orgb88cfe52011-07-18 18:40:32 +000098 static SkTDArray<ShaderCanonicalEntry>& CanonicalShaders();
99 static SkMutex& CanonicalShadersMutex();
vandebo@chromium.orgda912d62011-03-08 18:31:02 +0000100
101 static SkPDFObject* rangeObject();
102
103 SkPDFShader(State* state);
104
105 void doFunctionShader();
106 void doImageShader();
107 SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
108};
109
110#endif