code:
/* libs/graphics/animator/SkMemberInfo.h
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#ifndef SkMemberInfo_DEFINED
#define SkMemberInfo_DEFINED

#if defined SK_BUILD_CONDENSED
    #define SK_USE_CONDENSED_INFO 0
#endif

#include "SkDisplayType.h"
#include "SkScript.h"
#include "SkString.h"
#include "SkIntArray.h"

class SkAnimateMaker;
class SkDisplayable;
class SkScriptEngine;

// temporary hacks until name change is more complete
#define SkFloat SkScalar
#define SkInt SkS32

struct SkMemberInfo {
    //!!! alternative:
    // if fCount == 0, record is member property
    // then fType can be type, so caller doesn't have to check
#if SK_USE_CONDENSED_INFO == 0
    const char* fName;  // may be NULL for anonymous functions
    size_t fOffset; // if negative, is index into member pointer table (for properties and functions)
    SkDisplayTypes fType;
    int fCount;         // for properties, actual type (count is always assumed to be 1)
#else
    unsigned char fName;
    signed char fOffset;
    unsigned char fType;
    signed char fCount;
#endif
    SkDisplayTypes arrayType() const {
        SkASSERT(fType == SkType_Array);
        return (SkDisplayTypes) fCount;  // hack, but worth it?
    }
    int functionIndex() const {
        SkASSERT(fType == SkType_MemberFunction);
        return (signed) fOffset > 0 ? -1 + (int) fOffset : -1 - (int) fOffset;
    }
    bool getArrayValue(const SkDisplayable* displayable, int index, SkOperand* value) const;
    int getCount() const {
        return fType == SkType_MemberProperty || fType == SkType_Array ||
            fType == SkType_MemberFunction ? 1 : fCount;
    }
    const SkMemberInfo* getInherited() const;
    size_t getSize(const SkDisplayable* ) const;
    void getString(const SkDisplayable* , SkString** string) const;
    SkDisplayTypes getType() const {
        return fType == SkType_MemberProperty || fType == SkType_Array ||
            fType == SkType_MemberFunction ? (SkDisplayTypes) fCount : (SkDisplayTypes) fType;
    }
    void getValue(const SkDisplayable* , SkOperand values[], int count) const;
    bool isEnum() const;
    const char* mapEnums(const char* match, int* value) const;
    void* memberData(const SkDisplayable* displayable) const {
        SkASSERT(fType != SkType_MemberProperty &&  fType != SkType_MemberFunction);
        return (void*) ((const char*) displayable + fOffset);
    }
    int propertyIndex() const {
        SkASSERT(fType == SkType_MemberProperty);
        return (signed) fOffset > 0 ? -1 + (int) fOffset : -1 - (int) fOffset;
    }
    SkDisplayTypes propertyType() const {
        SkASSERT(fType == SkType_MemberProperty || fType == SkType_Array);
        return (SkDisplayTypes) fCount;  // hack, but worth it?
    }
    void setMemberData(SkDisplayable* displayable, const void* child, size_t size) const {
        SkASSERT(fType != SkType_MemberProperty &&  fType != SkType_MemberFunction);
        memcpy((char*) displayable + fOffset, child, size);
    }
    void setString(SkDisplayable* , SkString* ) const;
    void setValue(SkDisplayable* , const SkOperand values[], int count) const;
    bool setValue(SkAnimateMaker& , SkTDOperandArray* storage,
        int storageOffset, int maxStorage, SkDisplayable* ,
        SkDisplayTypes outType, const char value[], size_t len) const;
    bool setValue(SkAnimateMaker& , SkTDOperandArray* storage,
        int storageOffset, int maxStorage, SkDisplayable* ,
        SkDisplayTypes outType, SkString& str) const;
//  void setValue(SkDisplayable* , const char value[], const char name[]) const;
    bool writeValue(SkDisplayable* displayable, SkTDOperandArray* arrayStorage,
        int storageOffset, int maxStorage, void* untypedStorage, SkDisplayTypes outType,
        SkScriptValue& scriptValue) const;
#if SK_USE_CONDENSED_INFO == 0
    static const SkMemberInfo* Find(const SkMemberInfo [], int count, int* index);
    static const SkMemberInfo* Find(const SkMemberInfo [], int count, const char** name);
#else
    static const SkMemberInfo* Find(SkDisplayTypes type, int* index);
    static const SkMemberInfo* Find(SkDisplayTypes type, const char** name);
#endif
    static size_t GetSize(SkDisplayTypes type); // size of simple types only
//  static bool SetValue(void* value, const char* name, SkDisplayTypes , int count);
};

#define SK_MEMBER(_member, _type) \
    { #_member, SK_OFFSETOF(BASE_CLASS, _member), SkType_##_type, \
    sizeof(((BASE_CLASS*) 1)->_member) / sizeof(SkScalar) }

#define SK_MEMBER_ALIAS(_member, _alias, _type) \
    { #_member, SK_OFFSETOF(BASE_CLASS, _alias), SkType_##_type, \
    sizeof(((BASE_CLASS*) 1)->_alias) / sizeof(SkScalar) }

#define SK_MEMBER_ARRAY(_member, _type) \
    { #_member, SK_OFFSETOF(BASE_CLASS, _member), SkType_Array, \
    (int) SkType_##_type }

#define SK_MEMBER_INHERITED \
    { (const char*) INHERITED::fInfo, 0, SkType_BaseClassInfo, INHERITED::fInfoCount }

// #define SK_MEMBER_KEY_TYPE(_member, _type)
//  {#_member, (size_t) -1, SkType_##_type, 0}

#define SK_FUNCTION(_member) \
    k_##_member##Function

#define SK_PROPERTY(_member) \
    k_##_member##Property

#define SK_MEMBER_DYNAMIC_FUNCTION(_member, _type) \
    {#_member, (size_t) (+1 + SK_FUNCTION(_member)), SkType_MemberFunction, \
    (int) SkType_##_type }

#define SK_MEMBER_DYNAMIC_PROPERTY(_member, _type) \
    {#_member, (size_t) (1 + SK_PROPERTY(_member)), SkType_MemberProperty, \
    (int) SkType_##_type }

#define SK_MEMBER_FUNCTION(_member, _type) \
    {#_member, (size_t) (-1 - SK_FUNCTION(_member)), SkType_MemberFunction, \
    (int) SkType_##_type }

#define SK_MEMBER_PROPERTY(_member, _type) \
    {#_member, (size_t) (-1 - SK_PROPERTY(_member)), SkType_MemberProperty, \
    (int) SkType_##_type }

#if SK_USE_CONDENSED_INFO == 0

#define DECLARE_PRIVATE_MEMBER_INFO(_type) \
public: \
    static const SkMemberInfo fInfo[]; \
    static const int fInfoCount; \
    virtual const SkMemberInfo* getMember(int index); \
    virtual const SkMemberInfo* getMember(const char name[]); \
    typedef Sk##_type BASE_CLASS

#define DECLARE_MEMBER_INFO(_type) \
public: \
    static const SkMemberInfo fInfo[]; \
    static const int fInfoCount; \
    virtual const SkMemberInfo* getMember(int index); \
    virtual const SkMemberInfo* getMember(const char name[]); \
    virtual SkDisplayTypes getType() const { return SkType_##_type; } \
    typedef Sk##_type BASE_CLASS

#define DECLARE_DRAW_MEMBER_INFO(_type) \
public: \
    static const SkMemberInfo fInfo[]; \
    static const int fInfoCount; \
    virtual const SkMemberInfo* getMember(int index); \
    virtual const SkMemberInfo* getMember(const char name[]); \
    virtual SkDisplayTypes getType() const { return SkType_##_type; } \
    typedef SkDraw##_type BASE_CLASS

#define DECLARE_DISPLAY_MEMBER_INFO(_type) \
public: \
    static const SkMemberInfo fInfo[]; \
    static const int fInfoCount; \
    virtual const SkMemberInfo* getMember(int index); \
    virtual const SkMemberInfo* getMember(const char name[]); \
    virtual SkDisplayTypes getType() const { return SkType_##_type; } \
    typedef SkDisplay##_type BASE_CLASS

#define DECLARE_EMPTY_MEMBER_INFO(_type) \
public: \
    virtual SkDisplayTypes getType() const { return SkType_##_type; }

#define DECLARE_EXTRAS_MEMBER_INFO(_type) \
public: \
    static const SkMemberInfo fInfo[]; \
    static const int fInfoCount; \
    virtual const SkMemberInfo* getMember(int index); \
    virtual const SkMemberInfo* getMember(const char name[]); \
    SkDisplayTypes fType; \
    virtual SkDisplayTypes getType() const { return fType; } \
    typedef _type BASE_CLASS

#define DECLARE_NO_VIRTUALS_MEMBER_INFO(_type) \
public: \
    static const SkMemberInfo fInfo[]; \
    static const int fInfoCount; \
    typedef Sk##_type BASE_CLASS

#define DEFINE_GET_MEMBER(_class) \
    const SkMemberInfo* _class::getMember(int index) { \
        const SkMemberInfo* result = SkMemberInfo::Find(fInfo, SK_ARRAY_COUNT(fInfo), &index); \
        return result; \
    } \
    const SkMemberInfo* _class::getMember(const char name[]) { \
        const SkMemberInfo* result = SkMemberInfo::Find(fInfo, SK_ARRAY_COUNT(fInfo), &name); \
        return result; \
    } \
    const int _class::fInfoCount = SK_ARRAY_COUNT(fInfo)

#define DEFINE_NO_VIRTUALS_GET_MEMBER(_class) \
    const int _class::fInfoCount = SK_ARRAY_COUNT(fInfo)

#else

#define DECLARE_PRIVATE_MEMBER_INFO(_type) \
public: \
    typedef Sk##_type BASE_CLASS

#define DECLARE_MEMBER_INFO(_type) \
public: \
    virtual const SkMemberInfo* getMember(int index) { \
        return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \
    virtual const SkMemberInfo* getMember(const char name[]) { \
        return SkDisplayType::GetMember(NULL, SkType_##_type, &name); } \
    virtual SkDisplayTypes getType() const { return SkType_##_type; } \
    typedef Sk##_type BASE_CLASS

#define DECLARE_DRAW_MEMBER_INFO(_type) \
public: \
    virtual const SkMemberInfo* getMember(int index) { \
        return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \
    virtual const SkMemberInfo* getMember(const char name[]) { \
        return SkDisplayType::GetMember(NULL, SkType_##_type, &name); } \
    virtual SkDisplayTypes getType() const { return SkType_##_type; } \
    typedef SkDraw##_type BASE_CLASS

#define DECLARE_DISPLAY_MEMBER_INFO(_type) \
public: \
    virtual const SkMemberInfo* getMember(int index) { \
        return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \
    virtual const SkMemberInfo* getMember(const char name[]) { \
        return SkDisplayType::GetMember(NULL, SkType_##_type, &name); } \
    virtual SkDisplayTypes getType() const { return SkType_##_type; } \
    typedef SkDisplay##_type BASE_CLASS

#define DECLARE_EXTRAS_MEMBER_INFO(_type) \
public: \
    virtual const SkMemberInfo* getMember(int index) { \
        return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \
    virtual const SkMemberInfo* getMember(const char name[]) { \
        return SkDisplayType::GetMember(NULL, fType, &name); } \
    SkDisplayTypes fType; \
    virtual SkDisplayTypes getType() const { return fType; } \
    typedef _type BASE_CLASS

#define DECLARE_NO_VIRTUALS_MEMBER_INFO(_type) \
public: \
    typedef Sk##_type BASE_CLASS

#define DEFINE_GET_MEMBER(_class)
#define DEFINE_NO_VIRTUALS_GET_MEMBER(_class)

#endif

#endif // SkMemberInfo_DEFINED


code:
#ifndef SkMeshUtils_DEFINED
#define SkMeshUtils_DEFINED

#include "SkPoint.h"
#include "SkColor.h"

class SkBitmap;
class SkCanvas;
class SkPaint;

class SkMeshIndices {
public:
    SkMeshIndices();
    ~SkMeshIndices();

    bool init(int texW, int texH, int rows, int cols) {
        return this->init(NULL, NULL, texW, texH, rows, cols);
    }

    bool init(SkPoint tex[], uint16_t indices[],
              int texW, int texH, int rows, int cols);

    size_t          indexCount() const { return fIndexCount; }
    const uint16_t* indices() const { return fIndices; }

    size_t          texCount() const { return fTexCount; }
    const SkPoint*  tex() const { return fTex; }

private:
    size_t      fIndexCount, fTexCount;
    SkPoint*    fTex;
    uint16_t*   fIndices;
    void*       fStorage; // may be null
};

class SkMeshUtils {
public:
    static void Draw(SkCanvas*, const SkBitmap&, int rows, int cols,
                     const SkPoint verts[], const SkColor colors[],
                     const SkPaint& paint);
};

#endif

license: mit


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkMetaData_DEFINED
#define SkMetaData_DEFINED

#include "SkScalar.h"

class SkRefCnt;

class SK_API SkMetaData {
public:
    /**
     *  Used to manage the life-cycle of a ptr in the metadata. This is option
     *  in setPtr, and is only invoked when either copying one metadata to
     *  another, or when the metadata is destroyed.
     *
     *  setPtr(name, ptr, proc) {
     *      fPtr = proc(ptr, true);
     *  }
     *
     *  copy: A = B {
     *      A.fPtr = B.fProc(B.fPtr, true);
     *  }
     *
     *  ~SkMetaData {
     *      fProc(fPtr, false);
     *  }
     */
    typedef void* (*PtrProc)(void* ptr, bool doRef);

    /**
     *  Implements PtrProc for SkRefCnt pointers
     */
    static void* RefCntProc(void* ptr, bool doRef);

    SkMetaData();
    SkMetaData(const SkMetaData& src);
    ~SkMetaData();

    SkMetaData& operator=(const SkMetaData& src);

    void reset();

    bool findS32(const char name[], int32_t* value = NULL) const;
    bool findScalar(const char name[], SkScalar* value = NULL) const;
    const SkScalar* findScalars(const char name[], int* count,
                                SkScalar values[] = NULL) const;
    const char* findString(const char name[]) const;
    bool findPtr(const char name[], void** value = NULL, PtrProc* = NULL) const;
    bool findBool(const char name[], bool* value = NULL) const;
    const void* findData(const char name[], size_t* byteCount = NULL) const;

    bool hasS32(const char name[], int32_t value) const {
        int32_t v;
        return this->findS32(name, &v) && v == value;
    }
    bool hasScalar(const char name[], SkScalar value) const {
        SkScalar v;
        return this->findScalar(name, &v) && v == value;
    }
    bool hasString(const char name[], const char value[]) const {
        const char* v = this->findString(name);
        return  (v == NULL && value == NULL) ||
                (v != NULL && value != NULL && !strcmp(v, value));
    }
    bool hasPtr(const char name[], void* value) const {
        void* v;
        return this->findPtr(name, &v) && v == value;
    }
    bool hasBool(const char name[], bool value) const {
        bool    v;
        return this->findBool(name, &v) && v == value;
    }
    bool hasData(const char name[], const void* data, size_t byteCount) const {
        size_t len;
        const void* ptr = this->findData(name, &len);
        return NULL != ptr && len == byteCount && !memcmp(ptr, data, len);
    }

    void setS32(const char name[], int32_t value);
    void setScalar(const char name[], SkScalar value);
    SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL);
    void setString(const char name[], const char value[]);
    void setPtr(const char name[], void* value, PtrProc proc = NULL);
    void setBool(const char name[], bool value);
    // the data is copied from the input pointer.
    void setData(const char name[], const void* data, size_t byteCount);

    bool removeS32(const char name[]);
    bool removeScalar(const char name[]);
    bool removeString(const char name[]);
    bool removePtr(const char name[]);
    bool removeBool(const char name[]);
    bool removeData(const char name[]);

    // helpers for SkRefCnt
    bool findRefCnt(const char name[], SkRefCnt** ptr = NULL) {
        return this->findPtr(name, reinterpret_cast<void**>(ptr));
    }
    bool hasRefCnt(const char name[], SkRefCnt* ptr) {
        return this->hasPtr(name, ptr);
    }
    void setRefCnt(const char name[], SkRefCnt* ptr) {
        this->setPtr(name, ptr, RefCntProc);
    }
    bool removeRefCnt(const char name[]) {
        return this->removePtr(name);
    }

    enum Type {
        kS32_Type,
        kScalar_Type,
        kString_Type,
        kPtr_Type,
        kBool_Type,
        kData_Type,

        kTypeCount
    };

    struct Rec;
    class Iter;
    friend class Iter;

    class Iter {
    public:
        Iter() : fRec(NULL) {}
        Iter(const SkMetaData&);

        /** Reset the iterator, so that calling next() will return the first
            data element. This is done implicitly in the constructor.
        */
        void reset(const SkMetaData&);

        /** Each time next is called, it returns the name of the next data element,
            or null when there are no more elements. If non-null is returned, then the
            element's type is returned (if not null), and the number of data values
            is returned in count (if not null).
        */
        const char* next(Type*, int* count);

    private:
        Rec* fRec;
    };

