Home | History | Annotate | Download | only in xps
      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 "SkTypes.h"
     12 
     13 #ifdef SK_BUILD_FOR_WIN
     14 
     15 #include <ObjBase.h>
     16 #include <XpsObjectModel.h>
     17 
     18 #include "SkAutoCoInitialize.h"
     19 #include "SkBitSet.h"
     20 #include "SkBitmapDevice.h"
     21 #include "SkCanvas.h"
     22 #include "SkClipStackDevice.h"
     23 #include "SkColor.h"
     24 #include "SkPaint.h"
     25 #include "SkPath.h"
     26 #include "SkPoint.h"
     27 #include "SkShader.h"
     28 #include "SkSize.h"
     29 #include "SkTArray.h"
     30 #include "SkTScopedComPtr.h"
     31 #include "SkTypeface.h"
     32 
     33 //#define SK_XPS_USE_DETERMINISTIC_IDS
     34 
     35 /** \class SkXPSDevice
     36 
     37     The drawing context for the XPS backend.
     38 */
     39 class SkXPSDevice : public SkClipStackDevice {
     40 public:
     41     SK_API SkXPSDevice(SkISize);
     42     SK_API virtual ~SkXPSDevice();
     43 
     44     bool beginPortfolio(SkWStream* outputStream, IXpsOMObjectFactory*);
     45     /**
     46       @param unitsPerMeter converts geometry units into physical units.
     47       @param pixelsPerMeter resolution to use when geometry must be rasterized.
     48       @param trimSize final page size in physical units.
     49                       The top left of the trim is the origin of physical space.
     50       @param mediaBox The size of the physical media in physical units.
     51                       The top and left must be less than zero.
     52                       The bottom and right must be greater than the trimSize.
     53                       The default is to coincide with the trimSize.
     54       @param bleedBox The size of the bleed box in physical units.
     55                       Must be contained within the mediaBox.
     56                       The default is to coincide with the mediaBox.
     57       @param artBox The size of the content box in physical units.
     58                     Must be contained within the trimSize.
     59                     The default is to coincide with the trimSize.
     60       @param cropBox The size of the recommended view port in physical units.
     61                      Must be contained within the mediaBox.
     62                      The default is to coincide with the mediaBox.
     63      */
     64     bool beginSheet(
     65         const SkVector& unitsPerMeter,
     66         const SkVector& pixelsPerMeter,
     67         const SkSize& trimSize,
     68         const SkRect* mediaBox = NULL,
     69         const SkRect* bleedBox = NULL,
     70         const SkRect* artBox = NULL,
     71         const SkRect* cropBox = NULL);
     72 
     73     bool endSheet();
     74     bool endPortfolio();
     75 
     76 protected:
     77     void drawPaint(const SkPaint& paint) override;
     78     void drawPoints(SkCanvas::PointMode mode, size_t count,
     79                     const SkPoint[], const SkPaint& paint) override;
     80     void drawRect(const SkRect& r,
     81                   const SkPaint& paint) override;
     82     void drawOval(const SkRect& oval,
     83                   const SkPaint& paint) override;
     84     void drawRRect(const SkRRect& rr,
     85                    const SkPaint& paint) override;
     86     void drawPath(const SkPath& path,
     87                   const SkPaint& paint,
     88                   const SkMatrix* prePathMatrix = NULL,
     89                   bool pathIsMutable = false) override;
     90     void drawBitmap(const SkBitmap& bitmap,
     91                     const SkMatrix& matrix, const SkPaint& paint) override;
     92     void drawSprite(const SkBitmap& bitmap,
     93                     int x, int y, const SkPaint& paint) override;
     94     void drawBitmapRect(const SkBitmap&,
     95                         const SkRect* srcOrNull, const SkRect& dst,
     96                         const SkPaint& paint,
     97                         SkCanvas::SrcRectConstraint) override;
     98     void drawText(const void* text, size_t len,
     99                   SkScalar x, SkScalar y, const SkPaint& paint) override;
    100     void drawPosText(const void* text, size_t len,
    101                      const SkScalar pos[], int scalarsPerPos,
    102                      const SkPoint& offset, const SkPaint& paint) override;
    103     void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
    104     void drawDevice(SkBaseDevice*, int x, int y,
    105                     const SkPaint&) override;
    106 
    107 private:
    108     class TypefaceUse : ::SkNoncopyable {
    109     public:
    110         SkFontID typefaceId;
    111         int ttcIndex;
    112         SkStream* fontData;
    113         IXpsOMFontResource* xpsFont;
    114         SkBitSet* glyphsUsed;
    115 
    116         explicit TypefaceUse();
    117         ~TypefaceUse();
    118     };
    119     friend HRESULT subset_typeface(TypefaceUse* current);
    120 
    121     bool createCanvasForLayer();
    122 
    123     SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
    124     SkTScopedComPtr<IStream> fOutputStream;
    125     SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
    126 
    127     unsigned int fCurrentPage;
    128     SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
    129     SkSize fCurrentCanvasSize;
    130     SkVector fCurrentUnitsPerMeter;
    131     SkVector fCurrentPixelsPerMeter;
    132 
    133     SkTArray<TypefaceUse, true> fTypefaces;
    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 = NULL);
    166 
    167     HRESULT createXpsSolidColorBrush(
    168         const SkColor skColor, const SkAlpha alpha,
    169         IXpsOMBrush** xpsBrush);
    170 
    171     HRESULT createXpsImageBrush(
    172         const SkBitmap& bitmap,
    173         const SkMatrix& localMatrix,
    174         const SkShader::TileMode (&xy)[2],
    175         const SkAlpha alpha,
    176         IXpsOMTileBrush** xpsBrush);
    177 
    178     HRESULT createXpsLinearGradient(
    179         SkShader::GradientInfo info,
    180         const SkAlpha alpha,
    181         const SkMatrix& localMatrix,
    182         IXpsOMMatrixTransform* xpsMatrixToUse,
    183         IXpsOMBrush** xpsBrush);
    184 
    185     HRESULT createXpsRadialGradient(
    186         SkShader::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 SkPaint& paint,
    213         TypefaceUse** fontResource);
    214 
    215     HRESULT AddGlyphs(
    216         IXpsOMObjectFactory* xpsFactory,
    217         IXpsOMCanvas* canvas,
    218         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     SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
    276 
    277     // Disable the default copy and assign implementation.
    278     SkXPSDevice(const SkXPSDevice&);
    279     void operator=(const SkXPSDevice&);
    280 
    281     typedef SkClipStackDevice INHERITED;
    282 };
    283 
    284 #endif  // SK_BUILD_FOR_WIN
    285 #endif  // SkXPSDevice_DEFINED
    286