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