blob: f9247a712251a7a92c22382004cda577e37de79a [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"
22#include "SkString.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;
32class SkPDFStream;
33
34class SkPDFDeviceFactory : public SkDeviceFactory {
reed@android.comf2b98d62010-12-20 18:26:13 +000035 virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width, int height,
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000036 bool isOpaque, bool isForLayer);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000037};
38
39/** \class SkPDFDevice
40
41 The drawing context for the PDF backend.
42*/
43class SkPDFDevice : public SkDevice {
44public:
vandebo@chromium.orgf60a0012011-02-24 23:14:04 +000045 /** Skia generally uses the top left as the origin and PDFs natively use
46 the bottom left. We can move the origin to the top left in the PDF
47 with a transform, but we have to be careful to apply the transform
48 only once.
49 */
50 enum OriginTransform {
51 kFlip_OriginTransform,
52 kNoFlip_OriginTransform,
53 };
54
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000055 /** Create a PDF drawing context with the given width and height.
56 * 72 points/in means letter paper is 612x792.
57 * @param width Page width in points.
58 * @param height Page height in points.
vandebo@chromium.orgf60a0012011-02-24 23:14:04 +000059 * @param flipOrigin Flip the origin from lower left to upper left.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000060 */
vandebo@chromium.orgf60a0012011-02-24 23:14:04 +000061 SkPDFDevice(int width, int height,
62 OriginTransform flipOrigin = kFlip_OriginTransform);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000063 virtual ~SkPDFDevice();
64
65 virtual SkDeviceFactory* getDeviceFactory() {
66 return SkNEW(SkPDFDeviceFactory);
67 }
68
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000069 virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
70
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000071 virtual int width() const { return fWidth; };
72
73 virtual int height() const { return fHeight; };
74
75 /** Called with the correct matrix and clip before this device is drawn
76 to using those settings. If your subclass overrides this, be sure to
77 call through to the base class as well.
78 */
reed@google.com46799cd2011-02-22 20:56:26 +000079 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
80 const SkClipStack&);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000081
reed@android.comf2b98d62010-12-20 18:26:13 +000082 virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
83 return false;
84 }
85
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000086 /** These are called inside the per-device-layer loop for each draw call.
87 When these are called, we have already applied any saveLayer operations,
88 and are handling any looping from the paint, and any effects from the
89 DrawFilter.
90 */
91 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
92 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
93 size_t count, const SkPoint[],
94 const SkPaint& paint);
95 virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
96 virtual void drawPath(const SkDraw&, const SkPath& path,
vandebo@chromium.org02cc5aa2011-01-25 22:06:29 +000097 const SkPaint& paint, const SkMatrix* prePathMatrix,
98 bool pathIsMutable);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000099 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
reed@android.comf2b98d62010-12-20 18:26:13 +0000100 const SkIRect* srcRectOrNull,
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000101 const SkMatrix& matrix, const SkPaint& paint);
102 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
103 const SkPaint& paint);
104 virtual void drawText(const SkDraw&, const void* text, size_t len,
105 SkScalar x, SkScalar y, const SkPaint& paint);
106 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
107 const SkScalar pos[], SkScalar constY,
108 int scalarsPerPos, const SkPaint& paint);
109 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
110 const SkPath& path, const SkMatrix* matrix,
111 const SkPaint& paint);
112 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
113 int vertexCount, const SkPoint verts[],
114 const SkPoint texs[], const SkColor colors[],
115 SkXfermode* xmode, const uint16_t indices[],
116 int indexCount, const SkPaint& paint);
117 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
118 const SkPaint&);
119
120 // PDF specific methods.
121
122 /** Returns a reference to the resource dictionary for this device.
123 */
124 const SkRefPtr<SkPDFDict>& getResourceDict();
125
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000126 /** Get the list of resources (PDF objects) used on this page.
127 * @param resourceList A list to append the resources to.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000128 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000129 void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000130
131 /** Returns the media box for this device.
132 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000133 SkRefPtr<SkPDFArray> getMediaBox() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000134
135 /** Returns a string with the page contents.
136 */
vandebo@chromium.orgf60a0012011-02-24 23:14:04 +0000137 SkString content() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000138
139private:
140 int fWidth;
141 int fHeight;
vandebo@chromium.orgf60a0012011-02-24 23:14:04 +0000142 OriginTransform fFlipOrigin;
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.org9b49dc02010-10-20 22:23:29 +0000148
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000149 // In PDF, transforms and clips can only be undone by popping the graphic
150 // state to before the transform or clip was applied. Because it can be
151 // a lot of work to reapply a clip and because this class has to apply
152 // different transforms to accomplish various operations, the clip is
153 // always applied before a transform and always at a different graphic
154 // state-stack level than a transform. This strategy results in the
155 // following possible states for the graphic state stack:
156 // empty: (identity transform and clip to page)
157 // one entry: a transform
158 // one entry: a clip
159 // two entries: a clip and then a transform
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000160 // Pointers are owned by the respective Resources list.
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000161 struct GraphicStackEntry {
162 SkColor fColor;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000163 SkScalar fTextSize;
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000164 SkScalar fTextScaleX;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000165 SkPaint::Style fTextFill;
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000166 SkPDFFont* fFont;
167 SkPDFGraphicState* fGraphicState;
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000168 SkRegion fClip;
169 SkMatrix fTransform;
170 };
171 struct GraphicStackEntry fGraphicStack[3];
172 int fGraphicStackIndex;
173
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000174 SkString fContent;
175
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000176 void updateGSFromPaint(const SkPaint& newPaint, bool forText);
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000177 void updateFont(const SkPaint& paint, uint16_t glyphID);
178 int getFontResourceIndex(uint32_t fontID, uint16_t glyphID);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000179
180 void moveTo(SkScalar x, SkScalar y);
181 void appendLine(SkScalar x, SkScalar y);
182 void appendCubic(SkScalar ctl1X, SkScalar ctl1Y,
183 SkScalar ctl2X, SkScalar ctl2Y,
184 SkScalar dstX, SkScalar dstY);
185 void appendRectangle(SkScalar x, SkScalar y, SkScalar w, SkScalar h);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000186 void emitPath(const SkPath& path);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000187 void closePath();
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000188 void paintPath(SkPaint::Style style, SkPath::FillType fill);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000189 void strokePath();
190 void pushGS();
191 void popGS();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000192 void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000193 void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
vandebo@chromium.orgbefebb82011-01-29 01:38:50 +0000194 const SkIRect* srcRect, const SkPaint& paint);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000195
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000196 SkMatrix setTransform(const SkMatrix& matrix);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000197};
198
199#endif