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