1 /* 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 26 class SkObjRef; 27 class 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 35 class SkPDFShader : public SkPDFObject { 36 public: 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 61 private: 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. 98 static SkTDArray<ShaderCanonicalEntry>& canonicalShaders(); 99 static SkMutex& canonicalShadersMutex(); 100 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 111