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