1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkXPSDevice_DEFINED
9#define SkXPSDevice_DEFINED
10
11#include "SkTypes.h"
12#include <ObjBase.h>
13#include <XpsObjectModel.h>
14
15#include "SkAutoCoInitialize.h"
16#include "SkBitSet.h"
17#include "SkCanvas.h"
18#include "SkColor.h"
19#include "SkDevice.h"
20#include "SkPaint.h"
21#include "SkPath.h"
22#include "SkPoint.h"
23#include "SkShader.h"
24#include "SkSize.h"
25#include "SkTArray.h"
26#include "SkTScopedComPtr.h"
27#include "SkTypeface.h"
28
29/** \class SkXPSDevice
30
31    The drawing context for the XPS backend.
32*/
33class SkXPSDevice : public SkDevice {
34public:
35    SK_API SkXPSDevice();
36    SK_API virtual ~SkXPSDevice();
37
38    virtual bool beginPortfolio(SkWStream* outputStream);
39    /**
40      @param unitsPerMeter converts geometry units into physical units.
41      @param pixelsPerMeter resolution to use when geometry must be rasterized.
42      @param trimSize final page size in physical units.
43                      The top left of the trim is the origin of physical space.
44      @param mediaBox The size of the physical media in physical units.
45                      The top and left must be less than zero.
46                      The bottom and right must be greater than the trimSize.
47                      The default is to coincide with the trimSize.
48      @param bleedBox The size of the bleed box in physical units.
49                      Must be contained within the mediaBox.
50                      The default is to coincide with the mediaBox.
51      @param artBox The size of the content box in physical units.
52                    Must be contained within the trimSize.
53                    The default is to coincide with the trimSize.
54      @param cropBox The size of the recommended view port in physical units.
55                     Must be contained within the mediaBox.
56                     The default is to coincide with the mediaBox.
57     */
58    virtual bool beginSheet(
59        const SkVector& unitsPerMeter,
60        const SkVector& pixelsPerMeter,
61        const SkSize& trimSize,
62        const SkRect* mediaBox = NULL,
63        const SkRect* bleedBox = NULL,
64        const SkRect* artBox = NULL,
65        const SkRect* cropBox = NULL);
66
67    virtual bool endSheet();
68    virtual bool endPortfolio();
69
70    virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
71
72protected:
73    virtual void clear(SkColor color) SK_OVERRIDE;
74
75    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
76
77    virtual void drawPoints(
78        const SkDraw&,
79        SkCanvas::PointMode mode,
80        size_t count, const SkPoint[],
81        const SkPaint& paint) SK_OVERRIDE;
82
83    virtual void drawRect(
84        const SkDraw&,
85        const SkRect& r,
86        const SkPaint& paint) SK_OVERRIDE;
87
88    virtual void drawPath(
89        const SkDraw&,
90        const SkPath& platonicPath,
91        const SkPaint& paint,
92        const SkMatrix* prePathMatrix,
93        bool pathIsMutable) SK_OVERRIDE;
94
95    virtual void drawBitmap(
96        const SkDraw&,
97        const SkBitmap& bitmap,
98        const SkMatrix& matrix,
99        const SkPaint& paint) SK_OVERRIDE;
100
101    virtual void drawSprite(
102        const SkDraw&,
103        const SkBitmap& bitmap,
104        int x, int y,
105        const SkPaint& paint) SK_OVERRIDE;
106
107    virtual void drawText(
108        const SkDraw&,
109        const void* text, size_t len,
110        SkScalar x, SkScalar y,
111        const SkPaint& paint) SK_OVERRIDE;
112
113    virtual void drawPosText(
114        const SkDraw&,
115        const void* text, size_t len,
116        const SkScalar pos[], SkScalar constY, int scalarsPerPos,
117        const SkPaint& paint) SK_OVERRIDE;
118
119    virtual void drawTextOnPath(
120        const SkDraw&,
121        const void* text, size_t len,
122        const SkPath& path,
123        const SkMatrix* matrix,
124        const SkPaint& paint) SK_OVERRIDE;
125
126    virtual void drawVertices(
127        const SkDraw&,
128        SkCanvas::VertexMode,
129        int vertexCount, const SkPoint verts[],
130        const SkPoint texs[], const SkColor colors[],
131        SkXfermode* xmode,
132        const uint16_t indices[], int indexCount,
133        const SkPaint& paint) SK_OVERRIDE;
134
135    virtual void drawDevice(
136        const SkDraw&,
137        SkDevice* device,
138        int x, int y,
139        const SkPaint& paint) SK_OVERRIDE;
140
141    virtual bool onReadPixels(const SkBitmap& bitmap,
142                              int x,
143                              int y,
144                              SkCanvas::Config8888) SK_OVERRIDE;
145
146    virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE;
147
148private:
149    class TypefaceUse : ::SkNoncopyable {
150    public:
151        SkFontID typefaceId;
152        int ttcIndex;
153        SkStream* fontData;
154        IXpsOMFontResource* xpsFont;
155        SkBitSet* glyphsUsed;
156
157        explicit TypefaceUse();
158        ~TypefaceUse();
159    };
160    friend static HRESULT subset_typeface(TypefaceUse* current);
161
162    SkXPSDevice(IXpsOMObjectFactory* xpsFactory);
163
164    SkAutoCoInitialize fAutoCo;
165    SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
166    SkTScopedComPtr<IStream> fOutputStream;
167    SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
168
169    unsigned int fCurrentPage;
170    SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
171    SkSize fCurrentCanvasSize;
172    SkVector fCurrentUnitsPerMeter;
173    SkVector fCurrentPixelsPerMeter;
174
175    SkTArray<TypefaceUse, true> fTypefaces;
176
177    HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
178
179    HRESULT createXpsPage(
180        const XPS_SIZE& pageSize,
181        IXpsOMPage** page);
182
183    HRESULT createXpsThumbnail(
184        IXpsOMPage* page, const unsigned int pageNumber,
185        IXpsOMImageResource** image);
186
187    void internalDrawRect(
188        const SkDraw&,
189        const SkRect& r,
190        bool transformRect,
191        const SkPaint& paint);
192
193    HRESULT createXpsBrush(
194        const SkPaint& skPaint,
195        IXpsOMBrush** xpsBrush,
196        const SkMatrix* parentTransform = NULL);
197
198    HRESULT createXpsSolidColorBrush(
199        const SkColor skColor, const SkAlpha alpha,
200        IXpsOMBrush** xpsBrush);
201
202    HRESULT createXpsImageBrush(
203        const SkBitmap& bitmap,
204        const SkMatrix& localMatrix,
205        const SkShader::TileMode (&xy)[2],
206        const SkAlpha alpha,
207        IXpsOMTileBrush** xpsBrush);
208
209    HRESULT createXpsLinearGradient(
210        SkShader::GradientInfo info,
211        const SkAlpha alpha,
212        const SkMatrix& localMatrix,
213        IXpsOMMatrixTransform* xpsMatrixToUse,
214        IXpsOMBrush** xpsBrush);
215
216    HRESULT createXpsRadialGradient(
217        SkShader::GradientInfo info,
218        const SkAlpha alpha,
219        const SkMatrix& localMatrix,
220        IXpsOMMatrixTransform* xpsMatrixToUse,
221        IXpsOMBrush** xpsBrush);
222
223    HRESULT createXpsGradientStop(
224        const SkColor skColor,
225        const SkScalar offset,
226        IXpsOMGradientStop** xpsGradStop);
227
228    HRESULT createXpsTransform(
229        const SkMatrix& matrix,
230        IXpsOMMatrixTransform ** xpsTransform);
231
232    HRESULT createXpsRect(
233        const SkRect& rect,
234        BOOL stroke, BOOL fill,
235        IXpsOMGeometryFigure** xpsRect);
236
237    HRESULT createXpsQuad(
238        const SkPoint (&points)[4],
239        BOOL stroke, BOOL fill,
240        IXpsOMGeometryFigure** xpsQuad);
241
242    HRESULT CreateTypefaceUse(
243        const SkPaint& paint,
244        TypefaceUse** fontResource);
245
246    HRESULT AddGlyphs(
247        const SkDraw& d,
248        IXpsOMObjectFactory* xpsFactory,
249        IXpsOMCanvas* canvas,
250        TypefaceUse* font,
251        LPCWSTR text,
252        XPS_GLYPH_INDEX* xpsGlyphs,
253        UINT32 xpsGlyphsLen,
254        XPS_POINT *origin,
255        FLOAT fontSize,
256        XPS_STYLE_SIMULATION sims,
257        const SkMatrix& transform,
258        const SkPaint& paint);
259
260    HRESULT addXpsPathGeometry(
261        IXpsOMGeometryFigureCollection* figures,
262        BOOL stroke, BOOL fill, const SkPath& path);
263
264    HRESULT createPath(
265        IXpsOMGeometryFigure* figure,
266        IXpsOMVisualCollection* visuals,
267        IXpsOMPath** path);
268
269    HRESULT sideOfClamp(
270        const SkRect& leftPoints, const XPS_RECT& left,
271        IXpsOMImageResource* imageResource,
272        IXpsOMVisualCollection* visuals);
273
274    HRESULT cornerOfClamp(
275        const SkRect& tlPoints,
276        const SkColor color,
277        IXpsOMVisualCollection* visuals);
278
279    HRESULT clip(
280        IXpsOMVisual* xpsVisual,
281        const SkDraw& d);
282    HRESULT clipToPath(
283        IXpsOMVisual* xpsVisual,
284        const SkPath& clipPath,
285        XPS_FILL_RULE fillRule);
286
287    HRESULT drawInverseWindingPath(
288        const SkDraw& d,
289        const SkPath& devicePath,
290        IXpsOMPath* xpsPath);
291
292    HRESULT shadePath(
293        IXpsOMPath* shadedPath,
294        const SkPaint& shaderPaint,
295        const SkMatrix& matrix,
296        BOOL* fill, BOOL* stroke);
297
298    void convertToPpm(
299        const SkMaskFilter* filter,
300        SkMatrix* matrix,
301        SkVector* ppuScale,
302        const SkIRect& clip, SkIRect* clipIRect);
303
304    HRESULT applyMask(
305        const SkDraw& d,
306        const SkMask& mask,
307        const SkVector& ppuScale,
308        IXpsOMPath* shadedPath);
309
310    // override from SkDevice
311    virtual SkDevice* onCreateCompatibleDevice(
312        SkBitmap::Config config,
313        int width, int height,
314        bool isOpaque,
315        Usage usage) SK_OVERRIDE;
316
317    // Disable the default copy and assign implementation.
318    SkXPSDevice(const SkXPSDevice&);
319    void operator=(const SkXPSDevice&);
320
321    typedef SkDevice INHERITED;
322};
323
324#endif
325