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