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