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 SkImageDecoder_DEFINED
#define SkImageDecoder_DEFINED

#include "SkBitmap.h"
#include "SkRefCnt.h"

class SkStream;

/** \class SkImageDecoder

    Base class for decoding compressed images into a SkBitmap
*/
class SK_API SkImageDecoder {
public:
    virtual ~SkImageDecoder();

    enum Format {
        kUnknown_Format,
        kBMP_Format,
        kGIF_Format,
        kICO_Format,
        kJPEG_Format,
        kPNG_Format,
        kWBMP_Format,

        kLastKnownFormat = kWBMP_Format
    };

    /** Return the compressed data's format (see Format enum)
    */
    virtual Format getFormat() const;

    /** Returns true if the decoder should try to dither the resulting image.
        The default setting is true.
    */
    bool getDitherImage() const { return fDitherImage; }

    /** Set to true if the the decoder should try to dither the resulting image.
        The default setting is true.
    */
    void setDitherImage(bool dither) { fDitherImage = dither; }

    /** \class Peeker

        Base class for optional callbacks to retrieve meta/chunk data out of
        an image as it is being decoded.
    */
    class Peeker : public SkRefCnt {
    public:
        /** Return true to continue decoding, or false to indicate an error, which
            will cause the decoder to not return the image.
        */
        virtual bool peek(const char tag[], const void* data, size_t length) = 0;
    };

    Peeker* getPeeker() const { return fPeeker; }
    Peeker* setPeeker(Peeker*);

    /** \class Peeker

        Base class for optional callbacks to retrieve meta/chunk data out of
        an image as it is being decoded.
    */
    class Chooser : public SkRefCnt {
    public:
        virtual void begin(int count) {}
        virtual void inspect(int index, SkBitmap::Config config, int width, int height) {}
        /** Return the index of the subimage you want, or -1 to choose none of them.
        */
        virtual int choose() = 0;
    };

    Chooser* getChooser() const { return fChooser; }
    Chooser* setChooser(Chooser*);

    /** This optional table describes the caller's preferred config based on
        information about the src data. For this table, the src attributes are
        described in terms of depth (index (8), 16, 32/24) and if there is
        per-pixel alpha. These inputs combine to create an index into the
        pref[] table, which contains the caller's preferred config for that
        input, or kNo_Config if there is no preference.

        To specify no preferrence, call setPrefConfigTable(NULL), which is
        the default.

        Note, it is still at the discretion of the codec as to what output
        config is actually returned, as it may not be able to support the
        caller's preference.

        Here is how the index into the table is computed from the src:
            depth [8, 16, 32/24] -> 0, 2, 4
            alpha [no, yes] -> 0, 1
        The two index values are OR'd together.
            src: 8-index, no-alpha  -> 0
            src: 8-index, yes-alpha -> 1
            src: 16bit,   no-alpha  -> 2    // e.g. 565
            src: 16bit,   yes-alpha -> 3    // e.g. 1555
            src: 32/24,   no-alpha  -> 4
            src: 32/24,   yes-alpha -> 5
     */
    void setPrefConfigTable(const SkBitmap::Config pref[6]);

    SkBitmap::Allocator* getAllocator() const { return fAllocator; }
    SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);

    // sample-size, if set to > 1, tells the decoder to return a smaller than
    // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample
    // size is set to 3, then the returned bitmap will be 1/3 as wide and high,
    // and will contain 1/9 as many pixels as the original.
    // Note: this is a hint, and the codec may choose to ignore this, or only
    // approximate the sample size.
    int getSampleSize() const { return fSampleSize; }
    void setSampleSize(int size);

    /** Reset the sampleSize to its default of 1
     */
    void resetSampleSize() { this->setSampleSize(1); }

    /** Decoding is synchronous, but for long decodes, a different thread can
        call this method safely. This sets a state that the decoders will
        periodically check, and if they see it changed to cancel, they will
        cancel. This will result in decode() returning false. However, there is
        no guarantee that the decoder will see the state change in time, so
        it is possible that cancelDecode() will be called, but will be ignored
        and decode() will return true (assuming no other problems were
        encountered).

        This state is automatically reset at the beginning of decode().
     */
    void cancelDecode() {
        // now the subclass must query shouldCancelDecode() to be informed
        // of the request
        fShouldCancelDecode = true;
    }

    /** Passed to the decode method. If kDecodeBounds_Mode is passed, then
        only the bitmap's width/height/config need be set. If kDecodePixels_Mode
        is passed, then the bitmap must have pixels or a pixelRef.
    */
    enum Mode {
        kDecodeBounds_Mode, //!< only return width/height/config in bitmap
        kDecodePixels_Mode  //!< return entire bitmap (including pixels)
    };

    /** Given a stream, decode it into the specified bitmap.
        If the decoder can decompress the image, it calls bitmap.setConfig(),
        and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
        which will allocated a pixelRef. To access the pixel memory, the codec
        needs to call lockPixels/unlockPixels on the
        bitmap. It can then set the pixels with the decompressed image.
    *   If the image cannot be decompressed, return false. After the
    *   decoding, the function converts the decoded config in bitmap
    *   to pref if possible. Whether a conversion is feasible is
    *   tested by Bitmap::canCopyTo(pref).

        note: document use of Allocator, Peeker and Chooser
    */
    bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
    bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
        return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode);
    }

    /** Given a stream, this will try to find an appropriate decoder object.
        If none is found, the method returns NULL.
    */
    static SkImageDecoder* Factory(SkStream*);

    /** Decode the image stored in the specified file, and store the result
        in bitmap. Return true for success or false on failure.

        If pref is kNo_Config, then the decoder is free to choose the most natural
        config given the image data. If pref something other than kNo_Config,
        the decoder will attempt to decode the image into that format, unless
        there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
        config does not support that), in which case the decoder will choose a
        closest match configuration.

        @param format On success, if format is non-null, it is set to the format
                      of the decoded file. On failure it is ignored.
    */
    static bool DecodeFile(const char file[], SkBitmap* bitmap,
                           SkBitmap::Config prefConfig, Mode,
                           Format* format = NULL);
    static bool DecodeFile(const char file[], SkBitmap* bitmap) {
        return DecodeFile(file, bitmap, SkBitmap::kNo_Config,
                          kDecodePixels_Mode, NULL);
    }
    /** Decode the image stored in the specified memory buffer, and store the
        result in bitmap. Return true for success or false on failure.

        If pref is kNo_Config, then the decoder is free to choose the most natural
        config given the image data. If pref something other than kNo_Config,
        the decoder will attempt to decode the image into that format, unless
        there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
        config does not support that), in which case the decoder will choose a
        closest match configuration.

        @param format On success, if format is non-null, it is set to the format
                       of the decoded buffer. On failure it is ignored.
     */
    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap,
                             SkBitmap::Config prefConfig, Mode,
                             Format* format = NULL);
    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){
        return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config,
                            kDecodePixels_Mode, NULL);
    }
    /** Decode the image stored in the specified SkStream, and store the result
        in bitmap. Return true for success or false on failure.

        If pref is kNo_Config, then the decoder is free to choose the most
        natural config given the image data. If pref something other than
        kNo_Config, the decoder will attempt to decode the image into that
        format, unless there is a conflict (e.g. the image has per-pixel alpha
        and the bitmap's config does not support that), in which case the
        decoder will choose a closest match configuration.

        @param format On success, if format is non-null, it is set to the format
                      of the decoded stream. On failure it is ignored.
     */
    static bool DecodeStream(SkStream* stream, SkBitmap* bitmap,
                             SkBitmap::Config prefConfig, Mode,
                             Format* format = NULL);
    static bool DecodeStream(SkStream* stream, SkBitmap* bitmap) {
        return DecodeStream(stream, bitmap, SkBitmap::kNo_Config,
                            kDecodePixels_Mode, NULL);
    }

    /** Return the default config for the running device.
        Currently this used as a suggestion to image decoders that need to guess
        what config they should decode into.
        Default is kNo_Config, but this can be changed with SetDeviceConfig()
    */
    static SkBitmap::Config GetDeviceConfig();
    /** Set the default config for the running device.
        Currently this used as a suggestion to image decoders that need to guess
        what config they should decode into.
        Default is kNo_Config.
        This can be queried with GetDeviceConfig()
    */
    static void SetDeviceConfig(SkBitmap::Config);

  /** @cond UNIT_TEST */
    SkDEBUGCODE(static void UnitTest();)
  /** @endcond */

protected:
    // must be overridden in subclasses. This guy is called by decode(...)
    virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;

    /** Can be queried from within onDecode, to see if the user (possibly in
        a different thread) has requested the decode to cancel. If this returns
        true, your onDecode() should stop and return false.
        Each subclass needs to decide how often it can query this, to balance
        responsiveness with performance.

        Calling this outside of onDecode() may return undefined values.
     */

public:
    bool shouldCancelDecode() const { return fShouldCancelDecode; }

protected:
    SkImageDecoder();

    // helper function for decoders to handle the (common) case where there is only
    // once choice available in the image file.
    bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const;

    /*  Helper for subclasses. Call this to allocate the pixel memory given the bitmap's
        width/height/rowbytes/config. Returns true on success. This method handles checking
        for an optional Allocator.
    */
    bool allocPixelRef(SkBitmap*, SkColorTable*) const;

    enum SrcDepth {
        kIndex_SrcDepth,
        k16Bit_SrcDepth,
        k32Bit_SrcDepth
    };
    /** The subclass, inside onDecode(), calls this to determine the config of
        the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the
        src image. This routine returns the caller's preference given
        srcDepth and hasAlpha, or kNo_Config if there is no preference.

        Note: this also takes into account GetDeviceConfig(), so the subclass
        need not call that.
     */
    SkBitmap::Config getPrefConfig(SrcDepth, bool hasAlpha) const;

