blob: 2b9e5e6324ef5f95786fc256b05dc3b4fca0cc63 [file] [log] [blame]
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +00001/*
vandebo@chromium.org2a22e102011-01-25 21:01:34 +00002 * Copyright (C) 2011 Google Inc.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +00003 *
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 SkPDFDevice_DEFINED
18#define SkPDFDevice_DEFINED
19
20#include "SkRefCnt.h"
21#include "SkDevice.h"
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +000022#include "SkStream.h"
vandebo@chromium.orga5180862010-10-26 19:48:49 +000023#include "SkPaint.h"
24#include "SkPath.h"
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000025
26class SkPDFArray;
27class SkPDFDevice;
28class SkPDFDict;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000029class SkPDFFont;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000030class SkPDFGraphicState;
31class SkPDFObject;
vandebo@chromium.orgda912d62011-03-08 18:31:02 +000032class SkPDFShader;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000033class SkPDFStream;
34
35class SkPDFDeviceFactory : public SkDeviceFactory {
vandebo@chromium.org75f97e42011-04-11 23:24:18 +000036 virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
37 int height, bool isOpaque, bool isForLayer);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000038};
39
40/** \class SkPDFDevice
41
42 The drawing context for the PDF backend.
43*/
44class SkPDFDevice : public SkDevice {
45public:
46 /** Create a PDF drawing context with the given width and height.
47 * 72 points/in means letter paper is 612x792.
48 * @param width Page width in points.
49 * @param height Page height in points.
vandebo@chromium.org75f97e42011-04-11 23:24:18 +000050 * @param initialTransform The initial transform to apply to the page.
51 * This may be useful to, for example, move the origin in and
52 * over a bit to account for a margin, scale the canvas,
53 * or apply a rotation. Note1: the SkPDFDevice also applies
54 * a scale+translate transform to move the origin from the
55 * bottom left (PDF default) to the top left. Note2: drawDevice
56 * (used by layer restore) draws the device after this initial
57 * transform is applied, so the PDF device factory does an
58 * inverse scale+translate to accommodate the one that SkPDFDevice
59 * always does.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000060 */
vandebo@chromium.org75f97e42011-04-11 23:24:18 +000061 SkPDFDevice(int width, int height, const SkMatrix& initialTransform);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000062 virtual ~SkPDFDevice();
63
64 virtual SkDeviceFactory* getDeviceFactory() {
65 return SkNEW(SkPDFDeviceFactory);
66 }
67
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000068 virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
69
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000070 virtual int width() const { return fWidth; };
71
72 virtual int height() const { return fHeight; };
73
74 /** Called with the correct matrix and clip before this device is drawn
75 to using those settings. If your subclass overrides this, be sure to
76 call through to the base class as well.
77 */
reed@google.com46799cd2011-02-22 20:56:26 +000078 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
79 const SkClipStack&);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000080
reed@android.comf2b98d62010-12-20 18:26:13 +000081 virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
82 return false;
83 }
84
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000085 /** These are called inside the per-device-layer loop for each draw call.
86 When these are called, we have already applied any saveLayer operations,
87 and are handling any looping from the paint, and any effects from the
88 DrawFilter.
89 */
90 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
91 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
92 size_t count, const SkPoint[],
93 const SkPaint& paint);
94 virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
95 virtual void drawPath(const SkDraw&, const SkPath& path,
vandebo@chromium.org02cc5aa2011-01-25 22:06:29 +000096 const SkPaint& paint, const SkMatrix* prePathMatrix,
97 bool pathIsMutable);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000098 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
reed@android.comf2b98d62010-12-20 18:26:13 +000099 const SkIRect* srcRectOrNull,
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000100 const SkMatrix& matrix, const SkPaint& paint);
101 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
102 const SkPaint& paint);
103 virtual void drawText(const SkDraw&, const void* text, size_t len,
104 SkScalar x, SkScalar y, const SkPaint& paint);
105 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
106 const SkScalar pos[], SkScalar constY,
107 int scalarsPerPos, const SkPaint& paint);
108 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
109 const SkPath& path, const SkMatrix* matrix,
110 const SkPaint& paint);
111 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
112 int vertexCount, const SkPoint verts[],
113 const SkPoint texs[], const SkColor colors[],
114 SkXfermode* xmode, const uint16_t indices[],
115 int indexCount, const SkPaint& paint);
116 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
117 const SkPaint&);
118
119 // PDF specific methods.
120
121 /** Returns a reference to the resource dictionary for this device.
122 */
123 const SkRefPtr<SkPDFDict>& getResourceDict();
124
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000125 /** Get the list of resources (PDF objects) used on this page.
126 * @param resourceList A list to append the resources to.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000127 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000128 void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000129
130 /** Returns the media box for this device.
131 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000132 SkRefPtr<SkPDFArray> getMediaBox() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000133
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000134 /** Returns a SkStream with the page contents. The caller is responsible
135 for a reference to the returned value.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000136 */
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000137 SkStream* content() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000138
139private:
140 int fWidth;
141 int fHeight;
vandebo@chromium.org75f97e42011-04-11 23:24:18 +0000142 SkMatrix fInitialTransform;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000143 SkRefPtr<SkPDFDict> fResourceDict;
144
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000145 SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
146 SkTDArray<SkPDFObject*> fXObjectResources;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000147 SkTDArray<SkPDFFont*> fFontResources;
vandebo@chromium.orgda912d62011-03-08 18:31:02 +0000148 SkTDArray<SkPDFShader*> fShaderResources;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000149
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000150 // In PDF, transforms and clips can only be undone by popping the graphic
151 // state to before the transform or clip was applied. Because it can be
152 // a lot of work to reapply a clip and because this class has to apply
153 // different transforms to accomplish various operations, the clip is
154 // always applied before a transform and always at a different graphic
155 // state-stack level than a transform. This strategy results in the
156 // following possible states for the graphic state stack:
157 // empty: (identity transform and clip to page)
158 // one entry: a transform
159 // one entry: a clip
160 // two entries: a clip and then a transform
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000161 // Pointers are owned by the respective Resources list.
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000162 struct GraphicStackEntry {
163 SkColor fColor;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000164 SkScalar fTextSize;
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000165 SkScalar fTextScaleX;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000166 SkPaint::Style fTextFill;
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000167 SkPDFFont* fFont;
vandebo@chromium.orgda912d62011-03-08 18:31:02 +0000168 SkPDFShader* fShader;
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000169 SkPDFGraphicState* fGraphicState;
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000170 SkRegion fClip;
171 SkMatrix fTransform;
172 };
173 struct GraphicStackEntry fGraphicStack[3];
174 int fGraphicStackIndex;
175
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000176 SkDynamicMemoryWStream fContent;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000177
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000178 void updateGSFromPaint(const SkPaint& newPaint, bool forText);
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000179 void updateFont(const SkPaint& paint, uint16_t glyphID);
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000180 int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000181
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000182 void pushGS();
183 void popGS();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000184 void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000185 void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
vandebo@chromium.orgbefebb82011-01-29 01:38:50 +0000186 const SkIRect* srcRect, const SkPaint& paint);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000187
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000188 SkMatrix setTransform(const SkMatrix& matrix);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000189};
190
191#endif