• 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 = NULL,
71         const SkRect* bleedBox = NULL,
72         const SkRect* artBox = NULL,
73         const SkRect* cropBox = NULL);
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(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
96     void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
97     void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override;
98 
99 private:
100     class TypefaceUse {
101     public:
TypefaceUse(SkFontID id,int index,std::unique_ptr<SkStream> data,SkTScopedComPtr<IXpsOMFontResource> xps,size_t numGlyphs)102         TypefaceUse(SkFontID id, int index, std::unique_ptr<SkStream> data,
103                     SkTScopedComPtr<IXpsOMFontResource> xps, size_t numGlyphs)
104             : typefaceId(id), ttcIndex(index), fontData(std::move(data))
105             , xpsFont(std::move(xps)), glyphsUsed(numGlyphs) {}
106         const SkFontID typefaceId;
107         const int ttcIndex;
108         const std::unique_ptr<SkStream> fontData;
109         const SkTScopedComPtr<IXpsOMFontResource> xpsFont;
110         SkBitSet glyphsUsed;
111     };
112     friend HRESULT subset_typeface(const TypefaceUse& current);
113 
114     bool createCanvasForLayer();
115 
116     SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
117     SkTScopedComPtr<IStream> fOutputStream;
118     SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
119 
120     unsigned int fCurrentPage;
121     SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
122     SkSize fCurrentCanvasSize;
123     SkVector fCurrentUnitsPerMeter;
124     SkVector fCurrentPixelsPerMeter;
125 
126     SkTArray<TypefaceUse, true> fTypefaces;
127     SkTArray<TypefaceUse, true>* fTopTypefaces;
128 
129     /** Creates a GUID based id and places it into buffer.
130         buffer should have space for at least GUID_ID_LEN wide characters.
131         The string will always be wchar null terminated.
132         XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0
133         The string may begin with a digit,
134         and so may not be suitable as a bare resource key.
135      */
136     HRESULT createId(wchar_t* buffer, size_t bufferSize, wchar_t sep = '-');
137 #ifdef SK_XPS_USE_DETERMINISTIC_IDS
138     decltype(GUID::Data1) fNextId = 0;
139 #endif
140 
141     HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
142 
143     HRESULT createXpsPage(
144         const XPS_SIZE& pageSize,
145         IXpsOMPage** page);
146 
147     HRESULT createXpsThumbnail(
148         IXpsOMPage* page, const unsigned int pageNumber,
149         IXpsOMImageResource** image);
150 
151     void internalDrawRect(
152         const SkRect& r,
153         bool transformRect,
154         const SkPaint& paint);
155 
156     HRESULT createXpsBrush(
157         const SkPaint& skPaint,
158         IXpsOMBrush** xpsBrush,
159         const SkMatrix* parentTransform = NULL);
160 
161     HRESULT createXpsSolidColorBrush(
162         const SkColor skColor, const SkAlpha alpha,
163         IXpsOMBrush** xpsBrush);
164 
165     HRESULT createXpsImageBrush(
166         const SkBitmap& bitmap,
167         const SkMatrix& localMatrix,
168         const SkTileMode (&xy)[2],
169         const SkAlpha alpha,
170         IXpsOMTileBrush** xpsBrush);
171 
172     HRESULT createXpsLinearGradient(
173         SkShader::GradientInfo info,
174         const SkAlpha alpha,
175         const SkMatrix& localMatrix,
176         IXpsOMMatrixTransform* xpsMatrixToUse,
177         IXpsOMBrush** xpsBrush);
178 
179     HRESULT createXpsRadialGradient(
180         SkShader::GradientInfo info,
181         const SkAlpha alpha,
182         const SkMatrix& localMatrix,
183         IXpsOMMatrixTransform* xpsMatrixToUse,
184         IXpsOMBrush** xpsBrush);
185 
186     HRESULT createXpsGradientStop(
187         const SkColor skColor,
188         const SkScalar offset,
189         IXpsOMGradientStop** xpsGradStop);
190 
191     HRESULT createXpsTransform(
192         const SkMatrix& matrix,
193         IXpsOMMatrixTransform ** xpsTransform);
194 
195     HRESULT createXpsRect(
196         const SkRect& rect,
197         BOOL stroke, BOOL fill,
198         IXpsOMGeometryFigure** xpsRect);
199 
200     HRESULT createXpsQuad(
201         const SkPoint (&points)[4],
202         BOOL stroke, BOOL fill,
203         IXpsOMGeometryFigure** xpsQuad);
204 
205     HRESULT CreateTypefaceUse(
206         const SkFont& font,
207         TypefaceUse** fontResource);
208 
209     HRESULT AddGlyphs(
210         IXpsOMObjectFactory* xpsFactory,
211         IXpsOMCanvas* canvas,
212         const TypefaceUse* font,
213         LPCWSTR text,
214         XPS_GLYPH_INDEX* xpsGlyphs,
215         UINT32 xpsGlyphsLen,
216         XPS_POINT *origin,
217         FLOAT fontSize,
218         XPS_STYLE_SIMULATION sims,
219         const SkMatrix& transform,
220         const SkPaint& paint);
221 
222     HRESULT addXpsPathGeometry(
223         IXpsOMGeometryFigureCollection* figures,
224         BOOL stroke, BOOL fill, const SkPath& path);
225 
226     HRESULT createPath(
227         IXpsOMGeometryFigure* figure,
228         IXpsOMVisualCollection* visuals,
229         IXpsOMPath** path);
230 
231     HRESULT sideOfClamp(
232         const SkRect& leftPoints, const XPS_RECT& left,
233         IXpsOMImageResource* imageResource,
234         IXpsOMVisualCollection* visuals);
235 
236     HRESULT cornerOfClamp(
237         const SkRect& tlPoints,
238         const SkColor color,
239         IXpsOMVisualCollection* visuals);
240 
241     HRESULT clip(IXpsOMVisual* xpsVisual);
242 
243     HRESULT clipToPath(
244         IXpsOMVisual* xpsVisual,
245         const SkPath& clipPath,
246         XPS_FILL_RULE fillRule);
247 
248     HRESULT drawInverseWindingPath(
249         const SkPath& devicePath,
250         IXpsOMPath* xpsPath);
251 
252     HRESULT shadePath(
253         IXpsOMPath* shadedPath,
254         const SkPaint& shaderPaint,
255         const SkMatrix& matrix,
256         BOOL* fill, BOOL* stroke);
257 
258     void convertToPpm(
259         const SkMaskFilter* filter,
260         SkMatrix* matrix,
261         SkVector* ppuScale,
262         const SkIRect& clip, SkIRect* clipIRect);
263 
264     HRESULT applyMask(
265         const SkMask& mask,
266         const SkVector& ppuScale,
267         IXpsOMPath* shadedPath);
268 
269     SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
270 
271     // Disable the default copy and assign implementation.
272     SkXPSDevice(const SkXPSDevice&);
273     void operator=(const SkXPSDevice&);
274 
275     using INHERITED = SkClipStackDevice;
276 };
277 
278 #endif  // SK_BUILD_FOR_WIN
279 #endif  // SkXPSDevice_DEFINED
280