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 */
36 class SkXPSDevice : public SkBitmapDevice {
37 public:
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 
73 protected:
74     void drawPaint(const SkDraw&, const SkPaint& paint) override;
75 
76     virtual void drawPoints(
77         const SkDraw&,
78         SkCanvas::PointMode mode,
79         size_t count, const SkPoint[],
80         const SkPaint& paint) override;
81 
82     virtual void drawRect(
83         const SkDraw&,
84         const SkRect& r,
85         const SkPaint& paint) override;
86 
87     virtual void drawRRect(
88         const SkDraw&,
89         const SkRRect&,
90         const SkPaint& paint) override;
91 
92     virtual void drawPath(
93         const SkDraw&,
94         const SkPath& platonicPath,
95         const SkPaint& paint,
96         const SkMatrix* prePathMatrix,
97         bool pathIsMutable) override;
98 
99     virtual void drawBitmap(
100         const SkDraw&,
101         const SkBitmap& bitmap,
102         const SkMatrix& matrix,
103         const SkPaint& paint) override;
104 
105     virtual void drawSprite(
106         const SkDraw&,
107         const SkBitmap& bitmap,
108         int x, int y,
109         const SkPaint& paint) 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) 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) 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) override;
131 
132     virtual void drawDevice(
133         const SkDraw&,
134         SkBaseDevice* device,
135         int x, int y,
136         const SkPaint& paint) override;
137 
138 private:
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*) 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