blob: ada2791ec6fd22f7d35fb11dd85c72fa6232f5b3 [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;
29class SkPDFGraphicState;
30class SkPDFObject;
31class SkPDFStream;
32
33class SkPDFDeviceFactory : public SkDeviceFactory {
34 virtual SkDevice* newDevice(SkBitmap::Config config, int width, int height,
35 bool isOpaque, bool isForLayer);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000036};
37
38/** \class SkPDFDevice
39
40 The drawing context for the PDF backend.
41*/
42class SkPDFDevice : public SkDevice {
43public:
44 /** Create a PDF drawing context with the given width and height.
45 * 72 points/in means letter paper is 612x792.
46 * @param width Page width in points.
47 * @param height Page height in points.
48 */
49 SkPDFDevice(int width, int height);
50 virtual ~SkPDFDevice();
51
52 virtual SkDeviceFactory* getDeviceFactory() {
53 return SkNEW(SkPDFDeviceFactory);
54 }
55
vandebo@chromium.org35fc62b2010-10-26 19:47:30 +000056 virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
57
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000058 virtual int width() const { return fWidth; };
59
60 virtual int height() const { return fHeight; };
61
62 /** Called with the correct matrix and clip before this device is drawn
63 to using those settings. If your subclass overrides this, be sure to
64 call through to the base class as well.
65 */
66 virtual void setMatrixClip(const SkMatrix&, const SkRegion&);
67
68 /** These are called inside the per-device-layer loop for each draw call.
69 When these are called, we have already applied any saveLayer operations,
70 and are handling any looping from the paint, and any effects from the
71 DrawFilter.
72 */
73 virtual void drawPaint(const SkDraw&, const SkPaint& paint);
74 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
75 size_t count, const SkPoint[],
76 const SkPaint& paint);
77 virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
78 virtual void drawPath(const SkDraw&, const SkPath& path,
79 const SkPaint& paint);
80 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
81 const SkMatrix& matrix, const SkPaint& paint);
82 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
83 const SkPaint& paint);
84 virtual void drawText(const SkDraw&, const void* text, size_t len,
85 SkScalar x, SkScalar y, const SkPaint& paint);
86 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
87 const SkScalar pos[], SkScalar constY,
88 int scalarsPerPos, const SkPaint& paint);
89 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
90 const SkPath& path, const SkMatrix* matrix,
91 const SkPaint& paint);
92 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
93 int vertexCount, const SkPoint verts[],
94 const SkPoint texs[], const SkColor colors[],
95 SkXfermode* xmode, const uint16_t indices[],
96 int indexCount, const SkPaint& paint);
97 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
98 const SkPaint&);
99
100 // PDF specific methods.
101
102 /** Returns a reference to the resource dictionary for this device.
103 */
104 const SkRefPtr<SkPDFDict>& getResourceDict();
105
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000106 /** Get the list of resources (PDF objects) used on this page.
107 * @param resourceList A list to append the resources to.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000108 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000109 void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000110
111 /** Returns the media box for this device.
112 */
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000113 SkRefPtr<SkPDFArray> getMediaBox() const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000114
115 /** Returns a string with the page contents.
vandebo@chromium.orgddbbd802010-10-26 19:45:06 +0000116 * @param flipOrigin Flip the origin between top and bottom.
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000117 */
vandebo@chromium.orgddbbd802010-10-26 19:45:06 +0000118 SkString content(bool flipOrigin) const;
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000119
120private:
121 int fWidth;
122 int fHeight;
123 SkRefPtr<SkPDFDict> fResourceDict;
124
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000125 SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
126 SkTDArray<SkPDFObject*> fXObjectResources;
127
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000128 // In PDF, transforms and clips can only be undone by popping the graphic
129 // state to before the transform or clip was applied. Because it can be
130 // a lot of work to reapply a clip and because this class has to apply
131 // different transforms to accomplish various operations, the clip is
132 // always applied before a transform and always at a different graphic
133 // state-stack level than a transform. This strategy results in the
134 // following possible states for the graphic state stack:
135 // empty: (identity transform and clip to page)
136 // one entry: a transform
137 // one entry: a clip
138 // two entries: a clip and then a transform
139 struct GraphicStackEntry {
140 SkColor fColor;
141 SkScalar fTextScaleX;
142 SkRefPtr<SkPDFGraphicState> fGraphicState;
143 SkRegion fClip;
144 SkMatrix fTransform;
145 };
146 struct GraphicStackEntry fGraphicStack[3];
147 int fGraphicStackIndex;
148
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000149 SkString fContent;
150
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000151 void updateGSFromPaint(const SkPaint& newPaint, SkString* textStaetUpdate);
152
153 void moveTo(SkScalar x, SkScalar y);
154 void appendLine(SkScalar x, SkScalar y);
155 void appendCubic(SkScalar ctl1X, SkScalar ctl1Y,
156 SkScalar ctl2X, SkScalar ctl2Y,
157 SkScalar dstX, SkScalar dstY);
158 void appendRectangle(SkScalar x, SkScalar y, SkScalar w, SkScalar h);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000159 void emitPath(const SkPath& path);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000160 void closePath();
vandebo@chromium.orga5180862010-10-26 19:48:49 +0000161 void paintPath(SkPaint::Style style, SkPath::FillType fill);
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000162 void strokePath();
163 void pushGS();
164 void popGS();
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000165 void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
166 const SkPaint& paint);
167
vandebo@chromium.org7e2ff7c2010-11-03 23:55:28 +0000168 SkMatrix setTransform(const SkMatrix& matrix);
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000169};
170
171#endif