SkPDFDevice.h revision 28be72b63e457c680c192a34fb9f58e1c693363f
19b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org/*
27e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org * Copyright (C) 2010 The Android Open Source Project
39b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org *
49b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
59b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * you may not use this file except in compliance with the License.
69b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * You may obtain a copy of the License at
79b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org *
89b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org *      http://www.apache.org/licenses/LICENSE-2.0
99b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org *
109b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * Unless required by applicable law or agreed to in writing, software
119b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
129b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * See the License for the specific language governing permissions and
149b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * limitations under the License.
159b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org */
169b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
179b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#ifndef SkPDFDevice_DEFINED
189b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#define SkPDFDevice_DEFINED
199b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
209b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkRefCnt.h"
219b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkDevice.h"
229b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkString.h"
23a518086928494319b8968abc09808eff492c194fvandebo@chromium.org#include "SkPaint.h"
24a518086928494319b8968abc09808eff492c194fvandebo@chromium.org#include "SkPath.h"
259b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
269b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFArray;
279b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFDevice;
289b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFDict;
2928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgclass SkPDFFont;
309b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFGraphicState;
319b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFObject;
329b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFStream;
339b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
349b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFDeviceFactory : public SkDeviceFactory {
359b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual SkDevice* newDevice(SkBitmap::Config config, int width, int height,
369b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                                bool isOpaque, bool isForLayer);
379b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org};
389b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
399b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org/** \class SkPDFDevice
409b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
419b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    The drawing context for the PDF backend.
429b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org*/
439b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgclass SkPDFDevice : public SkDevice {
449b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgpublic:
459b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    /** Create a PDF drawing context with the given width and height.
469b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     *  72 points/in means letter paper is 612x792.
479b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     *  @param width  Page width in points.
489b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     *  @param height Page height in points.
499b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
509b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    SkPDFDevice(int width, int height);
519b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual ~SkPDFDevice();
529b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
539b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual SkDeviceFactory* getDeviceFactory() {
549b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        return SkNEW(SkPDFDeviceFactory);
559b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    }
569b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
5735fc62b960db6739b19c59576085663796951e47vandebo@chromium.org    virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
5835fc62b960db6739b19c59576085663796951e47vandebo@chromium.org
599b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual int width() const { return fWidth; };
609b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
619b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual int height() const { return fHeight; };
629b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
639b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    /** Called with the correct matrix and clip before this device is drawn
649b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        to using those settings. If your subclass overrides this, be sure to
659b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        call through to the base class as well.
669b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    */
679b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void setMatrixClip(const SkMatrix&, const SkRegion&);
689b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
699b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    /** These are called inside the per-device-layer loop for each draw call.
709b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     When these are called, we have already applied any saveLayer operations,
719b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     and are handling any looping from the paint, and any effects from the
729b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     DrawFilter.
739b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
749b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawPaint(const SkDraw&, const SkPaint& paint);
759b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
769b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                            size_t count, const SkPoint[],
779b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                            const SkPaint& paint);
789b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
799b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawPath(const SkDraw&, const SkPath& path,
809b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                          const SkPaint& paint);
819b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
829b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                            const SkMatrix& matrix, const SkPaint& paint);
839b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
849b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                            const SkPaint& paint);
859b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawText(const SkDraw&, const void* text, size_t len,
869b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                          SkScalar x, SkScalar y, const SkPaint& paint);
879b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
889b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                             const SkScalar pos[], SkScalar constY,
899b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                             int scalarsPerPos, const SkPaint& paint);
909b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
919b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                                const SkPath& path, const SkMatrix* matrix,
929b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                                const SkPaint& paint);
939b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
949b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                              int vertexCount, const SkPoint verts[],
959b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                              const SkPoint texs[], const SkColor colors[],
969b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                              SkXfermode* xmode, const uint16_t indices[],
979b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                              int indexCount, const SkPaint& paint);
989b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
999b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                            const SkPaint&);
1009b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1019b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    // PDF specific methods.
1029b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1039b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    /** Returns a reference to the resource dictionary for this device.
1049b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
1059b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    const SkRefPtr<SkPDFDict>& getResourceDict();
1069b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
107a518086928494319b8968abc09808eff492c194fvandebo@chromium.org    /** Get the list of resources (PDF objects) used on this page.
108a518086928494319b8968abc09808eff492c194fvandebo@chromium.org     *  @param resourceList A list to append the resources to.
1099b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
110a518086928494319b8968abc09808eff492c194fvandebo@chromium.org    void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
1119b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1129b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    /** Returns the media box for this device.
1139b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
114a518086928494319b8968abc09808eff492c194fvandebo@chromium.org    SkRefPtr<SkPDFArray> getMediaBox() const;
1159b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1169b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    /** Returns a string with the page contents.
117ddbbd805b5b453e12cda0b3300e5655d8fb2bc19vandebo@chromium.org     *  @param flipOrigin  Flip the origin between top and bottom.
1189b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org     */
119ddbbd805b5b453e12cda0b3300e5655d8fb2bc19vandebo@chromium.org    SkString content(bool flipOrigin) const;
1209b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1219b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgprivate:
1229b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    int fWidth;
1239b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    int fHeight;
1249b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    SkRefPtr<SkPDFDict> fResourceDict;
1259b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1269b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
1279b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    SkTDArray<SkPDFObject*> fXObjectResources;
12828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    SkTDArray<SkPDFFont*> fFontResources;
1299b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1307e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // In PDF, transforms and clips can only be undone by popping the graphic
1317e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // state to before the transform or clip was applied.  Because it can be
1327e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // a lot of work to reapply a clip and because this class has to apply
1337e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // different transforms to accomplish various operations, the clip is
1347e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // always applied before a transform and always at a different graphic
1357e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // state-stack level than a transform.  This strategy results in the
1367e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // following possible states for the graphic state stack:
1377e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // empty:  (identity transform and clip to page)
1387e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // one entry: a transform
1397e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // one entry: a clip
1407e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    // two entries: a clip and then a transform
1417e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    struct GraphicStackEntry {
1427e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org        SkColor fColor;
14328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org        SkScalar fTextSize;
1447e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org        SkScalar fTextScaleX;
14528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org        SkPaint::Style fTextFill;
14628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org        SkRefPtr<SkPDFFont> fFont;
1477e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org        SkRefPtr<SkPDFGraphicState> fGraphicState;
1487e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org        SkRegion fClip;
1497e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org        SkMatrix fTransform;
1507e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    };
1517e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    struct GraphicStackEntry fGraphicStack[3];
1527e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    int fGraphicStackIndex;
1539b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1547e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    SkString fContent;
1559b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
15628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    void updateGSFromPaint(const SkPaint& newPaint, bool forText);
15728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    int getFontResourceIndex(uint32_t fontID);
1589b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1599b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    void moveTo(SkScalar x, SkScalar y);
1609b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    void appendLine(SkScalar x, SkScalar y);
1619b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    void appendCubic(SkScalar ctl1X, SkScalar ctl1Y,
1629b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                     SkScalar ctl2X, SkScalar ctl2Y,
1639b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                     SkScalar dstX, SkScalar dstY);
1649b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    void appendRectangle(SkScalar x, SkScalar y, SkScalar w, SkScalar h);
1657e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    void emitPath(const SkPath& path);
1669b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    void closePath();
167a518086928494319b8968abc09808eff492c194fvandebo@chromium.org    void paintPath(SkPaint::Style style, SkPath::FillType fill);
1687e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    void strokePath();
1697e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    void pushGS();
1707e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    void popGS();
17128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
1729b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
1739b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org                            const SkPaint& paint);
1749b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1757e2ff7cf7da604b29378978ef5d4655499485368vandebo@chromium.org    SkMatrix setTransform(const SkMatrix& matrix);
1769b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org};
1779b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
1789b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#endif
179