private:
    Peeker*                 fPeeker;
    Chooser*                fChooser;
    SkBitmap::Allocator*    fAllocator;
    int                     fSampleSize;
    SkBitmap::Config        fDefaultPref;   // use if fUsePrefTable is false
    SkBitmap::Config        fPrefTable[6];  // use if fUsePrefTable is true
    bool                    fDitherImage;
    bool                    fUsePrefTable;
    mutable bool            fShouldCancelDecode;

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

/** Calling newDecoder with a stream returns a new matching imagedecoder
    instance, or NULL if none can be found. The caller must manage its ownership
    of the stream as usual, calling unref() when it is done, as the returned
    decoder may have called ref() (and if so, the decoder is responsible for
    balancing its ownership when it is destroyed).
 */
class SkImageDecoderFactory : public SkRefCnt {
public:
    virtual SkImageDecoder* newDecoder(SkStream*) = 0;
};

class SkDefaultImageDecoderFactory : SkImageDecoderFactory {
public:
    // calls SkImageDecoder::Factory(stream)
    virtual SkImageDecoder* newDecoder(SkStream* stream) {
        return SkImageDecoder::Factory(stream);
    }
};

#endif


code:
#ifndef SkImageEncoder_DEFINED
#define SkImageEncoder_DEFINED

#include "SkTypes.h"

class SkBitmap;
class SkWStream;

class SkImageEncoder {
public:
    enum Type {
        kJPEG_Type,
        kPNG_Type
    };
    static SkImageEncoder* Create(Type);

    virtual ~SkImageEncoder();

    /*  Quality ranges from 0..100 */
    enum {
        kDefaultQuality = 80
    };

    bool encodeFile(const char file[], const SkBitmap&, int quality);
    bool encodeStream(SkWStream*, const SkBitmap&, int quality);

    static bool EncodeFile(const char file[], const SkBitmap&, Type,
                           int quality);
    static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
                           int quality);

protected:
    virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0;
};

#endif

license: mit


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 SkImageRef_DEFINED
#define SkImageRef_DEFINED

#include "SkPixelRef.h"
#include "SkBitmap.h"
#include "SkImageDecoder.h"
#include "SkString.h"

class SkImageRefPool;
class SkStream;

// define this to enable dumping whenever we add/remove/purge an imageref
//#define DUMP_IMAGEREF_LIFECYCLE

class SkImageRef : public SkPixelRef {
public:
    /** Create a new imageref from a stream. NOTE: the stream is not copied, but
        since it may be accessed from another thread, the caller must ensure
        that this imageref is the only owner of the stream. i.e. - sole
        ownership of the stream object is transferred to this imageref object.

        @param stream The stream containing the encoded image data. This may be
                      retained (by calling ref()), so the caller should not
                      explicitly delete it.
        @param config The preferred config of the decoded bitmap.
        @param sampleSize Requested sampleSize for decoding. Defaults to 1.
    */
    SkImageRef(SkStream*, SkBitmap::Config config, int sampleSize = 1);
    virtual ~SkImageRef();

    /** this value is passed onto the decoder. Default is true
     */
    void setDitherImage(bool dither) { fDoDither = dither; }

    /** Return true if the image can be decoded. If so, and bitmap is non-null,
        call its setConfig() with the corresponding values, but explicitly will
        not set its pixels or colortable. Use SkPixelRef::lockPixels() for that.

        If there has been an error decoding the bitmap, this will return false
        and ignore the bitmap parameter.
    */
    bool getInfo(SkBitmap* bm);

    /** Return true if the image can be decoded and is opaque. Calling this
        method will decode and set the pixels in the specified bitmap and
        sets the isOpaque flag.
     */
    bool isOpaque(SkBitmap* bm);

    SkImageDecoderFactory* getDecoderFactory() const { return fFactory; }
    // returns the factory parameter
    SkImageDecoderFactory* setDecoderFactory(SkImageDecoderFactory*);

    // overrides
    virtual void flatten(SkFlattenableWriteBuffer&) const;

protected:
    /** Override if you want to install a custom allocator.
        When this is called we will have already acquired the mutex!
    */
    virtual bool onDecode(SkImageDecoder* codec, SkStream*, SkBitmap*,
                          SkBitmap::Config, SkImageDecoder::Mode);

    /*  Overrides from SkPixelRef
        When these are called, we will have already acquired the mutex!
     */

    virtual void* onLockPixels(SkColorTable**);
    // override this in your subclass to clean up when we're unlocking pixels
    virtual void onUnlockPixels();

    SkImageRef(SkFlattenableReadBuffer&);

    SkBitmap fBitmap;

private:
    SkStream* setStream(SkStream*);
    // called with mutex already held. returns true if the bitmap is in the
    // requested state (or further, i.e. has pixels)
    bool prepareBitmap(SkImageDecoder::Mode);

    SkImageDecoderFactory*  fFactory;    // may be null
    SkStream*               fStream;
    SkBitmap::Config        fConfig;
    int                     fSampleSize;
    bool                    fDoDither;
    bool                    fErrorInDecoding;

    friend class SkImageRefPool;

    SkImageRef*  fPrev, *fNext;
    size_t ramUsed() const;

    typedef SkPixelRef INHERITED;
};

#endif


code:
#ifndef SkImageRefPool_DEFINED
#define SkImageRefPool_DEFINED

#include "SkTypes.h"

class SkImageRef;
class SkImageRef_GlobalPool;

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

    size_t  getRAMBudget() const { return fRAMBudget; }
    void    setRAMBudget(size_t);

    size_t  getRAMUsed() const { return fRAMUsed; }
    void    setRAMUsed(size_t limit);

    void addToHead(SkImageRef*);
    void addToTail(SkImageRef*);
    void detach(SkImageRef*);

    void dump() const;

private:
    size_t fRAMBudget;
    size_t fRAMUsed;

    int         fCount;
    SkImageRef* fHead, *fTail;

    int computeCount() const;

    friend class SkImageRef_GlobalPool;

    void justAddedPixels(SkImageRef*);
    void canLosePixels(SkImageRef*);
    void purgeIfNeeded();
};

#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 SkImageRef_GlobalPool_DEFINED
#define SkImageRef_GlobalPool_DEFINED

#include "SkImageRef.h"

class SkImageRef_GlobalPool : public SkImageRef {
public:
    // if pool is null, use the global pool
    SkImageRef_GlobalPool(SkStream*, SkBitmap::Config, int sampleSize = 1);
    virtual ~SkImageRef_GlobalPool();

    // overrides
    virtual Factory getFactory() const {
        return Create;
    }
    static SkPixelRef* Create(SkFlattenableReadBuffer&);

    // API to control the global pool

    /** Return the amount specified as the budget for the cache (in bytes).
     */
    static size_t GetRAMBudget();

    /** Set a new budget value for the cache.
     */
    static void SetRAMBudget(size_t);

    /** Return how much ram is currently in use by the global cache.
     */
    static size_t GetRAMUsed();

    /** Free up (approximately) enough such that the amount used by the cache
     is <= the specified amount. Since some images may be "in use", the
     amount actually freed may not always result in a ram usage value <=
     to the requested amount. In addition, because of the
     chunky nature of the cache, the resulting usage may be < the requested
     amount.
     */
    static void SetRAMUsed(size_t usageInBytes);

    static void DumpPool();

protected:
    virtual bool onDecode(SkImageDecoder* codec, SkStream* stream,
                          SkBitmap* bitmap, SkBitmap::Config config,
                          SkImageDecoder::Mode mode);

    virtual void onUnlockPixels();

    SkImageRef_GlobalPool(SkFlattenableReadBuffer&);

private:
    typedef SkImageRef INHERITED;
};

#endif


code:
#ifndef SkImageRef_ashmem_DEFINED
#define SkImageRef_ashmem_DEFINED

#include "SkImageRef.h"

struct SkAshmemRec {
    int     fFD;
    void*   fAddr;
    size_t  fSize;
    bool    fPinned;
};

class SkImageRef_ashmem : public SkImageRef {
public:
    SkImageRef_ashmem(SkStream*, SkBitmap::Config, int sampleSize = 1);
    virtual ~SkImageRef_ashmem();

    // overrides
    virtual void flatten(SkFlattenableWriteBuffer&) const;
    virtual Factory getFactory() const {
        return Create;
    }
    static SkPixelRef* Create(SkFlattenableReadBuffer&);

protected:
    virtual bool onDecode(SkImageDecoder* codec, SkStream* stream,
                          SkBitmap* bitmap, SkBitmap::Config config,
                          SkImageDecoder::Mode mode);

    virtual void* onLockPixels(SkColorTable**);
    virtual void onUnlockPixels();

private:
    SkImageRef_ashmem(SkFlattenableReadBuffer&);
    void closeFD();

    SkColorTable* fCT;
    SkAshmemRec fRec;

    typedef SkImageRef 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 SkImageView_DEFINED
#define SkImageView_DEFINED

#include "SkView.h"
#include "SkString.h"

class SkAnimator;
class SkBitmap;
class SkMatrix;

class SkImageView : public SkView {
public:
            SkImageView();
    virtual ~SkImageView();

