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