public:
    struct Rec {
        Rec*        fNext;
        uint16_t    fDataCount; // number of elements
        uint8_t     fDataLen;   // sizeof a single element
        uint8_t     fType;

        const void* data() const { return (this + 1); }
        void*       data() { return (this + 1); }
        const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
        char*       name() { return (char*)this->data() + fDataLen * fDataCount; }

        static Rec* Alloc(size_t);
        static void Free(Rec*);
    };
    Rec*    fRec;

    const Rec* find(const char name[], Type) const;
    void* set(const char name[], const void* data, size_t len, Type, int count);
    bool remove(const char name[], Type);
};

#endif


code:
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkMovie_DEFINED
#define SkMovie_DEFINED

#include "SkRefCnt.h"
#include "SkCanvas.h"

class SkStream;

class SkMovie : public SkRefCnt {
public:
    /** Try to create a movie from the stream. If the stream format is not
        supported, return NULL.
    */
    static SkMovie* DecodeStream(SkStream*);
    /** Try to create a movie from the specified file path. If the file is not
        found, or the format is not supported, return NULL. If a movie is
        returned, the stream may be retained by the movie (via ref()) until
        the movie is finished with it (by calling unref()).
    */
    static SkMovie* DecodeFile(const char path[]);
    /** Try to create a movie from the specified memory.
        If the format is not supported, return NULL. If a movie is returned,
        the data will have been read or copied, and so the caller may free
        it.
    */
    static SkMovie* DecodeMemory(const void* data, size_t length);

    SkMSec  duration();
    int     width();
    int     height();
    int     isOpaque();

