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 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 96 void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override; 97 void drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override; 98 99 void drawDevice(SkDevice*, const SkSamplingOptions&, const SkPaint&) override; 100 101 sk_sp<SkDevice> createDevice(const CreateInfo&, const SkPaint*) override; 102 103 private: 104 class TypefaceUse { 105 public: TypefaceUse(SkTypefaceID id,int index,std::unique_ptr<SkStream> data,SkTScopedComPtr<IXpsOMFontResource> xps,size_t numGlyphs)106 TypefaceUse(SkTypefaceID id, int index, std::unique_ptr<SkStream> data, 107 SkTScopedComPtr<IXpsOMFontResource> xps, size_t numGlyphs) 108 : typefaceId(id), ttcIndex(index), fontData(std::move(data)) 109 , xpsFont(std::move(xps)), glyphsUsed(numGlyphs) {} 110 const SkTypefaceID typefaceId; 111 const int ttcIndex; 112 const std::unique_ptr<SkStream> fontData; 113 const SkTScopedComPtr<IXpsOMFontResource> xpsFont; 114 SkBitSet glyphsUsed; 115 }; 116 friend HRESULT subset_typeface(const TypefaceUse& current); 117 118 void onDrawGlyphRunList(SkCanvas*, const sktext::GlyphRunList&, const SkPaint&) override; 119 120 bool createCanvasForLayer(); 121 122 SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory; 123 SkTScopedComPtr<IStream> fOutputStream; 124 SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter; 125 126 unsigned int fCurrentPage; 127 SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas; 128 SkSize fCurrentCanvasSize; 129 SkVector fCurrentUnitsPerMeter; 130 SkVector fCurrentPixelsPerMeter; 131 132 skia_private::TArray<TypefaceUse, true> fTypefaces; 133 skia_private::TArray<TypefaceUse, true>* fTopTypefaces; 134 135 /** Creates a GUID based id and places it into buffer. 136 buffer should have space for at least GUID_ID_LEN wide characters. 137 The string will always be wchar null terminated. 138 XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0 139 The string may begin with a digit, 140 and so may not be suitable as a bare resource key. 141 */ 142 HRESULT createId(wchar_t* buffer, size_t bufferSize, wchar_t sep = '-'); 143 #ifdef SK_XPS_USE_DETERMINISTIC_IDS 144 decltype(GUID::Data1) fNextId = 0; 145 #endif 146 147 HRESULT initXpsDocumentWriter(IXpsOMImageResource* image); 148 149 HRESULT createXpsPage( 150 const XPS_SIZE& pageSize, 151 IXpsOMPage** page); 152 153 HRESULT createXpsThumbnail( 154 IXpsOMPage* page, const unsigned int pageNumber, 155 IXpsOMImageResource** image); 156 157 void internalDrawRect( 158 const SkRect& r, 159 bool transformRect, 160 const SkPaint& paint); 161 162 HRESULT createXpsBrush( 163 const SkPaint& skPaint, 164 IXpsOMBrush** xpsBrush, 165 const SkMatrix* parentTransform = nullptr); 166 167 HRESULT createXpsSolidColorBrush( 168 const SkColor skColor, const SkAlpha alpha, 169 IXpsOMBrush** xpsBrush); 170 171 HRESULT createXpsImageBrush( 172 const SkPixmap& bitmap, 173 const SkMatrix& localMatrix, 174 const SkTileMode (&xy)[2], 175 const SkAlpha alpha, 176 IXpsOMTileBrush** xpsBrush); 177 178 HRESULT createXpsLinearGradient( 179 SkShaderBase::GradientInfo info, 180 const SkAlpha alpha, 181 const SkMatrix& localMatrix, 182 IXpsOMMatrixTransform* xpsMatrixToUse, 183 IXpsOMBrush** xpsBrush); 184 185 HRESULT createXpsRadialGradient( 186 SkShaderBase::GradientInfo info, 187 const SkAlpha alpha, 188 const SkMatrix& localMatrix, 189 IXpsOMMatrixTransform* xpsMatrixToUse, 190 IXpsOMBrush** xpsBrush); 191 192 HRESULT createXpsGradientStop( 193 const SkColor skColor, 194 const SkScalar offset, 195 IXpsOMGradientStop** xpsGradStop); 196 197 HRESULT createXpsTransform( 198 const SkMatrix& matrix, 199 IXpsOMMatrixTransform ** xpsTransform); 200 201 HRESULT createXpsRect( 202 const SkRect& rect, 203 BOOL stroke, BOOL fill, 204 IXpsOMGeometryFigure** xpsRect); 205 206 HRESULT createXpsQuad( 207 const SkPoint (&points)[4], 208 BOOL stroke, BOOL fill, 209 IXpsOMGeometryFigure** xpsQuad); 210 211 HRESULT CreateTypefaceUse( 212 const SkFont& font, 213 TypefaceUse** fontResource); 214 215 HRESULT AddGlyphs( 216 IXpsOMObjectFactory* xpsFactory, 217 IXpsOMCanvas* canvas, 218 const TypefaceUse* font, 219 LPCWSTR text, 220 XPS_GLYPH_INDEX* xpsGlyphs, 221 UINT32 xpsGlyphsLen, 222 XPS_POINT *origin, 223 FLOAT fontSize, 224 XPS_STYLE_SIMULATION sims, 225 const SkMatrix& transform, 226 const SkPaint& paint); 227 228 HRESULT addXpsPathGeometry( 229 IXpsOMGeometryFigureCollection* figures, 230 BOOL stroke, BOOL fill, const SkPath& path); 231 232 HRESULT createPath( 233 IXpsOMGeometryFigure* figure, 234 IXpsOMVisualCollection* visuals, 235 IXpsOMPath** path); 236 237 HRESULT sideOfClamp( 238 const SkRect& leftPoints, const XPS_RECT& left, 239 IXpsOMImageResource* imageResource, 240 IXpsOMVisualCollection* visuals); 241 242 HRESULT cornerOfClamp( 243 const SkRect& tlPoints, 244 const SkColor color, 245 IXpsOMVisualCollection* visuals); 246 247 HRESULT clip(IXpsOMVisual* xpsVisual); 248 249 HRESULT clipToPath( 250 IXpsOMVisual* xpsVisual, 251 const SkPath& clipPath, 252 XPS_FILL_RULE fillRule); 253 254 HRESULT drawInverseWindingPath( 255 const SkPath& devicePath, 256 IXpsOMPath* xpsPath); 257 258 HRESULT shadePath( 259 IXpsOMPath* shadedPath, 260 const SkPaint& shaderPaint, 261 const SkMatrix& matrix, 262 BOOL* fill, BOOL* stroke); 263 264 void convertToPpm( 265 const SkMaskFilter* filter, 266 SkMatrix* matrix, 267 SkVector* ppuScale, 268 const SkIRect& clip, SkIRect* clipIRect); 269 270 HRESULT applyMask( 271 const SkMask& mask, 272 const SkVector& ppuScale, 273 IXpsOMPath* shadedPath); 274 275 // Disable the default copy and assign implementation. 276 SkXPSDevice(const SkXPSDevice&); 277 void operator=(const SkXPSDevice&); 278 }; 279 280 #endif // SK_BUILD_FOR_WIN 281 #endif // SkXPSDevice_DEFINED 282