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