    /** Specify the time code (between 0...duration) to sample a bitmap
        from the movie. Returns true if this time code generated a different
        bitmap/frame from the previous state (i.e. true means you need to
        redraw).
    */
    bool setTime(SkMSec);

    // return the right bitmap for the current time code
    const SkBitmap& bitmap();

protected:
    struct Info {
        SkMSec  fDuration;
        int     fWidth;
        int     fHeight;
        bool    fIsOpaque;
    };

    virtual bool onGetInfo(Info*) = 0;
    virtual bool onSetTime(SkMSec) = 0;
    virtual bool onGetBitmap(SkBitmap*) = 0;

    // visible for subclasses
    SkMovie();

private:
    Info        fInfo;
    SkMSec      fCurrTime;
    SkBitmap    fBitmap;
    bool        fNeedBitmap;

    void ensureInfo();
};

#endif


code:
#ifndef SkNWayCanvas_DEFINED
#define SkNWayCanvas_DEFINED

#include "SkCanvas.h"

class SkNWayCanvas : public SkCanvas {
public:
    SkNWayCanvas();
    virtual ~SkNWayCanvas();

    void addCanvas(SkCanvas*);
    void removeCanvas(SkCanvas*);
    void removeAll();

    ///////////////////////////////////////////////////////////////////////////
    // These are forwarded to the N canvases we're referencing

    virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
    virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
                          SaveFlags flags = kARGB_ClipLayer_SaveFlag);
    virtual void restore();
    virtual bool translate(SkScalar dx, SkScalar dy);
    virtual bool scale(SkScalar sx, SkScalar sy);
    virtual bool rotate(SkScalar degrees);
    virtual bool skew(SkScalar sx, SkScalar sy);
    virtual bool concat(const SkMatrix& matrix);
    virtual void setMatrix(const SkMatrix& matrix);
    virtual bool clipRect(const SkRect& rect,
                          SkRegion::Op op = SkRegion::kIntersect_Op);
    virtual bool clipPath(const SkPath& path,
                          SkRegion::Op op = SkRegion::kIntersect_Op);
    virtual bool clipRegion(const SkRegion& deviceRgn,
                            SkRegion::Op op = SkRegion::kIntersect_Op);

    virtual void drawPaint(const SkPaint& paint);
    virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
                            const SkPaint& paint);
    virtual void drawRect(const SkRect& rect, const SkPaint& paint);
    virtual void drawPath(const SkPath& path, const SkPaint& paint);
    virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
                            const SkPaint* paint = NULL);
    virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
                                const SkRect& dst, const SkPaint* paint = NULL);
    virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
                                  const SkPaint* paint = NULL);
    virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
                            const SkPaint* paint = NULL);
    virtual void drawText(const void* text, size_t byteLength, SkScalar x,
                          SkScalar y, const SkPaint& paint);
    virtual void drawPosText(const void* text, size_t byteLength,
                             const SkPoint pos[], const SkPaint& paint);
    virtual void drawPosTextH(const void* text, size_t byteLength,
                              const SkScalar xpos[], SkScalar constY,
                              const SkPaint& paint);
    virtual void drawTextOnPath(const void* text, size_t byteLength,
                                const SkPath& path, const SkMatrix* matrix,
                                const SkPaint& paint);
    virtual void drawPicture(SkPicture&);
    virtual void drawVertices(VertexMode vmode, int vertexCount,
                              const SkPoint vertices[], const SkPoint texs[],
                              const SkColor colors[], SkXfermode* xmode,
                              const uint16_t indices[], int indexCount,
                              const SkPaint& paint);

    virtual SkBounder* setBounder(SkBounder* bounder);
    virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);

private:
    SkTDArray<SkCanvas*> fList;

    class Iter;

    typedef SkCanvas INHERITED;
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkNinePatch_DEFINED
#define SkNinePatch_DEFINED

#include "SkRect.h"
#include "SkRegion.h"

class SkBitmap;
class SkCanvas;
class SkPaint;

class SkNinePatch {
public:
    static void DrawNine(SkCanvas* canvas, const SkRect& dst,
                     const SkBitmap& bitmap, const SkIRect& margins,
                     const SkPaint* paint = NULL);

    static void DrawMesh(SkCanvas* canvas, const SkRect& dst,
                         const SkBitmap& bitmap,
                         const int32_t xDivs[], int numXDivs,
                         const int32_t yDivs[], int numYDivs,
                         const SkPaint* paint = NULL);
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
#ifndef SkOSFile_DEFINED
#define SkOSFile_DEFINED

#include "SkString.h"

#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
    #include <dirent.h>
#endif

struct SkFILE;

enum SkFILE_Flags {
    kRead_SkFILE_Flag   = 0x01,
    kWrite_SkFILE_Flag  = 0x02
};

SkFILE* sk_fopen(const char path[], SkFILE_Flags);
void    sk_fclose(SkFILE*);

size_t  sk_fgetsize(SkFILE*);
/** Return true if the file could seek back to the beginning
*/
bool    sk_frewind(SkFILE*);

size_t  sk_fread(void* buffer, size_t byteCount, SkFILE*);
size_t  sk_fwrite(const void* buffer, size_t byteCount, SkFILE*);
void    sk_fflush(SkFILE*);

int     sk_fseek( SkFILE*, size_t, int );
size_t  sk_ftell( SkFILE* );

class SkOSFile {
public:
    class Iter {
    public:
        Iter();
        Iter(const char path[], const char suffix[] = NULL);
        ~Iter();

        void reset(const char path[], const char suffix[] = NULL);
        bool next(SkString* name, bool getDir = false);

    private:
#ifdef SK_BUILD_FOR_WIN
        HANDLE      fHandle;
        uint16_t*   fPath16;
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
        DIR*        fDIR;
        SkString    fPath, fSuffix;
#endif
    };
};

class SkUTF16_Str {
public:
    SkUTF16_Str(const char src[]);
    ~SkUTF16_Str()
    {
        sk_free(fStr);
    }
    const uint16_t* get() const { return fStr; }

private:
    uint16_t*   fStr;
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkOSMenu_DEFINED
#define SkOSMenu_DEFINED

#include "SkEvent.h"
#include "SkTDArray.h"

class SkOSMenu {
public:
    explicit SkOSMenu(const char title[]);
    ~SkOSMenu();

    const char* getTitle() const { return fTitle; }

    void    appendItem(const char title[], const char eventType[], int32_t eventData);

    // called by SkOSWindow when it receives an OS menu event
    int         countItems() const;
    const char* getItem(int index, uint32_t* cmdID) const;

    SkEvent* createEvent(uint32_t os_cmd);

private:
    const char* fTitle;

    struct Item {
        const char* fTitle;
        const char* fEventType;
        uint32_t    fEventData;
        uint32_t    fOSCmd; // internal
    };
    SkTDArray<Item> fItems;

    // illegal
    SkOSMenu(const SkOSMenu&);
    SkOSMenu& operator=(const SkOSMenu&);
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkOSWindow_Mac_DEFINED
#define SkOSWindow_Mac_DEFINED

#include <Carbon/Carbon.h>
#include "SkWindow.h"

class SkOSWindow : public SkWindow {
public:
    SkOSWindow(void* hwnd);

    void*   getHWND() const { return fHWND; }
    void*   getHVIEW() const { return fHVIEW; }
    void    updateSize();

    static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);

    static OSStatus EventHandler(EventHandlerCallRef inHandler,
                                 EventRef inEvent, void* userData);

    void   doPaint(void* ctx);

    bool attachGL();
    void detachGL();
    void presentGL();

protected:
    // overrides from SkEventSink
    virtual bool onEvent(const SkEvent& evt);
    // overrides from SkWindow
    virtual void onHandleInval(const SkIRect&);
    // overrides from SkView
    virtual void onAddMenu(const SkOSMenu*);
    virtual void onSetTitle(const char[]);

private:
    void*   fHWND;
    void*   fHVIEW;
    void*   fAGLCtx;

    typedef SkWindow INHERITED;
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkOSWindow_SDL_DEFINED
#define SkOSWindow_SDL_DEFINED

#include "SDL.h"
#include "SkWindow.h"

class SkGLCanvas;

class SkOSWindow : public SkWindow {
public:
    SkOSWindow(void* screen);
    virtual ~SkOSWindow();

    static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);

    void handleSDLEvent(const SDL_Event& event);

protected:
    // overrides from SkWindow
    virtual void onHandleInval(const SkIRect&);
    // overrides from SkView
    virtual void onAddMenu(const SkOSMenu*);
    virtual void onSetTitle(const char[]);

private:
    SDL_Surface* fScreen;
    SDL_Surface* fSurface;
    SkGLCanvas* fGLCanvas;

    void doDraw();

    typedef SkWindow INHERITED;
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkOSWindow_Unix_DEFINED
#define SkOSWindow_Unix_DEFINED

#include "SkWindow.h"
#include <X11/Xlib.h>
#include <GL/glx.h>

class SkBitmap;
class SkEvent;

struct SkUnixWindow {
  Display* fDisplay;
  Window fWin;
  size_t fOSWin;
  GC fGc;
  GLXContext fGLContext;
  bool fGLCreated;
};

class SkOSWindow : public SkWindow {
public:
    SkOSWindow(void*);
    ~SkOSWindow();

