xref: /third_party/skia/src/xps/SkXPSDevice.h (revision cb93a386)
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
35class SkGlyphRunList;
36
37//#define SK_XPS_USE_DETERMINISTIC_IDS
38
39/** \class SkXPSDevice
40
41    The drawing context for the XPS backend.
42*/
43class SkXPSDevice : public SkClipStackDevice {
44public:
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
80protected:
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
101private:
102    class TypefaceUse {
103    public:
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