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