    void    getUri(SkString*) const;
    void    setUri(const char []);
    void    setUri(const SkString&);

    enum ScaleType {
        kMatrix_ScaleType,
        kFitXY_ScaleType,
        kFitStart_ScaleType,
        kFitCenter_ScaleType,
        kFitEnd_ScaleType
    };
    ScaleType   getScaleType() const { return (ScaleType)fScaleType; }
    void        setScaleType(ScaleType);

    bool    getImageMatrix(SkMatrix*) const;
    void    setImageMatrix(const SkMatrix*);

protected:
    // overrides
    virtual bool    onEvent(const SkEvent&);
    virtual void    onDraw(SkCanvas*);
    virtual void    onInflate(const SkDOM&, const SkDOMNode*);

private:
    SkString    fUri;
    SkMatrix*   fMatrix;    // null or copy of caller's matrix ,,,,,
    union {
        SkAnimator* fAnim;
        SkBitmap* fBitmap;
    } fData;
    uint8_t     fScaleType;
    SkBool8     fDataIsAnim;    // as opposed to bitmap
    SkBool8     fUriIsValid;

    void    onUriChange();
    bool    getDataBounds(SkRect* bounds);
    bool    freeData();
    bool    ensureUriIsLoaded();

    typedef SkView INHERITED;
};

#endif


code:
/* libs/graphics/animator/SkIntArray.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 SkIntArray_DEFINED
#define SkIntArray_DEFINED

#include "SkColor.h"
#include "SkDisplayType.h"
#include "SkMath.h"
#include "SkTDArray_Experimental.h"

class SkActive;
class SkAnimateBase;
class SkDataInput;
class SkDisplayable;
class SkDisplayEvent;
class SkDrawable;
class SkDrawColor;
class SkMatrixPart;
struct SkMemberInfo;
class SkPathPart;
class SkPaintPart;
class SkTypedArray;
class SkString;
union SkOperand;

typedef SkIntArray(int) SkTDIntArray;
typedef SkIntArray(SkColor) SkTDColorArray;
typedef SkIntArray(SkDisplayTypes) SkTDDisplayTypesArray;
typedef SkIntArray(SkMSec) SkTDMSecArray;
typedef SkIntArray(SkScalar) SkTDScalarArray;

typedef SkLongArray(SkActive*) SkTDActiveArray;
typedef SkLongArray(SkAnimateBase*) SkTDAnimateArray;
typedef SkLongArray(SkDataInput*) SkTDDataArray;
typedef SkLongArray(SkDisplayable*) SkTDDisplayableArray;
typedef SkLongArray(SkDisplayEvent*) SkTDDisplayEventArray;
typedef SkLongArray(SkDrawable*) SkTDDrawableArray;
typedef SkLongArray(SkDrawColor*) SkTDDrawColorArray;
typedef SkLongArray(SkMatrixPart*) SkTDMatrixPartArray;
typedef SkLongArray(const SkMemberInfo*) SkTDMemberInfoArray;
typedef SkLongArray(SkPaintPart*) SkTDPaintPartArray;
typedef SkLongArray(SkPathPart*) SkTDPathPartArray;
typedef SkLongArray(SkTypedArray*) SkTDTypedArrayArray;
typedef SkLongArray(SkString*) SkTDStringArray;
typedef SkLongArray(SkOperand) SkTDOperandArray;
typedef SkLongArray(SkOperand*) SkTDOperandPtrArray;

#endif // SkIntArray_DEFINED


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 SkInterpolator_DEFINED
#define SkInterpolator_DEFINED

#include "SkScalar.h"

class SkInterpolatorBase : SkNoncopyable {
public:
    enum Result {
        kNormal_Result,
        kFreezeStart_Result,
        kFreezeEnd_Result
    };
protected:
    SkInterpolatorBase();
    ~SkInterpolatorBase();
public:
    void    reset(int elemCount, int frameCount);

    /** Return the start and end time for this interpolator.
        If there are no key frames, return false.
        @param startTime If not null, returns the time (in milliseconds) of the
                         first keyframe. If there are no keyframes, this param
                         is ignored (left unchanged).
        @param endTime If not null, returns the time (in milliseconds) of the
                       last keyframe. If there are no keyframes, this parameter
                       is ignored (left unchanged).
        @return True if there are key frames, or false if there are none.
    */
    bool    getDuration(SkMSec* startTime, SkMSec* endTime) const;

    /** Set the whether the repeat is mirrored.
        @param mirror If true, the odd repeats interpolate from the last key
                      frame and the first.
    */
    void setMirror(bool mirror) {
        fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror);
    }

    /** Set the repeat count. The repeat count may be fractional.
        @param repeatCount Multiplies the total time by this scalar.
    */
    void    setRepeatCount(SkScalar repeatCount) { fRepeat = repeatCount; }

    /** Set the whether the repeat is mirrored.
        @param reset If true, the odd repeats interpolate from the last key
                     frame and the first.
    */
    void setReset(bool reset) {
        fFlags = SkToU8((fFlags & ~kReset) | (int)reset);
    }

    Result  timeToT(SkMSec time, SkScalar* T, int* index, SkBool* exact) const;

protected:
    enum Flags {
        kMirror = 1,
        kReset = 2,
        kHasBlend = 4
    };
    static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime,
                             SkMSec nextTime, const SkScalar blend[4] = NULL);
    int16_t fFrameCount;
    uint8_t fElemCount;
    uint8_t fFlags;
    SkScalar fRepeat;
    struct SkTimeCode {
        SkMSec  fTime;
        SkScalar fBlend[4];
    };
    SkTimeCode* fTimes;     // pointer into fStorage
    void* fStorage;
#ifdef SK_DEBUG
    SkTimeCode(* fTimesArray)[10];
#endif
};

class SkInterpolator : public SkInterpolatorBase {
public:
    SkInterpolator();
    SkInterpolator(int elemCount, int frameCount);
    void    reset(int elemCount, int frameCount);

    /** 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)
    */
    bool setKeyFrame(int index, SkMSec time, const SkScalar values[],
                     const SkScalar blend[4] = NULL);

    /** Return the computed values given the specified time. Return whether
        those values are the result of pinning to either the first
        (kFreezeStart) or last (kFreezeEnd), or from interpolated the two
        nearest key values (kNormal).
        @param time The time to sample (in milliseconds)
        @param (may be null) where to write the computed values.
    */
    Result timeToValues(SkMSec time, SkScalar values[] = NULL) const;

    SkDEBUGCODE(static void UnitTest();)
private:
    SkScalar* fValues;  // pointer into fStorage
#ifdef SK_DEBUG
    SkScalar(* fScalarsArray)[10];
#endif
    typedef SkInterpolatorBase INHERITED;
};

/** Given all the parameters are [0...1], apply the cubic specified by (0,0)
    (bx,by) (cx,cy) (1,1) to value, returning the answer, also [0...1].
*/
SkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by,
                           SkScalar cx, SkScalar cy);

#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.
 */

#include "SkTypes.h"
#include "SkWindow.h"

extern "C" {
    typedef long JSWord;
    typedef JSWord jsword;
    typedef jsword  jsval;
    typedef struct JSRuntime JSRuntime;
    typedef struct JSContext JSContext;
    typedef struct JSObject JSObject;
}

class SkString;

class SkJS : public SkOSWindow {
public:
    SkJS(void* hwnd);
    ~SkJS();
    SkBool EvaluateScript(const char* script, jsval* rVal);
    SkBool ValueToString(jsval value, SkString* string);
#ifdef SK_DEBUG
    static void Test(void* hwnd);
#endif
protected:
    void InitializeDisplayables(const SkBitmap& , JSContext *, JSObject *, JSObject *);
    void DisposeDisplayables();
    JSRuntime *fRuntime;
    JSContext *fContext;
    JSObject *fGlobal;
};


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 SkJpegUtility_DEFINED
#define SkJpegUtility_DEFINED

#include "SkImageDecoder.h"
#include "SkStream.h"

extern "C" {
    #include "jpeglib.h"
    #include "jerror.h"
}

#include <setjmp.h>

/* Our error-handling struct.
 *
*/
struct skjpeg_error_mgr : jpeg_error_mgr {
    jmp_buf fJmpBuf;
};

void skjpeg_error_exit(j_common_ptr cinfo);

///////////////////////////////////////////////////////////////////////////
/* Our source struct for directing jpeg to our stream object.
*/
struct skjpeg_source_mgr : jpeg_source_mgr {
    skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder, bool ownStream);
    ~skjpeg_source_mgr();

    SkStream*   fStream;
    void*       fMemoryBase;
    size_t      fMemoryBaseSize;
    bool        fUnrefStream;
    SkImageDecoder* fDecoder;
    enum {
        kBufferSize = 1024
    };
    char    fBuffer[kBufferSize];
};

/////////////////////////////////////////////////////////////////////////////
/* Our destination struct for directing decompressed pixels to our stream
 * object.
 */
struct skjpeg_destination_mgr : jpeg_destination_mgr {
    skjpeg_destination_mgr(SkWStream* stream);

    SkWStream*  fStream;

    enum {
        kBufferSize = 1024
    };
    uint8_t fBuffer[kBufferSize];
};

#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 SkKernel33MaskFilter_DEFINED
#define SkKernel33MaskFilter_DEFINED