    void* getHWND() const { return (void*)fUnixWindow.fWin; }
    void* getDisplay() const { return (void*)fUnixWindow.fDisplay; }
    void* getUnixWindow() const { return (void*)&fUnixWindow; }
    void loop();
    void post_linuxevent();
    bool attachGL();
    void detachGL();
    void presentGL();

    //static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);

    //static bool WndProc(SkUnixWindow* w,  XEvent &e);

protected:
    // overrides from SkWindow
    virtual bool onEvent(const SkEvent&);
    virtual void onHandleInval(const SkIRect&);
    virtual bool onHandleChar(SkUnichar);
    virtual bool onHandleKey(SkKey);
    virtual bool onHandleKeyUp(SkKey);
    virtual void onSetTitle(const char title[]);

private:
    SkUnixWindow  fUnixWindow;
    bool fGLAttached;

    // Needed for GL
    XVisualInfo* fVi;

    void    doPaint();
    void    mapWindowAndWait();

    typedef SkWindow INHERITED;
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkOSWindow_Win_DEFINED
#define SkOSWindow_Win_DEFINED

#include "SkWindow.h"

class SkOSWindow : public SkWindow {
public:
    SkOSWindow(void* hwnd);
    virtual ~SkOSWindow();

    void*   getHWND() const { return fHWND; }
    void    setSize(int width, int height);
    void    updateSize();

    static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);

    bool attachGL();
    void detachGL();
    void presentGL();

    bool attachD3D9();
    void detachD3D9();
    void presentD3D9();

    void* d3d9Device() { return fD3D9Device; }

    bool wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    static bool QuitOnDeactivate(HWND hWnd);

    enum {
        SK_WM_SkEvent = WM_APP + 1000,
        SK_WM_SkTimerID = 0xFFFF    // just need a non-zero value
    };

protected:
    virtual bool quitOnDeactivate() { return true; }

    // overrides from SkWindow
    virtual void onHandleInval(const SkIRect&);
    // overrides from SkView
    virtual void onAddMenu(const SkOSMenu*);

    virtual void onSetTitle(const char title[]);

private:
    void*               fHWND;

    void                doPaint(void* ctx);

    void*               fHGLRC;

    bool                fGLAttached;

    void*               fD3D9Device;
    bool                fD3D9Attached;

    HMENU               fMBar;

    typedef SkWindow INHERITED;
};

#endif


code:
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 *  SkOSWindow_wxwidgets.h
 *  wxwidgets
 *
 *  Copyright 2005 __MyCompanyName__. All rights reserved.
 *
 */

#ifndef SkOSWindow_wxwidgets_DEFINED
#define SkOSWindow_wxwidgets_DEFINED

#include "SkWindow.h"
#include "wx/frame.h"

class SkOSWindow: public SkWindow
{
public:
    SkOSWindow();
    SkOSWindow(const wxString& title, int x, int y, int width, int height);
    ~SkOSWindow();

    wxFrame* getWXFrame() const { return fFrame; }

    void updateSize();

protected:
    virtual void onHandleInval(const SkIRect&);
    virtual void onAddMenu(const SkOSMenu*);

private:
    wxFrame* fFrame;
    typedef SkWindow INHERITED;

};

#endifpedef SkWindow INHERITED;


code:
#ifndef SkOpArray_DEFINED
#define SkOpArray_DEFINED

#include "SkOperand2.h"
#include "SkTDArray_Experimental.h"

typedef SkLongArray(SkOperand2) SkTDOperand2Array;

class SkOpArray : public SkTDOperand2Array {
public:
	SkOpArray();
	SkOpArray(SkOperand2::OpType type);
	bool getIndex(int index, SkOperand2* operand);
	SkOperand2::OpType getType() { return fType; }
	void setType(SkOperand2::OpType type) {
		fType = type;
	}
protected:
	SkOperand2::OpType fType;
};

#endif // SkOpArray_DEFINED


code:
/* libs/graphics/animator/SkOperand.h
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#ifndef SkOperand_DEFINED
#define SkOperand_DEFINED

#include "SkDisplayType.h"

class SkTypedArray;
class SkDisplayable;
class SkDrawable;
class SkString;

union SkOperand {
//  SkOperand() {}
//  SkOperand(SkScalar scalar) : fScalar(scalar) {}
    SkTypedArray* fArray;
    SkDisplayable* fDisplayable;
    SkDrawable* fDrawable;
    void* fObject;
    int32_t fS32;
    SkMSec fMSec;
    SkScalar fScalar;
    SkString* fString;
};

struct SkScriptValue {
    SkOperand fOperand;
    SkDisplayTypes fType;
    SkTypedArray* getArray() { SkASSERT(fType == SkType_Array); return fOperand.fArray; }
    SkDisplayable* getDisplayable() { SkASSERT(fType == SkType_Displayable); return fOperand.fDisplayable; }
    SkDrawable* getDrawable() { SkASSERT(fType == SkType_Drawable); return fOperand.fDrawable; }
    int32_t getS32(SkAnimateMaker* maker) { SkASSERT(fType == SkType_Int || fType == SkType_Boolean ||
        SkDisplayType::IsEnum(maker, fType)); return fOperand.fS32; }
    SkMSec getMSec() { SkASSERT(fType == SkType_MSec); return fOperand.fMSec; }
    SkScalar getScalar() { SkASSERT(fType == SkType_Float); return fOperand.fScalar; }
    SkString* getString() { SkASSERT(fType == SkType_String); return fOperand.fString; }
};

#endif // SkOperand_DEFINED


code:
#ifndef SkOperand2_DEFINED
#define SkOperand2_DEFINED

#include "SkScalar.h"

class SkOpArray;
class SkString;

union SkOperand2 {
	enum OpType {
		kNoType,
		kS32 = 1,
		kScalar = 2,
		kString = 4,
		kArray = 8,
		kObject = 16
	};
	SkOpArray* fArray;
	void* fObject;
	size_t fReference;
	int32_t fS32;
	SkScalar fScalar;
	SkString* fString;
};

struct SkScriptValue2 {
	enum IsConstant {
		kConstant,
		kVariable
	};
	enum IsWritten {
		kUnwritten,
		kWritten
	};
	SkOperand2 fOperand;
	SkOperand2::OpType fType : 8;
	IsConstant fIsConstant : 8;
	IsWritten fIsWritten : 8;
	SkOpArray* getArray() { SkASSERT(fType == SkOperand2::kArray); return fOperand.fArray; }
	void* getObject() { SkASSERT(fType == SkOperand2::kObject); return fOperand.fObject; }
	int32_t getS32() { SkASSERT(fType == SkOperand2::kS32); return fOperand.fS32; }
	SkScalar getScalar() { SkASSERT(fType == SkOperand2::kScalar); return fOperand.fScalar; }
	SkString* getString() { SkASSERT(fType == SkOperand2::kString); return fOperand.fString; }
        bool isConstant() const { return fIsConstant == kConstant; }
};

#endif // SkOperand2_DEFINED


code:
/* libs/graphics/animator/SkOperandInterpolator.h
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#ifndef SkOperandInterpolator_DEFINED
#define SkOperandInterpolator_DEFINED

#include "SkDisplayType.h"
#include "SkInterpolator.h"
#include "SkOperand.h"

class SkOperandInterpolator : public SkInterpolatorBase {
public:
    SkOperandInterpolator();
    SkOperandInterpolator(int elemCount, int frameCount, SkDisplayTypes type);
    SkOperand* getValues() { return fValues; }
    int getValuesCount() { return fFrameCount * fElemCount; }
    void    reset(int elemCount, int frameCount, SkDisplayTypes type);

    /** Add or replace a key frame, copying the values[] data into the interpolator.
        @param index    The index of this frame (frames must be ordered by time)
        @param time The millisecond time for this frame
        @param values   The array of values [elemCount] for this frame. The data is copied
                        into the interpolator.
        @param blend    A positive scalar specifying how to blend between this and the next key frame.
                        [0...1) is a cubic lag/log/lag blend (slow to change at the beginning and end)
                        1 is a linear blend (default)
                        (1...inf) is a cubic log/lag/log blend (fast to change at the beginning and end)
    */
    bool    setKeyFrame(int index, SkMSec time, const SkOperand values[], SkScalar blend = SK_Scalar1);
    Result timeToValues(SkMSec time, SkOperand values[]) const;
    SkDEBUGCODE(static void UnitTest();)
private:
    SkDisplayTypes fType;
    SkOperand* fValues;     // pointer into fStorage
#ifdef SK_DEBUG
    SkOperand(* fValuesArray)[10];
#endif
    typedef SkInterpolatorBase INHERITED;
};

#endif // SkOperandInterpolator_DEFINED


code:
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFCatalog_DEFINED
#define SkPDFCatalog_DEFINED

#include <sys/types.h>

#include "SkPDFTypes.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"

/** \class SkPDFCatalog

    The PDF catalog manages object numbers and file offsets.  It is used
    to create the PDF cross reference table.
*/
class SK_API SkPDFCatalog {
public:
    /** Create a PDF catalog.
     */
    SkPDFCatalog();
    ~SkPDFCatalog();

    /** Add the passed object to the catalog.  Refs obj.
     *  @param obj         The object to add.
     *  @param onFirstPage Is the object on the first page.
     *  @return The obj argument is returned.
     */
    SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage);

    /** Inform the catalog of the object's position in the final stream.
     *  The object should already have been added to the catalog.  Returns
     *  the object's size.
     *  @param obj         The object to add.
     *  @param offset      The byte offset in the output stream of this object.
     */
    size_t setFileOffset(SkPDFObject* obj, size_t offset);

