blob: b92dc3db2ba742a322db9c7d9e390d0d26889c6f [file] [log] [blame]
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +00001/*
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +00002 * Copyright (C) 2010 The Android Open Source Project
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 {
35 virtual SkDevice* newDevice(SkBitmap::Config config, int width, int height,
36 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:
45 /** Create a PDF drawing context with the given width and height.
46 * 72 points/in means letter paper is 612x792.
47 * @param width Page width in points.
48 * @param height Page height in points.
49 */
50 SkPDFDevice(int width, int height);
51 virtual ~SkPDFDevice();
52
53 virtual SkDeviceFactory* getDeviceFactory() {
54 return SkNEW(SkPDFDeviceFactory);
55 }
56
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000057 virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
58
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000059 virtual int width() const { return fWidth; };
60
61 virtual int height() const { return fHeight; };
62
63 /** Called with the correct matrix and clip before this device is drawn
64 to using those settings. If your subclass overrides this, be sure to
65 call through to the base class as well.
66 */
67 virtual void setMatrixClip(const SkMatrix&, const SkRegion&);
68
69 /** These are called inside the per-device-layer loop for each draw call.
70 When these are called, we have already applied any saveLayer operations,
71 and are handling any looping from the paint, and any effects from the
72 DrawFilter.
73 */
74 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
75 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
76 size_t count, const SkPoint[],
77 const SkPaint& paint);
78 virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
79 virtual void drawPath(const SkDraw&, const SkPath& path,
80 const SkPaint& paint);
81 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
82 const SkMatrix& matrix, const SkPaint& paint);
83 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
84 const SkPaint& paint);
85 virtual void drawText(const SkDraw&, const void* text, size_t len,
86 SkScalar x, SkScalar y, const SkPaint& paint);
87 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
88 const SkScalar pos[], SkScalar constY,
89 int scalarsPerPos, const SkPaint& paint);
90 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
91 const SkPath& path, const SkMatrix* matrix,
92 const SkPaint& paint);
93 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
94 int vertexCount, const SkPoint verts[],
95 const SkPoint texs[], const SkColor colors[],
96 SkXfermode* xmode, const uint16_t indices[],
97 int indexCount, const SkPaint& paint);
98 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
99 const SkPaint&);
100
101 // PDF specific methods.
102
103 /** Returns a reference to the resource dictionary for this device.
104 */
105 const SkRefPtr<SkPDFDict>& getResourceDict();
106
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000107 /** Get the list of resources (PDF objects) used on this page.
108 * @param resourceList A list to append the resources to.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000109 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000110 void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000111
112 /** Returns the media box for this device.
113 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000114 SkRefPtr<SkPDFArray> getMediaBox() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000115
116 /** Returns a string with the page contents.
vandebo@chromium.orgddbbd802010-10-26 19:45:06 +0000117 * @param flipOrigin Flip the origin between top and bottom.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000118 */
vandebo@chromium.orgddbbd802010-10-26 19:45:06 +0000119 SkString content(bool flipOrigin) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000120
121private:
122 int fWidth;
123 int fHeight;
124 SkRefPtr<SkPDFDict> fResourceDict;
125
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000126 SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
127 SkTDArray<SkPDFObject*> fXObjectResources;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000128 SkTDArray<SkPDFFont*> fFontResources;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000129
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000130 // In PDF, transforms and clips can only be undone by popping the graphic
131 // state to before the transform or clip was applied. Because it can be
132 // a lot of work to reapply a clip and because this class has to apply
133 // different transforms to accomplish various operations, the clip is
134 // always applied before a transform and always at a different graphic
135 // state-stack level than a transform. This strategy results in the
136 // following possible states for the graphic state stack:
137 // empty: (identity transform and clip to page)
138 // one entry: a transform
139 // one entry: a clip
140 // two entries: a clip and then a transform
141 struct GraphicStackEntry {
142 SkColor fColor;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000143 SkScalar fTextSize;
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000144 SkScalar fTextScaleX;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000145 SkPaint::Style fTextFill;
146 SkRefPtr<SkPDFFont> fFont;
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000147 SkRefPtr<SkPDFGraphicState> fGraphicState;
148 SkRegion fClip;
149 SkMatrix fTransform;
150 };
151 struct GraphicStackEntry fGraphicStack[3];
152 int fGraphicStackIndex;
153
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000154 SkString fContent;
155
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000156 void updateGSFromPaint(const SkPaint& newPaint, bool forText);
157 int getFontResourceIndex(uint32_t fontID);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000158
159 void moveTo(SkScalar x, SkScalar y);
160 void appendLine(SkScalar x, SkScalar y);
161 void appendCubic(SkScalar ctl1X, SkScalar ctl1Y,
162 SkScalar ctl2X, SkScalar ctl2Y,
163 SkScalar dstX, SkScalar dstY);
164 void appendRectangle(SkScalar x, SkScalar y, SkScalar w, SkScalar h);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000165 void emitPath(const SkPath& path);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000166 void closePath();
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000167 void paintPath(SkPaint::Style style, SkPath::FillType fill);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000168 void strokePath();
169 void pushGS();
170 void popGS();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000171 void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000172 void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
173 const SkPaint& paint);
174
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000175 SkMatrix setTransform(const SkMatrix& matrix);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000176};
177
178#endif