#include "SkMaskFilter.h"

class SkKernel33ProcMaskFilter : public SkMaskFilter {
public:
    SkKernel33ProcMaskFilter(unsigned percent256 = 256)
        : fPercent256(percent256) {}

    virtual uint8_t computeValue(uint8_t* const* srcRows) = 0;

    // overrides from SkMaskFilter
    virtual SkMask::Format getFormat();
    virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&, SkIPoint*);

    // overrides from SkFlattenable
    virtual void flatten(SkFlattenableWriteBuffer& wb);

protected:
    SkKernel33ProcMaskFilter(SkFlattenableReadBuffer& rb);

private:
    int fPercent256;

    typedef SkMaskFilter INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

class SkKernel33MaskFilter : public SkKernel33ProcMaskFilter {
public:
    SkKernel33MaskFilter(const int coeff[3][3], int shift, int percent256 = 256)
            : SkKernel33ProcMaskFilter(percent256) {
        memcpy(fKernel, coeff, 9 * sizeof(int));
        fShift = shift;
    }

    // override from SkKernel33ProcMaskFilter
    virtual uint8_t computeValue(uint8_t* const* srcRows);

    // overrides from SkFlattenable
    virtual void flatten(SkFlattenableWriteBuffer& wb);
    virtual Factory getFactory();

private:
    int fKernel[3][3];
    int fShift;

    SkKernel33MaskFilter(SkFlattenableReadBuffer& rb);
    static SkFlattenable* Create(SkFlattenableReadBuffer& rb);

    typedef SkKernel33ProcMaskFilter 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 SkKey_DEFINED
#define SkKey_DEFINED

#include "SkTypes.h"

enum SkKey {
    //reordering these to match android.app.KeyEvent
    kNONE_SkKey,    //corresponds to android's UNKNOWN

    kLeftSoftKey_SkKey,
    kRightSoftKey_SkKey,

    kHome_SkKey,    //!< the home key - added to match android
    kBack_SkKey,    //!< (CLR)
    kSend_SkKey,    //!< the green (talk) key
    kEnd_SkKey,     //!< the red key

    k0_SkKey,
    k1_SkKey,
    k2_SkKey,
    k3_SkKey,
    k4_SkKey,
    k5_SkKey,
    k6_SkKey,
    k7_SkKey,
    k8_SkKey,
    k9_SkKey,
    kStar_SkKey,    //!< the * key
    kHash_SkKey,    //!< the # key

    kUp_SkKey,
    kDown_SkKey,
    kLeft_SkKey,
    kRight_SkKey,

    kOK_SkKey,      //!< the center key

    kVolUp_SkKey,   //!< volume up - match android
    kVolDown_SkKey, //!< volume down - same
    kPower_SkKey,   //!< power button - same
    kCamera_SkKey,  //!< camera         - same

    kSkKeyCount
};

#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 SkLayer_DEFINED
#define SkLayer_DEFINED

#include "SkRefCnt.h"
#include "SkTDArray.h"
#include "SkColor.h"
#include "SkMatrix.h"
#include "SkPoint.h"
#include "SkRect.h"
#include "SkSize.h"

class SkCanvas;

class SkLayer : public SkRefCnt {

public:
    SkLayer();
    SkLayer(const SkLayer&);
    virtual ~SkLayer();

    bool isInheritFromRootTransform() const;
    SkScalar getOpacity() const { return m_opacity; }
    const SkSize& getSize() const { return m_size; }
    const SkPoint& getPosition() const { return m_position; }
    const SkPoint& getAnchorPoint() const { return m_anchorPoint; }
    const SkMatrix& getMatrix() const { return fMatrix; }
    const SkMatrix& getChildrenMatrix() const { return fChildrenMatrix; }

    SkScalar getWidth() const { return m_size.width(); }
    SkScalar getHeight() const { return m_size.height(); }

    void setInheritFromRootTransform(bool);
    void setOpacity(SkScalar opacity) { m_opacity = opacity; }
    void setSize(SkScalar w, SkScalar h) { m_size.set(w, h); }
    void setPosition(SkScalar x, SkScalar y) { m_position.set(x, y); }
    void setAnchorPoint(SkScalar x, SkScalar y) { m_anchorPoint.set(x, y); }
    void setMatrix(const SkMatrix&);
    void setChildrenMatrix(const SkMatrix&);

    // children

    /** Return the number of layers in our child list.
     */
    int countChildren() const;

    /** Return the child at the specified index (starting at 0). This does not
        affect the reference count of the child.
     */
    SkLayer* getChild(int index) const;

    /** Add this layer to our child list at the end (top-most), and ref() it.
        If it was already in another hierarchy, remove it from that list.
        Return the new child.
     */
    SkLayer* addChild(SkLayer* child);

    /** Remove this layer from its parent's list (or do nothing if it has no
        parent.) If it had a parent, then unref() is called.
     */
    void detachFromParent();

    /** Remove, and unref(), all of the layers in our child list.
     */
    void removeChildren();

    /** Return our parent layer, or NULL if we have none.
     */
    SkLayer* getParent() const { return fParent; }

    /** Return the root layer in this hiearchy. If this layer is the root
        (i.e. has no parent), then this returns itself.
     */
    SkLayer* getRootLayer() const;

    // coordinate system transformations

    /** Return, in matrix, the matix transfomations that are applied locally
        when this layer draws (i.e. its position and matrix/anchorPoint).
        This does not include the childrenMatrix, since that is only applied
        after this layer draws (but before its children draw).
     */
    void getLocalTransform(SkMatrix* matrix) const;

    /** Return, in matrix, the concatenation of transforms that are applied
        from this layer's root parent to the layer itself.
        This is the matrix that is applied to the layer during drawing.
     */
    void localToGlobal(SkMatrix* matrix) const;

    // paint method

    void draw(SkCanvas*, SkScalar opacity);
    void draw(SkCanvas* canvas) {
        this->draw(canvas, SK_Scalar1);
    }

protected:
    virtual void onDraw(SkCanvas*, SkScalar opacity);

private:
    enum Flags {
        kInheritFromRootTransform_Flag = 0x01
    };

    SkLayer*    fParent;
    SkScalar    m_opacity;
    SkSize      m_size;
    SkPoint     m_position;
    SkPoint     m_anchorPoint;
    SkMatrix    fMatrix;
    SkMatrix    fChildrenMatrix;
    uint32_t    fFlags;

    SkTDArray<SkLayer*> m_children;

    typedef SkRefCnt INHERITED;
};

#endif


code:
#ifndef SkLayerDrawLooper_DEFINED
#define SkLayerDrawLooper_DEFINED

#include "SkDrawLooper.h"
#include "SkXfermode.h"

struct SkPoint;

class SK_API SkLayerDrawLooper : public SkDrawLooper {
public:
            SkLayerDrawLooper();
    virtual ~SkLayerDrawLooper();

    /**
     *  Bits specifies which aspects of the layer's paint should replace the
     *  corresponding aspects on the draw's paint.
     *  kEntirePaint_Bits means use the layer's paint completely.
     *  0 means ignore the layer's paint.
     */
    enum Bits {
        kStyle_Bit      = 1 << 0,   //!< use this layer's Style/stroke settings
        kTextSkewX_Bit  = 1 << 1,   //!< use this layer's textskewx
        kPathEffect_Bit = 1 << 2,   //!< use this layer's patheffect
        kMaskFilter_Bit = 1 << 3,   //!< use this layer's maskfilter
        kShader_Bit     = 1 << 4,   //!< use this layer's shader
        kColorFilter_Bit = 1 << 5,  //!< use this layer's colorfilter
        kXfermode_Bit   = 1 << 6,   //!< use this layer's xfermode

        kEntirePaint_Bits = -1,      //!< use this layer's paint entirely
    };
    typedef int32_t BitFlags;

    /**
     *  Info for how to apply the layer's paint and offset.
     *
     *  fFlagsMask selects which flags in the layer's paint should be applied.
     *      result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask)
     *  In the extreme:
     *      If fFlagsMask is 0, we ignore all of the layer's flags
     *      If fFlagsMask is -1, we use all of the layer's flags
     *
     *  fColorMode controls how we compute the final color for the layer:
     *      The layer's paint's color is treated as the SRC
     *      The draw's paint's color is treated as the DST
     *      final-color = Mode(layers-color, draws-color);
     *  Any SkXfermode::Mode will work. Two common choices are:
     *      kSrc_Mode: to use the layer's color, ignoring the draw's
     *      kDst_Mode: to just keep the draw's color, ignoring the layer's
     */
    struct SK_API LayerInfo {
        uint32_t            fFlagsMask; // SkPaint::Flags
        BitFlags            fPaintBits;
        SkXfermode::Mode    fColorMode;
        SkVector            fOffset;
        bool                fPostTranslate; //!< applies to fOffset

        /**
         *  Initial the LayerInfo. Defaults to settings that will draw the
         *  layer with no changes: e.g.
         *      fPaintBits == 0
         *      fColorMode == kDst_Mode
         *      fOffset == (0, 0)
         */
        LayerInfo();
    };

    /**
     *  Call for each layer you want to add (from top to bottom).
     *  This returns a paint you can modify, but that ptr is only valid until
     *  the next call made to addLayer().
     */
    SkPaint* addLayer(const LayerInfo&);

    /**
     *  This layer will draw with the original paint, ad the specified offset
     */
    void addLayer(SkScalar dx, SkScalar dy);