    /** Output the object number for the passed object.
     *  @param obj         The object of interest.
     *  @param stream      The writable output stream to send the output to.
     */
    void emitObjectNumber(SkWStream* stream, SkPDFObject* obj);

    /** Return the number of bytes that would be emitted for the passed
     *  object's object number.
     *  @param obj         The object of interest
     */
    size_t getObjectNumberSize(SkPDFObject* obj);

    /** Output the cross reference table for objects in the catalog.
     *  Returns the total number of objects.
     *  @param stream      The writable output stream to send the output to.
     *  @param firstPage   If true, include first page objects only, otherwise
     *                     include all objects not on the first page.
     */
    int32_t emitXrefTable(SkWStream* stream, bool firstPage);

private:
    struct Rec {
        Rec(SkPDFObject* object, bool onFirstPage)
            : fObject(object),
              fFileOffset(0),
              fObjNumAssigned(false),
              fOnFirstPage(onFirstPage) {
        }
        SkPDFObject* fObject;
        off_t fFileOffset;
        bool fObjNumAssigned;
        bool fOnFirstPage;
    };

    // TODO(vandebo) Make this a hash if it's a performance problem.
    SkTDArray<struct Rec> fCatalog;

    // Number of objects on the first page.
    uint32_t fFirstPageCount;
    // Next object number to assign (on page > 1).
    uint32_t fNextObjNum;
    // Next object number to assign on the first page.
    uint32_t fNextFirstPageObjNum;

    int findObjectIndex(SkPDFObject* obj) const;

    int assignObjNum(SkPDFObject* obj);
};

#endif


code:
/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFDevice_DEFINED
#define SkPDFDevice_DEFINED

#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRefCnt.h"
#include "SkStream.h"
#include "SkTScopedPtr.h"

class SkPDFArray;
class SkPDFDevice;
class SkPDFDict;
class SkPDFFont;
class SkPDFFormXObject;
class SkPDFGraphicState;
class SkPDFObject;
class SkPDFShader;
class SkPDFStream;

// Private classes.
struct ContentEntry;
struct GraphicStateEntry;

class SkPDFDeviceFactory : public SkDeviceFactory {
public:
    virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
                                int height, bool isOpaque, bool isForLayer);
};

/** \class SkPDFDevice

    The drawing context for the PDF backend.
*/
class SkPDFDevice : public SkDevice {
public:
    /** Create a PDF drawing context with the given width and height.
     *  72 points/in means letter paper is 612x792.
     *  @param pageSize Page size in points.
     *  @param contentSize The content size of the page in points. This will be
     *         combined with the initial transform to determine the drawing area
     *         (as reported by the width and height methods). Anything outside
     *         of the drawing area will be clipped.
     *  @param initialTransform The initial transform to apply to the page.
     *         This may be useful to, for example, move the origin in and
     *         over a bit to account for a margin, scale the canvas,
     *         or apply a rotation.  Note1: the SkPDFDevice also applies
     *         a scale+translate transform to move the origin from the
     *         bottom left (PDF default) to the top left.  Note2: drawDevice
     *         (used by layer restore) draws the device after this initial
     *         transform is applied, so the PDF device factory does an
     *         inverse scale+translate to accommodate the one that SkPDFDevice
     *         always does.
     */
    // TODO(vandebo) The sizes should be SkSize and not SkISize.
    SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
                       const SkMatrix& initialTransform);
    SK_API virtual ~SkPDFDevice();

    virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }

    virtual void clear(SkColor color);

    virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
        return false;
    }

    /** These are called inside the per-device-layer loop for each draw call.
     When these are called, we have already applied any saveLayer operations,
     and are handling any looping from the paint, and any effects from the
     DrawFilter.
     */
    virtual void drawPaint(const SkDraw&, const SkPaint& paint);
    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
                            size_t count, const SkPoint[],
                            const SkPaint& paint);
    virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
    virtual void drawPath(const SkDraw&, const SkPath& origpath,
                          const SkPaint& paint, const SkMatrix* prePathMatrix,
                          bool pathIsMutable);
    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
                            const SkIRect* srcRectOrNull,
                            const SkMatrix& matrix, const SkPaint& paint);
    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
                            const SkPaint& paint);
    virtual void drawText(const SkDraw&, const void* text, size_t len,
                          SkScalar x, SkScalar y, const SkPaint& paint);
    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
                             const SkScalar pos[], SkScalar constY,
                             int scalarsPerPos, const SkPaint& paint);
    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
                                const SkPath& path, const SkMatrix* matrix,
                                const SkPaint& paint);
    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
                              int vertexCount, const SkPoint verts[],
                              const SkPoint texs[], const SkColor colors[],
                              SkXfermode* xmode, const uint16_t indices[],
                              int indexCount, const SkPaint& paint);
    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
                            const SkPaint&);

    // PDF specific methods.

    /** Returns a reference to the resource dictionary for this device.
     */
    SK_API const SkRefPtr<SkPDFDict>& getResourceDict();

    /** Get the list of resources (PDF objects) used on this page.
     *  @param resourceList A list to append the resources to.
     */
    SK_API void getResources(SkTDArray<SkPDFObject*>* resourceList) const;

    /** Get the fonts used on this device.
     */
    SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;

    /** Returns the media box for this device.
     */
    SK_API SkRefPtr<SkPDFArray> getMediaBox() const;

    /** Returns a SkStream with the page contents.  The caller is responsible
        for a reference to the returned value.
        DEPRECATED: use copyContentToData()
     */
    SK_API SkStream* content() const;

    /** Returns a SkStream with the page contents.  The caller is responsible
     *  for calling data->unref() when it is finished.
     */
    SK_API SkData* copyContentToData() const;

    SK_API const SkMatrix& initialTransform() const {
        return fInitialTransform;
    }

protected:
    // override
    virtual SkDeviceFactory* onNewDeviceFactory();

private:
    friend class SkPDFDeviceFactory;
    // TODO(vandebo) push most of SkPDFDevice's state into a core object in
    // order to get the right access levels without using friend.
    friend class ScopedContentEntry;

    SkISize fPageSize;
    SkISize fContentSize;
    SkMatrix fInitialTransform;
    SkClipStack fExistingClipStack;
    SkRegion fExistingClipRegion;
    SkRefPtr<SkPDFDict> fResourceDict;

    SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
    SkTDArray<SkPDFObject*> fXObjectResources;
    SkTDArray<SkPDFFont*> fFontResources;
    SkTDArray<SkPDFShader*> fShaderResources;

    SkTScopedPtr<ContentEntry> fContentEntries;
    ContentEntry* fLastContentEntry;

    // For use by the DeviceFactory.
    SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
                const SkRegion& existingClipRegion);

    // override from SkDevice
    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
                                               int width, int height,
                                               bool isOpaque,
                                               Usage usage);

    void init();
    void cleanUp();
    void createFormXObjectFromDevice(SkRefPtr<SkPDFFormXObject>* xobject);

    // Clear the passed clip from all existing content entries.
    void clearClipFromContent(const SkClipStack* clipStack,
                              const SkRegion& clipRegion);
    void drawFormXObjectWithClip(SkPDFFormXObject* form,
                                 const SkClipStack* clipStack,
                                 const SkRegion& clipRegion,
                                 bool invertClip);

    // If the paint or clip is such that we shouldn't draw anything, this
    // returns NULL and does not create a content entry.
    // setUpContentEntry and finishContentEntry can be used directly, but
    // the preferred method is to use the ScopedContentEntry helper class.
    ContentEntry* setUpContentEntry(const SkClipStack* clipStack,
                                    const SkRegion& clipRegion,
                                    const SkMatrix& matrix,
                                    const SkPaint& paint,
                                    bool hasText,
                                    SkRefPtr<SkPDFFormXObject>* dst);
    void finishContentEntry(SkXfermode::Mode xfermode,
                            SkPDFFormXObject* dst);
    bool isContentEmpty();

    void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
                                            const SkClipStack& clipStack,
                                            const SkRegion& clipRegion,
                                            const SkPaint& paint,
                                            bool hasText,
                                            GraphicStateEntry* entry);
    int addGraphicStateResource(SkPDFGraphicState* gs);

    void updateFont(const SkPaint& paint, uint16_t glyphID,
                    ContentEntry* contentEntry);
    int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);

    void internalDrawPaint(const SkPaint& paint, ContentEntry* contentEntry);
    void internalDrawBitmap(const SkMatrix& matrix,
                            const SkClipStack* clipStack,
                            const SkRegion& clipRegion,
                            const SkBitmap& bitmap,
                            const SkIRect* srcRect,
                            const SkPaint& paint);

    // Disable the default copy and assign implementation.
    SkPDFDevice(const SkPDFDevice&);
    void operator=(const SkPDFDevice&);
};

#endif


code:
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFDocument_DEFINED
#define SkPDFDocument_DEFINED

#include "SkPDFCatalog.h"
#include "SkPDFTypes.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"

class SkPDFDevice;
class SkPDFPage;
class SkWSteam;

/** \class SkPDFDocument

    A SkPDFDocument assembles pages together and generates the final PDF file.
*/
class SkPDFDocument {
public:
    /** Create a PDF document.
     */
    SK_API SkPDFDocument();
    SK_API ~SkPDFDocument();

    /** Output the PDF to the passed stream.
     *  @param stream    The writable output stream to send the PDF to.
     */
    SK_API bool emitPDF(SkWStream* stream);

