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 "SkBitmapDevice.h"
     20 #include "SkBitSet.h"
     21 #include "SkCanvas.h"
     22 #include "SkColor.h"
     23 #include "SkPaint.h"
     24 #include "SkPath.h"
     25 #include "SkPoint.h"
     26 #include "SkShader.h"
     27 #include "SkSize.h"
     28 #include "SkTArray.h"
     29 #include "SkTScopedComPtr.h"
     30 #include "SkTypeface.h"
     31 
     32 //#define SK_XPS_USE_DETERMINISTIC_IDS
     33 
     34 /** \class SkXPSDevice
     35 
     36     The drawing context for the XPS backend.
     37 */
     38 class SkXPSDevice : public SkBitmapDevice {
     39 public:
     40     SK_API SkXPSDevice();
     41     SK_API virtual ~SkXPSDevice();
     42 
     43     virtual bool beginPortfolio(SkWStream* outputStream);
     44     /**
     45       @param unitsPerMeter converts geometry units into physical units.
     46       @param pixelsPerMeter resolution to use when geometry must be rasterized.
     47       @param trimSize final page size in physical units.
     48                       The top left of the trim is the origin of physical space.
     49       @param mediaBox The size of the physical media in physical units.
     50                       The top and left must be less than zero.
     51                       The bottom and right must be greater than the trimSize.
     52                       The default is to coincide with the trimSize.
     53       @param bleedBox The size of the bleed box in physical units.
     54                       Must be contained within the mediaBox.
     55                       The default is to coincide with the mediaBox.
     56       @param artBox The size of the content box in physical units.
     57                     Must be contained within the trimSize.
     58                     The default is to coincide with the trimSize.
     59       @param cropBox The size of the recommended view port in physical units.
     60                      Must be contained within the mediaBox.
     61                      The default is to coincide with the mediaBox.
     62      */
     63     virtual bool beginSheet(
     64         const SkVector& unitsPerMeter,
     65         const SkVector& pixelsPerMeter,
     66         const SkSize& trimSize,
     67         const SkRect* mediaBox = NULL,
     68         const SkRect* bleedBox = NULL,
     69         const SkRect* artBox = NULL,
     70         const SkRect* cropBox = NULL);
     71 
     72     virtual bool endSheet();
     73     virtual bool endPortfolio();
     74 
     75 protected:
     76     void drawPaint(const SkDraw&, const SkPaint& paint) override;
     77 
     78     virtual void drawPoints(
     79         const SkDraw&,
     80         SkCanvas::PointMode mode,
     81         size_t count, const SkPoint[],
     82         const SkPaint& paint) override;
     83 
     84     virtual void drawRect(
     85         const SkDraw&,
     86         const SkRect& r,
     87         const SkPaint& paint) override;
     88 
     89     virtual void drawRRect(
     90         const SkDraw&,
     91         const SkRRect&,
     92         const SkPaint& paint) override;
     93 
     94     virtual void drawPath(
     95         const SkDraw&,
     96         const SkPath& platonicPath,
     97         const SkPaint& paint,
     98         const SkMatrix* prePathMatrix,
     99         bool pathIsMutable) override;
    100 
    101     virtual void drawBitmap(
    102         const SkDraw&,
    103         const SkBitmap& bitmap,
    104         const SkMatrix& matrix,
    105         const SkPaint& paint) override;
    106 
    107     virtual void drawSprite(
    108         const SkDraw&,
    109         const SkBitmap& bitmap,
    110         int x, int y,
    111         const SkPaint& paint) override;
    112 
    113     virtual void drawText(
    114         const SkDraw&,
    115         const void* text, size_t len,
    116         SkScalar x, SkScalar y,
    117         const SkPaint& paint) override;
    118 
    119     virtual void drawPosText(
    120         const SkDraw&,
    121         const void* text, size_t len,
    122         const SkScalar pos[], int scalarsPerPos,
    123         const SkPoint& offset, const SkPaint& paint) override;
    124 
    125     virtual void drawVertices(
    126         const SkDraw&,
    127         SkCanvas::VertexMode,
    128         int vertexCount, const SkPoint verts[],
    129         const SkPoint texs[], const SkColor colors[],
    130         SkXfermode* xmode,
    131         const uint16_t indices[], int indexCount,
    132         const SkPaint& paint) override;
    133 
    134     virtual void drawDevice(
    135         const SkDraw&,
    136         SkBaseDevice* device,
    137         int x, int y,
    138         const SkPaint& paint) override;
    139 
    140 private:
    141     class TypefaceUse : ::SkNoncopyable {
    142     public:
    143         SkFontID typefaceId;
    144         int ttcIndex;
    145         SkStream* fontData;
    146         IXpsOMFontResource* xpsFont;
    147         SkBitSet* glyphsUsed;
    148 
    149         explicit TypefaceUse();
    150         ~TypefaceUse();
    151     };
    152     friend static HRESULT subset_typeface(TypefaceUse* current);
    153 
    154     SkXPSDevice(IXpsOMObjectFactory* xpsFactory);
    155 
    156     SkAutoCoInitialize fAutoCo;
    157     SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
    158     SkTScopedComPtr<IStream> fOutputStream;
    159     SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
    160 
    161     unsigned int fCurrentPage;
    162     SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
    163     SkSize fCurrentCanvasSize;
    164     SkVector fCurrentUnitsPerMeter;
    165     SkVector fCurrentPixelsPerMeter;
    166 
    167     SkTArray<TypefaceUse, true> fTypefaces;
    168 
    169     /** Creates a GUID based id and places it into buffer.
    170         buffer should have space for at least GUID_ID_LEN wide characters.
    171         The string will always be wchar null terminated.
    172         XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0
    173         The string may begin with a digit,
    174         and so may not be suitable as a bare resource key.
    175      */
    176     HRESULT createId(wchar_t* buffer, size_t bufferSize, wchar_t sep = '-');
    177 #ifdef SK_XPS_USE_DETERMINISTIC_IDS
    178     decltype(GUID::Data1) fNextId = 0;
    179 #endif
    180 
    181     HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
    182 
    183     HRESULT createXpsPage(
    184         const XPS_SIZE& pageSize,
    185         IXpsOMPage** page);
    186 
    187     HRESULT createXpsThumbnail(
    188         IXpsOMPage* page, const unsigned int pageNumber,
    189         IXpsOMImageResource** image);
    190 
    191     void internalDrawRect(
    192         const SkDraw&,
    193         const SkRect& r,
    194         bool transformRect,
    195         const SkPaint& paint);
    196 
    197     HRESULT createXpsBrush(
    198         const SkPaint& skPaint,
    199         IXpsOMBrush** xpsBrush,
    200         const SkMatrix* parentTransform = NULL);
    201 
    202     HRESULT createXpsSolidColorBrush(
    203         const SkColor skColor, const SkAlpha alpha,
    204         IXpsOMBrush** xpsBrush);
    205 
    206     HRESULT createXpsImageBrush(
    207         const SkBitmap& bitmap,
    208         const SkMatrix& localMatrix,
    209         const SkShader::TileMode (&xy)[2],
    210         const SkAlpha alpha,
    211         IXpsOMTileBrush** xpsBrush);
    212 
    213     HRESULT createXpsLinearGradient(
    214         SkShader::GradientInfo info,
    215         const SkAlpha alpha,
    216         const SkMatrix& localMatrix,
    217         IXpsOMMatrixTransform* xpsMatrixToUse,
    218         IXpsOMBrush** xpsBrush);
    219 
    220     HRESULT createXpsRadialGradient(
    221         SkShader::GradientInfo info,
    222         const SkAlpha alpha,
    223         const SkMatrix& localMatrix,
    224         IXpsOMMatrixTransform* xpsMatrixToUse,
    225         IXpsOMBrush** xpsBrush);
    226 
    227     HRESULT createXpsGradientStop(
    228         const SkColor skColor,
    229         const SkScalar offset,
    230         IXpsOMGradientStop** xpsGradStop);
    231 
    232     HRESULT createXpsTransform(
    233         const SkMatrix& matrix,
    234         IXpsOMMatrixTransform ** xpsTransform);
    235 
    236     HRESULT createXpsRect(
    237         const SkRect& rect,
    238         BOOL stroke, BOOL fill,
    239         IXpsOMGeometryFigure** xpsRect);
    240 
    241     HRESULT createXpsQuad(
    242         const SkPoint (&points)[4],
    243         BOOL stroke, BOOL fill,
    244         IXpsOMGeometryFigure** xpsQuad);
    245 
    246     HRESULT CreateTypefaceUse(
    247         const SkPaint& paint,
    248         TypefaceUse** fontResource);
    249 
    250     HRESULT AddGlyphs(
    251         const SkDraw& d,
    252         IXpsOMObjectFactory* xpsFactory,
    253         IXpsOMCanvas* canvas,
    254         TypefaceUse* font,
    255         LPCWSTR text,
    256         XPS_GLYPH_INDEX* xpsGlyphs,
    257         UINT32 xpsGlyphsLen,
    258         XPS_POINT *origin,
    259         FLOAT fontSize,
    260         XPS_STYLE_SIMULATION sims,
    261         const SkMatrix& transform,
    262         const SkPaint& paint);
    263 
    264     HRESULT addXpsPathGeometry(
    265         IXpsOMGeometryFigureCollection* figures,
    266         BOOL stroke, BOOL fill, const SkPath& path);
    267 
    268     HRESULT createPath(
    269         IXpsOMGeometryFigure* figure,
    270         IXpsOMVisualCollection* visuals,
    271         IXpsOMPath** path);
    272 
    273     HRESULT sideOfClamp(
    274         const SkRect& leftPoints, const XPS_RECT& left,
    275         IXpsOMImageResource* imageResource,
    276         IXpsOMVisualCollection* visuals);
    277 
    278     HRESULT cornerOfClamp(
    279         const SkRect& tlPoints,
    280         const SkColor color,
    281         IXpsOMVisualCollection* visuals);
    282 
    283     HRESULT clip(
    284         IXpsOMVisual* xpsVisual,
    285         const SkDraw& d);
    286     HRESULT clipToPath(
    287         IXpsOMVisual* xpsVisual,
    288         const SkPath& clipPath,
    289         XPS_FILL_RULE fillRule);
    290 
    291     HRESULT drawInverseWindingPath(
    292         const SkDraw& d,
    293         const SkPath& devicePath,
    294         IXpsOMPath* xpsPath);
    295 
    296     HRESULT shadePath(
    297         IXpsOMPath* shadedPath,
    298         const SkPaint& shaderPaint,
    299         const SkMatrix& matrix,
    300         BOOL* fill, BOOL* stroke);
    301 
    302     void convertToPpm(
    303         const SkMaskFilter* filter,
    304         SkMatrix* matrix,
    305         SkVector* ppuScale,
    306         const SkIRect& clip, SkIRect* clipIRect);
    307 
    308     HRESULT applyMask(
    309         const SkDraw& d,
    310         const SkMask& mask,
    311         const SkVector& ppuScale,
    312         IXpsOMPath* shadedPath);
    313 
    314     SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
    315 
    316     // Disable the default copy and assign implementation.
    317     SkXPSDevice(const SkXPSDevice&);
    318     void operator=(const SkXPSDevice&);
    319 
    320     typedef SkBitmapDevice INHERITED;
    321 };
    322 
    323 #endif  // SK_BUILD_FOR_WIN
    324 #endif  // SkXPSDevice_DEFINED
    325