    /**
     *  This layer will with the original paint and no offset.
     */
    void addLayer() { this->addLayer(0, 0); }

    // overrides from SkDrawLooper
    virtual void init(SkCanvas*);
    virtual bool next(SkCanvas*, SkPaint* paint);

    // must be public for Registrar :(
    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
        return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
    }

protected:
    SkLayerDrawLooper(SkFlattenableReadBuffer&);

    // overrides from SkFlattenable
    virtual void flatten(SkFlattenableWriteBuffer& );
    virtual Factory getFactory() { return CreateProc; }

private:
    struct Rec {
        Rec*    fNext;
        SkPaint fPaint;
        LayerInfo fInfo;

        static Rec* Reverse(Rec*);
    };
    Rec*    fRecs;
    int     fCount;

    // state-machine during the init/next cycle
    Rec* fCurrRec;

    static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);

    class MyRegistrar : public SkFlattenable::Registrar {
    public:
        MyRegistrar();
    };

    typedef SkDrawLooper 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 SkLayerRasterizer_DEFINED
#define SkLayerRasterizer_DEFINED

#include "SkRasterizer.h"
#include "SkDeque.h"
#include "SkScalar.h"

class SkPaint;

class SkLayerRasterizer : public SkRasterizer {
public:
            SkLayerRasterizer();
    virtual ~SkLayerRasterizer();

    void addLayer(const SkPaint& paint) {
        this->addLayer(paint, 0, 0);
    }

	/**	Add a new layer (above any previous layers) to the rasterizer.
		The layer will extract those fields that affect the mask from
		the specified paint, but will not retain a reference to the paint
		object itself, so it may be reused without danger of side-effects.
	*/
    void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy);

    // overrides from SkFlattenable
    virtual Factory getFactory();
    virtual void    flatten(SkFlattenableWriteBuffer&);

protected:
    SkLayerRasterizer(SkFlattenableReadBuffer&);

    // override from SkRasterizer
    virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
                             const SkIRect* clipBounds,
                             SkMask* mask, SkMask::CreateMode mode);

private:
    SkDeque fLayers;

    static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);

    typedef SkRasterizer INHERITED;
};

#endif


code:
#ifndef SkLineClipper_DEFINED
#define SkLineClipper_DEFINED

#include "SkRect.h"
#include "SkPoint.h"

class SkLineClipper {
public:
    enum {
        kMaxPoints = 4
    };

    /*  Clip the line pts[0]...pts[1] against clip, ignoring segments that
        lie completely above or below the clip. For portions to the left or
        right, turn those into vertical line segments that are aligned to the
        edge of the clip.

        Return the number of line segments that result, and store the end-points
        of those segments sequentially in lines as follows:
            1st segment: lines[0]..lines[1]
            2nd segment: lines[1]..lines[2]
            3rd segment: lines[2]..lines[3]
     */
    static int ClipLine(const SkPoint pts[2], const SkRect& clip,
                        SkPoint lines[kMaxPoints]);

    /*  Intersect the line segment against the rect. If there is a non-empty
        resulting segment, return true and set dst[] to that segment. If not,
        return false and ignore dst[].

        ClipLine is specialized for scan-conversion, as it adds vertical
        segments on the sides to show where the line extended beyond the
        left or right sides. IntersectLine does not.
     */
    static bool IntersectLine(const SkPoint src[2], const SkRect& clip,
                              SkPoint dst[2]);
};

#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 SkMMapStream_DEFINED
#define SkMMapStream_DEFINED

#include "SkStream.h"

class SkMMAPStream : public SkMemoryStream {
public:
    SkMMAPStream(const char filename[]);
    virtual ~SkMMAPStream();

    virtual void setMemory(const void* data, size_t length, bool);
private:
    int     fFildes;
    void*   fAddr;
    size_t  fSize;

    void closeMMap();

    typedef SkMemoryStream INHERITED;
};

#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 SkMallocPixelRef_DEFINED
#define SkMallocPixelRef_DEFINED

#include "SkPixelRef.h"

/** We explicitly use the same allocator for our pixels that SkMask does,
    so that we can freely assign memory allocated by one class to the other.
*/
class SkMallocPixelRef : public SkPixelRef {
public:
    /** Allocate the specified buffer for pixels. The memory is freed when the
        last owner of this pixelref is gone. If addr is NULL, sk_malloc_throw()
        is called to allocate it.
     */
    SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable);
    virtual ~SkMallocPixelRef();

    //! Return the allocation size for the pixels
    size_t getSize() const { return fSize; }
    void* getAddr() const { return fStorage; }

    // overrides from SkPixelRef
    virtual void flatten(SkFlattenableWriteBuffer&) const;
    virtual Factory getFactory() const {
        return Create;
    }
    static SkPixelRef* Create(SkFlattenableReadBuffer& buffer) {
        return SkNEW_ARGS(SkMallocPixelRef, (buffer));
    }

protected:
    // overrides from SkPixelRef
    virtual void* onLockPixels(SkColorTable**);
    virtual void onUnlockPixels();

    SkMallocPixelRef(SkFlattenableReadBuffer& buffer);

private:
    void*           fStorage;
    size_t          fSize;
    SkColorTable*   fCTable;

    typedef SkPixelRef 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 SkMask_DEFINED
#define SkMask_DEFINED

#include "SkRect.h"

/** \class SkMask
    SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
    the 3-channel 3D format. These are passed to SkMaskFilter objects.
*/
struct SkMask {
    enum Format {
        kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
        kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
        k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
        kARGB32_Format,         //!< SkPMColor
        kLCD16_Format,          //!< 565 alpha for r/g/b
        kLCD32_Format           //!< 888 alpha for r/g/b
    };

    enum {
        kCountMaskFormats = kLCD32_Format + 1
    };

    uint8_t*    fImage;
    SkIRect     fBounds;
    uint32_t    fRowBytes;
    Format      fFormat;

    /** Returns true if the mask is empty: i.e. it has an empty bounds.
     */
    bool isEmpty() const { return fBounds.isEmpty(); }

    /** Return the byte size of the mask, assuming only 1 plane.
        Does not account for k3D_Format. For that, use computeTotalImageSize().
        If there is an overflow of 32bits, then returns 0.
    */
    size_t computeImageSize() const;

    /** Return the byte size of the mask, taking into account
        any extra planes (e.g. k3D_Format).
        If there is an overflow of 32bits, then returns 0.
    */
    size_t computeTotalImageSize() const;

    /** Returns the address of the byte that holds the specified bit.
        Asserts that the mask is kBW_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */
    uint8_t* getAddr1(int x, int y) const {
        SkASSERT(fFormat == kBW_Format);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != NULL);
        return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
    }

    /** Returns the address of the specified byte.
        Asserts that the mask is kA8_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */
    uint8_t* getAddr(int x, int y) const {
        SkASSERT(fFormat != kBW_Format);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != NULL);
        return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
    }

    /**
     *  Return the address of the specified 16bit mask. In the debug build,
     *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
     *  are contained in the mask's fBounds.
     */
    uint16_t* getAddrLCD16(int x, int y) const {
        SkASSERT(kLCD16_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != NULL);
        uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
        return row + (x - fBounds.fLeft);
    }

    /**
     *  Return the address of the specified 32bit mask. In the debug build,
     *  this asserts that the mask's format is kLCD32_Format, and that (x,y)
     *  are contained in the mask's fBounds.
     */
    uint32_t* getAddrLCD32(int x, int y) const {
        SkASSERT(kLCD32_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != NULL);
        uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
        return row + (x - fBounds.fLeft);
    }

    static uint8_t* AllocImage(size_t bytes);
    static void FreeImage(void* image);

    enum CreateMode {
        kJustComputeBounds_CreateMode,      //!< compute bounds and return
        kJustRenderImage_CreateMode,        //!< render into preallocate mask
        kComputeBoundsAndRenderImage_CreateMode  //!< compute bounds, alloc image and render into it
    };
};

#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 SkMaskFilter_DEFINED
#define SkMaskFilter_DEFINED

#include "SkFlattenable.h"
#include "SkMask.h"

class SkBlitter;
class SkBounder;
class SkMatrix;
class SkPath;
class SkRegion;

/** \class SkMaskFilter

    SkMaskFilter is the base class for object that perform transformations on
    an alpha-channel mask before drawing it. A subclass of SkMaskFilter may be
    installed into a SkPaint. Once there, each time a primitive is drawn, it
    is first scan converted into a SkMask::kA8_Format mask, and handed to the
    filter, calling its filterMask() method. If this returns true, then the
    new mask is used to render into the device.

    Blur and emboss are implemented as subclasses of SkMaskFilter.
*/
class SkMaskFilter : public SkFlattenable {
public:
    SkMaskFilter() {}

    /** Returns the format of the resulting mask that this subclass will return
        when its filterMask() method is called.
    */
    virtual SkMask::Format getFormat() = 0;

