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