Home | History | Annotate | Download | only in pdf
      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