    /** Append the passed pdf device to the document as a new page.  Returns
     *  true if successful.  Will fail if the document has already been emitted.
     *
     *  @param pdfDevice The page to add to this document.
     */
    SK_API bool appendPage(const SkRefPtr<SkPDFDevice>& pdfDevice);

    /** Get the list of pages in this document.
     */
    SK_API const SkTDArray<SkPDFPage*>& getPages();

private:
    SkPDFCatalog fCatalog;
    int64_t fXRefFileOffset;

    SkTDArray<SkPDFPage*> fPages;
    SkTDArray<SkPDFDict*> fPageTree;
    SkRefPtr<SkPDFDict> fDocCatalog;
    SkTDArray<SkPDFObject*> fPageResources;
    int fSecondPageFirstResourceIndex;

    SkRefPtr<SkPDFDict> fTrailerDict;

    /** Output the PDF header to the passed stream.
     *  @param stream    The writable output stream to send the header to.
     */
    void emitHeader(SkWStream* stream);

    /** Get the size of the header.
     */
    size_t headerSize();

    /** Output the PDF footer to the passed stream.
     *  @param stream    The writable output stream to send the footer to.
     *  @param objCount  The number of objects in the PDF.
     */
    void emitFooter(SkWStream* stream, int64_t objCount);
};

#endif


code:
/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFFont_DEFINED
#define SkPDFFont_DEFINED

#include "SkAdvancedTypefaceMetrics.h"
#include "SkPDFTypes.h"
#include "SkTDArray.h"
#include "SkThread.h"

class SkPaint;

/** \class SkPDFFont
    A PDF Object class representing a font.  The font may have resources
    attached to it in order to embed the font.  SkPDFFonts are canonicalized
    so that resource deduplication will only include one copy of a font.
    This class uses the same pattern as SkPDFGraphicState, a static weak
    reference to each instantiated class.
*/
class SkPDFFont : public SkPDFDict {
public:
    SK_API virtual ~SkPDFFont();

    SK_API virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);

    /** Returns the typeface represented by this class. Returns NULL for the
     *  default typeface.
     */
    SK_API SkTypeface* typeface();

    /** Returns the font type represented in this font.  For Type0 fonts,
     *  returns the type of the decendant font.
     */
    SK_API SkAdvancedTypefaceMetrics::FontType getType();

    /** Return true if this font has an encoding for the passed glyph id.
     */
    SK_API bool hasGlyph(uint16_t glyphID);

    /** Returns true if this font encoding supports glyph IDs above 255.
     */
    SK_API bool multiByteGlyphs();

    /** Convert (in place) the input glyph IDs into the font encoding.  If the
     *  font has more glyphs than can be encoded (like a type 1 font with more
     *  than 255 glyphs) this method only converts up to the first out of range
     *  glyph ID.
     *  @param glyphIDs       The input text as glyph IDs.
     *  @param numGlyphs      The number of input glyphs.
     *  @return               Returns the number of glyphs consumed.
     */
    SK_API size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs);

    /** Get the font resource for the passed typeface and glyphID. The
     *  reference count of the object is incremented and it is the caller's
     *  responsibility to unreference it when done.  This is needed to
     *  accommodate the weak reference pattern used when the returned object
     *  is new and has no other references.
     *  @param typeface  The typeface to find.
     *  @param glyphID   Specify which section of a large font is of interest.
     */
    SK_API static SkPDFFont* getFontResource(SkTypeface* typeface,
                                             uint16_t glyphID);

private:
    SkRefPtr<SkTypeface> fTypeface;
    SkAdvancedTypefaceMetrics::FontType fType;
#ifdef SK_DEBUG
    bool fDescendant;
#endif
    bool fMultiByteGlyphs;

    // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
    // this will be a subset if the font has more than 255 glyphs.
    uint16_t fFirstGlyphID;
    uint16_t fLastGlyphID;
    // The font info is only kept around after construction for large
    // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs.
    SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
    SkTDArray<SkPDFObject*> fResources;
    SkRefPtr<SkPDFDict> fDescriptor;

    class FontRec {
    public:
        SkPDFFont* fFont;
        uint32_t fFontID;
        uint16_t fGlyphID;

        // A fGlyphID of 0 with no fFont always matches.
        bool operator==(const FontRec& b) const;
        FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
    };

    // This should be made a hash table if performance is a problem.
    static SkTDArray<FontRec>& canonicalFonts();
    static SkMutex& canonicalFontsMutex();

    /** Construct a new font dictionary and support objects.
     *  @param fontInfo       Information about the to create.
     *  @param typeface       The typeface for the font.
     *  @param glyphID        The glyph ID the caller is interested in. This
     *                        is important only for Type1 fonts, which have
     *                        more than 255 glyphs.
     *  @param descendantFont If this is the descendant (true) or root
     *                        (Type 0 font - false) font dictionary.  Only True
     *                        Type and CID encoded fonts will use a true value.
     *  @param fontDescriptor If the font descriptor has already have generated
     *                        for this font, pass it in here, otherwise pass
     *                        NULL.
     */
    SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
              uint16_t glyphID, bool descendantFont, SkPDFDict* fontDescriptor);

    void populateType0Font();
    void populateCIDFont();
    bool populateType1Font(int16_t glyphID);

    /** Populate the PDF font dictionary as Type3 font which includes glyph
     *  descriptions with instructions for painting the glyphs. This function
     *  doesn't use any fields from SkAdvancedTypefaceMetrics (fFontInfo). Font
     *  information including glyph paths are queried from the platform
     *  dependent SkGlyphCache.
    */
    void populateType3Font(int16_t glyphID);
    bool addFontDescriptor(int16_t defaultWidth);
    void populateToUnicodeTable();
    void addWidthInfoFromRange(int16_t defaultWidth,
        const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry);
    /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
     *  including the passed glyphID.
     */
    void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);

    static bool find(uint32_t fontID, uint16_t glyphID, int* index);
};

#endif


code:
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFFormXObject_DEFINED
#define SkPDFFormXObject_DEFINED

#include "SkPDFStream.h"
#include "SkPDFTypes.h"
#include "SkRefCnt.h"
#include "SkString.h"

class SkMatrix;
class SkPDFDevice;
class SkPDFCatalog;

/** \class SkPDFFormXObject

    A form XObject; a self contained description of graphics objects.  A form
    XObject is basically a page object with slightly different syntax, that
    can be drawn onto a page.
*/

// The caller could keep track of the form XObjects it creates and
// canonicalize them, but the Skia API doesn't provide enough context to
// automatically do it (trivially).
class SkPDFFormXObject : public SkPDFObject {
public:
    /** Create a PDF form XObject. Entries for the dictionary entries are
     *  automatically added.
     *  @param device      The set of graphical elements on this form.
     */
    explicit SkPDFFormXObject(SkPDFDevice* device);
    virtual ~SkPDFFormXObject();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
    virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);

    /** Add the value to the stream dictionary with the given key.  Refs value.
     *  @param key   The key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     *  @return The value argument is returned.
     */
    SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);

    /** Add the value to the stream dictionary with the given key.  Refs value.
     *  @param key   The text of the key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     *  @return The value argument is returned.
     */
    SkPDFObject* insert(const char key[], SkPDFObject* value);

private:
    SkRefPtr<SkPDFStream> fStream;
    SkTDArray<SkPDFObject*> fResources;
};

#endif


code:
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFGraphicState_DEFINED
#define SkPDFGraphicState_DEFINED

#include "SkPaint.h"
#include "SkPDFTypes.h"
#include "SkTemplates.h"
#include "SkThread.h"

class SkPDFFormXObject;

/** \class SkPDFGraphicState
    SkPaint objects roughly correspond to graphic state dictionaries that can
    be installed. So that a given dictionary is only output to the pdf file
    once, we want to canonicalize them. Static methods in this class manage
    a weakly referenced set of SkPDFGraphicState objects: when the last
    reference to a SkPDFGraphicState is removed, it removes itself from the
    static set of objects.

*/
class SkPDFGraphicState : public SkPDFDict {
public:
    virtual ~SkPDFGraphicState();

    virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);

    // Override emitObject and getOutputSize so that we can populate
    // the dictionary on demand.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

    /** Get the graphic state for the passed SkPaint. The reference count of
     *  the object is incremented and it is the caller's responsibility to
     *  unreference it when done. This is needed to accommodate the weak
     *  reference pattern used when the returned object is new and has no
     *  other references.
     *  @param paint  The SkPaint to emulate.
     */
    static SkPDFGraphicState* getGraphicStateForPaint(const SkPaint& paint);

    /** Make a graphic state that only sets the passed soft mask. The
     *  reference count of the object is incremented and it is the caller's
     *  responsibility to unreference it when done.
     *  @param sMask  The form xobject to use as a soft mask.
     *  @param invert Indicates if the alpha of the sMask should be inverted.
     */
    static SkPDFGraphicState* getSMaskGraphicState(SkPDFFormXObject* sMask,
                                                   bool invert);

    /** Get a graphic state that only unsets the soft mask. The reference
     *  count of the object is incremented and it is the caller's responsibility
     *  to unreference it when done. This is needed to accommodate the weak
     *  reference pattern used when the returned object is new and has no
     *  other references.
     */
    static SkPDFGraphicState* getNoSMaskGraphicState();