    /** Create a new mask by filter the src mask.
        If src.fImage == null, then do not allocate or create the dst image
        but do fill out the other fields in dstMask.
        If you do allocate a dst image, use SkMask::AllocImage()
        If this returns false, dst mask is ignored.
        @param  dst the result of the filter. If src.fImage == null, dst should not allocate its image
        @param src the original image to be filtered.
        @param matrix the CTM
        @param margin   if not null, return the buffer dx/dy need when calculating the effect. Used when
                        drawing a clipped object to know how much larger to allocate the src before
                        applying the filter. If returning false, ignore this parameter.
        @return true if the dst mask was correctly created.
    */
    virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                            SkIPoint* margin);

    /** Helper method that, given a path in device space, will rasterize it into a kA8_Format mask
        and then call filterMask(). If this returns true, the specified blitter will be called
        to render that mask. Returns false if filterMask() returned false.
        This method is not exported to java.
    */
    bool filterPath(const SkPath& devPath, const SkMatrix& devMatrix,
                    const SkRegion& devClip, SkBounder*, SkBlitter* blitter);

    virtual void flatten(SkFlattenableWriteBuffer& ) {}

protected:
    // empty for now, but lets get our subclass to remember to init us for the future
    SkMaskFilter(SkFlattenableReadBuffer&) {}
};

/** \class SkAutoMaskImage

    Stack class used to manage the fImage buffer in a SkMask.
    When this object loses scope, the buffer is freed with SkMask::FreeImage().
*/
class SkAutoMaskImage {
public:
    SkAutoMaskImage(SkMask* mask, bool alloc) {
        if (alloc) {
            mask->fImage = SkMask::AllocImage(mask->computeImageSize());
        }
        fImage = mask->fImage;
    }

    ~SkAutoMaskImage() {
        SkMask::FreeImage(fImage);
    }
private:
    uint8_t*    fImage;
};

#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 SkMath_DEFINED
#define SkMath_DEFINED

#include "SkTypes.h"

//! Returns the number of leading zero bits (0...32)
int SkCLZ_portable(uint32_t);

/** Computes the 64bit product of a * b, and then shifts the answer down by
    shift bits, returning the low 32bits. shift must be [0..63]
    e.g. to perform a fixedmul, call SkMulShift(a, b, 16)
*/
int32_t SkMulShift(int32_t a, int32_t b, unsigned shift);

/** Computes numer1 * numer2 / denom in full 64 intermediate precision.
    It is an error for denom to be 0. There is no special handling if
    the result overflows 32bits.
*/
int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);

/** Computes (numer1 << shift) / denom in full 64 intermediate precision.
    It is an error for denom to be 0. There is no special handling if
    the result overflows 32bits.
*/
int32_t SkDivBits(int32_t numer, int32_t denom, int shift);

/** Return the integer square root of value, with a bias of bitBias
*/
int32_t SkSqrtBits(int32_t value, int bitBias);

/** Return the integer square root of n, treated as a SkFixed (16.16)
*/
#define SkSqrt32(n)         SkSqrtBits(n, 15)

/** Return the integer cube root of value, with a bias of bitBias
 */
int32_t SkCubeRootBits(int32_t value, int bitBias);

/** Returns -1 if n < 0, else returns 0
*/
#define SkExtractSign(n)    ((int32_t)(n) >> 31)

/** If sign == -1, returns -n, else sign must be 0, and returns n.
    Typically used in conjunction with SkExtractSign().
*/
static inline int32_t SkApplySign(int32_t n, int32_t sign) {
    SkASSERT(sign == 0 || sign == -1);
    return (n ^ sign) - sign;
}

/** Return x with the sign of y */
static inline int32_t SkCopySign32(int32_t x, int32_t y) {
    return SkApplySign(x, SkExtractSign(x ^ y));
}

/** Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
*/
static inline int SkClampPos(int value) {
    return value & ~(value >> 31);
}

/** Given an integer and a positive (max) integer, return the value
    pinned against 0 and max, inclusive.
    @param value    The value we want returned pinned between [0...max]
    @param max      The positive max value
    @return 0 if value < 0, max if value > max, else value
*/
static inline int SkClampMax(int value, int max) {
    // ensure that max is positive
    SkASSERT(max >= 0);
    if (value < 0) {
        value = 0;
    }
    if (value > max) {
        value = max;
    }
    return value;
}

/** Given a positive value and a positive max, return the value
    pinned against max.
    Note: only works as long as max - value doesn't wrap around
    @return max if value >= max, else value
*/
static inline unsigned SkClampUMax(unsigned value, unsigned max) {
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
    if (value > max) {
        value = max;
    }
    return value;
#else
    int diff = max - value;
    // clear diff if diff is positive
    diff &= diff >> 31;

    return value + diff;
#endif
}

///////////////////////////////////////////////////////////////////////////////

#if defined(__arm__)
    #define SkCLZ(x)    __builtin_clz(x)
#endif

#ifndef SkCLZ
    #define SkCLZ(x)    SkCLZ_portable(x)
#endif

///////////////////////////////////////////////////////////////////////////////

/** Returns the smallest power-of-2 that is >= the specified value. If value
    is already a power of 2, then it is returned unchanged. It is undefined
    if value is <= 0.
*/
static inline int SkNextPow2(int value) {
    SkASSERT(value > 0);
    return 1 << (32 - SkCLZ(value - 1));
}

/** Returns the log2 of the specified value, were that value to be rounded up
    to the next power of 2. It is undefined to pass 0. Examples:
         SkNextLog2(1) -> 0
         SkNextLog2(2) -> 1
         SkNextLog2(3) -> 2
         SkNextLog2(4) -> 2
         SkNextLog2(5) -> 3
*/
static inline int SkNextLog2(uint32_t value) {
    SkASSERT(value != 0);
    return 32 - SkCLZ(value - 1);
}

/** Returns true if value is a power of 2. Does not explicitly check for
    value <= 0.
 */
static inline bool SkIsPow2(int value) {
    return (value & (value - 1)) == 0;
}

///////////////////////////////////////////////////////////////////////////////

/** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
    With this requirement, we can generate faster instructions on some
    architectures.
*/
#if defined(__arm__) \
  && !defined(__thumb__) \
  && !defined(__ARM_ARCH_4T__) \
  && !defined(__ARM_ARCH_5T__)
    static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
        SkASSERT((int16_t)x == x);
        SkASSERT((int16_t)y == y);
        int32_t product;
        asm("smulbb %0, %1, %2 \n"
            : "=r"(product)
            : "r"(x), "r"(y)
            );
        return product;
    }
#else
    #ifdef SK_DEBUG
        static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
            SkASSERT((int16_t)x == x);
            SkASSERT((int16_t)y == y);
            return x * y;
        }
    #else
        #define SkMulS16(x, y)  ((x) * (y))
    #endif
#endif

/** Return a*b/255, truncating away any fractional bits. Only valid if both
    a and b are 0..255
*/
static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
    SkASSERT((uint8_t)a == a);
    SkASSERT((uint8_t)b == b);
    unsigned prod = SkMulS16(a, b) + 1;
    return (prod + (prod >> 8)) >> 8;
}

/** Return a*b/255, rounding any fractional bits. Only valid if both
    a and b are 0..255
 */
static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
    SkASSERT((uint8_t)a == a);
    SkASSERT((uint8_t)b == b);
    unsigned prod = SkMulS16(a, b) + 128;
    return (prod + (prod >> 8)) >> 8;
}

/** Return (a*b)/255, taking the ceiling of any fractional bits. Only valid if
    both a and b are 0..255. The expected result equals (a * b + 254) / 255.
 */
static inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) {
    SkASSERT((uint8_t)a == a);
    SkASSERT((uint8_t)b == b);
    unsigned prod = SkMulS16(a, b) + 255;
    return (prod + (prod >> 8)) >> 8;
}

/** Return a*b/((1 << shift) - 1), rounding any fractional bits.
    Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
*/
static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
    SkASSERT(a <= 32767);
    SkASSERT(b <= 32767);
    SkASSERT(shift > 0 && shift <= 8);
    unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
    return (prod + (prod >> shift)) >> shift;
}

/** Just the rounding step in SkDiv255Round: round(value / 255)
 */
static inline unsigned SkDiv255Round(unsigned prod) {
    prod += 128;
    return (prod + (prod >> 8)) >> 8;
}

#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 SkMatrix_DEFINED
#define SkMatrix_DEFINED

#include "SkRect.h"

class SkString;

/** \class SkMatrix

    The SkMatrix class holds a 3x3 matrix for transforming coordinates.
    SkMatrix does not have a constructor, so it must be explicitly initialized
    using either reset() - to construct an identity matrix, or one of the set
    functions (e.g. setTranslate, setRotate, etc.).
*/
class SK_API SkMatrix {
public:
    /** Enum of bit fields for the mask return by getType().
        Use this to identify the complexity of the matrix.
    */
    enum TypeMask {
        kIdentity_Mask      = 0,
        kTranslate_Mask     = 0x01,  //!< set if the matrix has translation
        kScale_Mask         = 0x02,  //!< set if the matrix has X or Y scale
        kAffine_Mask        = 0x04,  //!< set if the matrix skews or rotates
        kPerspective_Mask   = 0x08   //!< set if the matrix is in perspective
    };

    /** Returns a mask bitfield describing the types of transformations
        that the matrix will perform. This information is used by routines
        like mapPoints, to optimize its inner loops to only perform as much
        arithmetic as is necessary.
    */
    TypeMask getType() const {
        if (fTypeMask & kUnknown_Mask) {
            fTypeMask = this->computeTypeMask();
        }
        // only return the public masks
        return (TypeMask)(fTypeMask & 0xF);
    }

    /** Returns true if the matrix is identity.
    */
    bool isIdentity() const {
        return this->getType() == 0;
    }

