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 "SkBitmapDevice.h"
17#include "SkBitSet.h"
18#include "SkCanvas.h"
19#include "SkColor.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 SkBitmapDevice {
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
70protected:
71    virtual void clear(SkColor color) SK_OVERRIDE;
72
73    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
74
75    virtual void drawPoints(
76        const SkDraw&,
77        SkCanvas::PointMode mode,
78        size_t count, const SkPoint[],
79        const SkPaint& paint) SK_OVERRIDE;
80
81    virtual void drawRect(
82        const SkDraw&,
83        const SkRect& r,
84        const SkPaint& paint) SK_OVERRIDE;
85
86    virtual void drawRRect(
87        const SkDraw&,
88        const SkRRect&,
89        const SkPaint& paint) SK_OVERRIDE;
90
91    virtual void drawPath(
92        const SkDraw&,
93        const SkPath& platonicPath,
94        const SkPaint& paint,
95        const SkMatrix* prePathMatrix,
96        bool pathIsMutable) SK_OVERRIDE;
97
98    virtual void drawBitmap(
99        const SkDraw&,
100        const SkBitmap& bitmap,
101        const SkMatrix& matrix,
102        const SkPaint& paint) SK_OVERRIDE;
103
104    virtual void drawSprite(
105        const SkDraw&,
106        const SkBitmap& bitmap,
107        int x, int y,
108        const SkPaint& paint) SK_OVERRIDE;
109
110    virtual void drawText(
111        const SkDraw&,
112        const void* text, size_t len,
113        SkScalar x, SkScalar y,
114        const SkPaint& paint) SK_OVERRIDE;
115
116    virtual void drawPosText(
117        const SkDraw&,
118        const void* text, size_t len,
119        const SkScalar pos[], SkScalar constY, int scalarsPerPos,
120        const SkPaint& paint) SK_OVERRIDE;
121
122    virtual void drawTextOnPath(
123        const SkDraw&,
124        const void* text, size_t len,
125        const SkPath& path,
126        const SkMatrix* matrix,
127        const SkPaint& paint) SK_OVERRIDE;
128
129    virtual void drawVertices(
130        const SkDraw&,
131        SkCanvas::VertexMode,
132        int vertexCount, const SkPoint verts[],
133        const SkPoint texs[], const SkColor colors[],
134        SkXfermode* xmode,
135        const uint16_t indices[], int indexCount,
136        const SkPaint& paint) SK_OVERRIDE;
137
138    virtual void drawDevice(
139        const SkDraw&,
140        SkBaseDevice* device,
141        int x, int y,
142        const SkPaint& paint) SK_OVERRIDE;
143
144    virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE;
145
146private:
147    class TypefaceUse : ::SkNoncopyable {
148    public:
149        SkFontID typefaceId;
150        int ttcIndex;
151        SkStream* fontData;
152        IXpsOMFontResource* xpsFont;
153        SkBitSet* glyphsUsed;
154
155        explicit TypefaceUse();
156        ~TypefaceUse();
157    };
158    friend static HRESULT subset_typeface(TypefaceUse* current);
159
160    SkXPSDevice(IXpsOMObjectFactory* xpsFactory);
161
162    SkAutoCoInitialize fAutoCo;
163    SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
164    SkTScopedComPtr<IStream> fOutputStream;
165    SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
166
167    unsigned int fCurrentPage;
168    SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
169    SkSize fCurrentCanvasSize;
170    SkVector fCurrentUnitsPerMeter;
171    SkVector fCurrentPixelsPerMeter;
172
173    SkTArray<TypefaceUse, true> fTypefaces;
174
175    HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
176
177    HRESULT createXpsPage(
178        const XPS_SIZE& pageSize,
179        IXpsOMPage** page);
180
181    HRESULT createXpsThumbnail(
182        IXpsOMPage* page, const unsigned int pageNumber,
183        IXpsOMImageResource** image);
184
185    void internalDrawRect(
186        const SkDraw&,
187        const SkRect& r,
188        bool transformRect,
189        const SkPaint& paint);
190
191    HRESULT createXpsBrush(
192        const SkPaint& skPaint,
193        IXpsOMBrush** xpsBrush,
194        const SkMatrix* parentTransform = NULL);
195
196    HRESULT createXpsSolidColorBrush(
197        const SkColor skColor, const SkAlpha alpha,
198        IXpsOMBrush** xpsBrush);
199
200    HRESULT createXpsImageBrush(
201        const SkBitmap& bitmap,
202        const SkMatrix& localMatrix,
203        const SkShader::TileMode (&xy)[2],
204        const SkAlpha alpha,
205        IXpsOMTileBrush** xpsBrush);
206
207    HRESULT createXpsLinearGradient(
208        SkShader::GradientInfo info,
209        const SkAlpha alpha,
210        const SkMatrix& localMatrix,
211        IXpsOMMatrixTransform* xpsMatrixToUse,
212        IXpsOMBrush** xpsBrush);
213
214    HRESULT createXpsRadialGradient(
215        SkShader::GradientInfo info,
216        const SkAlpha alpha,
217        const SkMatrix& localMatrix,
218        IXpsOMMatrixTransform* xpsMatrixToUse,
219        IXpsOMBrush** xpsBrush);
220
221    HRESULT createXpsGradientStop(
222        const SkColor skColor,
223        const SkScalar offset,
224        IXpsOMGradientStop** xpsGradStop);
225
226    HRESULT createXpsTransform(
227        const SkMatrix& matrix,
228        IXpsOMMatrixTransform ** xpsTransform);
229
230    HRESULT createXpsRect(
231        const SkRect& rect,
232        BOOL stroke, BOOL fill,
233        IXpsOMGeometryFigure** xpsRect);
234
235    HRESULT createXpsQuad(
236        const SkPoint (&points)[4],
237        BOOL stroke, BOOL fill,
238        IXpsOMGeometryFigure** xpsQuad);
239
240    HRESULT CreateTypefaceUse(
241        const SkPaint& paint,
242        TypefaceUse** fontResource);
243
244    HRESULT AddGlyphs(
245        const SkDraw& d,
246        IXpsOMObjectFactory* xpsFactory,
247        IXpsOMCanvas* canvas,
248        TypefaceUse* font,
249        LPCWSTR text,
250        XPS_GLYPH_INDEX* xpsGlyphs,
251        UINT32 xpsGlyphsLen,
252        XPS_POINT *origin,
253        FLOAT fontSize,
254        XPS_STYLE_SIMULATION sims,
255        const SkMatrix& transform,
256        const SkPaint& paint);
257
258    HRESULT addXpsPathGeometry(
259        IXpsOMGeometryFigureCollection* figures,
260        BOOL stroke, BOOL fill, const SkPath& path);
261
262    HRESULT createPath(
263        IXpsOMGeometryFigure* figure,
264        IXpsOMVisualCollection* visuals,
265        IXpsOMPath** path);
266
267    HRESULT sideOfClamp(
268        const SkRect& leftPoints, const XPS_RECT& left,
269        IXpsOMImageResource* imageResource,
270        IXpsOMVisualCollection* visuals);
271
272    HRESULT cornerOfClamp(
273        const SkRect& tlPoints,
274        const SkColor color,
275        IXpsOMVisualCollection* visuals);
276
277    HRESULT clip(
278        IXpsOMVisual* xpsVisual,
279        const SkDraw& d);
280    HRESULT clipToPath(
281        IXpsOMVisual* xpsVisual,
282        const SkPath& clipPath,
283        XPS_FILL_RULE fillRule);
284
285    HRESULT drawInverseWindingPath(
286        const SkDraw& d,
287        const SkPath& devicePath,
288        IXpsOMPath* xpsPath);
289
290    HRESULT shadePath(
291        IXpsOMPath* shadedPath,
292        const SkPaint& shaderPaint,
293        const SkMatrix& matrix,
294        BOOL* fill, BOOL* stroke);
295
296    void convertToPpm(
297        const SkMaskFilter* filter,
298        SkMatrix* matrix,
299        SkVector* ppuScale,
300        const SkIRect& clip, SkIRect* clipIRect);
301
302    HRESULT applyMask(
303        const SkDraw& d,
304        const SkMask& mask,
305        const SkVector& ppuScale,
306        IXpsOMPath* shadedPath);
307
308    virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
309
310    // Disable the default copy and assign implementation.
311    SkXPSDevice(const SkXPSDevice&);
312    void operator=(const SkXPSDevice&);
313
314    typedef SkBitmapDevice INHERITED;
315};
316
317#endif
318