blob: 0d058fbeb66d25a40788fe5f150303b89fe4d12d [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
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000020#include "SkDevice.h"
vandebo@chromium.orga5180862010-10-26 19:48:49 +000021#include "SkPaint.h"
22#include "SkPath.h"
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +000023#include "SkRefCnt.h"
24#include "SkStream.h"
25#include "SkTScopedPtr.h"
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000026
27class SkPDFArray;
28class SkPDFDevice;
29class SkPDFDict;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000030class SkPDFFont;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000031class SkPDFGraphicState;
32class SkPDFObject;
vandebo@chromium.orgda912d62011-03-08 18:31:02 +000033class SkPDFShader;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000034class SkPDFStream;
35
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +000036// Private classes.
37struct ContentEntry;
38struct GraphicStateEntry;
39
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000040class SkPDFDeviceFactory : public SkDeviceFactory {
vandebo@chromium.org75f97e42011-04-11 23:24:18 +000041 virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
42 int height, bool isOpaque, bool isForLayer);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000043};
44
45/** \class SkPDFDevice
46
47 The drawing context for the PDF backend.
48*/
49class SkPDFDevice : public SkDevice {
50public:
51 /** Create a PDF drawing context with the given width and height.
52 * 72 points/in means letter paper is 612x792.
ctguil@chromium.org15261292011-04-29 17:54:16 +000053 * @param pageSize Page size in points.
54 * @param contentSize The content size of the page in points. This will be
55 * combined with the initial transform to determine the drawing area
56 * (as reported by the width and height methods). Anything outside
57 * of the drawing area will be clipped.
vandebo@chromium.org75f97e42011-04-11 23:24:18 +000058 * @param initialTransform The initial transform to apply to the page.
59 * This may be useful to, for example, move the origin in and
60 * over a bit to account for a margin, scale the canvas,
61 * or apply a rotation. Note1: the SkPDFDevice also applies
62 * a scale+translate transform to move the origin from the
63 * bottom left (PDF default) to the top left. Note2: drawDevice
64 * (used by layer restore) draws the device after this initial
65 * transform is applied, so the PDF device factory does an
66 * inverse scale+translate to accommodate the one that SkPDFDevice
67 * always does.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000068 */
vandebo@chromium.orgbe2048a2011-05-02 15:24:01 +000069 // TODO(vandebo) The sizes should be SkSize and not SkISize.
ctguil@chromium.org15261292011-04-29 17:54:16 +000070 SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
71 const SkMatrix& initialTransform);
72 SK_API virtual ~SkPDFDevice();
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000073
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000074 virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
75
vandebo@chromium.org77bcaa32011-04-15 20:57:37 +000076 virtual void clear(SkColor color);
77
reed@android.comf2b98d62010-12-20 18:26:13 +000078 virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
79 return false;
80 }
81
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000082 /** These are called inside the per-device-layer loop for each draw call.
83 When these are called, we have already applied any saveLayer operations,
84 and are handling any looping from the paint, and any effects from the
85 DrawFilter.
86 */
87 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
88 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
89 size_t count, const SkPoint[],
90 const SkPaint& paint);
91 virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
92 virtual void drawPath(const SkDraw&, const SkPath& path,
vandebo@chromium.org02cc5aa2011-01-25 22:06:29 +000093 const SkPaint& paint, const SkMatrix* prePathMatrix,
94 bool pathIsMutable);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000095 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
reed@android.comf2b98d62010-12-20 18:26:13 +000096 const SkIRect* srcRectOrNull,
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000097 const SkMatrix& matrix, const SkPaint& paint);
98 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
99 const SkPaint& paint);
100 virtual void drawText(const SkDraw&, const void* text, size_t len,
101 SkScalar x, SkScalar y, const SkPaint& paint);
102 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
103 const SkScalar pos[], SkScalar constY,
104 int scalarsPerPos, const SkPaint& paint);
105 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
106 const SkPath& path, const SkMatrix* matrix,
107 const SkPaint& paint);
108 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
109 int vertexCount, const SkPoint verts[],
110 const SkPoint texs[], const SkColor colors[],
111 SkXfermode* xmode, const uint16_t indices[],
112 int indexCount, const SkPaint& paint);
113 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
114 const SkPaint&);
115
116 // PDF specific methods.
117
118 /** Returns a reference to the resource dictionary for this device.
119 */
120 const SkRefPtr<SkPDFDict>& getResourceDict();
121
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000122 /** Get the list of resources (PDF objects) used on this page.
123 * @param resourceList A list to append the resources to.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000124 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000125 void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000126
127 /** Returns the media box for this device.
128 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000129 SkRefPtr<SkPDFArray> getMediaBox() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000130
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000131 /** Returns a SkStream with the page contents. The caller is responsible
132 for a reference to the returned value.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000133 */
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000134 SkStream* content() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000135
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +0000136protected:
137 // override
138 virtual SkDeviceFactory* onNewDeviceFactory();
139
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000140private:
ctguil@chromium.org15261292011-04-29 17:54:16 +0000141 SkISize fPageSize;
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000142 SkISize fContentSize;
vandebo@chromium.org75f97e42011-04-11 23:24:18 +0000143 SkMatrix fInitialTransform;
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000144 SkClipStack fExistingClipStack;
145 SkRegion fExistingClipRegion;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000146 SkRefPtr<SkPDFDict> fResourceDict;
147
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000148 SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
149 SkTDArray<SkPDFObject*> fXObjectResources;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000150 SkTDArray<SkPDFFont*> fFontResources;
vandebo@chromium.orgda912d62011-03-08 18:31:02 +0000151 SkTDArray<SkPDFShader*> fShaderResources;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000152
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000153 SkTScopedPtr<ContentEntry> fContentEntries;
154 ContentEntry* fCurrentContentEntry;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000155
vandebo@chromium.org77bcaa32011-04-15 20:57:37 +0000156 void init();
157 void cleanUp();
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000158 void setExistingClip(const SkClipStack& clipStack,
159 const SkRegion& clipRegion);
160
161 void setUpContentEntry(const SkClipStack& clipStack,
162 const SkRegion& clipRegion,
163 const SkMatrix& matrix,
164 const SkPaint& paint,
165 bool hasText = false);
166 void setUpContentEntryForText(const SkClipStack& clipStack,
167 const SkRegion& clipRegion,
168 const SkMatrix& matrix,
169 const SkPaint& paint);
170 void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
171 const SkClipStack& clipStack,
172 const SkRegion& clipRegion,
173 const SkPaint& paint,
174 bool hasText,
175 GraphicStateEntry* entry);
176
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000177 void updateFont(const SkPaint& paint, uint16_t glyphID);
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000178 int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000179 void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000180
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000181 void internalDrawPaint(const SkPaint& paint);
182 void internalDrawBitmap(const SkMatrix& matrix,
183 const SkClipStack& clipStack,
184 const SkRegion& clipRegion,
185 const SkBitmap& bitmap,
186 const SkIRect* srcRect,
187 const SkPaint& paint);
188
189 // Disable the default copy and assign implementation.
190 SkPDFDevice(const SkPDFDevice&);
191 void operator=(const SkPDFDevice&);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000192};
193
194#endif