SkPDFDevice.h revision 4b1e17edc78c0313d5cb8a415f816f654cdfa417
19b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
39b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
69b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org */
79b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
89b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#ifndef SkPDFDevice_DEFINED
99b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#define SkPDFDevice_DEFINED
109b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
115e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org#include "SkBitmap.h"
12b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org#include "SkCanvas.h"
13d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkClipStack.h"
1491fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary#include "SkData.h"
15d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkDevice.h"
16a518086928494319b8968abc09808eff492c194fvandebo@chromium.org#include "SkPaint.h"
17238be8c7e5de5a83517440a3db7f7965b47fb010vandebo@chromium.org#include "SkRect.h"
189fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org#include "SkRefCnt.h"
199fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org#include "SkStream.h"
20b58772f86659cfe0e8d9247fcee878dddd8fdad9epoger@google.com#include "SkTDArray.h"
219b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
222be7e01382ee9c036de9c09585677dfd25d70253halcanary#include "SkSinglyLinkedList.h"
232be7e01382ee9c036de9c09585677dfd25d70253halcanary
24b8d6af169bf631dcb68ba5a796436434ff78be65martina.kollarovaclass SkImageBitmap;
25b8d6af169bf631dcb68ba5a796436434ff78be65martina.kollarovaclass SkPath;
269b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFArray;
27a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanaryclass SkPDFCanon;
289b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFDevice;
29989da4a32cd6823359f31c971c3b3f31425e905ehalcanaryclass SkPDFDocument;
309b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFDict;
3128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgclass SkPDFFont;
329b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFObject;
334b1e17edc78c0313d5cb8a415f816f654cdfa417halcanaryclass SkPDFStream;
34a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comclass SkRRect;
359b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
369b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org/** \class SkPDFDevice
379b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
389b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    The drawing context for the PDF backend.
399b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org*/
4070d1554d8ea08ddb887550f98b9cfd0afd395d65halcanaryclass SkPDFDevice final : public SkBaseDevice {
419b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgpublic:
42a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    /** Create a PDF drawing context.  SkPDFDevice applies a
43a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *  scale-and-translate transform to move the origin from the
44a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *  bottom left (PDF default) to the top left (Skia default).
45a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *  @param pageSize Page size in point units.
46a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         1 point == 127/360 mm == 1/72 inch
47a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *  @param rasterDpi the DPI at which features without native PDF
48a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         support will be rasterized (e.g. draw image with
49a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         perspective, draw text with perspective, ...).  A
50a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         larger DPI would create a PDF that reflects the
51a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         original intent with better fidelity, but it can make
52a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         for larger PDF files too, which would use more memory
53a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         while rendering, and it would be slower to be processed
54a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         or sent online or to printer.  A good choice is
55a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary     *         SK_ScalarDefaultRasterDPI(72.0f).
56989da4a32cd6823359f31c971c3b3f31425e905ehalcanary     *  @param SkPDFDocument.  A non-null pointer back to the
57989da4a32cd6823359f31c971c3b3f31425e905ehalcanary     *         document.  The document is repsonsible for
58989da4a32cd6823359f31c971c3b3f31425e905ehalcanary     *         de-duplicating across pages (via the SkPDFCanon) and
59989da4a32cd6823359f31c971c3b3f31425e905ehalcanary     *         for early serializing of large immutable objects, such
60989da4a32cd6823359f31c971c3b3f31425e905ehalcanary     *         as images (via SkPDFDocument::serialize()).
619b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
62a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    static SkPDFDevice* Create(SkISize pageSize,
63a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary                               SkScalar rasterDpi,
64989da4a32cd6823359f31c971c3b3f31425e905ehalcanary                               SkPDFDocument* doc) {
65989da4a32cd6823359f31c971c3b3f31425e905ehalcanary        return new SkPDFDevice(pageSize, rasterDpi, doc, true);
66a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    }
67a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary
68a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    /** Create a PDF drawing context without fipping the y-axis. */
69a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    static SkPDFDevice* CreateUnflipped(SkISize pageSize,
70a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary                                        SkScalar rasterDpi,
71989da4a32cd6823359f31c971c3b3f31425e905ehalcanary                                        SkPDFDocument* doc) {
72989da4a32cd6823359f31c971c3b3f31425e905ehalcanary        return new SkPDFDevice(pageSize, rasterDpi, doc, false);
73a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    }
74a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary
75a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    virtual ~SkPDFDevice();
769b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
779b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    /** These are called inside the per-device-layer loop for each draw call.
789b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     When these are called, we have already applied any saveLayer operations,
799b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     and are handling any looping from the paint, and any effects from the
809b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     DrawFilter.
819b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
8236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void drawPaint(const SkDraw&, const SkPaint& paint) override;
83fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
84fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina                    size_t count, const SkPoint[],
8536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                    const SkPaint& paint) override;
8636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
8736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
8836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
89fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawPath(const SkDraw&, const SkPath& origpath,
90fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina                  const SkPaint& paint, const SkMatrix* prePathMatrix,
9136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                  bool pathIsMutable) override;
92562fe4767cc73e08a4e039362bc0336aea66ecfbreed    void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, const SkRect* src,
93562fe4767cc73e08a4e039362bc0336aea66ecfbreed                        const SkRect& dst, const SkPaint&, SkCanvas::SrcRectConstraint) override;
94fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
9536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                    const SkMatrix& matrix, const SkPaint&) override;
96fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
9736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                    const SkPaint& paint) override;
987a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    void drawImage(const SkDraw&,
997a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                   const SkImage*,
1007a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                   SkScalar x,
1017a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                   SkScalar y,
1027a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                   const SkPaint&) override;
1037a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    void drawImageRect(const SkDraw&,
1047a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                       const SkImage*,
1057a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                       const SkRect* src,
1067a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                       const SkRect& dst,
1077a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                       const SkPaint&,
1087a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                       SkCanvas::SrcRectConstraint) override;
109fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawText(const SkDraw&, const void* text, size_t len,
11036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                  SkScalar x, SkScalar y, const SkPaint&) override;
111fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawPosText(const SkDraw&, const void* text, size_t len,
112fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina                     const SkScalar pos[], int scalarsPerPos,
11336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                     const SkPoint& offset, const SkPaint&) override;
114fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawVertices(const SkDraw&, SkCanvas::VertexMode,
115fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina                      int vertexCount, const SkPoint verts[],
116fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina                      const SkPoint texs[], const SkColor colors[],
117fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina                      SkXfermode* xmode, const uint16_t indices[],
11836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                      int indexCount, const SkPaint& paint) override;
119fa4f6cba2f9260cec345ec51fb3687c20c50fa61tfarina    void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
12036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                    const SkPaint&) override;
1219b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
12236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkImageInfo imageInfo() const override;
12340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com
1249b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    // PDF specific methods.
1259b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1268103a34300c5de2e85793a96c4738a33fc6eb46dhalcanary    /** Create the resource dictionary for this device. */
1278103a34300c5de2e85793a96c4738a33fc6eb46dhalcanary    sk_sp<SkPDFDict> makeResourceDict() const;
1289b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
129f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org    /** Get the fonts used on this device.
130f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org     */
1314e4e8160459f68c1795f2297bcec6f7866e01fa8halcanary    const SkTDArray<SkPDFFont*>& getFontResources() const;
132f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org
133ef6c50a80f77e6da84e198a34755dd42b1b0cf1ewangxianzhu    /** Add our annotations (link to urls and destinations) to the supplied
134ef6c50a80f77e6da84e198a34755dd42b1b0cf1ewangxianzhu     *  array.
135ef6c50a80f77e6da84e198a34755dd42b1b0cf1ewangxianzhu     *  @param array Array to add annotations to.
136ef6c50a80f77e6da84e198a34755dd42b1b0cf1ewangxianzhu     */
137ef6c50a80f77e6da84e198a34755dd42b1b0cf1ewangxianzhu    void appendAnnotations(SkPDFArray* array) const;
138ef6c50a80f77e6da84e198a34755dd42b1b0cf1ewangxianzhu
139b58772f86659cfe0e8d9247fcee878dddd8fdad9epoger@google.com    /** Add our named destinations to the supplied dictionary.
140b58772f86659cfe0e8d9247fcee878dddd8fdad9epoger@google.com     *  @param dict  Dictionary to add destinations to.
141b58772f86659cfe0e8d9247fcee878dddd8fdad9epoger@google.com     *  @param page  The PDF object representing the page for this device.
142b58772f86659cfe0e8d9247fcee878dddd8fdad9epoger@google.com     */
1436d622703e578eddc64ab4e3340d0ab0033268799halcanary    void appendDestinations(SkPDFDict* dict, SkPDFObject* page) const;
144b58772f86659cfe0e8d9247fcee878dddd8fdad9epoger@google.com
1458103a34300c5de2e85793a96c4738a33fc6eb46dhalcanary    /** Returns a copy of the media box for this device. */
1468103a34300c5de2e85793a96c4738a33fc6eb46dhalcanary    sk_sp<SkPDFArray> copyMediaBox() const;
1479b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1488103a34300c5de2e85793a96c4738a33fc6eb46dhalcanary    /** Returns a SkStream with the page contents.
1499b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
1505f939ab658a228dce34a3b14a545638407150b92mtklein    std::unique_ptr<SkStreamAsset> content() const;
1519b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
152334fcbc167237f02058cb508cb5f51b718141461halcanary    /** Writes the page contents to the stream. */
1534e4e8160459f68c1795f2297bcec6f7866e01fa8halcanary    void writeContent(SkWStream*) const;
1549859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
1554e4e8160459f68c1795f2297bcec6f7866e01fa8halcanary    const SkMatrix& initialTransform() const {
1563509f050810ab95cc36265f3b486b9569799041dvandebo@chromium.org        return fInitialTransform;
1573509f050810ab95cc36265f3b486b9569799041dvandebo@chromium.org    }
15861d267879bdf85c84b05f0519eb53b9322abbf0evandebo@chromium.org
159989da4a32cd6823359f31c971c3b3f31425e905ehalcanary    SkPDFCanon* getCanon() const;
16026b5d15dab81883fac05a2d3685ca6e3a3459678halcanary
1612be7e01382ee9c036de9c09585677dfd25d70253halcanary    // It is important to not confuse GraphicStateEntry with SkPDFGraphicState, the
1622be7e01382ee9c036de9c09585677dfd25d70253halcanary    // later being our representation of an object in the PDF file.
1632be7e01382ee9c036de9c09585677dfd25d70253halcanary    struct GraphicStateEntry {
1642be7e01382ee9c036de9c09585677dfd25d70253halcanary        GraphicStateEntry();
1652be7e01382ee9c036de9c09585677dfd25d70253halcanary
1662be7e01382ee9c036de9c09585677dfd25d70253halcanary        // Compare the fields we care about when setting up a new content entry.
1672be7e01382ee9c036de9c09585677dfd25d70253halcanary        bool compareInitialState(const GraphicStateEntry& b);
1682be7e01382ee9c036de9c09585677dfd25d70253halcanary
1692be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkMatrix fMatrix;
1702be7e01382ee9c036de9c09585677dfd25d70253halcanary        // We can't do set operations on Paths, though PDF natively supports
1712be7e01382ee9c036de9c09585677dfd25d70253halcanary        // intersect.  If the clip stack does anything other than intersect,
1722be7e01382ee9c036de9c09585677dfd25d70253halcanary        // we have to fall back to the region.  Treat fClipStack as authoritative.
1732be7e01382ee9c036de9c09585677dfd25d70253halcanary        // See https://bugs.skia.org/221
1742be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkClipStack fClipStack;
1752be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkRegion fClipRegion;
1762be7e01382ee9c036de9c09585677dfd25d70253halcanary
1772be7e01382ee9c036de9c09585677dfd25d70253halcanary        // When emitting the content entry, we will ensure the graphic state
1782be7e01382ee9c036de9c09585677dfd25d70253halcanary        // is set to these values first.
1792be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkColor fColor;
1802be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkScalar fTextScaleX;  // Zero means we don't care what the value is.
1812be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkPaint::Style fTextFill;  // Only if TextScaleX is non-zero.
1822be7e01382ee9c036de9c09585677dfd25d70253halcanary        int fShaderIndex;
1832be7e01382ee9c036de9c09585677dfd25d70253halcanary        int fGraphicStateIndex;
1842be7e01382ee9c036de9c09585677dfd25d70253halcanary
1852be7e01382ee9c036de9c09585677dfd25d70253halcanary        // We may change the font (i.e. for Type1 support) within a
1862be7e01382ee9c036de9c09585677dfd25d70253halcanary        // ContentEntry.  This is the one currently in effect, or nullptr if none.
1872be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkPDFFont* fFont;
1882be7e01382ee9c036de9c09585677dfd25d70253halcanary        // In PDF, text size has no default value. It is only valid if fFont is
1892be7e01382ee9c036de9c09585677dfd25d70253halcanary        // not nullptr.
1902be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkScalar fTextSize;
1912be7e01382ee9c036de9c09585677dfd25d70253halcanary    };
1922be7e01382ee9c036de9c09585677dfd25d70253halcanary
19373a7ea3ae0d37ee28f90d6b38c49fda052638253edisonn@google.comprotected:
194e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
19573a7ea3ae0d37ee28f90d6b38c49fda052638253edisonn@google.com
196f70b531daaf47db1ee95c70da9843f1dd1f418d3reed    void drawAnnotation(const SkDraw&, const SkRect&, const char key[], SkData* value) override;
197f70b531daaf47db1ee95c70da9843f1dd1f418d3reed
198e51c356ae4e074b9c286c50a4efce11205f7463creed    void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override;
199e51c356ae4e074b9c286c50a4efce11205f7463creed    sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
200e51c356ae4e074b9c286c50a4efce11205f7463creed    sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
201e51c356ae4e074b9c286c50a4efce11205f7463creed    sk_sp<SkSpecialImage> snapSpecial() override;
202e51c356ae4e074b9c286c50a4efce11205f7463creed
2039b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgprivate:
20491fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary    struct RectWithData {
20591fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary        SkRect rect;
206d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        sk_sp<SkData> data;
20791fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary        RectWithData(const SkRect& rect, SkData* data)
20891fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary            : rect(rect), data(SkRef(data)) {}
209d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        RectWithData(RectWithData&& other)
210d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            : rect(other.rect), data(std::move(other.data)) {}
211d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        RectWithData& operator=(RectWithData&& other) {
212d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            rect = other.rect;
213d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            data = std::move(other.data);
214d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            return *this;
215d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        }
21691fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary    };
21791fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary
21891fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary    struct NamedDestination {
219d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        sk_sp<SkData> nameData;
22091fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary        SkPoint point;
22191fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary        NamedDestination(SkData* nameData, const SkPoint& point)
22291fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary            : nameData(SkRef(nameData)), point(point) {}
223d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        NamedDestination(NamedDestination&& other)
224d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            : nameData(std::move(other.nameData)), point(other.point) {}
225d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        NamedDestination& operator=(NamedDestination&& other) {
226d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            nameData = std::move(other.nameData);
227d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            point = other.point;
228d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary            return *this;
229d7b2885b90c6d248d8188cdb3720ea9150568a89halcanary        }
23091fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary    };
23191fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary
232769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    // TODO(vandebo): push most of SkPDFDevice's state into a core object in
233b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org    // order to get the right access levels without using friend.
23413d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org    friend class ScopedContentEntry;
235a0c7edbb0804144ab320951db5c741eea247fc0fvandebo@chromium.org
236152612938020fa46999f33668027d5bc0f7afd18ctguil@chromium.org    SkISize fPageSize;
2379fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org    SkISize fContentSize;
23875f97e452e8f2ee55cd2b283df7d7734f48bc2bfvandebo@chromium.org    SkMatrix fInitialTransform;
2399fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org    SkClipStack fExistingClipStack;
2409fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org    SkRegion fExistingClipRegion;
241ef6c50a80f77e6da84e198a34755dd42b1b0cf1ewangxianzhu
24291fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary    SkTArray<RectWithData> fLinkToURLs;
24391fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary    SkTArray<RectWithData> fLinkToDestinations;
24491fcb3ed58845ddd5afa98a7150f3024d87c7425halcanary    SkTArray<NamedDestination> fNamedDestinations;
2459b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
246be27a118c277af23377d38e9b3bfd3fcc276114fhalcanary    SkTDArray<SkPDFObject*> fGraphicStateResources;
2479b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    SkTDArray<SkPDFObject*> fXObjectResources;
24828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    SkTDArray<SkPDFFont*> fFontResources;
249421d6443fbd3a913dfa32b6492c4a2969bc6314bvandebo@chromium.org    SkTDArray<SkPDFObject*> fShaderResources;
2509b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
2512be7e01382ee9c036de9c09585677dfd25d70253halcanary    struct ContentEntry {
2522be7e01382ee9c036de9c09585677dfd25d70253halcanary        GraphicStateEntry fState;
2532be7e01382ee9c036de9c09585677dfd25d70253halcanary        SkDynamicMemoryWStream fContent;
2542be7e01382ee9c036de9c09585677dfd25d70253halcanary    };
2552be7e01382ee9c036de9c09585677dfd25d70253halcanary    SkSinglyLinkedList<ContentEntry> fContentEntries;
2568dcf74f27690476193f5d4ca34fba2e87ca7c98dctguil@chromium.org
2578c294900f31d8d032b62182f011019276d27d5d0commit-bot@chromium.org    SkScalar fRasterDpi;
258d9dfa18372119c8e1318125d2075fa80e0819094edisonn@google.com
259989da4a32cd6823359f31c971c3b3f31425e905ehalcanary    SkPDFDocument* fDocument;
260a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    ////////////////////////////////////////////////////////////////////////////
261a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary
262a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary    SkPDFDevice(SkISize pageSize,
263a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary                SkScalar rasterDpi,
264989da4a32cd6823359f31c971c3b3f31425e905ehalcanary                SkPDFDocument* doc,
265a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary                bool flip);
266a1f1ee98a1f6d0770f6243270ca2f0e6c92efabahalcanary
26736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
268e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com
26977bcaa324a574584331322d98768582d9232f7fcvandebo@chromium.org    void init();
2703c35fb3310c22eb0141c8f39c5423f7bcd42adffhalcanary    void cleanUp();
2714b1e17edc78c0313d5cb8a415f816f654cdfa417halcanary    sk_sp<SkPDFObject> makeFormXObjectFromDevice();
2729fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org
2733b416216d1e90cb8b1bba41bb95806fe2d40da88vandebo@chromium.org    void drawFormXObjectWithMask(int xObjectIndex,
2744b1e17edc78c0313d5cb8a415f816f654cdfa417halcanary                                 SkPDFObject* mask,
275481aef68333e01c19badda456d8e60bd1f1bee2avandebo@chromium.org                                 const SkClipStack* clipStack,
276481aef68333e01c19badda456d8e60bd1f1bee2avandebo@chromium.org                                 const SkRegion& clipRegion,
2773b416216d1e90cb8b1bba41bb95806fe2d40da88vandebo@chromium.org                                 SkXfermode::Mode mode,
278481aef68333e01c19badda456d8e60bd1f1bee2avandebo@chromium.org                                 bool invertClip);
279466f3d66f09285d2d988315bacde573a5359ce54vandebo@chromium.org
280b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org    // If the paint or clip is such that we shouldn't draw anything, this
28196fcdcc219d2a0d3579719b84b28bede76efba64halcanary    // returns nullptr and does not create a content entry.
282b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org    // setUpContentEntry and finishContentEntry can be used directly, but
28313d14a9dbd2cf0a9654045cc967e92626690631avandebo@chromium.org    // the preferred method is to use the ScopedContentEntry helper class.
284b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org    ContentEntry* setUpContentEntry(const SkClipStack* clipStack,
285b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org                                    const SkRegion& clipRegion,
286b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org                                    const SkMatrix& matrix,
287b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org                                    const SkPaint& paint,
288b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org                                    bool hasText,
2894b1e17edc78c0313d5cb8a415f816f654cdfa417halcanary                                    SkPDFObject** dst);
290b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org    void finishContentEntry(SkXfermode::Mode xfermode,
2914b1e17edc78c0313d5cb8a415f816f654cdfa417halcanary                            SkPDFObject* dst,
2923b416216d1e90cb8b1bba41bb95806fe2d40da88vandebo@chromium.org                            SkPath* shape);
293481aef68333e01c19badda456d8e60bd1f1bee2avandebo@chromium.org    bool isContentEmpty();
294481aef68333e01c19badda456d8e60bd1f1bee2avandebo@chromium.org
2959fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org    void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
2969fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org                                            const SkClipStack& clipStack,
2979fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org                                            const SkRegion& clipRegion,
2989fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org                                            const SkPaint& paint,
2999fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org                                            bool hasText,
3009fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org                                            GraphicStateEntry* entry);
301be27a118c277af23377d38e9b3bfd3fcc276114fhalcanary    int addGraphicStateResource(SkPDFObject* gs);
3023b416216d1e90cb8b1bba41bb95806fe2d40da88vandebo@chromium.org    int addXObjectResource(SkPDFObject* xObject);
3039fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org
3048e0c1500a78f450115ce1a8de438d66e2e892cdcrobertphillips    void updateFont(const SkPaint& paint, uint16_t glyphID, ContentEntry* contentEntry);
3059db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
3069fbdf875183f5142b8e0ba46ab430cc46ad701bfvandebo@chromium.org
307b069c8cfcd5df285193eb334b3bc33438782e8davandebo@chromium.org    void internalDrawPaint(const SkPaint& paint, ContentEntry* contentEntry);
308a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary
309a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    void internalDrawImage(const SkMatrix& origMatrix,
3107a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                           const SkClipStack* clipStack,
311a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary                           const SkRegion& origClipRegion,
312a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary                           SkImageBitmap imageBitmap,
3137a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                           const SkPaint& paint);
3149b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
31592ffe7d10ef5db05f1f4ffef0cfe898169ba13bfcommit-bot@chromium.org    bool handleInversePath(const SkDraw& d, const SkPath& origPath,
316a9ebd161a7c08515f0c4bd885e61c4b52688ececedisonn@google.com                           const SkPaint& paint, bool pathIsMutable,
31796fcdcc219d2a0d3579719b84b28bede76efba64halcanary                           const SkMatrix* prePathMatrix = nullptr);
318f70b531daaf47db1ee95c70da9843f1dd1f418d3reed    void handlePointAnnotation(const SkPoint&, const SkMatrix&, const char key[], SkData* value);
319f70b531daaf47db1ee95c70da9843f1dd1f418d3reed    void handlePathAnnotation(const SkPath&, const SkDraw& d, const char key[], SkData* value);
320238be8c7e5de5a83517440a3db7f7965b47fb010vandebo@chromium.org
32189443aba5bfa2b040dc9fd24938b7d0b3decd737reed    typedef SkBaseDevice INHERITED;
3225e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org
3235e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org    // TODO(edisonn): Only SkDocument_PDF and SkPDFImageShader should be able to create
3245e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org    // an SkPDFDevice
3255e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org    //friend class SkDocument_PDF;
3265e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org    //friend class SkPDFImageShader;
3279b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org};
3289b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
3299b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#endif
330