private:
    const SkPaint fPaint;
    SkTDArray<SkPDFObject*> fResources;
    bool fPopulated;
    bool fSMask;

    class GSCanonicalEntry {
    public:
        SkPDFGraphicState* fGraphicState;
        const SkPaint* fPaint;

        bool operator==(const GSCanonicalEntry& b) const;
        explicit GSCanonicalEntry(SkPDFGraphicState* gs)
            : fGraphicState(gs),
              fPaint(&gs->fPaint) {}
        explicit GSCanonicalEntry(const SkPaint* paint)
            : fGraphicState(NULL),
              fPaint(paint) {}
    };

    // This should be made a hash table if performance is a problem.
    static SkTDArray<GSCanonicalEntry>& canonicalPaints();
    static SkMutex& canonicalPaintsMutex();

    SkPDFGraphicState();
    explicit SkPDFGraphicState(const SkPaint& paint);

    void populateDict();

    static SkPDFObject* GetInvertFunction();

    static int find(const SkPaint& paint);
};

#endif


code:
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFImage_DEFINED
#define SkPDFImage_DEFINED

#include "SkPDFStream.h"
#include "SkPDFTypes.h"
#include "SkRefCnt.h"

class SkBitmap;
class SkPaint;
class SkPDFCatalog;
struct SkIRect;

/** \class SkPDFImage

    An image XObject.
*/

// We could play the same trick here as is done in SkPDFGraphicState, storing
// a copy of the Bitmap object (not the pixels), the pixel generation number,
// and settings used from the paint to canonicalize image objects.
class SkPDFImage : public SkPDFObject {
public:
    /** Create a new Image XObject to represent the passed bitmap.
     *  @param bitmap   The image to encode.
     *  @param srcRect  The rectangle to cut out of bitmap.
     *  @param paint    Used to calculate alpha, masks, etc.
     *  @return  The image XObject or NUll if there is nothing to draw for
     *           the given parameters.
     */
    static SkPDFImage* CreateImage(const SkBitmap& bitmap,
                                   const SkIRect& srcRect,
                                   const SkPaint& paint);

    virtual ~SkPDFImage();

    /** Add a Soft Mask (alpha or shape channel) to the image.  Refs mask.
     *  @param mask A gray scale image representing the mask.
     *  @return The mask argument is returned.
     */
    SkPDFImage* addSMask(SkPDFImage* mask);

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
    virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);

private:
    SkRefPtr<SkPDFStream> fStream;
    SkTDArray<SkPDFObject*> fResources;

    /** Create a PDF image XObject. Entries for the image properties are
     *  automatically added to the stream dictionary.
     *  @param imageData  The final raw bits representing the image.
     *  @param bitmap     The image parameters to use (Config, etc).
     *  @param srcRect    The clipping applied to bitmap before generating
     *                    imageData.
     *  @param alpha      Is this the alpha channel of the bitmap.
     *  @param paint      Used to calculate alpha, masks, etc.
     */
    SkPDFImage(SkStream* imageData, const SkBitmap& bitmap,
               const SkIRect& srcRect, bool alpha, const SkPaint& paint);

    /** Add the value to the stream dictionary with the given key.  Refs value.
     *  @param key   The key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     *  @return The value argument is returned.
     */
    SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);

    /** Add the value to the stream dictionary with the given key.  Refs value.
     *  @param key   The text of the key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     *  @return The value argument is returned.
     */
    SkPDFObject* insert(const char key[], SkPDFObject* value);
};

#endif


code:
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFPage_DEFINED
#define SkPDFPage_DEFINED

#include "SkPDFTypes.h"
#include "SkPDFStream.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"

class SkPDFCatalog;
class SkPDFDevice;
class SkWStream;

/** \class SkPDFPage

    A SkPDFPage contains meta information about a page, is used in the page
    tree and points to the content of the page.
*/
class SkPDFPage : public SkPDFDict {
public:
    /** Create a PDF page with the passed PDF device.  The device need not
     *  have content on it yet.
     *  @param content    The page content.
     */
    explicit SkPDFPage(const SkRefPtr<SkPDFDevice>& content);
    ~SkPDFPage();

    /** Before a page and its contents can be sized and emitted, it must
     *  be finalized.  No changes to the PDFDevice will be honored after
     *  finalizePage has been called.  This function adds the page content
     *  to the passed catalog, so it must be called for each document
     *  that the page is part of.
     *  @param catalog         The catalog to add page content objects to.
     *  @param firstPage       Indicate if this is the first page of a document.
     *  @param resourceObjects The resource objects used on the page are added
     *                         to this array.  This gives the caller a chance
     *                         to deduplicate resources across pages.
     */
    void finalizePage(SkPDFCatalog* catalog, bool firstPage,
                      SkTDArray<SkPDFObject*>* resourceObjects);

    /** Determine the size of the page content and store to the catalog
     *  the offsets of all nonresource-indirect objects that make up the page
     *  content.  This must be called before emitPage(), but after finalizePage.
     *  @param catalog    The catalog to add the object offsets to.
     *  @param fileOffset The file offset where the page content will be
     *                    emitted.
     */
    off_t getPageSize(SkPDFCatalog* catalog, off_t fileOffset);

    /** Output the page content to the passed stream.
     *  @param stream     The writable output stream to send the content to.
     *  @param catalog    The active object catalog.
     */
    void emitPage(SkWStream* stream, SkPDFCatalog* catalog);

    /** Generate a page tree for the passed vector of pages.  New objects are
     *  added to the catalog.  The pageTree vector is populated with all of
     *  the 'Pages' dictionaries as well as the 'Page' objects.  Page trees
     *  have both parent and children links, creating reference cycles, so
     *  it must be torn down explicitly.  The first page is not added to
     *  the pageTree dictionary array so the caller can handle it specially.
     *  @param pages      The ordered vector of page objects.
     *  @param catalog    The catalog to add new objects into.
     *  @param pageTree   An output vector with all of the internal and leaf
     *                    nodes of the pageTree.
     *  @param rootNode   An output parameter set to the root node.
     */
    static void generatePageTree(const SkTDArray<SkPDFPage*>& pages,
                                 SkPDFCatalog* catalog,
                                 SkTDArray<SkPDFDict*>* pageTree,
                                 SkPDFDict** rootNode);

    /** Get the fonts used on this page.
     */
    SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;

private:
    // Multiple pages may reference the content.
    SkRefPtr<SkPDFDevice> fDevice;

    // Once the content is finalized, put it into a stream for output.
    SkRefPtr<SkPDFStream> fContentStream;
};

#endif


code:
/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFShader_DEFINED
#define SkPDFShader_DEFINED

#include "SkPDFStream.h"
#include "SkPDFTypes.h"
#include "SkMatrix.h"
#include "SkRefCnt.h"
#include "SkShader.h"

class SkObjRef;
class SkPDFCatalog;

/** \class SkPDFShader

    In PDF parlance, this is a pattern, used in place of a color when the
    pattern color space is selected.
*/

class SkPDFShader : public SkPDFObject {
public:
    virtual ~SkPDFShader();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
    virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);

    /** Get the PDF shader for the passed SkShader. If the SkShader is
     *  invalid in some way, returns NULL. The reference count of
     *  the object is incremented and it is the caller's responsibility to
     *  unreference it when done.  This is needed to accommodate the weak
     *  reference pattern used when the returned object is new and has no
     *  other references.
     *  @param shader     The SkShader to emulate.
     *  @param matrix     The current transform. (PDF shaders are absolutely
     *                    positioned, relative to where the page is drawn.)
     *  @param surfceBBox The bounding box of the drawing surface (with matrix
     *                    already applied).
     */
    static SkPDFShader* getPDFShader(const SkShader& shader,
                                     const SkMatrix& matrix,
                                     const SkIRect& surfaceBBox);

private:
    class State {
    public:
        SkShader::GradientType fType;
        SkShader::GradientInfo fInfo;
        SkAutoFree fColorData;
        SkMatrix fCanvasTransform;
        SkMatrix fShaderTransform;
        SkIRect fBBox;

        SkBitmap fImage;
        uint32_t fPixelGeneration;
        SkShader::TileMode fImageTileModes[2];

        explicit State(const SkShader& shader, const SkMatrix& canvasTransform,
                       const SkIRect& bbox);
        bool operator==(const State& b) const;
    };

    SkRefPtr<SkPDFDict> fContent;
    SkTDArray<SkPDFObject*> fResources;
    SkAutoTDelete<const State> fState;

    class ShaderCanonicalEntry {
    public:
        SkPDFShader* fPDFShader;
        const State* fState;

        bool operator==(const ShaderCanonicalEntry& b) const {
            return fPDFShader == b.fPDFShader || *fState == *b.fState;
        }
        ShaderCanonicalEntry(SkPDFShader* pdfShader, const State* state)
            : fPDFShader(pdfShader),
              fState(state) {
        }
    };
    // This should be made a hash table if performance is a problem.
    static SkTDArray<ShaderCanonicalEntry>& canonicalShaders();
    static SkMutex& canonicalShadersMutex();

    static SkPDFObject* rangeObject();

    SkPDFShader(State* state);

    void doFunctionShader();
    void doImageShader();
    SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
};

#endif


