blob: 3e1edb7d975fa41fa099d148618263237b73a4ca [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
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000135 /** Returns a SkStream with the page contents. The caller is responsible
136 for a reference to the returned value.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000137 */
vandebo@chromium.orgc2a9b7f2011-02-24 23:22:30 +0000138 SkStream* content() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000139
140private:
141 int fWidth;
142 int fHeight;
vandebo@chromium.orgf60a0012011-02-24 23:14:04 +0000143 OriginTransform fFlipOrigin;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000144 SkRefPtr<SkPDFDict> fResourceDict;
145
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000146 SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
147 SkTDArray<SkPDFObject*> fXObjectResources;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000148 SkTDArray<SkPDFFont*> fFontResources;
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;
168 SkPDFGraphicState* fGraphicState;
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000169 SkRegion fClip;
170 SkMatrix fTransform;
171 };
172 struct GraphicStackEntry fGraphicStack[3];
173 int fGraphicStackIndex;
174
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000175 SkString fContent;
176
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000177 void updateGSFromPaint(const SkPaint& newPaint, bool forText);
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000178 void updateFont(const SkPaint& paint, uint16_t glyphID);
179 int getFontResourceIndex(uint32_t fontID, uint16_t glyphID);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000180
181 void moveTo(SkScalar x, SkScalar y);
182 void appendLine(SkScalar x, SkScalar y);
183 void appendCubic(SkScalar ctl1X, SkScalar ctl1Y,
184 SkScalar ctl2X, SkScalar ctl2Y,
185 SkScalar dstX, SkScalar dstY);
186 void appendRectangle(SkScalar x, SkScalar y, SkScalar w, SkScalar h);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000187 void emitPath(const SkPath& path);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000188 void closePath();
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000189 void paintPath(SkPaint::Style style, SkPath::FillType fill);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000190 void strokePath();
191 void pushGS();
192 void popGS();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000193 void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000194 void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
vandebo@chromium.orgbefebb82011-01-29 01:38:50 +0000195 const SkIRect* srcRect, const SkPaint& paint);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000196
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000197 SkMatrix setTransform(const SkMatrix& matrix);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000198};
199
200#endif