blob: 9ab0ae51f619a04766c1b04c6a8db0c537cac6a6 [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.orga0c7edb2011-05-09 07:58:08 +000041public:
vandebo@chromium.org75f97e42011-04-11 23:24:18 +000042 virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
43 int height, bool isOpaque, bool isForLayer);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000044};
45
46/** \class SkPDFDevice
47
48 The drawing context for the PDF backend.
49*/
50class SkPDFDevice : public SkDevice {
51public:
52 /** Create a PDF drawing context with the given width and height.
53 * 72 points/in means letter paper is 612x792.
ctguil@chromium.org15261292011-04-29 17:54:16 +000054 * @param pageSize Page size in points.
55 * @param contentSize The content size of the page in points. This will be
56 * combined with the initial transform to determine the drawing area
57 * (as reported by the width and height methods). Anything outside
58 * of the drawing area will be clipped.
vandebo@chromium.org75f97e42011-04-11 23:24:18 +000059 * @param initialTransform The initial transform to apply to the page.
60 * This may be useful to, for example, move the origin in and
61 * over a bit to account for a margin, scale the canvas,
62 * or apply a rotation. Note1: the SkPDFDevice also applies
63 * a scale+translate transform to move the origin from the
64 * bottom left (PDF default) to the top left. Note2: drawDevice
65 * (used by layer restore) draws the device after this initial
66 * transform is applied, so the PDF device factory does an
67 * inverse scale+translate to accommodate the one that SkPDFDevice
68 * always does.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000069 */
vandebo@chromium.orgbe2048a2011-05-02 15:24:01 +000070 // TODO(vandebo) The sizes should be SkSize and not SkISize.
ctguil@chromium.org15261292011-04-29 17:54:16 +000071 SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
72 const SkMatrix& initialTransform);
73 SK_API virtual ~SkPDFDevice();
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000074
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000075 virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
76
vandebo@chromium.org77bcaa32011-04-15 20:57:37 +000077 virtual void clear(SkColor color);
78
reed@android.comf2b98d62010-12-20 18:26:13 +000079 virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
80 return false;
81 }
82
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000083 /** These are called inside the per-device-layer loop for each draw call.
84 When these are called, we have already applied any saveLayer operations,
85 and are handling any looping from the paint, and any effects from the
86 DrawFilter.
87 */
88 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
89 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
90 size_t count, const SkPoint[],
91 const SkPaint& paint);
92 virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
93 virtual void drawPath(const SkDraw&, const SkPath& path,
vandebo@chromium.org02cc5aa2011-01-25 22:06:29 +000094 const SkPaint& paint, const SkMatrix* prePathMatrix,
95 bool pathIsMutable);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000096 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
reed@android.comf2b98d62010-12-20 18:26:13 +000097 const SkIRect* srcRectOrNull,
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000098 const SkMatrix& matrix, const SkPaint& paint);
99 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
100 const SkPaint& paint);
101 virtual void drawText(const SkDraw&, const void* text, size_t len,
102 SkScalar x, SkScalar y, const SkPaint& paint);
103 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
104 const SkScalar pos[], SkScalar constY,
105 int scalarsPerPos, const SkPaint& paint);
106 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
107 const SkPath& path, const SkMatrix* matrix,
108 const SkPaint& paint);
109 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
110 int vertexCount, const SkPoint verts[],
111 const SkPoint texs[], const SkColor colors[],
112 SkXfermode* xmode, const uint16_t indices[],
113 int indexCount, const SkPaint& paint);
114 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
115 const SkPaint&);
116
117 // PDF specific methods.
118
119 /** Returns a reference to the resource dictionary for this device.
120 */
121 const SkRefPtr<SkPDFDict>& getResourceDict();
122
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000123 /** Get the list of resources (PDF objects) used on this page.
124 * @param resourceList A list to append the resources to.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000125 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000126 void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000127
128 /** Returns the media box for this device.
129 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000130 SkRefPtr<SkPDFArray> getMediaBox() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000131
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000132 /** Returns a SkStream with the page contents. The caller is responsible
133 for a reference to the returned value.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000134 */
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000135 SkStream* content() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000136
mike@reedtribe.orgea4ac972011-04-26 11:48:33 +0000137protected:
138 // override
139 virtual SkDeviceFactory* onNewDeviceFactory();
140
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000141private:
vandebo@chromium.orga0c7edb2011-05-09 07:58:08 +0000142 friend class SkPDFDeviceFactory;
143
ctguil@chromium.org15261292011-04-29 17:54:16 +0000144 SkISize fPageSize;
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000145 SkISize fContentSize;
vandebo@chromium.org75f97e42011-04-11 23:24:18 +0000146 SkMatrix fInitialTransform;
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000147 SkClipStack fExistingClipStack;
148 SkRegion fExistingClipRegion;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000149 SkRefPtr<SkPDFDict> fResourceDict;
150
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000151 SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
152 SkTDArray<SkPDFObject*> fXObjectResources;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000153 SkTDArray<SkPDFFont*> fFontResources;
vandebo@chromium.orgda912d62011-03-08 18:31:02 +0000154 SkTDArray<SkPDFShader*> fShaderResources;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000155
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000156 SkTScopedPtr<ContentEntry> fContentEntries;
157 ContentEntry* fCurrentContentEntry;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000158
vandebo@chromium.orga0c7edb2011-05-09 07:58:08 +0000159 // For use by the DeviceFactory.
160 SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
161 const SkRegion& existingClipRegion);
162
vandebo@chromium.org77bcaa32011-04-15 20:57:37 +0000163 void init();
164 void cleanUp();
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000165
vandebo@chromium.org25adce82011-05-09 08:05:01 +0000166 // If the paint or clip is such that we shouldn't draw anything, these
167 // return false and do not create a content entry.
vandebo@chromium.org78dad542011-05-11 18:46:03 +0000168 bool setUpContentEntry(const SkClipStack* clipStack,
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000169 const SkRegion& clipRegion,
170 const SkMatrix& matrix,
171 const SkPaint& paint,
172 bool hasText = false);
vandebo@chromium.org78dad542011-05-11 18:46:03 +0000173 bool setUpContentEntryForText(const SkClipStack* clipStack,
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000174 const SkRegion& clipRegion,
175 const SkMatrix& matrix,
176 const SkPaint& paint);
177 void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
178 const SkClipStack& clipStack,
179 const SkRegion& clipRegion,
180 const SkPaint& paint,
181 bool hasText,
182 GraphicStateEntry* entry);
183
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000184 void updateFont(const SkPaint& paint, uint16_t glyphID);
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000185 int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000186 void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000187
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000188 void internalDrawPaint(const SkPaint& paint);
189 void internalDrawBitmap(const SkMatrix& matrix,
vandebo@chromium.org78dad542011-05-11 18:46:03 +0000190 const SkClipStack* clipStack,
vandebo@chromium.org9fbdf872011-05-09 07:55:58 +0000191 const SkRegion& clipRegion,
192 const SkBitmap& bitmap,
193 const SkIRect* srcRect,
194 const SkPaint& paint);
195
196 // Disable the default copy and assign implementation.
197 SkPDFDevice(const SkPDFDevice&);
198 void operator=(const SkPDFDevice&);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000199};
200
201#endif