    /** Returns true if will map a rectangle to another rectangle. This can be
        true if the matrix is identity, scale-only, or rotates a multiple of
        90 degrees.
    */
    bool rectStaysRect() const {
        if (fTypeMask & kUnknown_Mask) {
            fTypeMask = this->computeTypeMask();
        }
        return (fTypeMask & kRectStaysRect_Mask) != 0;
    }
    // alias for rectStaysRect()
    bool preservesAxisAlignment() const { return this->rectStaysRect(); }

    /**
     *  Returns true if the perspective contains perspective elements.
     */
    bool hasPerspective() const {
        return SkToBool(this->getType() & kPerspective_Mask);
    }

    enum {
        kMScaleX,
        kMSkewX,
        kMTransX,
        kMSkewY,
        kMScaleY,
        kMTransY,
        kMPersp0,
        kMPersp1,
        kMPersp2
    };

    SkScalar operator[](int index) const {
        SkASSERT((unsigned)index < 9);
        return fMat[index];
    }

    SkScalar get(int index) const {
        SkASSERT((unsigned)index < 9);
        return fMat[index];
    }

    SkScalar getScaleX() const { return fMat[kMScaleX]; }
    SkScalar getScaleY() const { return fMat[kMScaleY]; }
    SkScalar getSkewY() const { return fMat[kMSkewY]; }
    SkScalar getSkewX() const { return fMat[kMSkewX]; }
    SkScalar getTranslateX() const { return fMat[kMTransX]; }
    SkScalar getTranslateY() const { return fMat[kMTransY]; }
    SkScalar getPerspX() const { return fMat[kMPersp0]; }
    SkScalar getPerspY() const { return fMat[kMPersp1]; }

    SkScalar& operator[](int index) {
        SkASSERT((unsigned)index < 9);
        this->setTypeMask(kUnknown_Mask);
        return fMat[index];
    }

    void set(int index, SkScalar value) {
        SkASSERT((unsigned)index < 9);
        fMat[index] = value;
        this->setTypeMask(kUnknown_Mask);
    }

    void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
    void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
    void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
    void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
    void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
    void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
    void setPerspX(SkScalar v) { this->set(kMPersp0, v); }
    void setPerspY(SkScalar v) { this->set(kMPersp1, v); }

    void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
                SkScalar skewY, SkScalar scaleY, SkScalar transY,
                SkScalar persp0, SkScalar persp1, SkScalar persp2) {
        fMat[kMScaleX] = scaleX;
        fMat[kMSkewX]  = skewX;
        fMat[kMTransX] = transX;
        fMat[kMSkewY]  = skewY;
        fMat[kMScaleY] = scaleY;
        fMat[kMTransY] = transY;
        fMat[kMPersp0] = persp0;
        fMat[kMPersp1] = persp1;
        fMat[kMPersp2] = persp2;
        this->setTypeMask(kUnknown_Mask);
    }

    /** Set the matrix to identity
    */
    void reset();
    // alias for reset()
    void setIdentity() { this->reset(); }

    /** Set the matrix to translate by (dx, dy).
    */
    void setTranslate(SkScalar dx, SkScalar dy);
    /** Set the matrix to scale by sx and sy, with a pivot point at (px, py).
        The pivot point is the coordinate that should remain unchanged by the
        specified transformation.
    */
    void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
    /** Set the matrix to scale by sx and sy.
    */
    void setScale(SkScalar sx, SkScalar sy);
    /** Set the matrix to rotate by the specified number of degrees, with a
        pivot point at (px, py). The pivot point is the coordinate that should
        remain unchanged by the specified transformation.
    */
    void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
    /** Set the matrix to rotate about (0,0) by the specified number of degrees.
    */
    void setRotate(SkScalar degrees);
    /** Set the matrix to rotate by the specified sine and cosine values, with
        a pivot point at (px, py). The pivot point is the coordinate that
        should remain unchanged by the specified transformation.
    */
    void setSinCos(SkScalar sinValue, SkScalar cosValue,
                   SkScalar px, SkScalar py);
    /** Set the matrix to rotate by the specified sine and cosine values.
    */
    void setSinCos(SkScalar sinValue, SkScalar cosValue);
    /** Set the matrix to skew by sx and sy, with a pivot point at (px, py).
        The pivot point is the coordinate that should remain unchanged by the
        specified transformation.
    */
    void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
    /** Set the matrix to skew by sx and sy.
    */
    void setSkew(SkScalar kx, SkScalar ky);
    /** Set the matrix to the concatenation of the two specified matrices,
        returning true if the the result can be represented. Either of the
        two matrices may also be the target matrix. *this = a * b;
    */
    bool setConcat(const SkMatrix& a, const SkMatrix& b);

    /** Preconcats the matrix with the specified translation.
        M' = M * T(dx, dy)
    */
    bool preTranslate(SkScalar dx, SkScalar dy);
    /** Preconcats the matrix with the specified scale.
        M' = M * S(sx, sy, px, py)
    */
    bool preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
    /** Preconcats the matrix with the specified scale.
        M' = M * S(sx, sy)
    */
    bool preScale(SkScalar sx, SkScalar sy);
    /** Preconcats the matrix with the specified rotation.
        M' = M * R(degrees, px, py)
    */
    bool preRotate(SkScalar degrees, SkScalar px, SkScalar py);
    /** Preconcats the matrix with the specified rotation.
        M' = M * R(degrees)
    */
    bool preRotate(SkScalar degrees);
    /** Preconcats the matrix with the specified skew.
        M' = M * K(kx, ky, px, py)
    */
    bool preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
    /** Preconcats the matrix with the specified skew.
        M' = M * K(kx, ky)
    */
    bool preSkew(SkScalar kx, SkScalar ky);
    /** Preconcats the matrix with the specified matrix.
        M' = M * other
    */
    bool preConcat(const SkMatrix& other);

    /** Postconcats the matrix with the specified translation.
        M' = T(dx, dy) * M
    */
    bool postTranslate(SkScalar dx, SkScalar dy);
    /** Postconcats the matrix with the specified scale.
        M' = S(sx, sy, px, py) * M
    */
    bool postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
    /** Postconcats the matrix with the specified scale.
        M' = S(sx, sy) * M
    */
    bool postScale(SkScalar sx, SkScalar sy);
    /** Postconcats the matrix by dividing it by the specified integers.
        M' = S(1/divx, 1/divy, 0, 0) * M
    */
    bool postIDiv(int divx, int divy);
    /** Postconcats the matrix with the specified rotation.
        M' = R(degrees, px, py) * M
    */
    bool postRotate(SkScalar degrees, SkScalar px, SkScalar py);
    /** Postconcats the matrix with the specified rotation.
        M' = R(degrees) * M
    */
    bool postRotate(SkScalar degrees);
    /** Postconcats the matrix with the specified skew.
        M' = K(kx, ky, px, py) * M
    */
    bool postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
    /** Postconcats the matrix with the specified skew.
        M' = K(kx, ky) * M
    */
    bool postSkew(SkScalar kx, SkScalar ky);
    /** Postconcats the matrix with the specified matrix.
        M' = other * M
    */
    bool postConcat(const SkMatrix& other);

    enum ScaleToFit {
        /**
         * Scale in X and Y independently, so that src matches dst exactly.
         * This may change the aspect ratio of the src.
         */
        kFill_ScaleToFit,
        /**
         * Compute a scale that will maintain the original src aspect ratio,
         * but will also ensure that src fits entirely inside dst. At least one
         * axis (X or Y) will fit exactly. kStart aligns the result to the
         * left and top edges of dst.
         */
        kStart_ScaleToFit,
        /**
         * Compute a scale that will maintain the original src aspect ratio,
         * but will also ensure that src fits entirely inside dst. At least one
         * axis (X or Y) will fit exactly. The result is centered inside dst.
         */
        kCenter_ScaleToFit,
        /**
         * Compute a scale that will maintain the original src aspect ratio,
         * but will also ensure that src fits entirely inside dst. At least one
         * axis (X or Y) will fit exactly. kEnd aligns the result to the
         * right and bottom edges of dst.
         */
        kEnd_ScaleToFit
    };

    /** Set the matrix to the scale and translate values that map the source
        rectangle to the destination rectangle, returning true if the the result
        can be represented.
        @param src the source rectangle to map from.
        @param dst the destination rectangle to map to.
        @param stf the ScaleToFit option
        @return true if the matrix can be represented by the rectangle mapping.
    */
    bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf);

    /** Set the matrix such that the specified src points would map to the
        specified dst points. count must be within [0..4].
        @param src  The array of src points
        @param dst  The array of dst points
        @param count The number of points to use for the transformation
        @return true if the matrix was set to the specified transformation
    */
    bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count);

    /** If this matrix can be inverted, return true and if inverse is not null,
        set inverse to be the inverse of this matrix. If this matrix cannot be
        inverted, ignore inverse and return false
    */
    bool invert(SkMatrix* inverse) const;

    /** Fills the passed array with the tranform values in the right order
        for PDFs.  If the matrix is a perspective transform, returns false
        and fills the array with an identity transform.
        @param transform  The array to fill in.
    */
    bool pdfTransform(SkScalar transform[6]) const;

    /** Apply this matrix to the array of points specified by src, and write
        the transformed points into the array of points specified by dst.
        dst[] = M * src[]
        @param dst  Where the transformed coordinates are written. It must
                    contain at least count entries
        @param src  The original coordinates that are to be transformed. It
                    must contain at least count entries
        @param count The number of points in src to read, and then transform
                     into dst.
    */
    void mapPoints(SkPoint dst[], const SkPoint src[], int count) const;

    /** Apply this matrix to the array of points, overwriting it with the
        transformed values.
        dst[] = M * pts[]
        @param pts  The points to be transformed. It must contain at least
                    count entries
        @param count The number of points in pts.
    */
    void mapPoints(SkPoint pts[], int count) const {
        this->mapPoints(pts, pts, count);
    }

    void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
        SkASSERT(result);
        this->getMapXYProc()(*this, x, y, result);
    }

    /** Apply this matrix to the array of vectors specified by src, and write
        the transformed vectors into the array of vectors specified by dst.
        This is similar to mapPoints, but ignores any translation in the matrix.
        @param dst  Where the transformed coordinates are written. It must
                    contain at least count entries
        @param src  The original coordinates that are to be transformed. It
                    must contain at least count entries
        @param count The number of vectors in src to read, and then transform
                     into dst.
    */
    void mapVectors(SkVector dst[], const SkVector src[], int count) const;

    /** Apply this matrix to the array of vectors specified by src, and write
        the transformed vectors into the array of vectors specified by dst.
        This is similar to mapPoints, but ignores any translation in the matrix.
        @param vecs The vectors to be transformed. It must contain at least
                    count entries
        @param count The number of vectors in vecs.
    */
    void mapVectors(SkVector vecs[], int count) const {
        this->mapVectors(vecs, vecs, count);
    }

    /** Apply this matrix to the src rectangle, and write the transformed
        rectangle into dst. This is accomplished by transforming the 4 corners
        of src, and then setting dst to the bounds of those points.
        @param dst  Where the transformed rectangle is written.
        @param src  The original rectangle to be transformed.
        @return the result of calling rectStaysRect()
    */
    bool mapRect(SkRect* dst, const SkRect& src) const;

    /** Apply this matrix to the rectangle, and write the transformed rectangle
        back into it. This is accomplished by transforming the 4 corners of
        rect, and then setting it to the bounds of those points
        @param rect The rectangle to transform.
        @return the result of calling rectStaysRect()
    */
    bool mapRect(SkRect* rect) const {
        return this->mapRect(rect, *rect);
    }

    void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const {
        for (int i = 0; i < count; ++i) {
            this->mapPoints(pts, pts, 1);
            pts = (SkPoint*)((intptr_t)pts + stride);
        }
    }

    /** Return the mean radius of a circle after it has been mapped by
        this matrix. NOTE: in perspective this value assumes the circle
        has its center at the origin.
    */
    SkScalar mapRadius(SkScalar radius) const;

    typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y,
                                 SkPoint* result);

    static MapXYProc GetMapXYProc(TypeMask mask) {
        SkASSERT((mask & ~kAllMasks) == 0);
        return gMapXYProcs[mask & kAllMasks];
    }

    MapXYProc getMapXYProc() const {
        return GetMapXYProc(this->getType());
    }

    typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[],
                                  const SkPoint src[], int count);

    static MapPtsProc GetMapPtsProc(TypeMask mask) {
        SkASSERT((mask & ~kAllMasks) == 0);
        return gMapPtsProcs[mask & kAllMasks];
    }

    MapPtsProc getMapPtsProc() const {
        return GetMapPtsProc(this->getType());
    }

    /** If the matrix can be stepped in X (not complex perspective)
        then return true and if step[XY] is not null, return the step[XY] value.
        If it cannot, return false and ignore step.
    */
    bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;

