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