aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/pdf/SkPDFShader.h
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-08 18:31:02 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-08 18:31:02 +0000
commitda912d61ede86dd3dfa8f645c6f3977f2183812b (patch)
tree593e6cb838888c9cf6c7700e7ca2f65d322320d8 /include/pdf/SkPDFShader.h
parente8c701cbf5f8749415d4411173234aebb1add740 (diff)
[PDF] Add support for Shaders.
- Shaders, or as they are referred to in PDF, patterns, are drawn in the coordinate system of the initial page, so when we canonicalize them, we have to consider the current transform and where they are constructed. - Image shaders are tiled by default, this makes repeat and mirror modes easy, but means we have to draw a pattern as large as the current clip to support clamp mode. - Gradient shaders are implemented with type 4 functions, which are basically small snippets of post script code. I've tried to make the code generation modular and heavily commented to make it easy to understand or expand. Review URL: http://codereview.appspot.com/4239061 git-svn-id: http://skia.googlecode.com/svn/trunk@905 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/pdf/SkPDFShader.h')
-rw-r--r--include/pdf/SkPDFShader.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/include/pdf/SkPDFShader.h b/include/pdf/SkPDFShader.h
new file mode 100644
index 0000000000..17f7f03316
--- /dev/null
+++ b/include/pdf/SkPDFShader.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFShader_DEFINED
+#define SkPDFShader_DEFINED
+
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkMatrix.h"
+#include "SkRefCnt.h"
+#include "SkShader.h"
+
+class SkObjRef;
+class SkPDFCatalog;
+
+/** \class SkPDFShader
+
+ In PDF parlance, this is a pattern, used in place of a color when the
+ pattern color space is selected.
+*/
+
+class SkPDFShader : public SkPDFObject {
+public:
+ virtual ~SkPDFShader();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ /** Get the PDF shader for the passed SkShader. If the SkShader is
+ * invalid in some way, returns NULL. The reference count of
+ * the object is incremented and it is the caller's responsibility to
+ * unreference it when done. This is needed to accommodate the weak
+ * reference pattern used when the returned object is new and has no
+ * other references.
+ * @param shader The SkShader to emulate.
+ * @param matrix The current transform. (PDF shaders are absolutely
+ * positioned, relative to where the page is drawn.)
+ * @param surfceBBox The bounding box of the drawing surface (with matrix
+ * already applied).
+ */
+ static SkPDFShader* getPDFShader(const SkShader& shader,
+ const SkMatrix& matrix,
+ const SkIRect& surfaceBBox);
+
+private:
+ class State {
+ public:
+ SkShader::GradientType fType;
+ SkShader::GradientInfo fInfo;
+ SkAutoFree fColorData;
+ SkMatrix fCanvasTransform;
+ SkMatrix fShaderTransform;
+ SkIRect fBBox;
+
+ SkBitmap fImage;
+ uint32_t fPixelGeneration;
+ SkShader::TileMode fImageTileModes[2];
+
+ explicit State(const SkShader& shader, const SkMatrix& canvasTransform,
+ const SkIRect& bbox);
+ bool operator==(const State& b) const;
+ };
+
+ SkRefPtr<SkPDFDict> fContent;
+ SkTDArray<SkPDFObject*> fResources;
+ SkAutoTDelete<const State> fState;
+
+ class ShaderCanonicalEntry {
+ public:
+ SkPDFShader* fPDFShader;
+ const State* fState;
+
+ bool operator==(const ShaderCanonicalEntry& b) const {
+ return fPDFShader == b.fPDFShader || *fState == *b.fState;
+ }
+ ShaderCanonicalEntry(SkPDFShader* pdfShader, const State* state)
+ : fPDFShader(pdfShader),
+ fState(state) {
+ }
+ };
+ // This should be made a hash table if performance is a problem.
+ static SkTDArray<ShaderCanonicalEntry>& canonicalShaders();
+ static SkMutex& canonicalShadersMutex();
+
+ static SkPDFObject* rangeObject();
+
+ SkPDFShader(State* state);
+
+ void doFunctionShader();
+ void doImageShader();
+ SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
+};
+
+#endif