code:
/*
 * Copyright (C) 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFStream_DEFINED
#define SkPDFStream_DEFINED

#include "SkPDFTypes.h"
#include "SkRefCnt.h"
#include "SkStream.h"
#include "SkTemplates.h"

class SkPDFCatalog;

/** \class SkPDFStream

    A stream object in a PDF.  Note, all streams must be indirect objects (via
    SkObjRef).
*/
class SkPDFStream : public SkPDFDict {
public:
    /** Create a PDF stream. A Length entry is automatically added to the
     *  stream dictionary. The stream may be retained (stream->ref() may be
     *  called) so its contents must not be changed after calling this.
     *  @param stream The data part of the stream.
     */
    explicit SkPDFStream(SkStream* stream);
    virtual ~SkPDFStream();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

private:
    size_t fLength;
    // Only one of the two streams will be valid.
    SkRefPtr<SkStream> fPlainData;
    SkDynamicMemoryWStream fCompressedData;

    typedef SkPDFDict INHERITED;
};

#endif


code:
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFTypes_DEFINED
#define SkPDFTypes_DEFINED

#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkString.h"
#include "SkTDArray.h"
#include "SkTypes.h"

class SkPDFCatalog;
class SkWStream;

/** \class SkPDFObject

    A PDF Object is the base class for primitive elements in a PDF file.  A
    common subtype is used to ease the use of indirect object references,
    which are common in the PDF format.
*/
class SkPDFObject : public SkRefCnt {
public:
    /** Create a PDF object.
     */
    SkPDFObject();
    virtual ~SkPDFObject();

    /** Subclasses must implement this method to print the object to the
     *  PDF file.
     *  @param catalog  The object catalog to use.
     *  @param indirect If true, output an object identifier with the object.
     *  @param stream   The writable output stream to send the output to.
     */
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect) = 0;

    /** Return the size (number of bytes) of this object in the final output
     *  file. Compound objects or objects that are computationally intensive
     *  to output should override this method.
     *  @param catalog  The object catalog to use.
     *  @param indirect If true, output an object identifier with the object.
     */
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

    /** If this object explicitly depends on other objects, add them to the
     *  end of the list.  This only applies to higher level object, where
     *  the depenency is explicit and introduced by the class.  i.e. an
     *  SkPDFImage added to an SkPDFDevice, but not an SkPDFObjRef added to
     *  an SkPDFArray.
     *  @param resourceList  The list to append dependant resources to.
     */
    virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);

    /** Helper function to output an indirect object.
     *  @param catalog The object catalog to use.
     *  @param stream  The writable output stream to send the output to.
     */
    void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog);

    /** Helper function to find the size of an indirect object.
     *  @param catalog The object catalog to use.
     */
    size_t getIndirectOutputSize(SkPDFCatalog* catalog);
};

/** \class SkPDFObjRef

    An indirect reference to a PDF object.
*/
class SkPDFObjRef : public SkPDFObject {
public:
    /** Create a reference to an existing SkPDFObject.
     *  @param obj The object to reference.
     */
    explicit SkPDFObjRef(SkPDFObject* obj);
    virtual ~SkPDFObjRef();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

private:
    SkRefPtr<SkPDFObject> fObj;
};

/** \class SkPDFInt

    An integer object in a PDF.
*/
class SkPDFInt : public SkPDFObject {
public:
    /** Create a PDF integer (usually for indirect reference purposes).
     *  @param value An integer value between 2^31 - 1 and -2^31.
     */
    explicit SkPDFInt(int32_t value);
    virtual ~SkPDFInt();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);

private:
    int32_t fValue;
};

/** \class SkPDFBool

    An boolean value in a PDF.
*/
class SkPDFBool : public SkPDFObject {
public:
    /** Create a PDF boolean.
     *  @param value true or false.
     */
    explicit SkPDFBool(bool value);
    virtual ~SkPDFBool();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

private:
    bool fValue;
};

/** \class SkPDFScalar

    A real number object in a PDF.
*/
class SkPDFScalar : public SkPDFObject {
public:
    /** Create a PDF real number.
     *  @param value A real value.
     */
    explicit SkPDFScalar(SkScalar value);
    virtual ~SkPDFScalar();

    static void Append(SkScalar value, SkWStream* stream);

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);

private:
    SkScalar fValue;
};

/** \class SkPDFString

    A string object in a PDF.
*/
class SkPDFString : public SkPDFObject {
public:
    /** Create a PDF string. Maximum length (in bytes) is 65,535.
     *  @param value A string value.
     */
    explicit SkPDFString(const char value[]);
    explicit SkPDFString(const SkString& value);

    /** Create a PDF string. Maximum length (in bytes) is 65,535.
     *  @param value     A string value.
     *  @param len       The length of value.
     *  @param wideChars Indicates if the top byte in value is significant and
     *                   should be encoded (true) or not (false).
     */
    SkPDFString(const uint16_t* value, size_t len, bool wideChars);
    virtual ~SkPDFString();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

    static SkString formatString(const char* input, size_t len);
    static SkString formatString(const uint16_t* input, size_t len,
                                 bool wideChars);
private:
    static const size_t kMaxLen = 65535;

    const SkString fValue;

    static SkString doFormatString(const void* input, size_t len,
                                 bool wideInput, bool wideOutput);
};

/** \class SkPDFName

    A name object in a PDF.
*/
class SkPDFName : public SkPDFObject {
public:
    /** Create a PDF name object. Maximum length is 127 bytes.
     *  @param value The name.
     */
    explicit SkPDFName(const char name[]);
    explicit SkPDFName(const SkString& name);
    virtual ~SkPDFName();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

private:
    static const size_t kMaxLen = 127;

    const SkString fValue;

    static SkString formatName(const SkString& input);
};

/** \class SkPDFArray

    An array object in a PDF.
*/
class SkPDFArray : public SkPDFObject {
public:
    /** Create a PDF array. Maximum length is 8191.
     */
    SkPDFArray();
    virtual ~SkPDFArray();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

    /** The size of the array.
     */
    int size() { return fValue.count(); }

    /** Preallocate space for the given number of entries.
     *  @param length The number of array slots to preallocate.
     */
    void reserve(int length);

    /** Returns the object at the given offset in the array.
     *  @param index The index into the array to retrieve.
     */
    SkPDFObject* getAt(int index) { return fValue[index]; }

    /** Set the object at the given offset in the array. Ref's value.
     *  @param index The index into the array to set.
     *  @param value The value to add to the array.
     *  @return The value argument is returned.
     */
    SkPDFObject* setAt(int index, SkPDFObject* value);

    /** Append the object to the end of the array and increments its ref count.
     *  @param value The value to add to the array.
     *  @return The value argument is returned.
     */
    SkPDFObject* append(SkPDFObject* value);

private:
    static const int kMaxLen = 8191;
    SkTDArray<SkPDFObject*> fValue;
};

/** \class SkPDFDict

    A dictionary object in a PDF.
*/
class SkPDFDict : public SkPDFObject {
public:
    /** Create a PDF dictionary. Maximum number of entries is 4095.
     */
    SkPDFDict();

    /** Create a PDF dictionary with a Type entry.
     *  @param type   The value of the Type entry.
     */
    explicit SkPDFDict(const char type[]);

    virtual ~SkPDFDict();

    // The SkPDFObject interface.
    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
                            bool indirect);
    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);

    /** The size of the dictionary.
     */
    int size() { return fValue.count(); }

    /** Add the value to the dictionary with the given key.  Refs value.
     *  @param key   The key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     *  @return The value argument is returned.
     */
    SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);

    /** Add the value to the dictionary with the given key.  Refs value.  The
     *  method will create the SkPDFName object.
     *  @param key   The text of the key for this dictionary entry.
     *  @param value The value for this dictionary entry.
     *  @return The value argument is returned.
     */
    SkPDFObject* insert(const char key[], SkPDFObject* value);

    /** Remove all entries from the dictionary.
     */
    void clear();

private:
    static const int kMaxLen = 4095;

    struct Rec {
      SkPDFName* key;
      SkPDFObject* value;
    };

    SkTDArray<struct Rec> fValue;
};

#endif


code:
/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkPDFUtils_DEFINED
#define SkPDFUtils_DEFINED

#include "SkPath.h"

class SkMatrix;
class SkPath;
class SkPDFArray;
struct SkRect;

#if 0
#define PRINT_NOT_IMPL(str) fprintf(stderr, str)
#else
#define PRINT_NOT_IMPL(str)
#endif

#define NOT_IMPLEMENTED(condition, assert)                         \
    do {                                                           \
        if (condition) {                                           \
            PRINT_NOT_IMPL("NOT_IMPLEMENTED: " #condition "\n");   \
            SkDEBUGCODE(SkASSERT(!assert);)                        \
        }                                                          \
    } while(0)

class SkPDFUtils {
public:
    static SkPDFArray* MatrixToArray(const SkMatrix& matrix);
    static void AppendTransform(const SkMatrix& matrix, SkWStream* content);

    static void MoveTo(SkScalar x, SkScalar y, SkWStream* content);
    static void AppendLine(SkScalar x, SkScalar y, SkWStream* content);
    static void AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
                            SkScalar ctl2X, SkScalar ctl2Y,
                            SkScalar dstX, SkScalar dstY, SkWStream* content);
    static void AppendRectangle(const SkRect& rect, SkWStream* content);
    static void EmitPath(const SkPath& path, SkWStream* content);
    static void ClosePath(SkWStream* content);
    static void PaintPath(SkPaint::Style style, SkPath::FillType fill,
                          SkWStream* content);
    static void StrokePath(SkWStream* content);
    static void DrawFormXObject(int objectIndex, SkWStream* content);
    static void ApplyGraphicState(int objectIndex, SkWStream* content);
};

#endif