#ifdef SK_SCALAR_IS_FIXED
    friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
        return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) == 0;
    }

    friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
        return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
    }
#else
    friend bool operator==(const SkMatrix& a, const SkMatrix& b);
    friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
        return !(a == b);
    }
#endif

    enum {
        // flatten/unflatten will never return a value larger than this
        kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
    };
    // return the number of bytes written, whether or not buffer is null
    uint32_t flatten(void* buffer) const;
    // return the number of bytes read
    uint32_t unflatten(const void* buffer);

    void dump() const;
    void toDumpString(SkString*) const;

    /**
     * Calculates the maximum stretching factor of the matrix. Only defined if
     * the matrix does not have perspective.
     *
     * @return maximum strecthing factor or negative if matrix has perspective.
     */
    SkScalar getMaxStretch() const;

    /**
     *  Return a reference to a const identity matrix
     */
    static const SkMatrix& I();

    /**
     *  Return a reference to a const matrix that is "invalid", one that could
     *  never be used.
     */
    static const SkMatrix& InvalidMatrix();

    /**
     * Testing routine; the matrix's type cache should never need to be
     * manually invalidated during normal use.
     */
    void dirtyMatrixTypeCache() {
        this->setTypeMask(kUnknown_Mask);
    }

private:
    enum {
        /** Set if the matrix will map a rectangle to another rectangle. This
            can be true if the matrix is scale-only, or rotates a multiple of
            90 degrees. This bit is not set if the matrix is identity.

            This bit will be set on identity matrices
        */
        kRectStaysRect_Mask = 0x10,

        kUnknown_Mask = 0x80,

        kORableMasks =  kTranslate_Mask |
                        kScale_Mask |
                        kAffine_Mask |
                        kPerspective_Mask,

        kAllMasks = kTranslate_Mask |
                    kScale_Mask |
                    kAffine_Mask |
                    kPerspective_Mask |
                    kRectStaysRect_Mask
    };

    SkScalar        fMat[9];
    mutable uint8_t fTypeMask;

    uint8_t computeTypeMask() const;

    void setTypeMask(int mask) {
        // allow kUnknown or a valid mask
        SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask);
        fTypeMask = SkToU8(mask);
    }

    void orTypeMask(int mask) {
        SkASSERT((mask & kORableMasks) == mask);
        fTypeMask = SkToU8(fTypeMask | mask);
    }

    void clearTypeMask(int mask) {
        // only allow a valid mask
        SkASSERT((mask & kAllMasks) == mask);
        fTypeMask &= ~mask;
    }

    static bool Poly2Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
    static bool Poly3Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
    static bool Poly4Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);

    static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
    static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
    static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
    static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
    static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
    static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
    static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);

    static const MapXYProc gMapXYProcs[];

    static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int);
    static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
    static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
    static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
                               int count);
    static void Rot_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
    static void RotTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
                             int count);
    static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);

    static const MapPtsProc gMapPtsProcs[];

    friend class SkPerspIter;
};

#endif


code:
/* libs/graphics/animator/SkMatrixParts.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 SkMatrixParts_DEFINED
#define SkMatrixParts_DEFINED

#include "SkDisplayable.h"
#include "SkMemberInfo.h"
#include "SkPathMeasure.h"

class SkDrawPath;
class SkDrawRect;
class SkPolygon;

class SkDrawMatrix;
// class SkMatrix;

class SkMatrixPart : public SkDisplayable {
public:
    SkMatrixPart();
    virtual bool add() = 0;
    virtual void dirty();
    virtual SkDisplayable* getParent() const;
    virtual bool setParent(SkDisplayable* parent);
#ifdef SK_DEBUG
    virtual bool isMatrixPart() const { return true; }
#endif
protected:
    SkDrawMatrix* fMatrix;
};

class SkRotate : public SkMatrixPart {
    DECLARE_MEMBER_INFO(Rotate);
    SkRotate();
protected:
    virtual bool add();
    SkScalar degrees;
    SkPoint center;
};

class SkScale : public SkMatrixPart {
    DECLARE_MEMBER_INFO(Scale);
    SkScale();
protected:
    virtual bool add();
    SkScalar x;
    SkScalar y;
    SkPoint center;
};

class SkSkew : public SkMatrixPart {
    DECLARE_MEMBER_INFO(Skew);
    SkSkew();
protected:
    virtual bool add();
    SkScalar x;
    SkScalar y;
    SkPoint center;
};

class SkTranslate : public SkMatrixPart {
    DECLARE_MEMBER_INFO(Translate);
    SkTranslate();
protected:
    virtual bool add();
    SkScalar x;
    SkScalar y;
};

class SkFromPath : public SkMatrixPart {
    DECLARE_MEMBER_INFO(FromPath);
    SkFromPath();
    virtual ~SkFromPath();
protected:
    virtual bool add();
    int32_t mode;
    SkScalar offset;
    SkDrawPath* path;
    SkPathMeasure fPathMeasure;
};

class SkRectToRect : public SkMatrixPart {
    DECLARE_MEMBER_INFO(RectToRect);
    SkRectToRect();
    virtual ~SkRectToRect();
#ifdef SK_DUMP_ENABLED
    virtual void dump(SkAnimateMaker* );
#endif
    virtual const SkMemberInfo* preferredChild(SkDisplayTypes type);
protected:
    virtual bool add();
    SkDrawRect* source;
    SkDrawRect* destination;
};

class SkPolyToPoly : public SkMatrixPart {
    DECLARE_MEMBER_INFO(PolyToPoly);
    SkPolyToPoly();
    virtual ~SkPolyToPoly();
#ifdef SK_DUMP_ENABLED
    virtual void dump(SkAnimateMaker* );
#endif
    virtual void onEndElement(SkAnimateMaker& );
    virtual const SkMemberInfo* preferredChild(SkDisplayTypes type);
protected:
    virtual bool add();
    SkPolygon* source;
    SkPolygon* destination;
};

// !!! add concat matrix ?

#endif // SkMatrixParts_DEFINED