зеркало из https://github.com/mozilla/moz-skia.git
Initial checkin of skia source in google codebase.
* reviewed by me! git-svn-id: http://skia.googlecode.com/svn/trunk@2 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
586101c79b
Коммит
0f87cd842d
|
@ -0,0 +1,219 @@
|
|||
#ifndef Sk64_DEFINED
|
||||
#define Sk64_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
|
||||
/** \class Sk64
|
||||
|
||||
Sk64 is a 64-bit math package that does not require long long support from the compiler.
|
||||
*/
|
||||
struct Sk64 {
|
||||
int32_t fHi; //!< the high 32 bits of the number (including sign)
|
||||
uint32_t fLo; //!< the low 32 bits of the number
|
||||
|
||||
/** Returns non-zero if the Sk64 can be represented as a signed 32 bit integer
|
||||
*/
|
||||
SkBool is32() const { return fHi == ((int32_t)fLo >> 31); }
|
||||
/** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit integer
|
||||
*/
|
||||
SkBool is64() const { return fHi != ((int32_t)fLo >> 31); }
|
||||
/** Returns non-zero if the Sk64 can be represented as a signed 48 bit integer. Used to know
|
||||
if we can shift the value down by 16 to treat it as a SkFixed.
|
||||
*/
|
||||
SkBool isFixed() const;
|
||||
|
||||
/** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero.
|
||||
*/
|
||||
int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; }
|
||||
/** Return the number >> 16. Asserts that this does not loose any significant high bits.
|
||||
*/
|
||||
SkFixed getFixed() const
|
||||
{
|
||||
SkASSERT(this->isFixed());
|
||||
|
||||
uint32_t sum = fLo + (1 << 15);
|
||||
int32_t hi = fHi;
|
||||
if (sum < fLo)
|
||||
hi += 1;
|
||||
|
||||
return (hi << 16) | (sum >> 16);
|
||||
}
|
||||
/** Return the number >> 30. Asserts that this does not loose any significant high bits.
|
||||
*/
|
||||
SkFract getFract() const;
|
||||
|
||||
/** Returns the square-root of the number as a signed 32 bit value.
|
||||
*/
|
||||
int32_t getSqrt() const;
|
||||
|
||||
/** Returns the number of leading zeros of the absolute value of this.
|
||||
Will return in the range [0..64]
|
||||
*/
|
||||
int getClzAbs() const;
|
||||
|
||||
/** Returns non-zero if the number is zero
|
||||
*/
|
||||
SkBool isZero() const { return (fHi | fLo) == 0; }
|
||||
/** Returns non-zero if the number is non-zero
|
||||
*/
|
||||
SkBool nonZero() const { return fHi | fLo; }
|
||||
/** Returns non-zero if the number is negative (number < 0)
|
||||
*/
|
||||
SkBool isNeg() const { return (uint32_t)fHi >> 31; }
|
||||
/** Returns non-zero if the number is positive (number > 0)
|
||||
*/
|
||||
SkBool isPos() const { return ~(fHi >> 31) & (fHi | fLo); }
|
||||
/** Returns -1,0,+1 based on the sign of the number
|
||||
*/
|
||||
int sign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); }
|
||||
/** Negate the number
|
||||
*/
|
||||
void negate();
|
||||
|
||||
/** If the number < 0, negate the number
|
||||
*/
|
||||
void abs();
|
||||
|
||||
/** Returns the number of bits needed to shift the Sk64 to the right
|
||||
in order to make it fit in a signed 32 bit integer.
|
||||
*/
|
||||
int shiftToMake32() const;
|
||||
|
||||
/** Set the number to zero
|
||||
*/
|
||||
void setZero() { fHi = fLo = 0; }
|
||||
/** Set the high and low 32 bit values of the number
|
||||
*/
|
||||
void set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; }
|
||||
/** Set the number to the specified 32 bit integer
|
||||
*/
|
||||
void set(int32_t a) { fHi = a >> 31; fLo = a; }
|
||||
/** Set the number to the product of the two 32 bit integers
|
||||
*/
|
||||
void setMul(int32_t a, int32_t b);
|
||||
|
||||
/** extract 32bits after shifting right by bitCount.
|
||||
Note: itCount must be [0..63].
|
||||
Asserts that no significant high bits were lost.
|
||||
*/
|
||||
int32_t getShiftRight(unsigned bitCount) const;
|
||||
/** Shift the number left by the specified number of bits.
|
||||
@param bits How far to shift left, must be [0..63]
|
||||
*/
|
||||
void shiftLeft(unsigned bits);
|
||||
/** Shift the number right by the specified number of bits.
|
||||
@param bits How far to shift right, must be [0..63]. This
|
||||
performs an arithmetic right-shift (sign extending).
|
||||
*/
|
||||
void shiftRight(unsigned bits);
|
||||
/** Shift the number right by the specified number of bits, but
|
||||
round the result.
|
||||
@param bits How far to shift right, must be [0..63]. This
|
||||
performs an arithmetic right-shift (sign extending).
|
||||
*/
|
||||
void roundRight(unsigned bits);
|
||||
|
||||
/** Add the specified 32 bit integer to the number
|
||||
*/
|
||||
void add(int32_t lo)
|
||||
{
|
||||
int32_t hi = lo >> 31; // 0 or -1
|
||||
uint32_t sum = fLo + (uint32_t)lo;
|
||||
|
||||
fHi = fHi + hi + (sum < fLo);
|
||||
fLo = sum;
|
||||
}
|
||||
/** Add the specified Sk64 to the number
|
||||
*/
|
||||
void add(int32_t hi, uint32_t lo)
|
||||
{
|
||||
uint32_t sum = fLo + lo;
|
||||
|
||||
fHi = fHi + hi + (sum < fLo);
|
||||
fLo = sum;
|
||||
}
|
||||
/** Add the specified Sk64 to the number
|
||||
*/
|
||||
void add(const Sk64& other) { this->add(other.fHi, other.fLo); }
|
||||
/** Subtract the specified Sk64 from the number. (*this) = (*this) - num
|
||||
*/
|
||||
void sub(const Sk64& num);
|
||||
/** Subtract the number from the specified Sk64. (*this) = num - (*this)
|
||||
*/
|
||||
void rsub(const Sk64& num);
|
||||
/** Multiply the number by the specified 32 bit integer
|
||||
*/
|
||||
void mul(int32_t);
|
||||
|
||||
enum DivOptions {
|
||||
kTrunc_DivOption, //!< truncate the result when calling div()
|
||||
kRound_DivOption //!< round the result when calling div()
|
||||
};
|
||||
/** Divide the number by the specified 32 bit integer, using the specified
|
||||
divide option (either truncate or round).
|
||||
*/
|
||||
void div(int32_t, DivOptions);
|
||||
|
||||
SkFixed addGetFixed(const Sk64& other) const
|
||||
{
|
||||
return this->addGetFixed(other.fHi, other.fLo);
|
||||
}
|
||||
SkFixed addGetFixed(int32_t hi, uint32_t lo) const
|
||||
{
|
||||
#ifdef SK_DEBUG
|
||||
Sk64 tmp(*this);
|
||||
tmp.add(hi, lo);
|
||||
#endif
|
||||
uint32_t sum = fLo + lo + (1 << 15);
|
||||
|
||||
hi = fHi + hi + (sum < fLo);
|
||||
hi = (hi << 16) | (sum >> 16);
|
||||
|
||||
SkASSERT(hi == tmp.getFixed());
|
||||
return hi;
|
||||
}
|
||||
|
||||
/** Return the result of dividing the number by denom, treating the answer
|
||||
as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0.
|
||||
*/
|
||||
SkFixed getFixedDiv(const Sk64& denom) const;
|
||||
|
||||
friend bool operator==(const Sk64& a, const Sk64& b)
|
||||
{
|
||||
return a.fHi == b.fHi && a.fLo == b.fLo;
|
||||
}
|
||||
friend bool operator!=(const Sk64& a, const Sk64& b)
|
||||
{
|
||||
return a.fHi != b.fHi || a.fLo != b.fLo;
|
||||
}
|
||||
friend bool operator<(const Sk64& a, const Sk64& b)
|
||||
{
|
||||
return a.fHi < b.fHi || a.fHi == b.fHi && a.fLo < b.fLo;
|
||||
}
|
||||
friend bool operator<=(const Sk64& a, const Sk64& b)
|
||||
{
|
||||
return a.fHi < b.fHi || a.fHi == b.fHi && a.fLo <= b.fLo;
|
||||
}
|
||||
friend bool operator>(const Sk64& a, const Sk64& b)
|
||||
{
|
||||
return a.fHi > b.fHi || a.fHi == b.fHi && a.fLo > b.fLo;
|
||||
}
|
||||
friend bool operator>=(const Sk64& a, const Sk64& b)
|
||||
{
|
||||
return a.fHi > b.fHi || a.fHi == b.fHi && a.fLo >= b.fLo;
|
||||
}
|
||||
|
||||
#ifdef SK_CAN_USE_LONGLONG
|
||||
SkLONGLONG getLongLong() const;
|
||||
#endif
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** @cond UNIT_TEST */
|
||||
static void UnitTest();
|
||||
/** @endcond */
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
#ifndef SkBuffer_DEFINED
|
||||
#define SkBuffer_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
/** \class SkRBuffer
|
||||
|
||||
Light weight class for reading data from a memory block.
|
||||
The RBuffer is given the buffer to read from, with either a specified size
|
||||
or no size (in which case no range checking is performed). It is iillegal
|
||||
to attempt to read a value from an empty RBuffer (data == null).
|
||||
*/
|
||||
class SkRBuffer {
|
||||
public:
|
||||
SkRBuffer() : fData(0), fPos(0), fStop(0) {}
|
||||
/** Initialize RBuffer with a data pointer, but no specified length.
|
||||
This signals the RBuffer to not perform range checks during reading.
|
||||
*/
|
||||
SkRBuffer(const void* data)
|
||||
{
|
||||
fData = (const char*)data;
|
||||
fPos = (const char*)data;
|
||||
fStop = 0; // no bounds checking
|
||||
}
|
||||
/** Initialize RBuffer with a data point and length.
|
||||
*/
|
||||
SkRBuffer(const void* data, size_t size)
|
||||
{
|
||||
SkASSERT(data != 0 || size == 0);
|
||||
fData = (const char*)data;
|
||||
fPos = (const char*)data;
|
||||
fStop = (const char*)data + size;
|
||||
}
|
||||
|
||||
/** Return the number of bytes that have been read from the beginning
|
||||
of the data pointer.
|
||||
*/
|
||||
size_t pos() const { return fPos - fData; }
|
||||
/** Return the total size of the data pointer. Only defined if the length was
|
||||
specified in the constructor or in a call to reset().
|
||||
*/
|
||||
size_t size() const { return fStop - fData; }
|
||||
/** Return true if the buffer has read to the end of the data pointer.
|
||||
Only defined if the length was specified in the constructor or in a call
|
||||
to reset(). Always returns true if the length was not specified.
|
||||
*/
|
||||
bool eof() const { return fPos >= fStop; }
|
||||
|
||||
/** Read the specified number of bytes from the data pointer. If buffer is not
|
||||
null, copy those bytes into buffer.
|
||||
*/
|
||||
void read(void* buffer, size_t size) { if (size) this->readNoSizeCheck(buffer, size); }
|
||||
size_t skipToAlign4();
|
||||
|
||||
void* readPtr() { void* ptr; read(&ptr, sizeof(ptr)); return ptr; }
|
||||
SkScalar readScalar() { SkScalar x; read(&x, 4); return x; }
|
||||
uint32_t readU32() { uint32_t x; read(&x, 4); return x; }
|
||||
int32_t readS32() { int32_t x; read(&x, 4); return x; }
|
||||
uint16_t readU16() { uint16_t x; read(&x, 2); return x; }
|
||||
int16_t readS16() { int16_t x; read(&x, 2); return x; }
|
||||
uint8_t readU8() { uint8_t x; read(&x, 1); return x; }
|
||||
bool readBool() { return this->readU8() != 0; }
|
||||
|
||||
private:
|
||||
void readNoSizeCheck(void* buffer, size_t size);
|
||||
|
||||
const char* fData;
|
||||
const char* fPos;
|
||||
const char* fStop;
|
||||
};
|
||||
|
||||
/** \class SkWBuffer
|
||||
|
||||
Light weight class for writing data to a memory block.
|
||||
The WBuffer is given the buffer to write into, with either a specified size
|
||||
or no size, in which case no range checking is performed. An empty WBuffer
|
||||
is legal, in which case no data is ever written, but the relative pos()
|
||||
is updated.
|
||||
*/
|
||||
class SkWBuffer {
|
||||
public:
|
||||
SkWBuffer() : fData(0), fPos(0), fStop(0) {}
|
||||
SkWBuffer(void* data)
|
||||
{
|
||||
fData = (char*)data;
|
||||
fPos = (char*)data;
|
||||
fStop = 0; // no bounds checking
|
||||
}
|
||||
SkWBuffer(void* data, size_t size)
|
||||
{
|
||||
SkASSERT(data != 0 || size == 0);
|
||||
fData = (char*)data;
|
||||
fPos = (char*)data;
|
||||
fStop = (char*)data + size;
|
||||
}
|
||||
|
||||
void reset(void* data)
|
||||
{
|
||||
fData = (char*)data;
|
||||
fPos = (char*)data;
|
||||
fStop = 0; // no bounds checking
|
||||
}
|
||||
void reset(void* data, size_t size)
|
||||
{
|
||||
SkASSERT(data != 0 || size == 0);
|
||||
fData = (char*)data;
|
||||
fPos = (char*)data;
|
||||
fStop = (char*)data + size;
|
||||
}
|
||||
|
||||
void* data() const { return fData; }
|
||||
size_t pos() const { return fPos - fData; }
|
||||
size_t size() const { return fStop - fData; }
|
||||
bool eof() const { return fPos >= fStop; }
|
||||
|
||||
void write(const void* buffer, size_t size) { if (size) this->writeNoSizeCheck(buffer, size); }
|
||||
size_t padToAlign4();
|
||||
|
||||
void writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
|
||||
void writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
|
||||
void write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
|
||||
void write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
|
||||
void write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
|
||||
void writeBool(bool x) { this->write8(x); }
|
||||
|
||||
private:
|
||||
void writeNoSizeCheck(const void* buffer, size_t size);
|
||||
|
||||
char* fData;
|
||||
char* fPos;
|
||||
char* fStop;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef SkChunkAlloc_DEFINED
|
||||
#define SkChunkAlloc_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkChunkAlloc {
|
||||
public:
|
||||
SkChunkAlloc(size_t minSize) : fBlock(nil), fMinSize(SkAlign4(minSize)) {}
|
||||
~SkChunkAlloc();
|
||||
|
||||
void reset();
|
||||
|
||||
enum AllocFailType {
|
||||
kReturnNil_AllocFailType,
|
||||
kThrow_AllocFailType
|
||||
};
|
||||
void* alloc(size_t bytes, AllocFailType);
|
||||
|
||||
private:
|
||||
struct Block {
|
||||
Block* fNext;
|
||||
size_t fFreeSize;
|
||||
char* fFreePtr;
|
||||
// data[] follows
|
||||
};
|
||||
Block* fBlock;
|
||||
size_t fMinSize;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,82 @@
|
|||
#ifndef SkEndian_DEFINED
|
||||
#define SkEndian_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkEndian.h
|
||||
|
||||
Macros and helper functions for handling 16 and 32 bit values in
|
||||
big and little endian formats.
|
||||
*/
|
||||
|
||||
#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
|
||||
#error "can't have both LENDIAN and BENDIAN defined"
|
||||
#endif
|
||||
|
||||
#if !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
|
||||
#error "need either LENDIAN or BENDIAN defined"
|
||||
#endif
|
||||
|
||||
/** Swap the two bytes in the low 16bits of the parameters.
|
||||
e.g. 0x1234 -> 0x3412
|
||||
*/
|
||||
inline uint16_t SkEndianSwap16(U16CPU value)
|
||||
{
|
||||
SkASSERT(value == (uint16_t)value);
|
||||
return (uint16_t)((value >> 8) | (value << 8));
|
||||
}
|
||||
|
||||
/** Vector version of SkEndianSwap16(), which swaps the
|
||||
low two bytes of each value in the array.
|
||||
*/
|
||||
inline void SkEndianSwap16s(uint16_t array[], int count)
|
||||
{
|
||||
SkASSERT(count == 0 || array != nil);
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
*array = SkEndianSwap16(*array);
|
||||
array += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Reverse all 4 bytes in a 32bit value.
|
||||
e.g. 0x12345678 -> 0x78563412
|
||||
*/
|
||||
inline uint32_t SkEndianSwap32(uint32_t value)
|
||||
{
|
||||
return ((value & 0xFF) << 24) |
|
||||
((value & 0xFF00) << 8) |
|
||||
((value & 0xFF0000) >> 8) |
|
||||
(value >> 24);
|
||||
}
|
||||
|
||||
/** Vector version of SkEndianSwap16(), which swaps the
|
||||
bytes of each value in the array.
|
||||
*/
|
||||
inline void SkEndianSwap32s(uint32_t array[], int count)
|
||||
{
|
||||
SkASSERT(count == 0 || array != nil);
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
*array = SkEndianSwap32(*array);
|
||||
array += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_CPU_LENDIAN
|
||||
#define SkEndian_SwapBE16(n) SkEndianSwap16(n)
|
||||
#define SkEndian_SwapBE32(n) SkEndianSwap32(n)
|
||||
#define SkEndian_SwapLE16(n) (n)
|
||||
#define SkEndian_SwapLE32(n) (n)
|
||||
#else // SK_CPU_BENDIAN
|
||||
#define SkEndian_SwapBE16(n) (n)
|
||||
#define SkEndian_SwapBE32(n) (n)
|
||||
#define SkEndian_SwapLE16(n) SkEndianSwap16(n)
|
||||
#define SkEndian_SwapLE32(n) SkEndianSwap32(n)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef SkFDot6_DEFINED
|
||||
#define SkFDot6_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
|
||||
typedef int32_t SkFDot6;
|
||||
|
||||
#define SK_FDot61 (64)
|
||||
#define SK_FDot6Half (32)
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
inline SkFDot6 SkIntToFDot6(S16CPU x)
|
||||
{
|
||||
SkASSERT(SkToS16(x) == x);
|
||||
return x << 6;
|
||||
}
|
||||
#else
|
||||
#define SkIntToFDot6(x) ((x) << 6)
|
||||
#endif
|
||||
|
||||
#define SkFDot6Floor(x) ((x) >> 6)
|
||||
#define SkFDot6Ceil(x) (((x) + 63) >> 6)
|
||||
#define SkFDot6Round(x) (((x) + 32) >> 6)
|
||||
|
||||
#define SkFixedToFDot6(x) ((x) >> 10)
|
||||
|
||||
inline SkFixed SkFDot6ToFixed(SkFDot6 x)
|
||||
{
|
||||
SkASSERT((x << 10 >> 10) == x);
|
||||
|
||||
return x << 10;
|
||||
}
|
||||
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#define SkScalarToFDot6(x) (SkFDot6)((x) * 64)
|
||||
#else
|
||||
#define SkScalarToFDot6(x) ((x) >> 10)
|
||||
#endif
|
||||
|
||||
inline SkFixed SkFDot6Div(SkFDot6 a, SkFDot6 b)
|
||||
{
|
||||
SkASSERT(b != 0);
|
||||
|
||||
if (a == (int16_t)a)
|
||||
return (a << 16) / b;
|
||||
else
|
||||
return SkFixedDiv(a, b);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
#ifndef SkFixed_DEFINED
|
||||
#define SkFixed_DEFINED
|
||||
|
||||
/** \file SkFixed.h
|
||||
|
||||
Types and macros for 16.16 fixed point
|
||||
*/
|
||||
|
||||
/** 32 bit signed integer used to represent fractions values with 16 bits to the right of the decimal point
|
||||
*/
|
||||
typedef int32_t SkFixed;
|
||||
#define SK_Fixed1 (1 << 16)
|
||||
#define SK_FixedHalf (1 << 15)
|
||||
#define SK_FixedMax (0x7FFFFFFF)
|
||||
#define SK_FixedMin (0x1)
|
||||
#define SK_FixedNaN ((int) 0x80000000)
|
||||
#define SK_FixedPI (0x3243F)
|
||||
#define SK_FixedSqrt2 (92682)
|
||||
#define SK_FixedTanPIOver8 (0x6A0A)
|
||||
#define SK_FixedRoot2Over2 (0xB505)
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SkFixedToFloat(x) ((x) * 1.5258789e-5f)
|
||||
#define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
#endif
|
||||
|
||||
/** 32 bit signed integer used to represent fractions values with 30 bits to the right of the decimal point
|
||||
*/
|
||||
typedef int32_t SkFract;
|
||||
#define SK_Fract1 (1 << 30)
|
||||
#define Sk_FracHalf (1 << 29)
|
||||
#define SK_FractPIOver180 (0x11DF46A)
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SkFractToFloat(x) ((float)(x) * 0.00000000093132257f)
|
||||
#define SkFloatToFract(x) ((SkFract)((x) * SK_Fract1))
|
||||
#endif
|
||||
|
||||
/** Converts an integer to a SkFixed, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
*/
|
||||
#ifdef SK_DEBUG
|
||||
inline SkFixed SkIntToFixed(int n)
|
||||
{
|
||||
SkASSERT(n >= -32768 && n <= 32767);
|
||||
return n << 16;
|
||||
}
|
||||
#else
|
||||
// force the cast to SkFixed to ensure that the answer is signed (like the debug version)
|
||||
#define SkIntToFixed(n) (SkFixed)((n) << 16)
|
||||
#endif
|
||||
|
||||
/** Converts a SkFixed to a SkFract, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
*/
|
||||
#ifdef SK_DEBUG
|
||||
inline SkFract SkFixedToFract(SkFixed x)
|
||||
{
|
||||
SkASSERT(x >= (-2 << 16) && x <= (2 << 16) - 1);
|
||||
return x << 14;
|
||||
}
|
||||
#else
|
||||
#define SkFixedToFract(x) ((x) << 14)
|
||||
#endif
|
||||
|
||||
/** Returns the signed fraction of a SkFixed
|
||||
*/
|
||||
inline SkFixed SkFixedFraction(SkFixed x)
|
||||
{
|
||||
SkFixed mask = x >> 31 << 16;
|
||||
return x & 0xFFFF | mask;
|
||||
}
|
||||
|
||||
/** Converts a SkFract to a SkFixed
|
||||
*/
|
||||
#define SkFractToFixed(x) ((x) >> 14)
|
||||
/** Round a SkFixed to an integer
|
||||
*/
|
||||
#define SkFixedRound(x) (((x) + SK_FixedHalf) >> 16)
|
||||
#define SkFixedCeil(x) (((x) + SK_Fixed1 - 1) >> 16)
|
||||
#define SkFixedFloor(x) ((x) >> 16)
|
||||
#define SkFixedAbs(x) SkAbs32(x)
|
||||
#define SkFixedAve(a, b) (((a) + (b)) >> 1)
|
||||
|
||||
#if defined(SK_BUILD_FOR_BREW) && !defined(AEE_SIMULATOR)
|
||||
inline SkFixed SkFixedSquare(SkFixed a)
|
||||
{
|
||||
SkFixed answer;
|
||||
asm volatile ( "SMULL r6, r7, %0, %0" : : "r"(a) : "r6", "r7" );
|
||||
asm volatile ( "MOV r6, r6, LSR #16" );
|
||||
asm volatile ( "ORR r6, r6, r7, LSL #16" );
|
||||
asm volatile ( "STR r6, %0" : "=m"(answer) );
|
||||
return answer;
|
||||
}
|
||||
inline SkFixed SkFixedMul(SkFixed a, SkFixed b)
|
||||
{
|
||||
SkFixed answer;
|
||||
asm volatile ( "SMULL r6, r7, %0, %1" : : "r"(a), "r"(b) : "r6", "r7" );
|
||||
asm volatile ( "MOV r6, r6, LSR #16" );
|
||||
asm volatile ( "ORR r6, r6, r7, LSL #16" );
|
||||
asm volatile ( "STR r6, %0" : "=m"(answer) );
|
||||
return answer;
|
||||
}
|
||||
inline SkFract SkFractMul(SkFract a, SkFract b)
|
||||
{
|
||||
SkFract answer;
|
||||
asm volatile ( "SMULL r6, r7, %0, %1" : : "r"(a), "r"(b) : "r6", "r7" );
|
||||
asm volatile ( "MOV r6, r6, LSR #30" );
|
||||
asm volatile ( "ORR r6, r6, r7, LSL #2" );
|
||||
asm volatile ( "STR r6, %0" : "=m"(answer) );
|
||||
return answer;
|
||||
}
|
||||
#else
|
||||
inline SkFixed SkFixedSquare(SkFixed value)
|
||||
{
|
||||
uint32_t a = SkAbs32(value);
|
||||
uint32_t ah = a >> 16;
|
||||
uint32_t al = a & 0xFFFF;
|
||||
return ah * a + al * ah + (al * al >> 16);
|
||||
}
|
||||
SkFixed SkFixedMul(SkFixed, SkFixed);
|
||||
SkFract SkFractMul(SkFract, SkFract);
|
||||
#endif
|
||||
#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
|
||||
SkFixed SkFixedDivInt(int32_t numer, int32_t denom);
|
||||
SkFixed SkFixedMod(SkFixed numer, SkFixed denom);
|
||||
#define SkFixedInvert(n) SkDivBits(SK_Fixed1, n, 16)
|
||||
#define SkFixedSqrt(n) SkSqrtBits(n, 23)
|
||||
SkFixed SkFixedMean(SkFixed a, SkFixed b); //*< returns sqrt(x*y)
|
||||
int SkFixedMulCommon(SkFixed, int , int bias); // internal used by SkFixedMulFloor, SkFixedMulCeil, SkFixedMulRound
|
||||
|
||||
#define SkFractDiv(numer, denom) SkDivBits(numer, denom, 30)
|
||||
#define SkFractSqrt(n) SkSqrtBits(n, 30)
|
||||
|
||||
SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNil);
|
||||
#define SkFixedSin(radians) SkFixedSinCos(radians, nil)
|
||||
inline SkFixed SkFixedCos(SkFixed radians)
|
||||
{
|
||||
SkFixed cosValue;
|
||||
(void)SkFixedSinCos(radians, &cosValue);
|
||||
return cosValue;
|
||||
}
|
||||
SkFixed SkFixedTan(SkFixed radians);
|
||||
SkFixed SkFixedASin(SkFixed);
|
||||
SkFixed SkFixedACos(SkFixed);
|
||||
SkFixed SkFixedATan2(SkFixed y, SkFixed x);
|
||||
SkFixed SkFixedExp(SkFixed);
|
||||
SkFixed SkFixedLog(SkFixed);
|
||||
|
||||
#define SK_FixedNearlyZero (SK_Fixed1 >> 12)
|
||||
|
||||
inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero)
|
||||
{
|
||||
SkASSERT(tolerance > 0);
|
||||
return SkAbs32(x) < tolerance;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef SkFloatingPoint_DEFINED
|
||||
#define SkFloatingPoint_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef SK_BUILD_FOR_WINCE
|
||||
#define sk_float_sqrt(x) (float)::sqrt(x)
|
||||
#define sk_float_sin(x) (float)::sin(x)
|
||||
#define sk_float_cos(x) (float)::cos(x)
|
||||
#define sk_float_tan(x) (float)::tan(x)
|
||||
#define sk_float_acos(x) (float)::acos(x)
|
||||
#define sk_float_asin(x) (float)::asin(x)
|
||||
#define sk_float_atan2(y,x) (float)::atan2(y,x)
|
||||
#define sk_float_abs(x) (float)::fabs(x)
|
||||
#define sk_float_mod(x,y) (float)::fmod(x,y)
|
||||
#define sk_float_exp(x) (float)::exp(x)
|
||||
#define sk_float_log(x) (float)::log(x)
|
||||
#else
|
||||
#define sk_float_sqrt(x) sqrtf(x)
|
||||
#define sk_float_sin(x) sinf(x)
|
||||
#define sk_float_cos(x) cosf(x)
|
||||
#define sk_float_tan(x) tanf(x)
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
#define sk_float_acos(x) acos(x)
|
||||
#define sk_float_asin(x) asin(x)
|
||||
#else
|
||||
#define sk_float_acos(x) acosf(x)
|
||||
#define sk_float_asin(x) asinf(x)
|
||||
#endif
|
||||
#define sk_float_atan2(y,x) atan2f(y,x)
|
||||
#define sk_float_abs(x) fabsf(x)
|
||||
#define sk_float_mod(x,y) fmodf(x,y)
|
||||
#define sk_float_exp(x) expf(x)
|
||||
#define sk_float_log(x) logf(x)
|
||||
#define sk_float_isNaN(x) _isnan(x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,132 @@
|
|||
#ifndef SkMath_DEFINED
|
||||
#define SkMath_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkMath.h
|
||||
|
||||
This file defines various math types and functions. It also introduces
|
||||
SkScalar, the type used to describe fractional values and coordinates.
|
||||
SkScalar is defined at compile time to be either an IEEE float, or a
|
||||
16.16 fixed point integer. Various macros and functions in SkMath.h
|
||||
allow arithmetic operations to be performed on SkScalars without known
|
||||
which representation is being used. e.g. SkScalarMul(a, b) multiplies
|
||||
two SkScalar values, and returns a SkScalar, and this works with either
|
||||
float or fixed implementations.
|
||||
*/
|
||||
|
||||
//#if defined(SK_BUILD_FOR_BREW) && !defined(AEE_SIMULATOR)
|
||||
#if 0
|
||||
inline int SkCLZ(uint32_t value)
|
||||
{
|
||||
int answer;
|
||||
asm volatile ( "CLZ r6, %0" : : "r"(value) : "r6" );
|
||||
asm volatile ( "STR r6, %0" : "=m"(answer) );
|
||||
return answer;
|
||||
}
|
||||
#else
|
||||
int SkCLZ(uint32_t); //<! Returns the number of leading zero bits (0...32)
|
||||
#endif
|
||||
|
||||
/** 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);
|
||||
int32_t SkSqrtBits(int32_t value, int bits);
|
||||
#define SkSqrt32(n) SkSqrtBits(n, 15)
|
||||
int32_t SkCubeRootBits(int32_t value, int bits);
|
||||
|
||||
/** 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().
|
||||
*/
|
||||
inline int32_t SkApplySign(int32_t n, int32_t sign)
|
||||
{
|
||||
SkASSERT(sign == 0 || sign == -1);
|
||||
return (n ^ sign) - sign;
|
||||
}
|
||||
|
||||
/** Returns max(value, 0)
|
||||
*/
|
||||
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.
|
||||
Note: only works as long as max - value doesn't wrap around
|
||||
@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
|
||||
*/
|
||||
inline int SkClampMax(int value, int max)
|
||||
{
|
||||
// ensure that max is positive
|
||||
SkASSERT(max >= 0);
|
||||
// ensure that if value is negative, max - value doesn't wrap around
|
||||
SkASSERT(value >= 0 || max - value > 0);
|
||||
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
if (value > max)
|
||||
value = max;
|
||||
return value;
|
||||
#else
|
||||
|
||||
int diff = max - value;
|
||||
// clear diff if diff is positive
|
||||
diff &= diff >> 31;
|
||||
|
||||
// clear the result if value < 0
|
||||
return (value + diff) & ~(value >> 31);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** 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
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
#include "SkFixed.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
class SkMath {
|
||||
public:
|
||||
static void UnitTest();
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
#ifndef SkMatrix_DEFINED
|
||||
#define SkMatrix_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
/** \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 SkMatrix {
|
||||
public:
|
||||
/** Bit fields used to identify the characteristics of the matrix.
|
||||
See TypeMask for the corresponding mask values.
|
||||
*/
|
||||
enum TypeShift {
|
||||
kTranslate_Shift,
|
||||
kScale_Shift,
|
||||
kAffine_Shift,
|
||||
kPerspective_Shift,
|
||||
|
||||
kShiftCount
|
||||
};
|
||||
|
||||
/** Enum of bit fields for the mask return by getType().
|
||||
Use this to identify the complexity of the matrix.
|
||||
*/
|
||||
enum TypeMask {
|
||||
kIdentity_Mask = 0, //!< type is 0 iff the matrix is the identiy
|
||||
kTranslate_Mask = 1 << kTranslate_Shift, //!< set if the matrix has non-zero translation
|
||||
kScale_Mask = 1 << kScale_Shift, //!< set if the matrix has X or Y scale different from 1.0
|
||||
kAffine_Mask = 1 << kAffine_Shift, //!< set if the matrix skews or rotates
|
||||
kPerspective_Mask = 1 << kPerspective_Shift //!< set if the matrix is in perspective
|
||||
};
|
||||
|
||||
/** Returns true if the mask represents a matrix that will only scale
|
||||
or translate (i.e., will map a rectangle into another rectangle).
|
||||
*/
|
||||
static bool RectStaysRect(TypeMask mask)
|
||||
{
|
||||
return (mask & (kAffine_Mask | kPerspective_Mask)) == 0;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Returns true if the matrix is identity.
|
||||
This is faster than testing if (getType() == kIdentity_Mask)
|
||||
*/
|
||||
bool isIdentity() const;
|
||||
|
||||
/** Returns true if the matrix that will only scale
|
||||
or translate (i.e., will map a rectangle into another rectangle).
|
||||
*/
|
||||
bool rectStaysRect() const { return RectStaysRect(this->getType()); }
|
||||
|
||||
SkScalar getScaleX() const { return fMat[0]; }
|
||||
SkScalar getScaleY() const { return fMat[4]; }
|
||||
SkScalar getSkewY() const { return fMat[3]; }
|
||||
SkScalar getSkewX() const { return fMat[1]; }
|
||||
SkScalar getTranslateX() const { return fMat[2]; }
|
||||
SkScalar getTranslateY() const { return fMat[5]; }
|
||||
SkScalar getPerspX() const { return fMat[6]; }
|
||||
SkScalar getPerspY() const { return fMat[7]; }
|
||||
|
||||
void setScaleX(SkScalar v) { fMat[0] = v; }
|
||||
void setScaleY(SkScalar v) { fMat[4] = v; }
|
||||
void setSkewY(SkScalar v) { fMat[3] = v; }
|
||||
void setSkewX(SkScalar v) { fMat[1] = v; }
|
||||
void setTranslateX(SkScalar v) { fMat[2] = v; }
|
||||
void setTranslateY(SkScalar v) { fMat[5] = v; }
|
||||
#ifdef SK_SCALAR_IS_FIXED
|
||||
void setPerspX(SkFract v) { fMat[6] = v; }
|
||||
void setPerspY(SkFract v) { fMat[7] = v; }
|
||||
#else
|
||||
void setPerspX(SkScalar v) { fMat[6] = v; }
|
||||
void setPerspY(SkScalar v) { fMat[7] = v; }
|
||||
#endif
|
||||
/** Set the matrix to identity
|
||||
*/
|
||||
void reset();
|
||||
|
||||
void set(const SkMatrix& other) { *this = other; }
|
||||
|
||||
/** 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 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 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 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 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 rotation.
|
||||
M' = M * R(degrees, px, py)
|
||||
*/
|
||||
bool preRotate(SkScalar degrees, SkScalar px, SkScalar py);
|
||||
/** 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 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 rotation.
|
||||
M' = R(degrees, px, py) * M
|
||||
*/
|
||||
bool postRotate(SkScalar degrees, SkScalar px, SkScalar py);
|
||||
/** 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 matrix.
|
||||
M' = other * M
|
||||
*/
|
||||
bool postConcat(const SkMatrix& other);
|
||||
|
||||
enum ScaleToFit {
|
||||
kFill_ScaleToFit, //!< scale in X and Y independently
|
||||
kStart_ScaleToFit, //!< uniform scale in X/Y, align along left/top
|
||||
kCenter_ScaleToFit, //!< uniform scale in X/Y, align along center
|
||||
kEnd_ScaleToFit //!< uniform scale in X/Y, align along right/bottom
|
||||
};
|
||||
/** 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 = kFill_ScaleToFit);
|
||||
/** Set the matrix such that the specified src points would map to the
|
||||
specified dst points. count must be withing [0..4].
|
||||
*/
|
||||
bool setPolyToPoly(const SkPoint dst[], const SkPoint src[], int count);
|
||||
|
||||
|
||||
/** If this matrix can be inverted, return true and if inverse is not nil, 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;
|
||||
|
||||
/** 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.
|
||||
@param typeMask The mask bits returned by getType() for this matrix.
|
||||
*/
|
||||
bool mapPoints(SkPoint dst[], const SkPoint src[], int count, TypeMask typeMask) const;
|
||||
/** Apply this matrix to the array of vectors specified by src, and write the transformed
|
||||
vectors into the array of points 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.
|
||||
@param typeMask The mask bits returned by getType() for this matrix.
|
||||
*/
|
||||
bool mapVectors(SkVector dst[], const SkVector src[], int count, TypeMask typeMask) const;
|
||||
/** 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.
|
||||
@param typeMask The mask bits returned by getType() for this matrix.
|
||||
*/
|
||||
bool mapRect(SkRect* dst, const SkRect& src, TypeMask typeMask) const;
|
||||
|
||||
/** Helper method for mapPoints() where the TypeMask needs to be computed.
|
||||
*/
|
||||
bool mapPoints(SkPoint dst[], const SkPoint src[], int count) const
|
||||
{
|
||||
return this->mapPoints(dst, src, count, this->getType());
|
||||
}
|
||||
/** Helper method for mapPoints() where the src and dst arrays are the
|
||||
same, and the TypeMask needs to be computed.
|
||||
*/
|
||||
bool mapPoints(SkPoint pts[], int count) const
|
||||
{
|
||||
return this->mapPoints(pts, pts, count, this->getType());
|
||||
}
|
||||
/** Helper method for mapVectors() where the TypeMask needs to be computed.
|
||||
*/
|
||||
bool mapVectors(SkVector dst[], const SkVector src[], int count) const
|
||||
{
|
||||
return this->mapVectors(dst, src, count, this->getType());
|
||||
}
|
||||
/** Helper method for mapVectors() where the src and dst arrays are the
|
||||
same, and the TypeMask needs to be computed.
|
||||
*/
|
||||
bool mapVectors(SkVector vecs[], int count) const
|
||||
{
|
||||
return this->mapVectors(vecs, vecs, count, this->getType());
|
||||
}
|
||||
/** Helper method for mapRect() where the TypeMask needs to be computed.
|
||||
*/
|
||||
bool mapRect(SkRect* dst, const SkRect& src) const
|
||||
{
|
||||
return this->mapRect(dst, src, this->getType());
|
||||
}
|
||||
/** Helper method for mapRect() where the TypeMask needs to be computed
|
||||
and the src and dst rects are the same (i.e. map in place)
|
||||
*/
|
||||
bool mapRect(SkRect* rect) const
|
||||
{
|
||||
return this->mapRect(rect, *rect, this->getType());
|
||||
}
|
||||
|
||||
/** 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 (*MapPtProc)(const SkMatrix& mat, SkScalar x, SkScalar y, SkPoint* result);
|
||||
MapPtProc getMapPtProc() const;
|
||||
|
||||
/** If the matrix can be stepped in X (not complex perspective)
|
||||
then return true and if step[XY] is not nil, return the step[XY] value.
|
||||
If it cannot, return false and ignore step.
|
||||
*/
|
||||
bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;
|
||||
|
||||
friend bool operator==(const SkMatrix& a, const SkMatrix& b)
|
||||
{
|
||||
return memcmp(a.fMat, b.fMat, sizeof(a)) == 0;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** @cond UNIT_TEST */
|
||||
void dump() const;
|
||||
|
||||
static void UnitTest();
|
||||
/** @endcond */
|
||||
#endif
|
||||
|
||||
private:
|
||||
SkScalar fMat[9];
|
||||
|
||||
static void Map2Pt(const SkPoint srcPt[], SkMatrix* dst, SkScalar scale);
|
||||
static void Map3Pt(const SkPoint srcPt[], SkMatrix* dst, SkScalar scaleX, SkScalar scaleY);
|
||||
static void Map4Pt(const SkPoint srcPt[], SkMatrix* dst, SkScalar scaleX, SkScalar scaleY);
|
||||
|
||||
static void Perspective_ptProc(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Affine_ptProc(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Scale_ptProc(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Translate_ptProc(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Identity_ptProc(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
#ifndef SkPoint_DEFINED
|
||||
#define SkPoint_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
|
||||
/** \struct SkPoint16
|
||||
|
||||
SkPoint16 holds two 16 bit integer coordinates
|
||||
*/
|
||||
struct SkPoint16 {
|
||||
int16_t fX, fY;
|
||||
|
||||
void set(S16CPU x, S16CPU y) { fX = SkToS16(x); fY = SkToS16(y); }
|
||||
|
||||
/** Rotate the point clockwise, writing the new point into dst
|
||||
It is legal for dst == this
|
||||
*/
|
||||
void rotateCW(SkPoint16* dst) const;
|
||||
/** Rotate the point clockwise, writing the new point back into the point
|
||||
*/
|
||||
void rotateCW() { this->rotateCW(this); }
|
||||
/** Rotate the point counter-clockwise, writing the new point into dst.
|
||||
It is legal for dst == this
|
||||
*/
|
||||
void rotateCCW(SkPoint16* dst) const;
|
||||
/** Rotate the point counter-clockwise, writing the new point back into the point
|
||||
*/
|
||||
void rotateCCW() { this->rotateCCW(this); }
|
||||
/** Negate the X and Y coordinates of the point.
|
||||
*/
|
||||
void negate() { fX = -fX; fY = -fY; }
|
||||
/** Return a new point whose X and Y coordinates are the negative of the original point's
|
||||
*/
|
||||
SkPoint16 operator-() const
|
||||
{
|
||||
SkPoint16 neg;
|
||||
neg.fX = -fX;
|
||||
neg.fY = -fY;
|
||||
return neg;
|
||||
}
|
||||
/** Add v's coordinates to this point's
|
||||
*/
|
||||
void operator+=(const SkPoint16& v)
|
||||
{
|
||||
fX = SkToS16(fX + v.fX);
|
||||
fY = SkToS16(fY + v.fY);
|
||||
}
|
||||
/** Subtract v's coordinates from this point's
|
||||
*/
|
||||
void operator-=(const SkPoint16& v)
|
||||
{
|
||||
fX = SkToS16(fX - v.fX);
|
||||
fY = SkToS16(fY - v.fY);
|
||||
}
|
||||
/** Returns true if the point's coordinates equal (x,y)
|
||||
*/
|
||||
bool equals(S16CPU x, S16CPU y) const { return fX == x && fY == y; }
|
||||
friend bool operator==(const SkPoint16& a, const SkPoint16& b)
|
||||
{
|
||||
return a.fX == b.fX && a.fY == b.fY;
|
||||
}
|
||||
friend bool operator!=(const SkPoint16& a, const SkPoint16& b)
|
||||
{
|
||||
return a.fX != b.fX || a.fY != b.fY;
|
||||
}
|
||||
/** Returns a new point whose coordinates are the difference between a and b (a - b)
|
||||
*/
|
||||
friend SkPoint16 operator-(const SkPoint16& a, const SkPoint16& b)
|
||||
{
|
||||
SkPoint16 v;
|
||||
v.set(a.fX - b.fX, a.fY - b.fY);
|
||||
return v;
|
||||
}
|
||||
/** Returns a new point whose coordinates are the sum of a and b (a + b)
|
||||
*/
|
||||
friend SkPoint16 operator+(const SkPoint16& a, const SkPoint16& b)
|
||||
{
|
||||
SkPoint16 v;
|
||||
v.set(a.fX + b.fX, a.fY + b.fY);
|
||||
return v;
|
||||
}
|
||||
/** Returns the dot product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static int32_t DotProduct(const SkPoint16& a, const SkPoint16& b)
|
||||
{
|
||||
return a.fX * b.fX + a.fY * b.fY;
|
||||
}
|
||||
/** Returns the cross product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static int32_t CrossProduct(const SkPoint16& a, const SkPoint16& b)
|
||||
{
|
||||
return a.fX * b.fY - a.fY * b.fX;
|
||||
}
|
||||
};
|
||||
|
||||
struct SkPoint32 {
|
||||
int32_t fX, fY;
|
||||
|
||||
void set(int x, int y) { fX = x; fY = y; }
|
||||
};
|
||||
|
||||
struct SkPoint {
|
||||
SkScalar fX, fY;
|
||||
|
||||
/** Set the point's X and Y coordinates
|
||||
*/
|
||||
void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
|
||||
/** Set the point's X and Y coordinates by automatically promoting (x,y) to SkScalar values.
|
||||
*/
|
||||
void iset(S16CPU x, S16CPU y) { fX = SkIntToScalar(x); fY = SkIntToScalar(y); }
|
||||
/** Set the point's X and Y coordinates by automatically promoting p's coordinates to SkScalar values.
|
||||
*/
|
||||
void iset(const SkPoint16& p) { fX = SkIntToScalar(p.fX); fY = SkIntToScalar(p.fY); }
|
||||
|
||||
/** Return the euclidian distance from (0,0) to the point
|
||||
*/
|
||||
SkScalar length() const { return SkPoint::Length(fX, fY); }
|
||||
|
||||
/** Set the point (vector) to be unit-length in the same direction as it
|
||||
currently is, and return its old length. If the old length is
|
||||
degenerately small (nearly zero), do nothing and return 0.
|
||||
*/
|
||||
bool normalize();
|
||||
/** Set the point (vector) to be unit-length in the same direction as the
|
||||
x,y params, and return their old length. If the old length is
|
||||
degenerately small (nearly zero), do nothing and return 0.
|
||||
*/
|
||||
bool setUnit(SkScalar x, SkScalar y);
|
||||
/** Scale the point to have the specified length, and return that
|
||||
length. If the original length is
|
||||
degenerately small (nearly zero), do nothing and return 0.
|
||||
*/
|
||||
bool setLength(SkScalar length);
|
||||
/** Set the point to have the specified length in the same direction as (x,y),
|
||||
and return the old length of (x,y). If that old length is
|
||||
degenerately small (nearly zero), do nothing and return 0.
|
||||
*/
|
||||
bool setLength(SkScalar x, SkScalar y, SkScalar length);
|
||||
|
||||
/** Scale the point's coordinates by scale, writing the answer into dst.
|
||||
It is legal for dst == this.
|
||||
*/
|
||||
void scale(SkScalar scale, SkPoint* dst) const;
|
||||
/** Scale the point's coordinates by scale, writing the answer back into the point.
|
||||
*/
|
||||
void scale(SkScalar scale) { this->scale(scale, this); }
|
||||
|
||||
/** Rotate the point clockwise by 90 degrees, writing the answer into dst.
|
||||
It is legal for dst == this.
|
||||
*/
|
||||
void rotateCW(SkPoint* dst) const;
|
||||
/** Rotate the point clockwise by 90 degrees, writing the answer back into the point.
|
||||
*/
|
||||
void rotateCW() { this->rotateCW(this); }
|
||||
/** Rotate the point counter-clockwise by 90 degrees, writing the answer into dst.
|
||||
It is legal for dst == this.
|
||||
*/
|
||||
void rotateCCW(SkPoint* dst) const;
|
||||
/** Rotate the point counter-clockwise by 90 degrees, writing the answer back into the point.
|
||||
*/
|
||||
void rotateCCW() { this->rotateCCW(this); }
|
||||
/** Negate the point's coordinates
|
||||
*/
|
||||
void negate() { fX = -fX; fY = -fY; }
|
||||
/** Returns a new point whose coordinates are the negative of the point's
|
||||
*/
|
||||
SkPoint operator-() const
|
||||
{
|
||||
SkPoint neg;
|
||||
neg.fX = -fX;
|
||||
neg.fY = -fY;
|
||||
return neg;
|
||||
}
|
||||
|
||||
/** Add v's coordinates to the point's
|
||||
*/
|
||||
void operator+=(const SkPoint& v)
|
||||
{
|
||||
fX += v.fX;
|
||||
fY += v.fY;
|
||||
}
|
||||
/** Subtract v's coordinates from the point's
|
||||
*/
|
||||
void operator-=(const SkPoint& v)
|
||||
{
|
||||
fX -= v.fX;
|
||||
fY -= v.fY;
|
||||
}
|
||||
|
||||
/** Returns true if the point's coordinates equal (x,y)
|
||||
*/
|
||||
bool equals(SkScalar x, SkScalar y) const { return fX == x && fY == y; }
|
||||
friend bool operator==(const SkPoint& a, const SkPoint& b)
|
||||
{
|
||||
return a.fX == b.fX && a.fY == b.fY;
|
||||
}
|
||||
friend bool operator!=(const SkPoint& a, const SkPoint& b)
|
||||
{
|
||||
return a.fX != b.fX || a.fY != b.fY;
|
||||
}
|
||||
|
||||
/** Returns a new point whose coordinates are the difference between a's and b's (a - b)
|
||||
*/
|
||||
friend SkPoint operator-(const SkPoint& a, const SkPoint& b)
|
||||
{
|
||||
SkPoint v;
|
||||
v.set(a.fX - b.fX, a.fY - b.fY);
|
||||
return v;
|
||||
}
|
||||
/** Returns a new point whose coordinates are the sum of a's and b's (a + b)
|
||||
*/
|
||||
friend SkPoint operator+(const SkPoint& a, const SkPoint& b)
|
||||
{
|
||||
SkPoint v;
|
||||
v.set(a.fX + b.fX, a.fY + b.fY);
|
||||
return v;
|
||||
}
|
||||
/** Returns the euclidian distance from (0,0) to (x,y)
|
||||
*/
|
||||
static SkScalar Length(SkScalar x, SkScalar y);
|
||||
/** Returns the euclidian distance between a and b
|
||||
*/
|
||||
static SkScalar Distance(const SkPoint& a, const SkPoint& b)
|
||||
{
|
||||
return Length(a.fX - b.fX, a.fY - b.fY);
|
||||
}
|
||||
/** Returns the dot product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static SkScalar DotProduct(const SkPoint& a, const SkPoint& b)
|
||||
{
|
||||
return SkScalarMul(a.fX, b.fX) + SkScalarMul(a.fY, b.fY);
|
||||
}
|
||||
/** Returns the cross product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b)
|
||||
{
|
||||
return SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX);
|
||||
}
|
||||
};
|
||||
|
||||
typedef SkPoint SkVector;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#ifndef SkPostConfig_DEFINED
|
||||
#define SkPostConfig_DEFINED
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
|
||||
#define SK_BUILD_FOR_WIN
|
||||
#endif
|
||||
|
||||
#if defined(SK_DEBUG) && defined(SK_RELEASE)
|
||||
#error "cannot define both SK_DEBUG and SK_RELEASE"
|
||||
#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
#error "must define either SK_DEBUG or SK_RELEASE"
|
||||
#endif
|
||||
|
||||
#if defined SK_SUPPORT_UNITTEST && !defined(SK_DEBUG)
|
||||
#error "can't have unittests without debug"
|
||||
#endif
|
||||
|
||||
#if defined(SK_SCALAR_IS_FIXED) && defined(SK_SCALAR_IS_FLOAT)
|
||||
#error "cannot define both SK_SCALAR_IS_FIXED and SK_SCALAR_IS_FLOAT"
|
||||
#elif !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#else
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SK_SCALAR_IS_FLOAT) && !defined(SK_CAN_USE_FLOAT)
|
||||
#define SK_CAN_USE_FLOAT
|
||||
// we do nothing in the else case: fixed-scalars can have floats or not
|
||||
#endif
|
||||
|
||||
#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
|
||||
#error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
|
||||
#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
|
||||
#error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
|
||||
#endif
|
||||
|
||||
#ifndef SkNEW
|
||||
#define SkNEW(type_name) new type_name
|
||||
#define SkNEW_ARGS(type_name, args) new type_name args
|
||||
#define SkDELETE(obj) delete obj
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) do { if (!(cond)) DebugBreak(); } while (false)
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define strcasecmp(a, b) stricmp(a, b)
|
||||
#define strncasecmp(a, b, c) strnicmp(a, b, c)
|
||||
#elif defined(SK_BUILD_FOR_WINCE)
|
||||
#define strcasecmp(a, b) _stricmp(a, b)
|
||||
#define strncasecmp(a, b, c) _strnicmp(a, b, c)
|
||||
#endif
|
||||
#elif defined(SK_BUILD_FOR_MAC)
|
||||
#include <carbon/carbon.h>
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) do { if (!(cond)) sk_throw(); } while (false)
|
||||
#endif
|
||||
#else
|
||||
#ifdef SK_DEBUG
|
||||
#include <assert.h>
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) assert(cond)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// stdlib macros
|
||||
|
||||
#if 0
|
||||
#if !defined(strlen) && defined(SK_DEBUG)
|
||||
extern size_t sk_strlen(const char*);
|
||||
#define strlen(s) sk_strlen(s)
|
||||
#endif
|
||||
#ifndef sk_strcpy
|
||||
#define sk_strcpy(dst, src) strcpy(dst, src)
|
||||
#endif
|
||||
#ifndef sk_strchr
|
||||
#define sk_strchr(s, c) strchr(s, c)
|
||||
#endif
|
||||
#ifndef sk_strrchr
|
||||
#define sk_strrchr(s, c) strrchr(s, c)
|
||||
#endif
|
||||
#ifndef sk_strcmp
|
||||
#define sk_strcmp(s, t) strcmp(s, t)
|
||||
#endif
|
||||
#ifndef sk_strncmp
|
||||
#define sk_strncmp(s, t, n) strncmp(s, t, n)
|
||||
#endif
|
||||
#ifndef sk_memcpy
|
||||
#define sk_memcpy(dst, src, n) memcpy(dst, src, n)
|
||||
#endif
|
||||
#ifndef memmove
|
||||
#define memmove(dst, src, n) memmove(dst, src, n)
|
||||
#endif
|
||||
#ifndef sk_memset
|
||||
#define sk_memset(dst, val, n) memset(dst, val, n)
|
||||
#endif
|
||||
#ifndef sk_memcmp
|
||||
#define sk_memcmp(s, t, n) memcmp(s, t, n)
|
||||
#endif
|
||||
|
||||
#define sk_strequal(s, t) (!sk_strcmp(s, t))
|
||||
#define sk_strnequal(s, t, n) (!sk_strncmp(s, t, n))
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SK_BUILD_FOR_WINCE
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#define _CMNINTRIN_DECLARE_ONLY
|
||||
#include "cmnintrin.h"
|
||||
#endif
|
||||
|
||||
#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
|
||||
//#define _CRTDBG_MAP_ALLOC
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
#include <crtdbg.h>
|
||||
#undef free
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
|
||||
void * operator new(
|
||||
size_t cb,
|
||||
int nBlockUse,
|
||||
const char * szFileName,
|
||||
int nLine,
|
||||
int foo
|
||||
);
|
||||
void * operator new[](
|
||||
size_t cb,
|
||||
int nBlockUse,
|
||||
const char * szFileName,
|
||||
int nLine,
|
||||
int foo
|
||||
);
|
||||
void operator delete(
|
||||
void *pUserData,
|
||||
int, const char*, int, int
|
||||
);
|
||||
void operator delete(
|
||||
void *pUserData
|
||||
);
|
||||
void operator delete[]( void * p );
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
|
||||
#else
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
|
||||
#endif
|
||||
#define new DEBUG_CLIENTBLOCK
|
||||
#else
|
||||
#define DEBUG_CLIENTBLOCK
|
||||
#endif // _DEBUG
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef SkPreConfig_DEFINED
|
||||
#define SkPreConfig_DEFINED
|
||||
|
||||
#ifdef ANDROID
|
||||
#define SK_BUILD_FOR_UNIX
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
#define SK_CAN_USE_FLOAT
|
||||
#endif
|
||||
|
||||
#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
|
||||
#if defined(__APPLE__) || defined(__MC68K__)
|
||||
#define SK_CPU_BENDIAN
|
||||
#else
|
||||
#define SK_CPU_LENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC)
|
||||
|
||||
#if defined(PALMOS_SDK_VERSION)
|
||||
#define SK_BUILD_FOR_PALM
|
||||
#elif defined(UNDER_CE)
|
||||
#define SK_BUILD_FOR_WINCE
|
||||
#elif defined(WIN32)
|
||||
#define SK_BUILD_FOR_WIN32
|
||||
#elif defined(__SYMBIAN32__)
|
||||
#define SK_BUILD_FOR_WIN32
|
||||
#elif defined(linux)
|
||||
#define SK_BUILD_FOR_UNIX
|
||||
#else
|
||||
#define SK_BUILD_FOR_MAC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
#ifdef NDEBUG
|
||||
#define SK_RELEASE
|
||||
#else
|
||||
#define SK_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#endif
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
|
||||
#define SK_CAN_USE_FLOAT
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
#define SK_CAN_USE_LONGLONG
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_CAN_USE_LONGLONG
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define SkLONGLONG __int64
|
||||
#else
|
||||
#define SkLONGLONG long long
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
|
||||
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
#define SK_CPU_BENDIAN
|
||||
#else
|
||||
#define SK_CPU_LENDIAN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SK_BUILD_FOR_BREW) || defined(SK_BUILD_FOR_WINCE) || (defined(SK_BUILD_FOR_SYMBIAN) && !defined(__MARM_THUMB__))
|
||||
/* e.g. the ARM instructions have conditional execution, making tiny branches cheap */
|
||||
#define SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Conditional features based on build target
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
|
||||
#ifndef SK_BUILD_NO_IMAGE_ENCODE
|
||||
#define SK_SUPPORT_IMAGE_ENCODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_SYMBIAN
|
||||
#define SK_USE_RUNTIME_GLOBALS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef SkRandom_DEFINED
|
||||
#define SkRandom_DEFINED
|
||||
|
||||
#include "Sk64.h"
|
||||
|
||||
/** \class SkRandom
|
||||
|
||||
Utility class that implements pseudo random 32bit numbers using a fast
|
||||
linear equation. Unlike rand(), this class holds its own seed (initially
|
||||
set to 0), so that multiple instances can be used with no side-effects.
|
||||
*/
|
||||
class SkRandom {
|
||||
public:
|
||||
SkRandom() : fSeed(0) {}
|
||||
SkRandom(uint32_t seed) : fSeed(seed) {}
|
||||
|
||||
/** Return the next pseudo random number as an unsigned 32bit value.
|
||||
*/
|
||||
uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }
|
||||
/** Return the next pseudo random number as a signed 32bit value.
|
||||
*/
|
||||
int32_t nextS() { return (int32_t)this->nextU(); }
|
||||
/** Return the next pseudo random number as an unsigned 16bit value.
|
||||
*/
|
||||
U16CPU nextU16() { return this->nextU() >> 16; }
|
||||
/** Return the next pseudo random number as a signed 16bit value.
|
||||
*/
|
||||
S16CPU nextS16() { return this->nextS() >> 16; }
|
||||
|
||||
/** Return the next pseudo random number, as an unsigned value of
|
||||
at most bitCount bits.
|
||||
@param bitCount The maximum number of bits to be returned
|
||||
*/
|
||||
uint32_t nextBits(unsigned bitCount)
|
||||
{
|
||||
SkASSERT(bitCount > 0 && bitCount <= 32);
|
||||
return this->nextU() >> (32 - bitCount);
|
||||
}
|
||||
/** Return the next pseudo random unsigned number, mapped to lie within
|
||||
[min, max] inclusive.
|
||||
*/
|
||||
uint32_t nextRangeU(uint32_t min, uint32_t max)
|
||||
{
|
||||
SkASSERT(min <= max);
|
||||
return min + this->nextU() % (max - min + 1);
|
||||
}
|
||||
|
||||
/** Return the next pseudo random number expressed as an unsigned SkFixed
|
||||
in the range [0..SK_Fixed1).
|
||||
*/
|
||||
SkFixed nextUFixed1() { return this->nextU() >> 16; }
|
||||
/** Return the next pseudo random number expressed as a signed SkFixed
|
||||
in the range (-SK_Fixed1..SK_Fixed1).
|
||||
*/
|
||||
SkFixed nextSFixed1() { return this->nextS() >> 15; }
|
||||
|
||||
/** Return the next pseudo random number expressed as a SkScalar
|
||||
in the range [0..SK_Scalar1).
|
||||
*/
|
||||
SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
|
||||
/** Return the next pseudo random number expressed as a SkScalar
|
||||
in the range (-SK_Scalar1..SK_Scalar1).
|
||||
*/
|
||||
SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
|
||||
|
||||
/** Return the next pseudo random number as a signed 64bit value.
|
||||
*/
|
||||
void next64(Sk64* a) { SkASSERT(a); a->set(this->nextS(), this->nextU()); }
|
||||
/** Set the seed of the random object. The seed is initialized to 0 when the
|
||||
object is first created, and is updated each time the next pseudo random
|
||||
number is requested.
|
||||
*/
|
||||
void setSeed(int32_t seed) { fSeed = (uint32_t)seed; }
|
||||
|
||||
private:
|
||||
// "Numerical Recipes in C", 1992 page 284
|
||||
enum {
|
||||
kMul = 1664525,
|
||||
kAdd = 1013904223
|
||||
};
|
||||
uint32_t fSeed;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
#ifndef SkRect_DEFINED
|
||||
#define SkRect_DEFINED
|
||||
|
||||
#include "SkPoint.h"
|
||||
|
||||
/** \struct SkRect16
|
||||
|
||||
SkRect16 holds four 16 bit integer coordinates for a rectangle
|
||||
*/
|
||||
struct SkRect16 {
|
||||
S16 fLeft, fTop, fRight, fBottom;
|
||||
|
||||
/** Returns true if the rectangle is empty (e.g. left >= right or top >= bottom)
|
||||
*/
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
/** Returns the rectangle's width. This does not check for a valid rectangle (i.e. left <= right)
|
||||
so the result may be negative.
|
||||
*/
|
||||
int width() const { return fRight - fLeft; }
|
||||
/** Returns the rectangle's height. This does not check for a valid rectangle (i.e. top <= bottom)
|
||||
so the result may be negative.
|
||||
*/
|
||||
int height() const { return fBottom - fTop; }
|
||||
|
||||
friend int operator==(const SkRect16& a, const SkRect16& b)
|
||||
{
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
friend int operator!=(const SkRect16& a, const SkRect16& b)
|
||||
{
|
||||
return memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
/** Set the rectangle to (0,0,0,0)
|
||||
*/
|
||||
void setEmpty() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
void set(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom)
|
||||
{
|
||||
fLeft = SkToS16(left);
|
||||
fTop = SkToS16(top);
|
||||
fRight = SkToS16(right);
|
||||
fBottom = SkToS16(bottom);
|
||||
}
|
||||
/** Offset set the rectangle by adding dx to its left and right,
|
||||
and adding dy to its top and bottom.
|
||||
*/
|
||||
void offset(S16CPU dx, S16CPU dy)
|
||||
{
|
||||
fLeft = SkToS16(fLeft + dx);
|
||||
fTop = SkToS16(fTop + dy);
|
||||
fRight = SkToS16(fRight + dx);
|
||||
fBottom = SkToS16(fBottom + dy);
|
||||
}
|
||||
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
|
||||
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
|
||||
making the rectangle wider. The same hods true for dy and the top and bottom.
|
||||
*/
|
||||
void inset(S16CPU dx, S16CPU dy)
|
||||
{
|
||||
fLeft = SkToS16(fLeft + dx);
|
||||
fTop = SkToS16(fTop + dy);
|
||||
fRight = SkToS16(fRight - dx);
|
||||
fBottom = SkToS16(fBottom - dy);
|
||||
}
|
||||
/** Returns true if (x,y) is inside the rectangle. The left and top are considered to be
|
||||
inside, while the right and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
|
||||
points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not.
|
||||
*/
|
||||
bool contains(S16CPU x, S16CPU y) const
|
||||
{
|
||||
return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) &&
|
||||
(unsigned)(y - fTop) < (unsigned)(fBottom - fTop);
|
||||
}
|
||||
/** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle.
|
||||
*/
|
||||
bool contains(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom) const
|
||||
{
|
||||
return fLeft <= left && fTop <= top &&
|
||||
fRight >= right && fBottom >= bottom;
|
||||
}
|
||||
/** Returns true if the specified rectangle r is inside or equal to this rectangle.
|
||||
*/
|
||||
bool contains(const SkRect16& r) const
|
||||
{
|
||||
return fLeft <= r.fLeft && fTop <= r.fTop &&
|
||||
fRight >= r.fRight && fBottom >= r.fBottom;
|
||||
}
|
||||
/** If r intersects this rectangle, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
*/
|
||||
bool intersect(const SkRect16& r);
|
||||
/** If rectangles a and b intersect, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
*/
|
||||
bool intersect(const SkRect16& a, const SkRect16& b);
|
||||
/** If the rectangle specified by left,top,right,bottom intersects this rectangle,
|
||||
return true and set this rectangle to that intersection,
|
||||
otherwise return false and do not change this rectangle.
|
||||
*/
|
||||
bool intersect(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom);
|
||||
/** Returns true if a and b intersect
|
||||
*/
|
||||
static bool Intersects(const SkRect16& a, const SkRect16& b)
|
||||
{
|
||||
return a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
void join(const SkRect16& r)
|
||||
{
|
||||
fLeft = SkToS16(SkMin32(fLeft, r.fLeft));
|
||||
fTop = SkToS16(SkMin32(fTop, r.fTop));
|
||||
fRight = SkToS16(SkMax32(fRight, r.fRight));
|
||||
fBottom = SkToS16(SkMax32(fBottom, r.fBottom));
|
||||
}
|
||||
|
||||
/** Swap top/bottom or left/right if there are flipped.
|
||||
This can be called if the edges are computed separately,
|
||||
and may have crossed over each other.
|
||||
When this returns, left <= right && top <= bottom
|
||||
*/
|
||||
void sort();
|
||||
};
|
||||
|
||||
/** \struct SkRect
|
||||
*/
|
||||
struct SkRect {
|
||||
SkScalar fLeft, fTop, fRight, fBottom;
|
||||
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
SkScalar width() const { return fRight - fLeft; }
|
||||
SkScalar height() const { return fBottom - fTop; }
|
||||
SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); }
|
||||
SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); }
|
||||
|
||||
friend int operator==(const SkRect& a, const SkRect& b)
|
||||
{
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
friend int operator!=(const SkRect& a, const SkRect& b)
|
||||
{
|
||||
return memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
/** return the 4 points that enclose the rectangle
|
||||
*/
|
||||
void toQuad(SkPoint quad[4]) const;
|
||||
|
||||
/** Set this rectangle to the empty rectangle (0,0,0,0)
|
||||
*/
|
||||
void setEmpty() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
void set(const SkRect16& src)
|
||||
{
|
||||
fLeft = SkIntToScalar(src.fLeft);
|
||||
fTop = SkIntToScalar(src.fTop);
|
||||
fRight = SkIntToScalar(src.fRight);
|
||||
fBottom = SkIntToScalar(src.fBottom);
|
||||
}
|
||||
|
||||
void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
|
||||
{
|
||||
fLeft = left;
|
||||
fTop = top;
|
||||
fRight = right;
|
||||
fBottom = bottom;
|
||||
}
|
||||
/** Set this rectangle to be the bounds of the array of points.
|
||||
If the array is empty (count == 0), then set this rectangle
|
||||
to the empty rectangle (0,0,0,0)
|
||||
*/
|
||||
void set(const SkPoint pts[], int count);
|
||||
|
||||
/** Offset set the rectangle by adding dx to its left and right,
|
||||
and adding dy to its top and bottom.
|
||||
*/
|
||||
void offset(SkScalar dx, SkScalar dy)
|
||||
{
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight += dx;
|
||||
fBottom += dy;
|
||||
}
|
||||
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
|
||||
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
|
||||
making the rectangle wider. The same hods true for dy and the top and bottom.
|
||||
*/
|
||||
void inset(SkScalar dx, SkScalar dy)
|
||||
{
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight -= dx;
|
||||
fBottom -= dy;
|
||||
}
|
||||
|
||||
/** If this rectangle intersects r, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
*/
|
||||
bool intersect(const SkRect& r);
|
||||
/** If this rectangle intersects the rectangle specified by left, top, right, bottom,
|
||||
return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
*/
|
||||
bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
|
||||
/** Return true if rectangles a and b intersect.
|
||||
*/
|
||||
static bool Intersects(const SkRect& a, const SkRect& b)
|
||||
{
|
||||
return a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
|
||||
/** Returns true if (p.fX,p.fY) is inside the rectangle. The left and top coordinates of
|
||||
the rectangle are considered to be inside, while the right and bottom coordinates
|
||||
are not. Thus for the rectangle (0, 0, 5, 10), the points (0,0) and (0,9) are inside,
|
||||
while (-1,0) and (5,9) are not.
|
||||
*/
|
||||
bool contains(const SkPoint& p) const
|
||||
{
|
||||
return fLeft <= p.fX && p.fX < fRight &&
|
||||
fTop <= p.fY && p.fY < fBottom;
|
||||
}
|
||||
/** Returns true if (x,y) is inside the rectangle. The left and top coordinates of
|
||||
the rectangle are considered to be inside, while the right and bottom coordinates
|
||||
are not. Thus for the rectangle (0, 0, 5, 10), the points (0,0) and (0,9) are inside,
|
||||
while (-1,0) and (5,9) are not.
|
||||
*/
|
||||
bool contains(SkScalar x, SkScalar y) const
|
||||
{
|
||||
return fLeft <= x && x < fRight &&
|
||||
fTop <= y && y < fBottom;
|
||||
}
|
||||
/** Return true if this rectangle contains r
|
||||
*/
|
||||
bool contains(const SkRect& r) const
|
||||
{
|
||||
return fLeft <= r.fLeft && fTop <= r.fTop &&
|
||||
fRight >= r.fRight && fBottom >= r.fBottom;
|
||||
}
|
||||
/** Set the dst integer rectangle by rounding this rectangle's coordinates
|
||||
to their nearest integer values.
|
||||
*/
|
||||
void round(SkRect16* dst) const
|
||||
{
|
||||
SkASSERT(dst);
|
||||
dst->set(SkScalarRound(fLeft), SkScalarRound(fTop), SkScalarRound(fRight), SkScalarRound(fBottom));
|
||||
}
|
||||
/** Set the dst integer rectangle by rounding "out" this rectangle, choosing the floor of top and left,
|
||||
and the ceiling of right and bototm.
|
||||
*/
|
||||
void roundOut(SkRect16* dst) const
|
||||
{
|
||||
SkASSERT(dst);
|
||||
dst->set(SkScalarFloor(fLeft), SkScalarFloor(fTop), SkScalarCeil(fRight), SkScalarCeil(fBottom));
|
||||
}
|
||||
|
||||
/** Swap top/bottom or left/right if there are flipped.
|
||||
This can be called if the edges are computed separately,
|
||||
and may have crossed over each other.
|
||||
When this returns, left <= right && top <= bottom
|
||||
*/
|
||||
void sort();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
#ifndef SkRegion_DEFINED
|
||||
#define SkRegion_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkPath;
|
||||
class SkRgnBuilder;
|
||||
|
||||
namespace android {
|
||||
class Region;
|
||||
}
|
||||
|
||||
#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1)
|
||||
#define SkRegion_gRectRunHeadPtr 0
|
||||
|
||||
/** \class SkRegion
|
||||
|
||||
The SkRegion class encapsulates the geometric region used to specify
|
||||
clipping areas for drawing.
|
||||
*/
|
||||
class SkRegion {
|
||||
public:
|
||||
typedef int16_t RunType;
|
||||
|
||||
SkRegion();
|
||||
explicit SkRegion(const SkRegion&);
|
||||
explicit SkRegion(const SkRect16&);
|
||||
~SkRegion();
|
||||
|
||||
SkRegion& operator=(const SkRegion&);
|
||||
|
||||
friend int operator==(const SkRegion& a, const SkRegion& b);
|
||||
friend int operator!=(const SkRegion& a, const SkRegion& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
// provide explicitly, so we'll have a java equivalent
|
||||
void set(const SkRegion& src)
|
||||
{
|
||||
SkASSERT(&src);
|
||||
*this = src;
|
||||
}
|
||||
/** Swap the contents of this and the specified region. This operation
|
||||
is gauarenteed to never fail.
|
||||
*/
|
||||
void swap(SkRegion&);
|
||||
|
||||
/** Return true if this region is empty */
|
||||
bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
|
||||
/** Return true if this region is a single, non-empty rectangle */
|
||||
bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
|
||||
/** Return true if this region consists of more than 1 rectangular area */
|
||||
bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
|
||||
/** Return the bounds of this region. If the region is empty, returns an
|
||||
empty rectangle.
|
||||
*/
|
||||
const SkRect16& getBounds() const { return fBounds; }
|
||||
|
||||
/** Returns true if the region is non-empty, and if so, sets the specified path to the
|
||||
boundary(s) of the region.
|
||||
*/
|
||||
bool getBoundaryPath(SkPath* path) const;
|
||||
|
||||
/** Set the region to be empty, and return false */
|
||||
bool setEmpty();
|
||||
/** If rect is non-empty, set this region to that rectangle and return true,
|
||||
otherwise set this region to empty and return false.
|
||||
*/
|
||||
bool setRect(const SkRect16&);
|
||||
/** If left < right and top < bottom, set this region to that rectangle and
|
||||
return true, otherwise set this region to empty and return false.
|
||||
*/
|
||||
bool setRect(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom);
|
||||
/** Set this region to the specified region, and return true if it is non-empty. */
|
||||
bool setRegion(const SkRegion&);
|
||||
/** Set this region to the area described by the path, optionally clipped (if clip is
|
||||
not nil). Return true if the resulting region is non-empty. This produces a region
|
||||
that is identical to the pixels that would be drawn by the path (with no antialiasing).
|
||||
*/
|
||||
bool setPath(const SkPath&, const SkRegion* clip = nil);
|
||||
/** Return true if the specified x,y coordinate is inside the region.
|
||||
*/
|
||||
bool contains(S16CPU x, S16CPU y) const;
|
||||
/** Return true if this region is a single rectangle (not complex) and the specified rectangle
|
||||
is contained by this region. Returning false is not a guarantee that the rectangle is not contained
|
||||
by this region, but return true is a guarantee that the rectangle is contained by this region.
|
||||
*/
|
||||
bool quickContains(const SkRect16& r) const
|
||||
{
|
||||
return this->isRect() && fBounds.contains(r);
|
||||
}
|
||||
/** Return true if this region is a single rectangle (not complex) and the specified rectangle
|
||||
is contained by this region. Returning false is not a guarantee that the rectangle is not contained
|
||||
by this region, but return true is a guarantee that the rectangle is contained by this region.
|
||||
*/
|
||||
bool quickContains(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom) const
|
||||
{
|
||||
return this->isRect() && fBounds.contains(left, top, right, bottom);
|
||||
}
|
||||
/** Return true if this region is empty, or if the specified rectangle does not intersect
|
||||
the region. Returning false is not a guarantee that they intersect, but returning
|
||||
true is a guarantee that they do not.
|
||||
*/
|
||||
bool quickReject(const SkRect16& rect) const
|
||||
{
|
||||
return this->isEmpty() || !SkRect16::Intersects(fBounds, rect);
|
||||
}
|
||||
/** Return true if this region, or rgn, is empty, or if their bounds do not intersect.
|
||||
Returning false is not a guarantee that they intersect, but returning true is a guarantee
|
||||
that they do not.
|
||||
*/
|
||||
bool quickReject(const SkRegion& rgn) const
|
||||
{
|
||||
return this->isEmpty() || rgn.isEmpty() || !SkRect16::Intersects(fBounds, rgn.fBounds);
|
||||
}
|
||||
|
||||
void translate(int dx, int dy)
|
||||
{
|
||||
this->translate(dx, dy, this);
|
||||
}
|
||||
void translate(int dx, int dy, SkRegion* dst) const;
|
||||
|
||||
enum Op {
|
||||
kDifference_Op,
|
||||
kIntersect_Op,
|
||||
kUnion_Op,
|
||||
kXOR_Op,
|
||||
|
||||
kOpCount
|
||||
};
|
||||
/** Set this region to the result of applying the Opereation to this region and the specified
|
||||
rectangle. Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkRect16&, Op);
|
||||
// helper for java, so it doesn't have to create a Rect object
|
||||
bool op(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom, Op op)
|
||||
{
|
||||
SkRect16 r;
|
||||
r.set(left, top, right, bottom);
|
||||
return this->op(r, op);
|
||||
}
|
||||
/** Set this region to the result of applying the Opereation to this region and the specified
|
||||
region. Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
|
||||
/** Set this region to the result of applying the Opereation to the specified rectangle and region.
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkRect16&, const SkRegion&, Op);
|
||||
/** Set this region to the result of applying the Opereation to the specified regions.
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkRegion&, const SkRegion&, Op);
|
||||
|
||||
/** Helper class that returns the sequence of rectangles that make up this region.
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator();
|
||||
Iterator(const SkRegion&);
|
||||
void reset(const SkRegion&);
|
||||
bool done() { return fDone; }
|
||||
void next();
|
||||
const SkRect16& rect() const { return fRect; }
|
||||
|
||||
private:
|
||||
const RunType* fRuns;
|
||||
SkRect16 fRect;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
/** Helper class that returns the sequence of rectangles that make up this region,
|
||||
intersected with the clip rectangle.
|
||||
*/
|
||||
class Cliperator {
|
||||
public:
|
||||
Cliperator(const SkRegion&, const SkRect16& clip);
|
||||
bool done() { return fDone; }
|
||||
void next();
|
||||
const SkRect16& rect() const { return fRect; }
|
||||
|
||||
private:
|
||||
Iterator fIter;
|
||||
SkRect16 fClip;
|
||||
SkRect16 fRect;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
/** Helper class that returns the sequence of scanline runs that make up this region.
|
||||
*/
|
||||
class Spanerator {
|
||||
public:
|
||||
Spanerator(const SkRegion&, int y, int left, int right);
|
||||
bool next(int* left, int* right);
|
||||
|
||||
private:
|
||||
const SkRegion::RunType* fRuns;
|
||||
int fLeft, fRight;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
/** Return the number of bytes need to write this region to a buffer.
|
||||
*/
|
||||
size_t computeBufferSize() const;
|
||||
/** Write the region to the buffer, and return the number of bytes written.
|
||||
*/
|
||||
size_t writeToBuffer(void* buffer) const;
|
||||
/** Initialized the region from the buffer, returning the number
|
||||
of bytes actually read.
|
||||
*/
|
||||
size_t readFromBuffer(const void* buffer);
|
||||
|
||||
SkDEBUGCODE(void dump() const;)
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
|
||||
private:
|
||||
enum {
|
||||
kRectRegionRuns = 6, // need to store a region of a rect [T B L R S S]
|
||||
kRunTypeSentinel = 0x7FFF
|
||||
};
|
||||
|
||||
friend class android::Region; // needed for marshalling efficiently
|
||||
void allocateRuns(int count); // allocate space for count runs
|
||||
|
||||
struct RunHead;
|
||||
|
||||
SkRect16 fBounds;
|
||||
RunHead* fRunHead;
|
||||
|
||||
void freeRuns();
|
||||
const RunType* getRuns(RunType tmpStorage[], int* count) const;
|
||||
bool setRuns(RunType runs[], int count);
|
||||
|
||||
int count_runtype_values(int* itop, int* ibot) const;
|
||||
|
||||
static void build_rect_runs(const SkRect16& bounds, RunType runs[kRectRegionRuns]);
|
||||
static bool compute_run_bounds(const RunType runs[], int count, SkRect16* bounds);
|
||||
|
||||
friend struct RunHead;
|
||||
friend class Iterator;
|
||||
friend class Spanerator;
|
||||
friend class SkRgnBuilder;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
#ifndef SkScalar_DEFINED
|
||||
#define SkScalar_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkScalar.h
|
||||
|
||||
Types and macros for the data type SkScalar. This is the fractional numeric type
|
||||
that, depending on the compile-time flag SK_SCALAR_IS_FLOAT, may be implemented
|
||||
either as an IEEE float, or as a 16.16 SkFixed. The macros in this file are written
|
||||
to allow the calling code to manipulate SkScalar values without knowing which representation
|
||||
is in effect.
|
||||
*/
|
||||
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#include "SkFloatingPoint.h"
|
||||
|
||||
/** SkScalar is our type for fractional values and coordinates. Depending on
|
||||
compile configurations, it is either represented as an IEEE float, or
|
||||
as a 16.16 fixed point integer.
|
||||
*/
|
||||
typedef float SkScalar;
|
||||
extern const uint32_t gIEEENotANumber;
|
||||
extern const uint32_t gIEEEInfinity;
|
||||
|
||||
/** SK_Scalar1 is defined to be 1.0 represented as an SkScalar
|
||||
*/
|
||||
#define SK_Scalar1 (1.0f)
|
||||
/** SK_Scalar1 is defined to be 1/2 represented as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarHalf (0.5f)
|
||||
/** SK_ScalarInfinity is defined to be infinity as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarInfinity (*(const float*)&gIEEEInfinity)
|
||||
/** SK_ScalarMax is defined to be the largest value representable as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarMax (3.4028235e+38f)
|
||||
/** SK_ScalarMin is defined to be the smallest value representable as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarMin (1.1754944e-38f)
|
||||
/** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarNaN (*(const float*)&gIEEENotANumber)
|
||||
/** SkScalarIsNaN(n) returns true if argument is not a number
|
||||
*/
|
||||
static inline bool SkScalarIsNaN(float x) { return x != x; }
|
||||
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
||||
*/
|
||||
#define SkIntToScalar(n) ((float)(n))
|
||||
/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar
|
||||
*/
|
||||
#define SkFixedToScalar(x) SkFixedToFloat(x)
|
||||
/** SkFixedToScalar(n) returns its SkScalar argument as an SkFixed
|
||||
*/
|
||||
#define SkScalarToFixed(x) (SkFixed)((x) * SK_Fixed1)
|
||||
|
||||
#define SkScalarToFloat(n) (n)
|
||||
#define SkFloatToScalar(n) (n)
|
||||
|
||||
/** SkScalarFraction(x) returns the signed fractional part of the argument
|
||||
*/
|
||||
#define SkScalarFraction(x) sk_float_mod(x, 1.0f)
|
||||
/** Rounds the SkScalar to the nearest integer value
|
||||
*/
|
||||
inline int SkScalarRound(SkScalar x)
|
||||
{
|
||||
if (x < 0)
|
||||
x -= SK_ScalarHalf;
|
||||
else
|
||||
x += SK_ScalarHalf;
|
||||
return (int)x;
|
||||
}
|
||||
/** Returns the smallest integer that is >= the specified SkScalar
|
||||
*/
|
||||
#define SkScalarCeil(x) (int)ceil(x)
|
||||
/** Returns the largest integer that is <= the specified SkScalar
|
||||
*/
|
||||
#define SkScalarFloor(x) (int)floor(x)
|
||||
/** Returns the absolute value of the specified SkScalar
|
||||
*/
|
||||
#define SkScalarAbs(x) sk_float_abs(x)
|
||||
/** Returns the value pinned between 0 and max inclusive
|
||||
*/
|
||||
inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) {
|
||||
return x < 0 ? 0 : x > max ? max : x;
|
||||
}
|
||||
/** Returns the value pinned between min and max inclusive
|
||||
*/
|
||||
inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) {
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
/** Returns the specified SkScalar squared (x*x)
|
||||
*/
|
||||
inline SkScalar SkScalarSquare(SkScalar x) { return x * x; }
|
||||
/** Returns the product of two SkScalars
|
||||
*/
|
||||
#define SkScalarMul(a, b) ((a) * (b))
|
||||
/** Returns the product of a SkScalar and an int rounded to the nearest integer value
|
||||
*/
|
||||
#define SkScalarMulRound(a, b) SkScalarRound((a) * (b))
|
||||
/** Returns the product of a SkScalar and an int promoted to the next larger int
|
||||
*/
|
||||
#define SkScalarMulCeil(a, b) SkScalarCeil((a) * (b))
|
||||
/** Returns the product of a SkScalar and an int truncated to the next smaller int
|
||||
*/
|
||||
#define SkScalarMulFloor(a, b) SkScalarFloor((a) * (b))
|
||||
/** Returns the quotient of two SkScalars (a/b)
|
||||
*/
|
||||
#define SkScalarDiv(a, b) ((a) / (b))
|
||||
/** Returns the mod of two SkScalars (a mod b)
|
||||
*/
|
||||
#define SkScalarMod(x,y) sk_float_mod(x,y)
|
||||
/** Returns the product of the first two arguments, divided by the third argument
|
||||
*/
|
||||
#define SkScalarMulDiv(a, b, c) ((a) * (b) / (c))
|
||||
/** Returns the multiplicative inverse of the SkScalar (1/x)
|
||||
*/
|
||||
#define SkScalarInvert(x) (SK_Scalar1 / (x))
|
||||
/** Returns the square root of the SkScalar
|
||||
*/
|
||||
#define SkScalarSqrt(x) sk_float_sqrt(x)
|
||||
/** Returns the average of two SkScalars (a+b)/2
|
||||
*/
|
||||
#define SkScalarAve(a, b) (((a) + (b)) * 0.5f)
|
||||
/** Returns the geometric mean of two SkScalars
|
||||
*/
|
||||
#define SkScalarMean(a, b) sk_float_sqrt((a) * (b))
|
||||
/** Returns one half of the specified SkScalar
|
||||
*/
|
||||
#define SkScalarHalf(a) ((a) * 0.5f)
|
||||
|
||||
#define SK_ScalarSqrt2 1.41421356f
|
||||
#define SK_ScalarPI 3.14159265f
|
||||
#define SK_ScalarTanPIOver8 0.414213562f
|
||||
#define SK_ScalarRoot2Over2 0.707106781f
|
||||
|
||||
#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
|
||||
float SkScalarSinCos(SkScalar radians, SkScalar* cosValue);
|
||||
#define SkScalarSin(radians) (float)sk_float_sin(radians)
|
||||
#define SkScalarCos(radians) (float)sk_float_cos(radians)
|
||||
#define SkScalarTan(radians) (float)sk_float_tan(radians)
|
||||
#define SkScalarASin(val) (float)sk_float_asin(val)
|
||||
#define SkScalarACos(val) (float)sk_float_acos(val)
|
||||
#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x)
|
||||
#define SkScalarExp(x) (float)sk_float_exp(x)
|
||||
#define SkScalarLog(x) (float)sk_float_log(x)
|
||||
|
||||
inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; }
|
||||
inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; }
|
||||
|
||||
#else
|
||||
#include "SkFixed.h"
|
||||
|
||||
typedef SkFixed SkScalar;
|
||||
|
||||
#define SK_Scalar1 SK_Fixed1
|
||||
#define SK_ScalarHalf SK_FixedHalf
|
||||
#define SK_ScalarInfinity SK_FixedMax
|
||||
#define SK_ScalarMax SK_FixedMax
|
||||
#define SK_ScalarMin SK_FixedMin
|
||||
#define SK_ScalarNaN SK_FixedNaN
|
||||
#define SkScalarIsNaN(x) ((x) == SK_FixedNaN)
|
||||
#define SkIntToScalar(n) SkIntToFixed(n)
|
||||
#define SkFixedToScalar(x) (x)
|
||||
#define SkScalarToFixed(x) (x)
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SkScalarToFloat(n) SkFixedToFloat(n)
|
||||
#define SkFloatToScalar(n) SkFloatToFixed(n)
|
||||
#endif
|
||||
#define SkScalarFraction(x) SkFixedFraction(x)
|
||||
#define SkScalarRound(x) SkFixedRound(x)
|
||||
#define SkScalarCeil(x) SkFixedCeil(x)
|
||||
#define SkScalarFloor(x) SkFixedFloor(x)
|
||||
#define SkScalarAbs(x) SkFixedAbs(x)
|
||||
#define SkScalarClampMax(x, max) SkClampMax(x, max)
|
||||
#define SkScalarPin(x, min, max) SkPin32(x, min, max)
|
||||
#define SkScalarSquare(x) SkFixedSquare(x)
|
||||
#define SkScalarMul(a, b) SkFixedMul(a, b)
|
||||
#define SkScalarMulRound(a, b) SkFixedMulCommon(a, b, SK_FixedHalf)
|
||||
#define SkScalarMulCeil(a, b) SkFixedMulCommon(a, b, SK_Fixed1 - 1)
|
||||
#define SkScalarMulFloor(a, b) SkFixedMulCommon(a, b, 0)
|
||||
#define SkScalarDiv(a, b) SkFixedDiv(a, b)
|
||||
#define SkScalarMod(a, b) SkFixedMod(a, b)
|
||||
#define SkScalarMulDiv(a, b, c) SkMulDiv(a, b, c)
|
||||
#define SkScalarInvert(x) SkFixedInvert(x)
|
||||
#define SkScalarSqrt(x) SkFixedSqrt(x)
|
||||
#define SkScalarAve(a, b) SkFixedAve(a, b)
|
||||
#define SkScalarMean(a, b) SkFixedMean(a, b)
|
||||
#define SkScalarHalf(a) ((a) >> 1)
|
||||
|
||||
#define SK_ScalarSqrt2 SK_FixedSqrt2
|
||||
#define SK_ScalarPI SK_FixedPI
|
||||
#define SK_ScalarTanPIOver8 SK_FixedTanPIOver8
|
||||
#define SK_ScalarRoot2Over2 SK_FixedRoot2Over2
|
||||
|
||||
#define SkDegreesToRadians(degrees) SkFractMul(degrees, SK_FractPIOver180)
|
||||
#define SkScalarSinCos(radians, cosPtr) SkFixedSinCos(radians, cosPtr)
|
||||
#define SkScalarSin(radians) SkFixedSin(radians)
|
||||
#define SkScalarCos(radians) SkFixedCos(radians)
|
||||
#define SkScalarTan(val) SkFixedTan(val)
|
||||
#define SkScalarASin(val) SkFixedASin(val)
|
||||
#define SkScalarACos(val) SkFixedACos(val)
|
||||
#define SkScalarATan2(y, x) SkFixedATan2(y,x)
|
||||
#define SkScalarExp(x) SkFixedExp(x)
|
||||
#define SkScalarLog(x) SkFixedLog(x)
|
||||
|
||||
#define SkMaxScalar(a, b) SkMax32(a, b)
|
||||
#define SkMinScalar(a, b) SkMin32(a, b)
|
||||
#endif
|
||||
|
||||
#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
|
||||
|
||||
/* <= is slower than < for floats, so we use < for our tolerance test
|
||||
*/
|
||||
|
||||
inline bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance = SK_ScalarNearlyZero)
|
||||
{
|
||||
SkASSERT(tolerance > 0);
|
||||
return SkScalarAbs(x) < tolerance;
|
||||
}
|
||||
|
||||
/** Linearly interpolate between A and B, based on t.
|
||||
If t is 0, return A
|
||||
If t is 1, return B
|
||||
else interpolate.
|
||||
t must be [0..SK_Scalar1]
|
||||
*/
|
||||
inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t)
|
||||
{
|
||||
SkASSERT(t >= 0 && t <= SK_Scalar1);
|
||||
return A + SkScalarMul(B - A, t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
#ifndef SkTemplates_DEFINED
|
||||
#define SkTemplates_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkTemplates.h
|
||||
|
||||
This file contains light-weight template classes for type-safe and exception-safe
|
||||
resource management.
|
||||
*/
|
||||
|
||||
/** \class SkAutoTCallProc
|
||||
|
||||
Similar to SkAutoTDelete, this class is used to auto delete an object
|
||||
when leaving the scope of the object. This is mostly useful when
|
||||
errors occur and objects need to be cleaned up. The template uses two
|
||||
parameters, the object, and a function that is to be called in the destructor.
|
||||
If detach() is called then the function is not called when SkAutoTCallProc goes out
|
||||
of scope. This also happens is the passed in object is nil.
|
||||
|
||||
*/
|
||||
template <typename T, void (*P)(T*)> class SkAutoTCallProc {
|
||||
public:
|
||||
SkAutoTCallProc(T* obj): fObj(obj) {}
|
||||
~SkAutoTCallProc()
|
||||
{
|
||||
if (fObj)
|
||||
P(fObj);
|
||||
}
|
||||
T* detach() { T* obj = fObj; fObj = nil; return obj; }
|
||||
private:
|
||||
T* fObj;
|
||||
};
|
||||
|
||||
template <typename T> class SkAutoTDelete {
|
||||
public:
|
||||
SkAutoTDelete(T* obj) : fObj(obj) {}
|
||||
~SkAutoTDelete() { delete fObj; }
|
||||
|
||||
void free() { delete fObj; fObj = nil; }
|
||||
T* detach() { T* obj = fObj; fObj = nil; return obj; }
|
||||
|
||||
private:
|
||||
T* fObj;
|
||||
};
|
||||
|
||||
template <typename T> class SkAutoTDeleteArray {
|
||||
public:
|
||||
SkAutoTDeleteArray(T array[]) : fArray(array) {}
|
||||
~SkAutoTDeleteArray() { delete[] fArray; }
|
||||
|
||||
void free() { delete[] fArray; fArray = nil; }
|
||||
T* detach() { T* array = fArray; fArray = nil; return array; }
|
||||
|
||||
private:
|
||||
T* fArray;
|
||||
};
|
||||
|
||||
template <typename T> class SkAutoTArray {
|
||||
public:
|
||||
SkAutoTArray(size_t count)
|
||||
{
|
||||
fArray = nil; // init first in case we throw
|
||||
if (count)
|
||||
fArray = new T[count];
|
||||
#ifdef SK_DEBUG
|
||||
fCount = count;
|
||||
#endif
|
||||
}
|
||||
~SkAutoTArray()
|
||||
{
|
||||
delete[] fArray;
|
||||
}
|
||||
|
||||
T* get() const { return fArray; }
|
||||
T& operator[](int index) const { SkASSERT((unsigned)index < fCount); return fArray[index]; }
|
||||
|
||||
void reset()
|
||||
{
|
||||
if (fArray)
|
||||
{
|
||||
delete[] fArray;
|
||||
fArray = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void replace(T* array)
|
||||
{
|
||||
if (fArray != array)
|
||||
{
|
||||
delete[] fArray;
|
||||
fArray = array;
|
||||
}
|
||||
}
|
||||
|
||||
/** Call swap to exchange your pointer to an array of T with the SkAutoTArray object.
|
||||
After this call, the SkAutoTArray object will be responsible for deleting your
|
||||
array, and you will be responsible for deleting its.
|
||||
*/
|
||||
void swap(T*& other)
|
||||
{
|
||||
T* tmp = fArray;
|
||||
fArray = other;
|
||||
other = tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef SK_DEBUG
|
||||
size_t fCount;
|
||||
#endif
|
||||
T* fArray;
|
||||
};
|
||||
|
||||
/** Allocate a temp array on the stack/heap.
|
||||
Does NOT call any constructors/destructors on T (i.e. T must be POD)
|
||||
*/
|
||||
template <typename T> class SkAutoTMalloc {
|
||||
public:
|
||||
SkAutoTMalloc(size_t count)
|
||||
{
|
||||
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
|
||||
}
|
||||
~SkAutoTMalloc()
|
||||
{
|
||||
sk_free(fPtr);
|
||||
}
|
||||
T* get() const { return fPtr; }
|
||||
|
||||
private:
|
||||
T* fPtr;
|
||||
// illegal
|
||||
SkAutoTMalloc(const SkAutoTMalloc&);
|
||||
SkAutoTMalloc& operator=(const SkAutoTMalloc&);
|
||||
};
|
||||
|
||||
template <size_t N, typename T> class SkAutoSTMalloc {
|
||||
public:
|
||||
SkAutoSTMalloc(size_t count)
|
||||
{
|
||||
if (count <= N)
|
||||
fPtr = (T*)fStorage;
|
||||
else
|
||||
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
|
||||
}
|
||||
~SkAutoSTMalloc()
|
||||
{
|
||||
if (fPtr != (T*)fStorage)
|
||||
sk_free(fPtr);
|
||||
}
|
||||
T* get() const { return fPtr; }
|
||||
|
||||
private:
|
||||
T* fPtr;
|
||||
uint32_t fStorage[(N*sizeof(T) + 3) >> 2];
|
||||
// illegal
|
||||
SkAutoSTMalloc(const SkAutoSTMalloc&);
|
||||
SkAutoSTMalloc& operator=(const SkAutoSTMalloc&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef SkThread_DEFINED
|
||||
#define SkThread_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include "SkThread_platform.h"
|
||||
|
||||
/****** SkThread_platform needs to define the following...
|
||||
|
||||
int32_t sk_atomic_inc(int32_t*);
|
||||
int32_t sk_atomic_dec(int32_t*);
|
||||
|
||||
class SkMutex {
|
||||
public:
|
||||
SkMutex();
|
||||
~SkMutex();
|
||||
|
||||
void acquire();
|
||||
void release();
|
||||
};
|
||||
|
||||
****************/
|
||||
|
||||
class SkAutoMutexAcquire {
|
||||
public:
|
||||
explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(mutex)
|
||||
{
|
||||
mutex.acquire();
|
||||
}
|
||||
~SkAutoMutexAcquire()
|
||||
{
|
||||
fMutex.release();
|
||||
}
|
||||
private:
|
||||
SkMutex& fMutex;
|
||||
|
||||
// illegal
|
||||
SkAutoMutexAcquire& operator=(SkAutoMutexAcquire&);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef SkThread_platform_DEFINED
|
||||
#define SkThread_platform_DEFINED
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Atomic.h>
|
||||
|
||||
#define sk_atomic_inc(addr) android_atomic_inc(addr)
|
||||
#define sk_atomic_dec(addr) android_atomic_dec(addr)
|
||||
|
||||
class SkMutex : android::Mutex {
|
||||
public:
|
||||
SkMutex() {}
|
||||
~SkMutex() {}
|
||||
|
||||
void acquire() { this->lock(); }
|
||||
void release() { this->unlock(); }
|
||||
};
|
||||
|
||||
#else /* SkThread_empty.cpp */
|
||||
|
||||
int32_t sk_atomic_inc(int32_t* addr);
|
||||
int32_t sk_atomic_dec(int32_t* addr);
|
||||
|
||||
class SkMutex {
|
||||
public:
|
||||
SkMutex();
|
||||
~SkMutex();
|
||||
|
||||
void acquire();
|
||||
void release();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,299 @@
|
|||
#ifndef SkTypes_DEFINED
|
||||
#define SkTypes_DEFINED
|
||||
|
||||
#include "SkPreConfig.h"
|
||||
#include "SkUserConfig.h"
|
||||
#include "SkPostConfig.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/** \file SkTypes.h
|
||||
*/
|
||||
|
||||
/*
|
||||
memory wrappers
|
||||
*/
|
||||
|
||||
extern void sk_out_of_memory(void); // platform specific, does not return
|
||||
extern void sk_throw(void); // platform specific, does not return
|
||||
enum {
|
||||
SK_MALLOC_TEMP = 0x01, //!< hint to sk_malloc that the requested memory will be freed in the scope of the stack frame
|
||||
SK_MALLOC_THROW = 0x02 //!< instructs sk_malloc to call sk_throw if the memory cannot be allocated.
|
||||
};
|
||||
/** Return a block of memory (at least 4-byte aligned) of at least the
|
||||
specified size. If the requested memory cannot be returned, either
|
||||
return nil (if SK_MALLOC_TEMP bit is clear) or call sk_throw()
|
||||
(if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free().
|
||||
*/
|
||||
extern void* sk_malloc_flags(size_t size, unsigned flags);
|
||||
/** Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag
|
||||
*/
|
||||
extern void* sk_malloc_throw(size_t size);
|
||||
/** Same as standard realloc(), but this one never returns nil on failure. It will throw
|
||||
an exception if it fails.
|
||||
*/
|
||||
extern void* sk_realloc_throw(void* buffer, size_t size);
|
||||
/** Free memory returned by sk_malloc(). It is safe to pass nil.
|
||||
*/
|
||||
extern void sk_free(void*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SK_INIT_TO_AVOID_WARNING = 0
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#define SkASSERT(cond) SK_DEBUGBREAK(cond)
|
||||
#define SkDEBUGCODE(code) code
|
||||
#define SkDECLAREPARAM(type, var) , type var
|
||||
#define SkPARAM(var) , var
|
||||
// #define SkDEBUGF(args ) SkDebugf##args
|
||||
#define SkDEBUGF(args ) SkDebugf args
|
||||
void SkDebugf(const char format[], ...);
|
||||
|
||||
#define SkAssertResult(cond) SkASSERT(cond)
|
||||
#else
|
||||
#define SkASSERT(cond)
|
||||
#define SkDEBUGCODE(code)
|
||||
#define SkDEBUGF(args)
|
||||
#define SkDECLAREPARAM(type, var)
|
||||
#define SkPARAM(var)
|
||||
|
||||
// unlike SkASSERT, this guy executes its condition in the non-debug build
|
||||
#define SkAssertResult(cond) cond
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef nil
|
||||
#define nil 0
|
||||
#endif
|
||||
|
||||
// legacy defines. will be removed before shipping
|
||||
typedef int8_t S8;
|
||||
typedef uint8_t U8;
|
||||
typedef int16_t S16;
|
||||
typedef uint16_t U16;
|
||||
typedef int32_t S32;
|
||||
typedef uint32_t U32;
|
||||
|
||||
/** Fast type for signed 8 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef int S8CPU;
|
||||
/** Fast type for unsigned 8 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef int S16CPU;
|
||||
/** Fast type for signed 16 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef unsigned U8CPU;
|
||||
/** Fast type for unsigned 16 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef unsigned U16CPU;
|
||||
|
||||
/** Meant to be faster than bool (doesn't promise to be 0 or 1, just 0 or non-zero
|
||||
*/
|
||||
typedef int SkBool;
|
||||
/** Meant to be a small version of bool, for storage purposes. Will be 0 or 1
|
||||
*/
|
||||
typedef uint8_t SkBool8;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
int8_t SkToS8(long);
|
||||
uint8_t SkToU8(size_t);
|
||||
int16_t SkToS16(long);
|
||||
uint16_t SkToU16(size_t);
|
||||
int32_t SkToS32(long);
|
||||
uint32_t SkToU32(size_t);
|
||||
#else
|
||||
#define SkToS8(x) ((int8_t)(x))
|
||||
#define SkToU8(x) ((uint8_t)(x))
|
||||
#define SkToS16(x) ((int16_t)(x))
|
||||
#define SkToU16(x) ((uint16_t)(x))
|
||||
#define SkToS32(x) ((int32_t)(x))
|
||||
#define SkToU32(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
/** Returns 0 or 1 based on the condition
|
||||
*/
|
||||
#define SkToBool(cond) ((cond) != 0)
|
||||
|
||||
#define SK_MaxS16 32767
|
||||
#define SK_MinS16 -32767
|
||||
#define SK_MaxU16 0xFFFF
|
||||
#define SK_MinU16 0
|
||||
#define SK_MaxS32 0x7FFFFFFF
|
||||
#define SK_MinS32 0x80000001
|
||||
#define SK_MaxU32 0xFFFFFFFF
|
||||
#define SK_MinU32 0
|
||||
#define SK_NaN32 0x80000000
|
||||
|
||||
#ifndef SK_OFFSETOF
|
||||
#define SK_OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1)
|
||||
#endif
|
||||
|
||||
/** Returns the number of entries in an array (not a pointer)
|
||||
*/
|
||||
#define SK_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
/** Returns x rounded up to a multiple of 2
|
||||
*/
|
||||
#define SkAlign2(x) (((x) + 1) >> 1 << 1)
|
||||
/** Returns x rounded up to a multiple of 4
|
||||
*/
|
||||
#define SkAlign4(x) (((x) + 3) >> 2 << 2)
|
||||
|
||||
typedef uint32_t SkFourByteTag;
|
||||
#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
|
||||
/** 32 bit integer to hold a unicode value
|
||||
*/
|
||||
typedef int32_t SkUnichar;
|
||||
/** 32 bit value to hold a millisecond count
|
||||
*/
|
||||
typedef uint32_t SkMSec;
|
||||
/** 1 second measured in milliseconds
|
||||
*/
|
||||
#define SK_MSec1 1000
|
||||
/** maximum representable milliseconds
|
||||
*/
|
||||
#define SK_MSecMax 0x7FFFFFFF
|
||||
/** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
|
||||
*/
|
||||
#define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0)
|
||||
/** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
|
||||
*/
|
||||
#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
The rest of these only build with C++
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
|
||||
/** Faster than SkToBool for integral conditions. Returns 0 or 1
|
||||
*/
|
||||
inline int Sk32ToBool(uint32_t n)
|
||||
{
|
||||
return (n | (0-n)) >> 31;
|
||||
}
|
||||
|
||||
template <typename T> inline void SkTSwap(T& a, T& b)
|
||||
{
|
||||
T c(a);
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
|
||||
inline int32_t SkAbs32(int32_t value)
|
||||
{
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value < 0)
|
||||
value = -value;
|
||||
return value;
|
||||
#else
|
||||
int32_t mask = value >> 31;
|
||||
return (value ^ mask) - mask;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int32_t SkMax32(int32_t a, int32_t b)
|
||||
{
|
||||
if (a < b)
|
||||
a = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int32_t SkMin32(int32_t a, int32_t b)
|
||||
{
|
||||
if (a > b)
|
||||
a = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int32_t SkSign32(int32_t a)
|
||||
{
|
||||
return (a >> 31) | ((unsigned) -a >> 31);
|
||||
}
|
||||
|
||||
inline int32_t SkFastMin32(int32_t value, int32_t max)
|
||||
{
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value > max)
|
||||
value = max;
|
||||
return value;
|
||||
#else
|
||||
int diff = max - value;
|
||||
// clear diff if it is negative (clear if value > max)
|
||||
diff &= (diff >> 31);
|
||||
return value + diff;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Returns signed 32 bit value pinned between min and max, inclusively
|
||||
*/
|
||||
inline int32_t SkPin32(int32_t value, int32_t min, int32_t max)
|
||||
{
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value < min)
|
||||
value = min;
|
||||
if (value > max)
|
||||
value = max;
|
||||
#else
|
||||
if (value < min)
|
||||
value = min;
|
||||
else if (value > max)
|
||||
value = max;
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
inline uint32_t SkSetClear32(uint32_t flags, bool cond, unsigned shift)
|
||||
{
|
||||
return flags & ~(1 << shift) | ((int)cond << shift);
|
||||
}
|
||||
|
||||
class SkAutoMalloc {
|
||||
public:
|
||||
SkAutoMalloc(size_t size)
|
||||
{
|
||||
fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
|
||||
}
|
||||
~SkAutoMalloc()
|
||||
{
|
||||
sk_free(fPtr);
|
||||
}
|
||||
void* get() const { return fPtr; }
|
||||
private:
|
||||
void* fPtr;
|
||||
// illegal
|
||||
SkAutoMalloc(const SkAutoMalloc&);
|
||||
SkAutoMalloc& operator=(const SkAutoMalloc&);
|
||||
};
|
||||
|
||||
template <size_t kSize> class SkAutoSMalloc {
|
||||
public:
|
||||
SkAutoSMalloc(size_t size)
|
||||
{
|
||||
if (size <= kSize)
|
||||
fPtr = fStorage;
|
||||
else
|
||||
fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
|
||||
}
|
||||
~SkAutoSMalloc()
|
||||
{
|
||||
if (fPtr != (void*)fStorage)
|
||||
sk_free(fPtr);
|
||||
}
|
||||
void* get() const { return fPtr; }
|
||||
private:
|
||||
void* fPtr;
|
||||
uint32_t fStorage[(kSize + 3) >> 2];
|
||||
// illegal
|
||||
SkAutoSMalloc(const SkAutoSMalloc&);
|
||||
SkAutoSMalloc& operator=(const SkAutoSMalloc&);
|
||||
};
|
||||
|
||||
#endif /* C++ */
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef SkUserConfig_DEFINED
|
||||
#define SkUserConfig_DEFINED
|
||||
|
||||
/* This file is included before all other headers, except for SkPreConfig.h.
|
||||
That file uses various heuristics to make a "best guess" at settings for
|
||||
the following build defines.
|
||||
|
||||
However, in this file you can override any of those decisions by either
|
||||
defining new symbols, or #undef symbols that were already set.
|
||||
*/
|
||||
|
||||
// experimental for now
|
||||
#define SK_SUPPORT_MIPMAP
|
||||
|
||||
// android specific defines and tests
|
||||
|
||||
#ifdef SK_FORCE_SCALARFIXED
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
#undef SK_SCALAR_IS_FLOAT
|
||||
#undef SK_CAN_USE_FLOAT
|
||||
#endif
|
||||
|
||||
#ifdef SK_FORCE_SCALARFLOAT
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#define SK_CAN_USE_FLOAT
|
||||
#undef SK_SCALAR_IS_FIXED
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <utils/misc.h>
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define SK_CPU_BENDIAN
|
||||
#undef SK_CPU_LENDIAN
|
||||
#else
|
||||
#define SK_CPU_LENDIAN
|
||||
#undef SK_CPU_BENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#define SK_SUPPORT_UNITTEST
|
||||
/* Define SK_SIMULATE_FAILED_MALLOC to have
|
||||
* sk_malloc throw an exception. Use this to
|
||||
* detect unhandled memory leaks. */
|
||||
//#define SK_SIMULATE_FAILED_MALLOC
|
||||
//#define SK_FIND_MEMORY_LEAKS
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_BREW
|
||||
#include "SkBrewUserConfig.h"
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
#define SK_CAN_USE_FLOAT
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/** \mainpage notitle
|
||||
* \htmlinclude "SGL Spec. rev 9.htm"
|
||||
*/
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef Sk1DPathEffect_DEFINED
|
||||
#define Sk1DPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
#include "SkPath.h"
|
||||
|
||||
class SkPathMeasure;
|
||||
|
||||
// This class is not exported to java.
|
||||
class Sk1DPathEffect : public SkPathEffect {
|
||||
public:
|
||||
Sk1DPathEffect() {}
|
||||
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
protected:
|
||||
/** Called at the start of each contour, returns the initial offset
|
||||
into that contour.
|
||||
*/
|
||||
virtual SkScalar begin(SkScalar contourLength);
|
||||
/** Called with the current distance along the path, with the current matrix
|
||||
for the point/tangent at the specified distance.
|
||||
Return the distance to travel for the next call. If return <= 0, then that
|
||||
contour is done.
|
||||
*/
|
||||
virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&);
|
||||
|
||||
Sk1DPathEffect(SkRBuffer& buffer) : SkPathEffect(buffer) {}
|
||||
|
||||
private:
|
||||
// illegal
|
||||
Sk1DPathEffect(const Sk1DPathEffect&);
|
||||
Sk1DPathEffect& operator=(const Sk1DPathEffect&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
class SkPath1DPathEffect : public Sk1DPathEffect {
|
||||
public:
|
||||
enum Style {
|
||||
kTranslate_Style, // translate the shape to each position
|
||||
kRotate_Style, // rotate the shape about its center
|
||||
kMorph_Style, // transform each point, and turn lines into curves
|
||||
|
||||
kStyleCount
|
||||
};
|
||||
SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
protected:
|
||||
virtual SkScalar begin(SkScalar contourLength);
|
||||
virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&);
|
||||
|
||||
private:
|
||||
SkPath fPath;
|
||||
SkScalar fAdvance, fPhase;
|
||||
Style fStyle;
|
||||
|
||||
typedef Sk1DPathEffect INHERITED;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef Sk2DPathEffect_DEFINED
|
||||
#define Sk2DPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
#include "SkMatrix.h"
|
||||
|
||||
// This class is not exported to java.
|
||||
class Sk2DPathEffect : public SkPathEffect {
|
||||
public:
|
||||
Sk2DPathEffect(const SkMatrix& mat);
|
||||
|
||||
// overrides
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual void flatten(SkWBuffer&);
|
||||
virtual Factory getFactory();
|
||||
|
||||
protected:
|
||||
/** New virtual, to be overridden by subclasses.
|
||||
This is called once from filterPath, and provides the
|
||||
uv parameter bounds for the path. Subsequent calls to
|
||||
next() will receive u and v values within these bounds,
|
||||
and then a call to end() will signal the end of processing.
|
||||
*/
|
||||
virtual void begin(const SkRect16& uvBounds, SkPath* dst);
|
||||
virtual void next(const SkPoint& loc, int u, int v, SkPath* dst);
|
||||
virtual void end(SkPath* dst);
|
||||
|
||||
/** Low-level virtual called per span of locations in the u-direction.
|
||||
The default implementation calls next() repeatedly with each
|
||||
location.
|
||||
*/
|
||||
virtual void nextSpan(int u, int v, int ucount, SkPath* dst);
|
||||
|
||||
const SkMatrix& getMatrix() const { return fMatrix; }
|
||||
|
||||
// protected so that subclasses can call this during unflattening
|
||||
Sk2DPathEffect(SkRBuffer&);
|
||||
|
||||
private:
|
||||
SkMatrix fMatrix, fInverse;
|
||||
// illegal
|
||||
Sk2DPathEffect(const Sk2DPathEffect&);
|
||||
Sk2DPathEffect& operator=(const Sk2DPathEffect&);
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
|
||||
friend class Sk2DPathEffectBlitter;
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,492 @@
|
|||
#ifndef SkAnimator_DEFINED
|
||||
#define SkAnimator_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkKey.h"
|
||||
#include "SkEventSink.h"
|
||||
|
||||
class SkAnimateMaker;
|
||||
class SkCanvas;
|
||||
class SkDisplayable;
|
||||
class SkEvent;
|
||||
class SkExtras;
|
||||
struct SkMemberInfo;
|
||||
class SkPaint;
|
||||
struct SkRect;
|
||||
class SkStream;
|
||||
class SkTypedArray;
|
||||
class SkXMLParserError;
|
||||
class SkDOM;
|
||||
struct SkDOMNode;
|
||||
|
||||
/** SkElementType is the type of element: a rectangle, a color, an animator, and so on.
|
||||
This enum is incomplete and will be fleshed out in a future release */
|
||||
enum SkElementType {
|
||||
kElementDummyType
|
||||
};
|
||||
/** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on.
|
||||
This enum is incomplete and will be fleshed out in a future release */
|
||||
enum SkFieldType {
|
||||
kFieldDummyType
|
||||
};
|
||||
|
||||
/** \class SkAnimator
|
||||
|
||||
The SkAnimator class decodes an XML stream into a display list. The
|
||||
display list can be drawn statically as a picture, or can drawn
|
||||
different elements at different times to form a moving animation.
|
||||
|
||||
SkAnimator does not read the system time on its own; it relies on the
|
||||
caller to pass the current time. The caller can pause, speed up, or
|
||||
reverse the animation by varying the time passed in.
|
||||
|
||||
The XML describing the display list must conform to the schema
|
||||
described by SkAnimateSchema.xsd.
|
||||
|
||||
The XML must contain an <event> element to draw. Usually, it contains
|
||||
an <event kind="onload" /> block to add some drawing elements to the
|
||||
display list when the document is first decoded.
|
||||
|
||||
Here's an "Hello World" XML sample:
|
||||
|
||||
<screenplay>
|
||||
<event kind="onload" >
|
||||
<text text="Hello World" y="20" />
|
||||
</event>
|
||||
</screenplay>
|
||||
|
||||
To read and draw this sample:
|
||||
|
||||
// choose one of these two
|
||||
SkAnimator animator; // declare an animator instance on the stack
|
||||
// SkAnimator* animator = new SkAnimator() // or one could instantiate the class
|
||||
|
||||
// choose one of these three
|
||||
animator.decodeMemory(buffer, size); // to read from RAM
|
||||
animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file)
|
||||
animator.decodeURI(filename); // to read from a web location, or from a local text file
|
||||
|
||||
// to draw to the current window:
|
||||
SkCanvas canvas(getBitmap()); // create a canvas
|
||||
animator.draw(canvas, &paint, 0); // draw the scene
|
||||
*/
|
||||
class SkAnimator : public SkEventSink {
|
||||
public:
|
||||
SkAnimator();
|
||||
virtual ~SkAnimator();
|
||||
|
||||
/** Add a drawable extension to the graphics engine. Experimental.
|
||||
@param extras A derived class that implements methods that identify and instantiate the class
|
||||
*/
|
||||
void addExtras(SkExtras* extras);
|
||||
|
||||
/** Read in XML from a stream, and append it to the current
|
||||
animator. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param stream The stream to append.
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
bool appendStream(SkStream* stream);
|
||||
|
||||
/** Read in XML from memory. Returns true if the file can be
|
||||
read without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param buffer The XML text as UTF-8 characters.
|
||||
@param size The XML text length in bytes.
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
bool decodeMemory(const void* buffer, size_t size);
|
||||
|
||||
/** Read in XML from a stream. Returns true if the file can be
|
||||
read without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param stream The stream containg the XML text as UTF-8 characters.
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
virtual bool decodeStream(SkStream* stream);
|
||||
|
||||
/** Parse the DOM tree starting at the specified node. Returns true if it can be
|
||||
parsed without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@return true if the DOM was parsed successfully.
|
||||
*/
|
||||
virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);
|
||||
|
||||
/** Read in XML from a URI. Returns true if the file can be
|
||||
read without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param uri The complete url path to be read (either ftp, http or https).
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
bool decodeURI(const char uri[]);
|
||||
|
||||
/** Pass a char event, usually a keyboard symbol, to the animator.
|
||||
This triggers events of the form <event kind="keyChar" key="... />
|
||||
@param ch The character to match against <event> element "key"
|
||||
attributes.
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doCharEvent(SkUnichar ch);
|
||||
|
||||
/** Experimental:
|
||||
Pass a mouse click event along with the mouse coordinates to
|
||||
the animator. This triggers events of the form <event kind="mouseDown" ... />
|
||||
and other mouse events.
|
||||
@param state The mouse state, described by SkView::Click::State : values are
|
||||
down == 0, moved == 1, up == 2
|
||||
@param x The x-position of the mouse
|
||||
@param y The y-position of the mouse
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doClickEvent(int state, SkScalar x, SkScalar y);
|
||||
|
||||
/** Pass a meta-key event, such as an arrow , to the animator.
|
||||
This triggers events of the form <event kind="keyPress" code="... />
|
||||
@param code The key to match against <event> element "code"
|
||||
attributes.
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doKeyEvent(SkKey code);
|
||||
bool doKeyUpEvent(SkKey code);
|
||||
|
||||
/** Send an event to the animator. The animator's clock is set
|
||||
relative to the current time.
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doUserEvent(const SkEvent& evt);
|
||||
|
||||
/** The possible results from the draw function.
|
||||
*/
|
||||
enum DifferenceType {
|
||||
kNotDifferent,
|
||||
kDifferent,
|
||||
kPartiallyDifferent
|
||||
};
|
||||
/** Draws one frame of the animation. The first call to draw always
|
||||
draws the initial frame of the animation. Subsequent calls draw
|
||||
the offset into the animation by
|
||||
subtracting the initial time from the current time.
|
||||
@param canvas The canvas to draw into.
|
||||
@param paint The paint to draw with.
|
||||
@param time The offset into the current animation.
|
||||
@return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
|
||||
kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
|
||||
redraw area.
|
||||
*/
|
||||
DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);
|
||||
|
||||
/** Draws one frame of the animation, using a new Paint each time.
|
||||
The first call to draw always
|
||||
draws the initial frame of the animation. Subsequent calls draw
|
||||
the offset into the animation by
|
||||
subtracting the initial time from the current time.
|
||||
@param canvas The canvas to draw into.
|
||||
@param time The offset into the current animation.
|
||||
@return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
|
||||
kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
|
||||
redraw area.
|
||||
*/
|
||||
DifferenceType draw(SkCanvas* canvas, SkMSec time);
|
||||
|
||||
/** Experimental:
|
||||
Helper to choose whether to return a SkView::Click handler.
|
||||
@param x ignored
|
||||
@param y ignored
|
||||
@return true if a mouseDown event handler is enabled.
|
||||
*/
|
||||
bool findClickEvent(SkScalar x, SkScalar y);
|
||||
|
||||
|
||||
/** Get the nested animator associated with this element, if any.
|
||||
Use this to access a movie's event sink, to send events to movies.
|
||||
@param element the value returned by getElement
|
||||
@return the internal animator.
|
||||
*/
|
||||
const SkAnimator* getAnimator(const SkDisplayable* element) const;
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param element the value returned by getElement
|
||||
@param field the value returned by getField
|
||||
@param index the array entry
|
||||
@return the integer value to retrieve, or SK_NaN32 if unsuccessful
|
||||
*/
|
||||
int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the integer value to retrieve, or SK_NaN32 if unsuccessful
|
||||
*/
|
||||
int32_t getArrayInt(const char* elementID, const char* fieldName, int index);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param element the value returned by getElement
|
||||
@param field the value returned by getField
|
||||
@param index the array entry
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
|
||||
*/
|
||||
SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
|
||||
*/
|
||||
SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);
|
||||
|
||||
/** Returns the string value of the specified element's attribute[index]
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@param index the array entry
|
||||
@return the string value to retrieve, or null if unsuccessful
|
||||
*/
|
||||
const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);
|
||||
|
||||
/** Returns the string value of the specified element's attribute[index]
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the string value to retrieve, or null if unsuccessful
|
||||
*/
|
||||
const char* getArrayString(const char* elementID, const char* fieldName, int index);
|
||||
|
||||
/** Returns the XML element corresponding to the given ID.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@return the element matching the ID, or nil if the element can't be found
|
||||
*/
|
||||
const SkDisplayable* getElement(const char* elementID);
|
||||
|
||||
/** Returns the element type corresponding to the XML element.
|
||||
The element type matches the element name; for instance, <line> returns kElement_LineType
|
||||
@param element is a value returned by getElement
|
||||
@return element type, or 0 if the element can't be found
|
||||
*/
|
||||
SkElementType getElementType(const SkDisplayable* element);
|
||||
|
||||
/** Returns the element type corresponding to the given ID.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@return element type, or 0 if the element can't be found
|
||||
*/
|
||||
SkElementType getElementType(const char* elementID);
|
||||
|
||||
/** Returns the XML field of the named attribute in the XML element.
|
||||
@param element is a value returned by getElement
|
||||
@param fieldName is the attribute to return
|
||||
@return the attribute matching the fieldName, or nil if the element can't be found
|
||||
*/
|
||||
const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);
|
||||
|
||||
/** Returns the XML field of the named attribute in the XML element matching the elementID.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName is the attribute to return
|
||||
@return the attribute matching the fieldName, or nil if the element can't be found
|
||||
*/
|
||||
const SkMemberInfo* getField(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the value type coresponding to the element's attribute.
|
||||
The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
|
||||
@param field is a value returned by getField
|
||||
@return the attribute type, or 0 if the element can't be found
|
||||
*/
|
||||
SkFieldType getFieldType(const SkMemberInfo* field);
|
||||
|
||||
/** Returns the value type coresponding to the element's attribute.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the attribute type, or 0 if the element can't be found
|
||||
*/
|
||||
SkFieldType getFieldType(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the recommended animation interval. Returns zero if no
|
||||
interval is specified.
|
||||
*/
|
||||
SkMSec getInterval();
|
||||
|
||||
/** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
|
||||
kIsPartiallyDifferent to do a mimimal inval(). */
|
||||
void getInvalBounds(SkRect* inval);
|
||||
|
||||
/** Returns the details of any error encountered while parsing the XML.
|
||||
*/
|
||||
const SkXMLParserError* getParserError();
|
||||
|
||||
/** Returns the details of any error encountered while parsing the XML as string.
|
||||
*/
|
||||
const char* getParserErrorString();
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@return the integer value to retrieve, or SK_NaN32 if not found
|
||||
*/
|
||||
int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the integer value to retrieve, or SK_NaN32 if not found
|
||||
*/
|
||||
int32_t getInt(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if not found
|
||||
*/
|
||||
SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if not found
|
||||
*/
|
||||
SkScalar getScalar(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the string value of the specified element's attribute
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@return the string value to retrieve, or null if not found
|
||||
*/
|
||||
const char* getString(const SkDisplayable* element, const SkMemberInfo* field);
|
||||
|
||||
/** Returns the string value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the string value to retrieve, or null if not found
|
||||
*/
|
||||
const char* getString(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
|
||||
const char* getURIBase();
|
||||
|
||||
/** Resets the animator to a newly created state with no animation data. */
|
||||
void initialize();
|
||||
|
||||
/** Experimental. Resets any active animations so that the next time passed is treated as
|
||||
time zero. */
|
||||
void reset();
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param array is the c-style array of integers
|
||||
@param count is the length of the array
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param array is the c-style array of strings
|
||||
@param count is the length of the array
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param data the integer value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setInt(const char* elementID, const char* fieldName, int32_t data);
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param data the scalar value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setScalar(const char* elementID, const char* fieldName, SkScalar data);
|
||||
|
||||
/** Sets the string value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param data the string value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setString(const char* elementID, const char* fieldName, const char* data);
|
||||
|
||||
/** Sets the file default directory of the URL base path
|
||||
@param path the directory path
|
||||
*/
|
||||
void setURIBase(const char* path);
|
||||
|
||||
typedef void* Handler;
|
||||
// This guy needs to be exported to java, so don't make it virtual
|
||||
void setHostHandler(Handler handler) {
|
||||
this->onSetHostHandler(handler);
|
||||
}
|
||||
|
||||
/** \class Timeline
|
||||
Returns current time to animator. To return a custom timeline, create a child
|
||||
class and override the getMSecs method.
|
||||
*/
|
||||
class Timeline {
|
||||
public:
|
||||
virtual ~Timeline() {}
|
||||
|
||||
/** Returns the current time in milliseconds */
|
||||
virtual SkMSec getMSecs() const = 0;
|
||||
};
|
||||
|
||||
/** Sets a user class to return the current time to the animator.
|
||||
Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead.
|
||||
@param callBack the time function
|
||||
*/
|
||||
void setTimeline(const Timeline& );
|
||||
|
||||
static void Init(bool runUnitTests);
|
||||
static void Term();
|
||||
|
||||
/** The event sink events generated by the animation are posted to.
|
||||
Screenplay also posts an inval event to this event sink after processing an
|
||||
event to force a redraw.
|
||||
@param target the event sink id
|
||||
*/
|
||||
void setHostEventSinkID(SkEventSinkID hostID);
|
||||
SkEventSinkID getHostEventSinkID() const;
|
||||
|
||||
// helper
|
||||
void setHostEventSink(SkEventSink* sink) {
|
||||
this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
|
||||
}
|
||||
|
||||
virtual void setJavaOwner(Handler owner);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
virtual void eventDone(const SkEvent& evt);
|
||||
virtual bool isTrackingEvents();
|
||||
static bool NoLeaks();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void onSetHostHandler(Handler handler);
|
||||
virtual void onEventPost(SkEvent*, SkEventSinkID);
|
||||
virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);
|
||||
|
||||
private:
|
||||
// helper functions for setters
|
||||
bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
|
||||
bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
|
||||
bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
|
||||
bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
|
||||
bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);
|
||||
|
||||
virtual bool onEvent(const SkEvent&);
|
||||
SkAnimateMaker* fMaker;
|
||||
friend class SkAnimateMaker;
|
||||
friend class SkAnimatorScript;
|
||||
friend class SkAnimatorScript2;
|
||||
friend class SkApply;
|
||||
friend class SkDisplayMovie;
|
||||
friend class SkDisplayType;
|
||||
friend class SkPost;
|
||||
friend class SkXMLAnimatorWriter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef SkAnimatorView_DEFINED
|
||||
#define SkAnimatorView_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
#include "SkAnimator.h"
|
||||
|
||||
class SkAnimatorView : public SkView {
|
||||
public:
|
||||
SkAnimatorView();
|
||||
virtual ~SkAnimatorView();
|
||||
|
||||
SkAnimator* getAnimator() const { return fAnimator; }
|
||||
|
||||
bool decodeFile(const char path[]);
|
||||
bool decodeMemory(const void* buffer, size_t size);
|
||||
bool decodeStream(SkStream* stream);
|
||||
|
||||
protected:
|
||||
// overrides
|
||||
virtual bool onEvent(const SkEvent&);
|
||||
virtual void onDraw(SkCanvas*);
|
||||
virtual void onInflate(const SkDOM&, const SkDOM::Node*);
|
||||
|
||||
private:
|
||||
SkAnimator* fAnimator;
|
||||
|
||||
typedef SkView INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef SkApplication_DEFINED
|
||||
#define SkApplication_DEFINED
|
||||
|
||||
class SkOSWindow;
|
||||
|
||||
extern SkOSWindow* create_sk_window(void* hwnd);
|
||||
extern void application_init();
|
||||
extern void application_term();
|
||||
|
||||
#endif // SkApplication_DEFINED
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef SkAvoidXfermode_DEFINED
|
||||
#define SkAvoidXfermode_DEFINED
|
||||
|
||||
#include "SkXfermode.h"
|
||||
|
||||
/** \class SkAvoidXfermode
|
||||
|
||||
This xfermode will draw the src everywhere except on top of the specified
|
||||
color.
|
||||
*/
|
||||
class SkAvoidXfermode : public SkXfermode {
|
||||
public:
|
||||
/** This xfermode will draw the src everywhere except on top of the specified
|
||||
color.
|
||||
@param opColor the color to avoid (or to target if reverse is true);
|
||||
@param tolerance How closely we compare a pixel to the opColor.
|
||||
0 - we only avoid on an exact match
|
||||
255 - maximum gradation (blending) based on how similar
|
||||
the pixel is to our opColor.
|
||||
@param reverse true means we target the opColor rather than avoid it.
|
||||
*/
|
||||
SkAvoidXfermode(SkColor opColor, U8CPU tolerance, bool reverse);
|
||||
|
||||
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, const SkAlpha aa[]);
|
||||
virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, const SkAlpha aa[]);
|
||||
virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, const SkAlpha aa[]);
|
||||
|
||||
private:
|
||||
SkColor fOpColor;
|
||||
uint32_t fDistMul; // x.14
|
||||
bool fReverse;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef SkBGViewArtist_DEFINED
|
||||
#define SkBGViewArtist_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
#include "SkPaint.h"
|
||||
|
||||
class SkBGViewArtist : public SkView::Artist {
|
||||
public:
|
||||
SkBGViewArtist(SkColor c = SK_ColorWHITE);
|
||||
virtual ~SkBGViewArtist();
|
||||
|
||||
const SkPaint& paint() const { return fPaint; }
|
||||
SkPaint& paint() { return fPaint; }
|
||||
|
||||
protected:
|
||||
// overrides
|
||||
virtual void onDraw(SkView*, SkCanvas*);
|
||||
virtual void onInflate(const SkDOM&, const SkDOM::Node*);
|
||||
|
||||
private:
|
||||
SkPaint fPaint;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef SkBML_WXMLParser_DEFINED
|
||||
#define SkBML_WXMLParser_DEFINED
|
||||
|
||||
#include "SkString.h"
|
||||
#include "SkXMLParser.h"
|
||||
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
class BML_WXMLParser : public SkXMLParser {
|
||||
public:
|
||||
BML_WXMLParser(SkWStream& writer);
|
||||
virtual ~BML_WXMLParser();
|
||||
static void Write(SkStream& s, const char filename[]);
|
||||
|
||||
/** @cond UNIT_TEST */
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
/** @endcond */
|
||||
private:
|
||||
virtual bool onAddAttribute(const char name[], const char value[]);
|
||||
virtual bool onEndElement(const char name[]);
|
||||
virtual bool onStartElement(const char name[]);
|
||||
BML_WXMLParser& operator=(const BML_WXMLParser& src);
|
||||
#ifdef SK_DEBUG
|
||||
int fElemsCount, fElemsReused;
|
||||
int fAttrsCount, fNamesReused, fValuesReused;
|
||||
#endif
|
||||
SkWStream& fWriter;
|
||||
char* fElems[256];
|
||||
char* fAttrNames[256];
|
||||
char* fAttrValues[256];
|
||||
|
||||
// important that these are U8, so we get automatic wrap-around
|
||||
U8 fNextElem, fNextAttrName, fNextAttrValue;
|
||||
};
|
||||
|
||||
#endif // SkBML_WXMLParser_DEFINED
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef SkBML_XMLParser_DEFINED
|
||||
#define SkBML_XMLParser_DEFINED
|
||||
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
class SkXMLParser;
|
||||
class SkXMLWriter;
|
||||
|
||||
class BML_XMLParser {
|
||||
public:
|
||||
/** Read the byte XML stream and write the decompressed XML.
|
||||
*/
|
||||
static void Read(SkStream& s, SkXMLWriter& writer);
|
||||
/** Read the byte XML stream and write the decompressed XML into a writable stream.
|
||||
*/
|
||||
static void Read(SkStream& s, SkWStream& output);
|
||||
/** Read the byte XML stream and write the decompressed XML into an XML parser.
|
||||
*/
|
||||
static void Read(SkStream& s, SkXMLParser& output);
|
||||
};
|
||||
|
||||
#endif // SkBML_XMLParser_DEFINED
|
||||
|
|
@ -0,0 +1,374 @@
|
|||
#ifndef SkBitmap_DEFINED
|
||||
#define SkBitmap_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
// Android - we need to run as an embedded product, not X11
|
||||
//#ifdef SK_BUILD_FOR_UNIX
|
||||
//#include <X11/Xlib.h>
|
||||
//#endif
|
||||
|
||||
|
||||
class SkColorTable;
|
||||
|
||||
/** \class SkBitmap
|
||||
|
||||
The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
|
||||
and height, and a format (config), and a pointer to the actual pixels.
|
||||
Bitmaps can be drawn into a SkCanvas, but they are also used to specify the target
|
||||
of a SkCanvas' drawing operations.
|
||||
*/
|
||||
class SkBitmap {
|
||||
public:
|
||||
enum Config {
|
||||
kNo_Config, //!< bitmap has not been configured
|
||||
kA1_Config, //!< 1-bit per pixel, (0 is transparent, 1 is opaque)
|
||||
kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
|
||||
kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
|
||||
kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
|
||||
|
||||
kConfigCount
|
||||
};
|
||||
|
||||
/** Default construct creates a bitmap with zero width and height, and no pixels.
|
||||
Its config is set to kNo_Config.
|
||||
*/
|
||||
SkBitmap();
|
||||
/** Constructor initializes the new bitmap by copying the src bitmap. All fields are copied,
|
||||
but ownership of the pixels remains with the src bitmap.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
SkBitmap(const SkBitmap& src);
|
||||
/** Destructor that, if getOwnsPixels() returns true, will delete the pixel's memory.
|
||||
*/
|
||||
~SkBitmap();
|
||||
|
||||
/** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
|
||||
with the src bitmap.
|
||||
*/
|
||||
SkBitmap& operator=(const SkBitmap& src);
|
||||
/** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
void swap(SkBitmap& other);
|
||||
|
||||
/** Return the config for the bitmap.
|
||||
*/
|
||||
Config getConfig() const { return (Config)fConfig; }
|
||||
/** Return the bitmap's width, in pixels.
|
||||
*/
|
||||
unsigned width() const { return fWidth; }
|
||||
/** Return the bitmap's height, in pixels.
|
||||
*/
|
||||
unsigned height() const { return fHeight; }
|
||||
/** Return the number of bytes between subsequent rows of the bitmap.
|
||||
*/
|
||||
unsigned rowBytes() const { return fRowBytes; }
|
||||
/** Return the address of the pixels for this SkBitmap. This can be set either with
|
||||
setPixels(), where the caller owns the buffer, or with allocPixels() or resizeAlloc(),
|
||||
which marks the pixel memory to be owned by the SkBitmap (e.g. will be freed automatically
|
||||
when the bitmap is destroyed).
|
||||
*/
|
||||
void* getPixels() const { return fPixels; }
|
||||
/** Return the byte size of the pixels, based on the height and rowBytes
|
||||
*/
|
||||
size_t getSize() const { return fHeight * fRowBytes; }
|
||||
|
||||
/** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
|
||||
*/
|
||||
bool isOpaque() const;
|
||||
/** Specify if this bitmap's pixels are all opaque or not. Is only meaningful for configs
|
||||
that support per-pixel alpha (RGB32, A1, A8).
|
||||
*/
|
||||
void setIsOpaque(bool);
|
||||
|
||||
/** Reset the bitmap to its initial state (see default constructor). If getOwnsPixels() returned
|
||||
true, then the memory for the pixels is freed.
|
||||
*/
|
||||
void reset();
|
||||
/** Set the bitmap's config and dimensions. If rowBytes is 0, then an appropriate value
|
||||
is computed based on the bitmap's config and width. If getOwnsPixels() returned true,
|
||||
then the pixel's memory is freed.
|
||||
*/
|
||||
void setConfig(Config, U16CPU width, U16CPU height, U16CPU rowBytes = 0);
|
||||
/** Use this to assign a new pixel address for an existing bitmap. If getOwnsPixels() returned
|
||||
true, then the previous pixel's memory is freed. The new address is "owned" by the called,
|
||||
and getOwnsPixels() will now return false. This method is not exported to java.
|
||||
*/
|
||||
void setPixels(void* p);
|
||||
/** If this is called, then the bitmap will dynamically allocate memory for its pixels
|
||||
based on rowBytes and height. The SkBitmap will remember that it allocated
|
||||
this, and will automatically free it as needed, thus getOwnsPixels() will now return true.
|
||||
*/
|
||||
void allocPixels();
|
||||
/** Realloc the memory for the pixels based on the specified width and height. This
|
||||
keeps the old value for config, and computes a rowBytes based on the config and the width.
|
||||
This is similar, but more efficient than calling setConfig() followed by allocPixels().
|
||||
*/
|
||||
// not implemented
|
||||
// void resizeAlloc(U16CPU width, U16CPU height);
|
||||
|
||||
/** Returns true if the current pixels have been allocated via allocPixels()
|
||||
or resizeAlloc(). This method is not exported to java.
|
||||
*/
|
||||
bool getOwnsPixels() const;
|
||||
/** Call this to explicitly change the ownership rule for the pixels. This may be called
|
||||
after one bitmap is copied into another, to specify which bitmap should handle freeing
|
||||
the memory. This method is not exported to java.
|
||||
*/
|
||||
void setOwnsPixels(bool ownsPixels);
|
||||
|
||||
/** Get the bitmap's colortable object.
|
||||
|
||||
Return the bitmap's colortable (if any). Does not affect the colortable's
|
||||
reference count.
|
||||
*/
|
||||
SkColorTable* getColorTable() const { return fColorTable; }
|
||||
/** Assign ctable to be the colortable for the bitmap, replacing any existing reference.
|
||||
The reference count of ctable (if it is not nil) is incremented, and any existing
|
||||
reference has its reference count decremented. NOTE: colortable's may be assigned
|
||||
to any bitmap, but are only interpreted for kIndex8_Config bitmaps, where they
|
||||
are required.
|
||||
@return the ctable argument
|
||||
*/
|
||||
SkColorTable* setColorTable(SkColorTable* ctable);
|
||||
|
||||
/** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is ignored.
|
||||
If the config is kA8_Config, then the r,g,b parameters are ignored.
|
||||
*/
|
||||
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
/** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is presumed
|
||||
to be 0xFF. If the config is kA8_Config, then the r,g,b parameters are ignored and the
|
||||
pixels are all set to 0xFF.
|
||||
*/
|
||||
void eraseRGB(U8CPU r, U8CPU g, U8CPU b)
|
||||
{
|
||||
this->eraseARGB(0xFF, r, g, b);
|
||||
}
|
||||
/** Initialize the bitmap's pixels with the specified color, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the color's alpha value is presumed
|
||||
to be 0xFF. If the config is kA8_Config, then only the color's alpha value is used.
|
||||
*/
|
||||
void eraseColor(SkColor c)
|
||||
{
|
||||
this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
|
||||
}
|
||||
|
||||
/** Returns the address of the pixel specified by x,y.
|
||||
Asserts that x,y are in range, and that the bitmap's config is either kARGB_8888_Config.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
inline uint32_t* getAddr32(int x, int y) const;
|
||||
/** Returns the address of the pixel specified by x,y.
|
||||
Asserts that x,y are in range, and that the bitmap's config is kRGB_565_Config.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
inline uint16_t* getAddr16(int x, int y) const;
|
||||
/** Returns the address of the pixel specified by x,y.
|
||||
Asserts that x,y are in range, and that the bitmap's config is either kA8_Config or kIndex8_Config.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
inline uint8_t* getAddr8(int x, int y) const;
|
||||
/** Returns the color corresponding to the pixel specified by x,y.
|
||||
Asserts that x,y are in range, and that the bitmap's config is kIndex8_Config.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
inline SkPMColor getIndex8Color(int x, int y) const;
|
||||
/** Returns the address of the byte containing the pixel specified by x,y.
|
||||
Asserts that x,y are in range, and that the bitmap's config is kA1_Config.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
inline uint8_t* getAddr1(int x, int y) const;
|
||||
|
||||
// OS-specific helpers
|
||||
#ifndef SK_USE_WXWIDGETS
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
/** On Windows and PocketPC builds, this will draw the SkBitmap onto the
|
||||
specified HDC
|
||||
*/
|
||||
void drawToHDC(HDC, int left, int top) const;
|
||||
#elif defined(SK_BUILD_FOR_MAC)
|
||||
/** On Mac OS X and Carbon builds, this will draw the SkBitmap onto the
|
||||
specified WindowRef
|
||||
*/
|
||||
void drawToPort(WindowRef) const;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void buildMipMap(bool forceRebuild);
|
||||
unsigned countMipLevels() const;
|
||||
|
||||
private:
|
||||
SkColorTable* fColorTable; // only meaningful for kIndex8
|
||||
|
||||
#ifdef SK_SUPPORT_MIPMAP
|
||||
struct MipLevel {
|
||||
void* fPixels;
|
||||
uint16_t fWidth, fHeight, fRowBytes;
|
||||
uint8_t fConfig, fShift;
|
||||
};
|
||||
enum {
|
||||
kMaxMipLevels = 5
|
||||
};
|
||||
struct MipMap {
|
||||
MipLevel fLevel[kMaxMipLevels];
|
||||
};
|
||||
MipMap* fMipMap;
|
||||
#endif
|
||||
|
||||
enum Flags {
|
||||
kWeOwnThePixels_Flag = 0x01,
|
||||
kWeOwnTheMipMap_Flag = 0x02,
|
||||
kImageIsOpaque_Flag = 0x04
|
||||
};
|
||||
|
||||
void* fPixels;
|
||||
uint16_t fWidth, fHeight, fRowBytes;
|
||||
uint8_t fConfig;
|
||||
uint8_t fFlags;
|
||||
|
||||
const MipLevel* getMipLevel(unsigned level) const;
|
||||
|
||||
void freePixels();
|
||||
|
||||
friend class SkBitmapShader;
|
||||
};
|
||||
|
||||
/** \class SkColorTable
|
||||
|
||||
SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
|
||||
8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
|
||||
*/
|
||||
class SkColorTable : public SkRefCnt {
|
||||
public:
|
||||
/** Constructs an empty color table (zero colors).
|
||||
*/
|
||||
SkColorTable();
|
||||
virtual ~SkColorTable();
|
||||
|
||||
enum Flags {
|
||||
kColorsAreOpaque_Flag = 0x01 //!< if set, all of the colors in the table are opaque (alpha==0xFF)
|
||||
};
|
||||
/** Returns the flag bits for the color table. These can be changed with setFlags().
|
||||
*/
|
||||
unsigned getFlags() const { return fFlags; }
|
||||
/** Set the flags for the color table. See the Flags enum for possible values.
|
||||
*/
|
||||
void setFlags(unsigned flags);
|
||||
|
||||
/** Returns the number of colors in the table.
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
|
||||
/** Returns the specified color from the table. In the debug build, this asserts that
|
||||
the index is in range (0 <= index < count).
|
||||
*/
|
||||
SkPMColor operator[](int index) const
|
||||
{
|
||||
SkASSERT(fColors != nil && (unsigned)index < fCount);
|
||||
return fColors[index];
|
||||
}
|
||||
|
||||
/** Specify the number of colors in the color table. This does not initialize the colors
|
||||
to any value, just allocates memory for them. To initialize the values, either call
|
||||
setColors(array, count), or follow setCount(count) with a call to
|
||||
lockColors()/{set the values}/unlockColors(true).
|
||||
*/
|
||||
void setColors(int count) { this->setColors(nil, count); }
|
||||
void setColors(const SkPMColor[], int count);
|
||||
|
||||
/** Return the array of colors for reading and/or writing. This must be
|
||||
balanced by a call to unlockColors(changed?), telling the colortable if
|
||||
the colors were changed during the lock.
|
||||
*/
|
||||
SkPMColor* lockColors()
|
||||
{
|
||||
SkDEBUGCODE(fColorLockCount += 1;)
|
||||
return fColors;
|
||||
}
|
||||
/** Balancing call to lockColors(). If the colors have been changed, pass true.
|
||||
*/
|
||||
void unlockColors(bool changed)
|
||||
{
|
||||
SkASSERT(fColorLockCount != 0);
|
||||
SkDEBUGCODE(fColorLockCount -= 1;)
|
||||
}
|
||||
|
||||
/** Similar to lockColors(), lock16BitCache() returns the array of
|
||||
RGB16 colors that mirror the 32bit colors. However, this function
|
||||
will return nil if kColorsAreOpaque_Flag is not set.
|
||||
Also, unlike lockColors(), the returned array here cannot be modified.
|
||||
*/
|
||||
const uint16_t* lock16BitCache();
|
||||
/** Balancing call to lock16BitCache().
|
||||
*/
|
||||
void unlock16BitCache()
|
||||
{
|
||||
SkASSERT(f16BitCacheLockCount > 0);
|
||||
SkDEBUGCODE(f16BitCacheLockCount -= 1);
|
||||
}
|
||||
|
||||
private:
|
||||
SkPMColor* fColors;
|
||||
uint16_t* f16BitCache;
|
||||
uint16_t fCount;
|
||||
uint8_t fFlags;
|
||||
SkDEBUGCODE(int fColorLockCount;)
|
||||
SkDEBUGCODE(int f16BitCacheLockCount;)
|
||||
|
||||
void inval16BitCache();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uint32_t* SkBitmap::getAddr32(int x, int y) const
|
||||
{
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kARGB_8888_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
|
||||
return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
|
||||
}
|
||||
|
||||
inline uint16_t* SkBitmap::getAddr16(int x, int y) const
|
||||
{
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kRGB_565_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
|
||||
return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
|
||||
}
|
||||
|
||||
inline uint8_t* SkBitmap::getAddr8(int x, int y) const
|
||||
{
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint8_t*)fPixels + y * fRowBytes + x;
|
||||
}
|
||||
|
||||
inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const
|
||||
{
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
SkASSERT(fColorTable);
|
||||
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
|
||||
}
|
||||
|
||||
// returns the address of the byte that contains the x coordinate
|
||||
inline uint8_t* SkBitmap::getAddr1(int x, int y) const
|
||||
{
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kA1_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint8_t*)fPixels + y * fRowBytes + (x >> 3);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef SkBitmapRef_DEFINED
|
||||
#define SkBitmapRef_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
|
||||
class SkStream;
|
||||
|
||||
/** Helper class to manage a cache of decoded images from the file system
|
||||
*/
|
||||
class SkBitmapRef : public SkRefCnt {
|
||||
public:
|
||||
/** Create a non-cached bitmap, trasfering ownership of pixels if needed
|
||||
*/
|
||||
SkBitmapRef(const SkBitmap& src, bool transferOwnsPixels);
|
||||
virtual ~SkBitmapRef();
|
||||
|
||||
const SkBitmap& bitmap();
|
||||
|
||||
static SkBitmapRef* create(const SkBitmap& src, bool transferOwnsPixels);
|
||||
static SkBitmapRef* DecodeFile(const char file[], bool forceDecode);
|
||||
static SkBitmapRef* DecodeMemory(const void* bytes, size_t len);
|
||||
static SkBitmapRef* DecodeStream(SkStream* stream);
|
||||
|
||||
/** Frees all cached images, asserting that all references have been removed
|
||||
*/
|
||||
static void PurgeCacheAll();
|
||||
|
||||
/** frees one cached image, returning true, or returns false if none could be freed
|
||||
*/
|
||||
static bool PurgeCacheOne();
|
||||
|
||||
private:
|
||||
struct Rec;
|
||||
Rec* fRec;
|
||||
|
||||
SkBitmapRef(Rec*);
|
||||
|
||||
friend class SkBitmapRef_Globals;
|
||||
};
|
||||
|
||||
class SkAutoBitmapRef {
|
||||
public:
|
||||
SkAutoBitmapRef(const char file[], bool forceDecode)
|
||||
{
|
||||
fRef = SkBitmapRef::DecodeFile(file, forceDecode);
|
||||
}
|
||||
~SkAutoBitmapRef() { delete fRef; }
|
||||
|
||||
const SkBitmap* bitmap() const
|
||||
{
|
||||
return fRef ? &fRef->bitmap() : nil;
|
||||
}
|
||||
private:
|
||||
SkBitmapRef* fRef;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef SkBlurMaskFilter_DEFINED
|
||||
#define SkBlurMaskFilter_DEFINED
|
||||
|
||||
#include "SkMaskFilter.h"
|
||||
|
||||
class SkBlurMaskFilter : public SkMaskFilter {
|
||||
public:
|
||||
enum BlurStyle {
|
||||
kNormal_BlurStyle, //!< fuzzy inside and outside
|
||||
kSolid_BlurStyle, //!< solid inside, fuzzy outside
|
||||
kOuter_BlurStyle, //!< nothing inside, fuzzy outside
|
||||
kInner_BlurStyle, //!< fuzzy inside, nothing outside
|
||||
|
||||
kBlurStyleCount
|
||||
};
|
||||
|
||||
/** Create a blur maskfilter.
|
||||
@param radius The radius to extend the blur from the original mask. Must be > 0.
|
||||
@param style The BlurStyle to use
|
||||
@return The new blur maskfilter
|
||||
*/
|
||||
static SkMaskFilter* Create(SkScalar radius, BlurStyle style);
|
||||
|
||||
/** Create an emboss maskfilter
|
||||
@param direction array of 3 scalars [x, y, z] specifying the direction of the light source
|
||||
@param ambient 0...1 amount of ambient light
|
||||
@param specular coefficient for specular highlights (e.g. 8)
|
||||
@param blurRadius amount to blur before applying lighting (e.g. 3)
|
||||
@return the emboss maskfilter
|
||||
*/
|
||||
static SkMaskFilter* CreateEmboss( const SkScalar direction[3],
|
||||
SkScalar ambient, SkScalar specular,
|
||||
SkScalar blurRadius);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef SkBorderView_DEFINED
|
||||
#define SkBorderView_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
#include "SkWidgetViews.h"
|
||||
#include "SkAnimator.h"
|
||||
|
||||
class SkBorderView : public SkWidgetView {
|
||||
public:
|
||||
SkBorderView();
|
||||
~SkBorderView();
|
||||
void setSkin(const char skin[]);
|
||||
SkScalar getLeft() const { return fLeft; }
|
||||
SkScalar getRight() const { return fRight; }
|
||||
SkScalar getTop() const { return fTop; }
|
||||
SkScalar getBottom() const { return fBottom; }
|
||||
protected:
|
||||
//overrides
|
||||
virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
|
||||
virtual void onSizeChange();
|
||||
virtual void onDraw(SkCanvas* canvas);
|
||||
virtual bool onEvent(const SkEvent& evt);
|
||||
private:
|
||||
SkAnimator fAnim;
|
||||
SkScalar fLeft, fRight, fTop, fBottom; //margin on each side
|
||||
SkRect fMargin;
|
||||
|
||||
typedef SkWidgetView INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef SkBounder_DEFINED
|
||||
#define SkBounder_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
struct SkRect16;
|
||||
struct SkPoint;
|
||||
struct SkRect;
|
||||
class SkPaint;
|
||||
class SkPath;
|
||||
class SkRegion;
|
||||
|
||||
/** \class SkBounder
|
||||
|
||||
Base class for intercepting the device bounds of shapes before they are drawn.
|
||||
Install a subclass of this in your canvas.
|
||||
*/
|
||||
class SkBounder : public SkRefCnt {
|
||||
public:
|
||||
bool doIRect(const SkRect16&, const SkRegion&);
|
||||
bool doHairline(const SkPoint&, const SkPoint&, const SkPaint&, const SkRegion&);
|
||||
bool doRect(const SkRect&, const SkPaint&, const SkRegion&);
|
||||
bool doPath(const SkPath&, const SkPaint&, const SkRegion&, bool doFill);
|
||||
|
||||
protected:
|
||||
/** Override in your subclass. This is called with the device bounds of an
|
||||
object (text, geometry, image) just before it is drawn. If your method
|
||||
returns false, the drawing for that shape is aborted. If your method
|
||||
returns true, drawing continues. The bounds your method receives have already
|
||||
been transformed in to device coordinates, and clipped to the current clip.
|
||||
*/
|
||||
virtual bool onIRect(const SkRect16&) = 0;
|
||||
|
||||
/** Called after each shape has been drawn. The default implementation does
|
||||
nothing, but your override could use this notification to signal itself
|
||||
that the offscreen being rendered into needs to be updated to the screen.
|
||||
*/
|
||||
virtual void commit();
|
||||
|
||||
friend class SkAutoBounderCommit;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef SkCamera_DEFINED
|
||||
#define SkCamera_DEFINED
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "Sk64.h"
|
||||
|
||||
#ifdef SK_SCALAR_IS_FIXED
|
||||
typedef SkFract SkUnitScalar;
|
||||
#define SK_UnitScalar1 SK_Fract1
|
||||
#define SkUnitScalarMul(a, b) SkFractMul(a, b)
|
||||
#define SkUnitScalarDiv(a, b) SkFractDiv(a, b)
|
||||
#else
|
||||
typedef float SkUnitScalar;
|
||||
#define SK_UnitScalar1 SK_Scalar1
|
||||
#define SkUnitScalarMul(a, b) SkScalarMul(a, b)
|
||||
#define SkUnitScalarDiv(a, b) SkScalarDiv(a, b)
|
||||
#endif
|
||||
|
||||
// Taken from Rob Johnson's most excellent QuickDraw GX library
|
||||
|
||||
struct SkUnit3D {
|
||||
SkUnitScalar fX, fY, fZ;
|
||||
|
||||
void set(SkUnitScalar x, SkUnitScalar y, SkUnitScalar z)
|
||||
{
|
||||
fX = x; fY = y; fZ = z;
|
||||
}
|
||||
static SkUnitScalar Dot(const SkUnit3D&, const SkUnit3D&);
|
||||
static void Cross(const SkUnit3D&, const SkUnit3D&, SkUnit3D* cross);
|
||||
};
|
||||
|
||||
struct SkPoint3D {
|
||||
SkScalar fX, fY, fZ;
|
||||
|
||||
void set(SkScalar x, SkScalar y, SkScalar z)
|
||||
{
|
||||
fX = x; fY = y; fZ = z;
|
||||
}
|
||||
SkScalar normalize(SkUnit3D*) const;
|
||||
};
|
||||
|
||||
class SkPatch3D {
|
||||
public:
|
||||
SkPatch3D();
|
||||
|
||||
void reset();
|
||||
void rotate(SkScalar radX, SkScalar radY, SkScalar radZ);
|
||||
void rotateDegrees(SkScalar degX, SkScalar degY, SkScalar degZ)
|
||||
{
|
||||
this->rotate(SkDegreesToRadians(degX),
|
||||
SkDegreesToRadians(degY),
|
||||
SkDegreesToRadians(degZ));
|
||||
}
|
||||
|
||||
// dot a unit vector with the patch's normal
|
||||
SkScalar dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const;
|
||||
|
||||
SkPoint3D fU, fV, fOrigin;
|
||||
private:
|
||||
friend class SkCamera3D;
|
||||
};
|
||||
|
||||
class SkCamera3D {
|
||||
public:
|
||||
SkCamera3D();
|
||||
|
||||
void update();
|
||||
void computeMatrix(const SkPatch3D&, SkMatrix* matrix) const;
|
||||
|
||||
SkPoint3D fLocation;
|
||||
SkPoint3D fAxis;
|
||||
SkPoint3D fZenith;
|
||||
SkPoint3D fObserver;
|
||||
|
||||
private:
|
||||
SkMatrix fOrientation;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,470 @@
|
|||
#ifndef SkCanvas_DEFINED
|
||||
#define SkCanvas_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkDeque.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPorterDuff.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRegion.h"
|
||||
|
||||
class SkBounder;
|
||||
|
||||
/** \class SkCanvas
|
||||
|
||||
The SkCanvas class holds the "draw" calls. To draw something, you need
|
||||
4 basic components: A SkBitmap to hold the pixels, a SkCanvas to host
|
||||
the draw calls (writing into the bitmap), a drawing primitive (e.g. SkRect, SkPath,
|
||||
text, SkBitmap), and a paint (to describe the colors and styles for the drawing).
|
||||
*/
|
||||
class SkCanvas {
|
||||
public:
|
||||
/** Construct an empty canvas. Use setPixels() to specify a bitmap to draw into.
|
||||
*/
|
||||
SkCanvas();
|
||||
/** Construct a canvas with the specified bitmap to draw into.
|
||||
@param bitmap Specifies a bitmap for the canvas to draw into. Its contents are copied to the canvas.
|
||||
*/
|
||||
SkCanvas(const SkBitmap& bitmap);
|
||||
~SkCanvas();
|
||||
|
||||
/** Return a copy of the bitmap that the canvas draws into. This does not make a copy
|
||||
of the bitmap's pixels, but just returns the pixel's address.
|
||||
@param bitmap The bitmap, allocated by the caller, that receives a copy of the canvas' bitmap
|
||||
(the one specified in the setPixels() call, or in the constructor).
|
||||
*/
|
||||
void getPixels(SkBitmap* bitmap) const;
|
||||
/** Specify a bitmap for the canvas to draw into. This routine makes a copy of the bitmap,
|
||||
but does not copy the actual pixels. Ownership of the bitmap's pixels stays with the caller's
|
||||
bitmap.
|
||||
@param bitmap Specifies a new bitmap for the canvas to draw into. Its contents are copied to the canvas.
|
||||
*/
|
||||
void setPixels(const SkBitmap& bitmap);
|
||||
|
||||
/** Return true if the bitmap that the current layer draws into is always opaque
|
||||
(i.e. does not support per-pixel alpha). e.g. kARGB_8888_Config returns false,
|
||||
kARGB_565_Config returns true.
|
||||
@return true if the bitmap that the current layer draws into is always opaque
|
||||
*/
|
||||
bool isBitmapOpaque() const;
|
||||
|
||||
/** Return the width of the bitmap that the current layer draws into
|
||||
@return the width of the bitmap that the current layer draws into
|
||||
*/
|
||||
int getBitmapWidth() const { return this->getCurrBitmap().width(); }
|
||||
/** Return the height of the bitmap that the current layer draws into
|
||||
@return the height of the bitmap that the current layer draws into
|
||||
*/
|
||||
int getBitmapHeight() const { return this->getCurrBitmap().height(); }
|
||||
|
||||
/** This call saves the current matrix and clip information, and pushes a copy onto a
|
||||
private stack. Subsequent calls to translate,scale,rotate,skew,concat or clipRect,clipPath
|
||||
all operate on this copy. When the balancing call to restore() is made, this copy is deleted
|
||||
and the previous matrix/clip state is restored.
|
||||
@return The value to pass to restoreToCount() to balance this save()
|
||||
*/
|
||||
int save();
|
||||
/** This behaves the same as save(), but in addition it allocates an offscreen bitmap.
|
||||
All drawing calls are directed there, and only when the balancing call to restore() is made
|
||||
is that offscreen transfered to the canvas (or the previous layer).
|
||||
Subsequent calls to translate,scale,rotate,skew,concat or clipRect,clipPath
|
||||
all operate on this copy. When the balancing call to restore() is made, this copy is deleted
|
||||
and the previous matrix/clip state is restored.
|
||||
@param bounds The maximum size the offscreen bitmap needs to be (in local coordinates)
|
||||
@param paint This is copied, and is applied to the offscreen when restore() is called.
|
||||
@return The value to pass to restoreToCount() to balance this save()
|
||||
*/
|
||||
int saveLayer(const SkRect& bounds, const SkPaint& paint);
|
||||
/** This call balances a previous call to save(), and is used to remove all modifications to
|
||||
the matrix/clip state since the last save call. It is an error to call restore() more times
|
||||
than save() was called.
|
||||
*/
|
||||
void restore();
|
||||
/** Returns the number of matrix/clip states on the SkCanvas' private stack. This will equal
|
||||
# save() calls - # restore() calls.
|
||||
*/
|
||||
int getSaveCount() const;
|
||||
/** Efficient way to pop any calls to save() that happened after the save count reached saveCount.
|
||||
It is an error for saveCount to be less than getSaveCount()
|
||||
@param saveCount The number of save() levels to restore from
|
||||
*/
|
||||
void restoreToCount(int saveCount);
|
||||
|
||||
/** Preconcat the current matrix with the specified translation
|
||||
@param dx The distance to translate in X
|
||||
@param dy The distance to translate in Y
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
bool translate(SkScalar dx, SkScalar dy);
|
||||
/** Preconcat the current matrix with the specified scale and pivot point.
|
||||
The pivot is the point that will remain unchanged after the scale is applied.
|
||||
@param sx The amount to scale in X, about the pivot point (px,py)
|
||||
@param sy The amount to scale in Y, about the pivot point (px,py)
|
||||
@param px The pivot's X coordinate
|
||||
@param py The pivot's Y coordinate
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
bool scale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
|
||||
/** Preconcat the current matrix with the specified rotation and pivot point.
|
||||
The pivot is the point that will remain unchanged after the rotation is applied.
|
||||
@param degrees The amount to rotate, in degrees
|
||||
@param px The pivot's X coordinate
|
||||
@param py The pivot's Y coordinate
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
bool rotate(SkScalar degrees, SkScalar px, SkScalar py);
|
||||
/** Preconcat the current matrix with the specified skew and pivot point.
|
||||
The pivot is the point that will remain unchanged after the skew is applied.
|
||||
@param sx The amount to skew in X, about the pivot point (px,py)
|
||||
@param sy The amount to skew in Y, about the pivot point (px,py)
|
||||
@param px The pivot's X coordinate
|
||||
@param py The pivot's Y coordinate
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
bool skew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
|
||||
/** Preconcat the current matrix with the specified matrix.
|
||||
@param matrix The matrix to preconcatenate with the current matrix
|
||||
@return true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
bool concat(const SkMatrix& matrix);
|
||||
|
||||
/** Intersect the current clip with the specified rectangle.
|
||||
@param rect The rect to intersect with the current clip
|
||||
*/
|
||||
void clipRect(const SkRect& rect);
|
||||
/** Intersect the current clip with the specified rectangle.
|
||||
@param left The left side of the rectangle to intersect with the current clip
|
||||
@param top The top side of the rectangle to intersect with the current clip
|
||||
@param right The right side of the rectangle to intersect with the current clip
|
||||
@param bottom The bottom side of the rectangle to intersect with the current clip
|
||||
*/
|
||||
void clipRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
|
||||
/** Intersect the current clip with the specified path.
|
||||
@param path The path to intersect with the current clip
|
||||
*/
|
||||
void clipPath(const SkPath& path);
|
||||
/** Intersect the current clip with the specified region. Note that unlike clipRect()
|
||||
and clipPath() which transform their arguments by the current matrix, clipDeviceRgn()
|
||||
assumes its argument is already in the coordinate system of the current layer's bitmap,
|
||||
and so not transformation is performed.
|
||||
@param deviceRgn The region to intersect with the current clip
|
||||
*/
|
||||
void clipDeviceRgn(const SkRegion& deviceRgn);
|
||||
|
||||
/** Return true if the specified rectangle, after being transformed by the current
|
||||
matrix, would lie completely outside of the current clip. Call this to check
|
||||
if an area you intend to draw into is clipped out (and therefore you can skip
|
||||
making the draw calls).
|
||||
@param rect the rect to compare with the current clip
|
||||
@param antialiased true if the rect should be considered antialiased, since that means it may
|
||||
affect a larger area (more pixels) than non-antialiased.
|
||||
@return true if the rect (transformed by the canvas' matrix) does not intersect with the canvas' clip
|
||||
*/
|
||||
bool quickReject(const SkRect& rect, bool antialiased = false) const;
|
||||
/** Return true if the specified path, after being transformed by the current
|
||||
matrix, would lie completely outside of the current clip. Call this to check
|
||||
if an area you intend to draw into is clipped out (and therefore you can skip
|
||||
making the draw calls).
|
||||
Note, for speed it may return false even if the path itself might not intersect
|
||||
the clip (i.e. the bounds of the path intersects, but the path doesnot).
|
||||
@param path The path to compare with the current clip
|
||||
@param antialiased true if the path should be considered antialiased, since that means it may
|
||||
affect a larger area (more pixels) than non-antialiased.
|
||||
@return true if the path (transformed by the canvas' matrix) does not intersect with the canvas' clip
|
||||
*/
|
||||
bool quickReject(const SkPath& path, bool antialiased = false) const;
|
||||
/** Return true if the specified rectangle, after being transformed by the current
|
||||
matrix, would lie completely outside of the current clip. Call this to check
|
||||
if an area you intend to draw into is clipped out (and therefore you can skip
|
||||
making the draw calls).
|
||||
@param left The left side of the rectangle to compare with the current clip
|
||||
@param top The top side of the rectangle to compare with the current clip
|
||||
@param right The right side of the rectangle to compare with the current clip
|
||||
@param bottom The bottom side of the rectangle to compare with the current clip
|
||||
@param antialiased true if the rect should be considered antialiased, since that means it may
|
||||
affect a larger area (more pixels) than non-antialiased.
|
||||
@return true if the rect (transformed by the canvas' matrix) does not intersect with the canvas' clip
|
||||
*/
|
||||
bool quickReject(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom, bool antialiased = false) const
|
||||
{
|
||||
SkRect r;
|
||||
r.set(left, top, right, bottom);
|
||||
return this->quickReject(r, antialiased);
|
||||
}
|
||||
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified RGB color, using srcover porterduff mode.
|
||||
@param r the red component (0..255) of the color used to draw onto the canvas
|
||||
@param g the green component (0..255) of the color used to draw onto the canvas
|
||||
@param b the blue component (0..255) of the color used to draw onto the canvas
|
||||
*/
|
||||
void drawRGB(U8CPU r, U8CPU g, U8CPU b);
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified ARGB color, using srcover porterduff mode.
|
||||
@param a the alpha component (0..255) of the color used to draw onto the canvas
|
||||
@param r the red component (0..255) of the color used to draw onto the canvas
|
||||
@param g the green component (0..255) of the color used to draw onto the canvas
|
||||
@param b the blue component (0..255) of the color used to draw onto the canvas
|
||||
*/
|
||||
void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified color, using srcover porterduff mode.
|
||||
@param color the color to draw onto the canvas
|
||||
*/
|
||||
void drawColor(SkColor color)
|
||||
{
|
||||
this->drawColor(color, SkPorterDuff::kSrcOver_Mode);
|
||||
}
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified color and porter-duff xfermode.
|
||||
@param color the color to draw with
|
||||
@param mode the porter-duff mode to apply to the color
|
||||
*/
|
||||
void drawColor(SkColor color, SkPorterDuff::Mode mode);
|
||||
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified paint. This is equivalent (but faster) to drawing an infinitely
|
||||
large rectangle with the specified paint.
|
||||
@param paint The paint used to draw onto the canvas
|
||||
*/
|
||||
void drawPaint(const SkPaint& paint);
|
||||
/** Draw a line segment with the specified start and stop points, using the specified
|
||||
paint. NOTE: since a line is always "framed", the Style is ignored in
|
||||
the paint.
|
||||
@param start The start point of the line
|
||||
@param stop The stop point of the line
|
||||
@param paint The paint used to draw the line
|
||||
*/
|
||||
void drawLine(const SkPoint& start, const SkPoint& stop, const SkPaint& paint);
|
||||
/** Draw a line segment with the specified start and stop x,y coordinates, using the specified
|
||||
paint. NOTE: since a line is always "framed", the Style is ignored in
|
||||
the paint.
|
||||
@param startX The x-coordinate of the start point of the line
|
||||
@param startY The y-coordinate of the start point of the line
|
||||
@param endX The x-coordinate of the end point of the line
|
||||
@param endY The y-coordinate of the end point of the line
|
||||
@param paint The paint used to draw the line
|
||||
*/
|
||||
void drawLine(SkScalar startX, SkScalar startY, SkScalar stopX, SkScalar stopY, const SkPaint& paint);
|
||||
/** Draw the specified SkRect using the specified paint. The rectangle will be filled
|
||||
or framed based on the Style in the paint.
|
||||
@param rect The rect to be drawn
|
||||
@param paint The paint used to draw the rect
|
||||
*/
|
||||
void drawRect(const SkRect& rect, const SkPaint& paint);
|
||||
/** Draw the specified SkRect using the specified paint. The rectangle will be filled
|
||||
or framed based on the Style in the paint.
|
||||
@param left The left side of the rectangle to be drawn
|
||||
@param top The top side of the rectangle to be drawn
|
||||
@param right The right side of the rectangle to be drawn
|
||||
@param bottom The bottom side of the rectangle to be drawn
|
||||
@param paint The paint used to draw the rect
|
||||
*/
|
||||
void drawRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom, const SkPaint& paint);
|
||||
/** Draw the specified oval using the specified paint. The oval will be filled
|
||||
or framed based on the Style in the paint.
|
||||
@param oval The rectangle bounds of the oval to be drawn
|
||||
@param paint The paint used to draw the oval
|
||||
*/
|
||||
void drawOval(const SkRect& oval, const SkPaint&);
|
||||
/** Draw the specified circle using the specified paint. If radius is <= 0, then
|
||||
nothing will be drawn. The circle will be filled
|
||||
or framed based on the Style in the paint.
|
||||
@param cx The x-coordinate of the center of the cirle to be drawn
|
||||
@param cy The y-coordinate of the center of the cirle to be drawn
|
||||
@param radius The radius of the cirle to be drawn
|
||||
@param paint The paint used to draw the circle
|
||||
*/
|
||||
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
|
||||
/** Draw the specified round-rect using the specified paint. The round-rect will be filled
|
||||
or framed based on the Style in the paint.
|
||||
@param rect The rectangular bounds of the roundRect to be drawn
|
||||
@param rx The x-radius of the oval used to round the corners
|
||||
@param ry The y-radius of the oval used to round the corners
|
||||
@param paint The paint used to draw the roundRect
|
||||
*/
|
||||
void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
|
||||
/** Draw the specified path using the specified paint. The path will be filled
|
||||
or framed based on the Style in the paint.
|
||||
@param path The path to be drawn
|
||||
@param paint The paint used to draw the path
|
||||
*/
|
||||
void drawPath(const SkPath& path, const SkPaint& paint);
|
||||
/** Draw the specified bitmap, with its top/left corner at (x,y), using the specified paint,
|
||||
transformed by the current matrix.
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param left The position of the left side of the bitmap being drawn
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
@param paint The paint used to draw the bitmap
|
||||
*/
|
||||
void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, const SkPaint& paint);
|
||||
/** Draw the specified bitmap, with its top/left corner at (x,y), transformed
|
||||
by the current matrix. Since no paint is specified, the bitmap is drawn with no overriding
|
||||
alpha or colorfilter, and in srcover porterduff mode.
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param left The position of the left side of the bitmap being drawn
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
*/
|
||||
void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top);
|
||||
/** Draw the specified bitmap, with its top/left corner at (x,y), NOT transformed
|
||||
by the current matrix. This method is not exported to java.
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param left The position of the left side of the bitmap being drawn
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
@param paint The paint used to draw the bitmap
|
||||
*/
|
||||
void drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint& paint);
|
||||
/** Draw the utf8-text, with origin at (x,y), using the specified paint. The origin is interpreted
|
||||
based on the Align setting in the paint.
|
||||
@param text The UTF8 text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param x The x-coordinate of the origin of the text being drawn
|
||||
@param y The y-coordinate of the origin of the text being drawn
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint);
|
||||
/** Draw the utf8-text, with origin at (x,y), using the specified paint. The origin is interpreted
|
||||
based on the Align setting in the paint.
|
||||
@param text The UTF16 text to be drawn
|
||||
@param numberOf16BitValues The number of 16bit values to read from the text parameter
|
||||
@param x The x-coordinate of the origin of the text being drawn
|
||||
@param y The y-coordinate of the origin of the text being drawn
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void drawText16(const uint16_t text[], size_t numberOf16BitValues, SkScalar x, SkScalar y, const SkPaint& paint);
|
||||
/** Draw the utf8-text, with origin at (x,y), using the specified paint. The origin is interpreted
|
||||
based on the Align setting in the paint.
|
||||
@param text The UTF8 text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param pos Array of positions, used to position each character
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void drawPosText(const char text[], size_t byteLength, const SkPoint pos[], const SkPaint& paint);
|
||||
/** Draw the utf8-text, with origin at (x,y), using the specified paint. The origin is interpreted
|
||||
based on the Align setting in the paint.
|
||||
@param text The UTF16 text to be drawn
|
||||
@param numberOf16BitValues The number of 16bit values to read from the text parameter
|
||||
@param pos Array of positions, used to position each character
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void drawPosText16(const uint16_t text[], size_t numberOf16BitValues, const SkPoint pos[], const SkPaint& paint);
|
||||
/** Draw the utf8-text, with origin at (x,y), using the specified paint, along the specified path.
|
||||
The paint's Align setting determins where along the path to start the text.
|
||||
@param text The UTF8 text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param path The path the text should follow for its baseline
|
||||
@param distance The distance along the path to add to the text's starting position
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void drawTextOnPath(const char text[], size_t byteLength, const SkPath& path, SkScalar distance, const SkPaint& paint);
|
||||
/** Draw the utf8-text, with origin at (x,y), using the specified paint, along the specified path.
|
||||
The paint's Align setting determins where along the path to start the text.
|
||||
@param text The UTF16 text to be drawn
|
||||
@param numberOf16BitValues The number of 16bit values to read from the text parameter
|
||||
@param path The path the text should follow for its baseline
|
||||
@param offset The distance along the path to add to the text's starting position
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void drawText16OnPath(const uint16_t text[], size_t numberOf16BitValues, const SkPath& path, SkScalar distance, const SkPaint& paint);
|
||||
|
||||
/** Return the current set mask, used to temporarily modify the paint's flags
|
||||
when something is being drawin.
|
||||
This method is not exported to java.
|
||||
*/
|
||||
uint32_t getPaintSetBits() const;
|
||||
/** Return the current clear mask, used to temporarily modify the paint's flags
|
||||
when something is being drawin.
|
||||
This method is not exported to java.
|
||||
*/
|
||||
uint32_t getPaintClearBits() const;
|
||||
/** Set the current set and clear masks, used to temporarily modify the paint's flags
|
||||
when something is being drawin. The setBits are applied before the clrBits.
|
||||
This method is not exported to java.
|
||||
@param setBits A mask of bits to be OR'd into the paint's flag bits
|
||||
@param clrBits A mask of bits to be cleared from the paint's flag bits
|
||||
*/
|
||||
void setPaintSetClearBits(uint32_t setBits, uint32_t clrBits);
|
||||
/** Helper for getPaintSetClearBits/setPaintSetClearBits. The parameters are OR'd into
|
||||
the current values, rather than replacing them as with setPaintSetClearBits.
|
||||
This method is not exported to java.
|
||||
@param setBits A mask of bits to be OR'd with the existing setBits on the canvas
|
||||
@param clearBits A mask of bits to be OR'd with the existing clearBits on the canvas
|
||||
*/
|
||||
void orPaintSetClearBits(uint32_t setBits, uint32_t clearBits);
|
||||
|
||||
/** Get the current bounder object.
|
||||
<p />
|
||||
The bounder's reference count is not affected.
|
||||
@return the canva's bounder (or NULL).
|
||||
*/
|
||||
SkBounder* getBounder() const { return fBounder; }
|
||||
/** Set a new bounder (or NULL).
|
||||
<p />
|
||||
Pass NULL to clear any previous bounder.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous bounder exists, its reference count is decremented.
|
||||
If bounder is not NULL, its reference count is incremented.
|
||||
@param bounder the new bounder (or NULL) to be installed in the canvas
|
||||
@return the set bounder object
|
||||
*/
|
||||
SkBounder* setBounder(SkBounder*);
|
||||
|
||||
/** Return a reference to the bitmap that the current layer draws into.
|
||||
This method is not exported to java.
|
||||
@return The a reference to the bitmap that the current layer draws into.
|
||||
*/
|
||||
const SkBitmap& getCurrBitmap() const;
|
||||
/** Return the MapPtProc for the current matrix on the canvas.
|
||||
This method is not exported to java.
|
||||
@return the MapPtProc for the current matrix on the canvas.
|
||||
*/
|
||||
SkMatrix::MapPtProc getCurrMapPtProc() const;
|
||||
/** Return the current matrix on the canvas.
|
||||
This method is not exported to java.
|
||||
@return The current matrix on the canvas.
|
||||
*/
|
||||
const SkMatrix& getTotalMatrix() const;
|
||||
/** Return the current device clip (concatenation of all clip calls).
|
||||
This method is not exported to java.
|
||||
@return the current device clip (concatenation of all clip calls).
|
||||
*/
|
||||
const SkRegion& getTotalClip() const;
|
||||
|
||||
private:
|
||||
struct MCRec;
|
||||
|
||||
SkDeque fMCStack;
|
||||
MCRec* fMCRec; // points to top of stack
|
||||
uint32_t fMCRecStorage[32]; // the first N recs that can fit here mean we won't call malloc
|
||||
|
||||
SkBitmap fBitmap;
|
||||
SkBounder* fBounder;
|
||||
|
||||
friend class SkDraw;
|
||||
};
|
||||
|
||||
/** Stack helper class to automatically call restoreToCount() on the canvas
|
||||
when this object goes out of scope. Use this to guarantee that the canvas
|
||||
is restored to a known state.
|
||||
*/
|
||||
class SkAutoCanvasRestore {
|
||||
public:
|
||||
SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas)
|
||||
{
|
||||
SkASSERT(canvas);
|
||||
fSaveCount = canvas->getSaveCount();
|
||||
if (doSave)
|
||||
canvas->save();
|
||||
}
|
||||
~SkAutoCanvasRestore()
|
||||
{
|
||||
fCanvas->restoreToCount(fSaveCount);
|
||||
}
|
||||
|
||||
private:
|
||||
SkCanvas* fCanvas;
|
||||
int fSaveCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
#ifndef SkColor_DEFINED
|
||||
#define SkColor_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
/** \file SkColor.h
|
||||
|
||||
Types and macros for colors
|
||||
*/
|
||||
|
||||
/** 8-bit type for an alpha value. 0xFF is 100% opaque, 0x00 is 100% transparent.
|
||||
*/
|
||||
typedef uint8_t SkAlpha;
|
||||
/** 32 bit ARGB color value, not premultiplied. The color components are always in
|
||||
a known order. This is different from SkPMColor, which has its bytes in a configuration
|
||||
dependent order, to match the format of kARGB32 bitmaps. SkColor is the type used to
|
||||
specify colors in SkPaint and in gradients.
|
||||
*/
|
||||
typedef uint32_t SkColor;
|
||||
|
||||
/** Return a SkColor value from 8 bit component values
|
||||
*/
|
||||
static inline SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
|
||||
{
|
||||
SkASSERT(a <= 255 && r <= 255 && g <= 255 && b <= 255);
|
||||
|
||||
return (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
||||
}
|
||||
|
||||
/** Return a SkColor value from 8 bit component values, with an implied value
|
||||
of 0xFF for alpha (fully opaque)
|
||||
*/
|
||||
#define SkColorSetRGB(r, g, b) SkColorSetARGB(0xFF, r, g, b)
|
||||
|
||||
#define SkColorGetA(color) ((color) >> 24) //!< return the alpha byte from a SkColor value
|
||||
#define SkColorGetR(color) ((color) << 8 >> 24) //!< return the red byte from a SkColor value
|
||||
#define SkColorGetG(color) ((color) << 16 >> 24) //!< return the green byte from a SkColor value
|
||||
#define SkColorGetB(color) ((color) << 24 >> 24) //!< return the blue byte from a SkColor value
|
||||
|
||||
// common colors
|
||||
|
||||
#define SK_ColorBLACK 0xFF000000 //!< black SkColor value
|
||||
#define SK_ColorDKGRAY 0xFF444444 //!< dark gray SkColor value
|
||||
#define SK_ColorGRAY 0xFF888888 //!< gray SkColor value
|
||||
#define SK_ColorLTGRAY 0xFFCCCCCC //!< light gray SkColor value
|
||||
#define SK_ColorWHITE 0xFFFFFFFF //!< white SkColor value
|
||||
|
||||
#define SK_ColorRED 0xFFFF0000 //!< red SkColor value
|
||||
#define SK_ColorGREEN 0xFF00FF00 //!< green SkColor value
|
||||
#define SK_ColorBLUE 0xFF0000FF //!< blue SkColor value
|
||||
#define SK_ColorYELLOW 0xFFFFFF00 //!< yellow SkColor value
|
||||
#define SK_ColorCYAN 0xFF00FFFF //!< cyan SkColor value
|
||||
#define SK_ColorMAGENTA 0xFFFF00FF //!< magenta SkColor value
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Convert RGB components to HSV.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
@param red red component value [0..255]
|
||||
@param green green component value [0..255]
|
||||
@param blue blue component value [0..255]
|
||||
@param hsv 3 element array which holds the resulting HSV components.
|
||||
*/
|
||||
void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]);
|
||||
|
||||
/** Convert the argb color to its HSV components.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
@param color the argb color to convert. Note: the alpha component is ignored.
|
||||
@param hsv 3 element array which holds the resulting HSV components.
|
||||
*/
|
||||
static inline void SkColorToHSV(SkColor color, SkScalar hsv[3])
|
||||
{
|
||||
SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv);
|
||||
}
|
||||
|
||||
/** Convert HSV components to an ARGB color. The alpha component is passed through unchanged.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
If hsv values are out of range, they are pinned.
|
||||
@param alpha the alpha component of the returned argb color.
|
||||
@param hsv 3 element array which holds the input HSV components.
|
||||
@return the resulting argb color
|
||||
*/
|
||||
SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]);
|
||||
|
||||
/** Convert HSV components to an ARGB color. The alpha component set to 0xFF.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
If hsv values are out of range, they are pinned.
|
||||
@param hsv 3 element array which holds the input HSV components.
|
||||
@return the resulting argb color
|
||||
*/
|
||||
static inline SkColor SkHSVToColor(const SkScalar hsv[3])
|
||||
{
|
||||
return SkHSVToColor(0xFF, hsv);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** 32 bit ARGB color value, premultiplied. The byte order for this value is
|
||||
configuration dependent, matching the format of kARGB32 bitmaps. This is different
|
||||
from SkColor, which is nonpremultiplied, and is always in the same byte order.
|
||||
*/
|
||||
typedef uint32_t SkPMColor;
|
||||
|
||||
/** Return a SkPMColor value from unpremultiplied 8 bit component values
|
||||
*/
|
||||
SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
/** Return a SkPMColor value from a SkColor value. This is done by multiplying the color
|
||||
components by the color's alpha, and by arranging the bytes in a configuration
|
||||
dependent order, to match the format of kARGB32 bitmaps.
|
||||
*/
|
||||
SkPMColor SkPreMultiplyColor(SkColor c);
|
||||
|
||||
/** Define a function pointer type for combining two premultiplied colors
|
||||
*/
|
||||
typedef SkPMColor (*SkXfermodeProc)(SkPMColor src, SkPMColor dst);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef SkColorFilter_DEFINED
|
||||
#define SkColorFilter_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkPorterDuff.h"
|
||||
|
||||
class SkColorFilter : public SkRefCnt {
|
||||
public:
|
||||
/** Called with a scanline of colors, as if there was a shader installed.
|
||||
The implementation writes out its filtered version into result[].
|
||||
@param shader array of colors, possibly generated by a shader
|
||||
@param count the number of entries in the shader[] and result[] arrays
|
||||
@param result written by the filter, these are the colors that are used to draw
|
||||
*/
|
||||
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]);
|
||||
|
||||
/** Create a colorfilter that uses the specified color and xfermode proc.
|
||||
@param srcColor The source color passed to the xfermode proc
|
||||
@param proc The xfermode proc that is applied to each color in the colorfilter's filterSpan method
|
||||
@return colorfilter object that applies the src color and xfermode proc, or NULL if proc is NULL
|
||||
*/
|
||||
static SkColorFilter* CreatXfermodeFilter(SkColor srcColor, SkXfermodeProc proc);
|
||||
/** Create a colorfilter that uses the specified color and porter-duff mode.
|
||||
@param srcColor The source color used with the specified porter-duff mode
|
||||
@param porterDuffMode The porter-duff mode that is applied to each color in the colorfilter's filterSpan method
|
||||
@return colorfilter object that applies the src color and porter-duff mode, or NULL is mode is out of range
|
||||
*/
|
||||
static SkColorFilter* CreatePorterDuffFilter(SkColor srcColor, SkPorterDuff::Mode porterDuffMode);
|
||||
|
||||
/** Create a colorfilter that multiplies the RGB channels by one color, and then adds a second color,
|
||||
pinning the result for each component to [0..255]. The alpha components of the mul and add arguments
|
||||
are ignored.
|
||||
*/
|
||||
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
|
||||
};
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkFilterShader : public SkShader {
|
||||
public:
|
||||
SkFilterShader(SkShader* shader, SkColorFilter* filter);
|
||||
virtual ~SkFilterShader();
|
||||
|
||||
// override
|
||||
virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix);
|
||||
virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
|
||||
|
||||
private:
|
||||
SkShader* fShader;
|
||||
SkColorFilter* fFilter;
|
||||
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,218 @@
|
|||
#ifndef SkColorPriv_DEFINED
|
||||
#define SkColorPriv_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
|
||||
inline unsigned SkAlpha255To256(U8CPU alpha)
|
||||
{
|
||||
SkASSERT(SkToU8(alpha) == alpha);
|
||||
return alpha + (alpha >> 7);
|
||||
}
|
||||
|
||||
#define SkAlphaMul(value, alpha256) ((value) * (alpha256) >> 8)
|
||||
|
||||
// The caller may want negative values, so keep all params signed (int)
|
||||
// so we don't accidentally slip into unsigned math and lose the sign
|
||||
// extension when we shift (in SkAlphaMul)
|
||||
inline int SkAlphaBlend(int src, int dst, int scale256)
|
||||
{
|
||||
SkASSERT((unsigned)scale256 <= 256);
|
||||
return dst + SkAlphaMul(src - dst, scale256);
|
||||
}
|
||||
|
||||
#define SK_R16_BITS 5
|
||||
#define SK_G16_BITS 6
|
||||
#define SK_B16_BITS 5
|
||||
|
||||
#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
|
||||
#define SK_G16_SHIFT (SK_B16_BITS)
|
||||
#define SK_B16_SHIFT 0
|
||||
|
||||
#define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
|
||||
#define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
|
||||
#define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
|
||||
|
||||
#define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
|
||||
#define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
|
||||
#define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
|
||||
|
||||
inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b)
|
||||
{
|
||||
SkASSERT(r <= SK_R16_MASK);
|
||||
SkASSERT(g <= SK_G16_MASK);
|
||||
SkASSERT(b <= SK_B16_MASK);
|
||||
|
||||
return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT));
|
||||
}
|
||||
|
||||
inline int SkShouldDitherXY(int x, int y)
|
||||
{
|
||||
return (x ^ y) & 1;
|
||||
}
|
||||
|
||||
inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b)
|
||||
{
|
||||
r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS);
|
||||
g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS);
|
||||
b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS);
|
||||
|
||||
return SkPackRGB16(r, g, b);
|
||||
}
|
||||
|
||||
#define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT)
|
||||
#define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT)
|
||||
#define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT)
|
||||
|
||||
#define SK_R16B16_MASK_IN_PLACE (SK_R16_MASK_IN_PLACE | SK_B16_MASK_IN_PLACE)
|
||||
|
||||
inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale)
|
||||
{
|
||||
#if SK_G16_MASK_IN_PLACE != 0x07E0
|
||||
return SkPackRGB16( SkAlphaMul(SkGetPackedR16(c), scale),
|
||||
SkAlphaMul(SkGetPackedG16(c), scale),
|
||||
SkAlphaMul(SkGetPackedB16(c), scale));
|
||||
#else
|
||||
scale >>= (8 - SK_G16_BITS);
|
||||
uint32_t rb = (c & SK_R16B16_MASK_IN_PLACE) * scale >> SK_G16_BITS;
|
||||
uint32_t g = (c & SK_G16_MASK_IN_PLACE) * scale >> SK_G16_BITS;
|
||||
return (g & SK_G16_MASK_IN_PLACE) | (rb & SK_R16B16_MASK_IN_PLACE);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, unsigned scale)
|
||||
{
|
||||
SkASSERT(scale <= 256);
|
||||
|
||||
return SkPackRGB16( SkAlphaBlend(SkGetPackedR16(src), SkGetPackedR16(dst), scale),
|
||||
SkAlphaBlend(SkGetPackedG16(src), SkGetPackedG16(dst), scale),
|
||||
SkAlphaBlend(SkGetPackedB16(src), SkGetPackedB16(dst), scale));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SK_A32_BITS 8
|
||||
#define SK_R32_BITS 8
|
||||
#define SK_G32_BITS 8
|
||||
#define SK_B32_BITS 8
|
||||
|
||||
#ifdef TEST_INTEL_MAC
|
||||
|
||||
#define SK_A32_SHIFT 0
|
||||
#define SK_R32_SHIFT 8
|
||||
#define SK_G32_SHIFT 16
|
||||
#define SK_B32_SHIFT 24
|
||||
|
||||
#else
|
||||
|
||||
#define SK_A32_SHIFT 24
|
||||
#define SK_R32_SHIFT 16
|
||||
#define SK_G32_SHIFT 8
|
||||
#define SK_B32_SHIFT 0
|
||||
|
||||
#endif
|
||||
|
||||
#define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
|
||||
#define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
|
||||
#define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
|
||||
#define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
|
||||
|
||||
#define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
|
||||
#define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
|
||||
#define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
|
||||
#define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
|
||||
|
||||
inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
|
||||
{
|
||||
SkASSERT(a <= SK_A32_MASK);
|
||||
SkASSERT(r <= a);
|
||||
SkASSERT(g <= a);
|
||||
SkASSERT(b <= a);
|
||||
|
||||
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
|
||||
}
|
||||
|
||||
inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale)
|
||||
{
|
||||
uint32_t rb = ((c & 0xFF00FF) * scale) >> 8;
|
||||
uint32_t ag = ((c >> 8) & 0xFF00FF) * scale;
|
||||
return (rb & 0xFF00FF) | (ag & ~0xFF00FF);
|
||||
}
|
||||
|
||||
inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst)
|
||||
{
|
||||
return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
|
||||
}
|
||||
|
||||
inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa)
|
||||
{
|
||||
SkASSERT((unsigned)aa <= 255);
|
||||
|
||||
unsigned src_scale = SkAlpha255To256(aa);
|
||||
unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale));
|
||||
|
||||
return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a 32bit pixel to a 16bit pixel (no dither)
|
||||
|
||||
#define SkR32ToR16(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
|
||||
#define SkG32ToG16(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
|
||||
#define SkB32ToB16(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
|
||||
|
||||
#define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK)
|
||||
#define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK)
|
||||
#define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK)
|
||||
|
||||
inline U16CPU SkPixel32ToPixel16(SkPMColor src)
|
||||
{
|
||||
#if 0
|
||||
return (SkPacked32ToR16(src) << SK_R16_SHIFT) |
|
||||
(SkPacked32ToG16(src) << SK_G16_SHIFT) |
|
||||
(SkPacked32ToB16(src) << SK_B16_SHIFT);
|
||||
#else // only works if the components are in the same order in both formats (i.e. foo32_shift >= foo16_shift)
|
||||
return ((src >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS - SK_R16_SHIFT)) & (SK_R16_MASK << SK_R16_SHIFT)) |
|
||||
((src >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS - SK_G16_SHIFT)) & (SK_G16_MASK << SK_G16_SHIFT)) |
|
||||
((src >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS - SK_B16_SHIFT)) & (SK_B16_MASK << SK_B16_SHIFT));
|
||||
#endif
|
||||
}
|
||||
|
||||
#define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a 16bit pixel to a 32bit pixel
|
||||
|
||||
inline unsigned SkR16ToR32(unsigned r)
|
||||
{
|
||||
return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
|
||||
}
|
||||
inline unsigned SkG16ToG32(unsigned g)
|
||||
{
|
||||
return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
|
||||
}
|
||||
inline unsigned SkB16ToB32(unsigned b)
|
||||
{
|
||||
return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
|
||||
}
|
||||
|
||||
#define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c))
|
||||
#define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c))
|
||||
#define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c))
|
||||
|
||||
inline SkPMColor SkPixel16ToPixel32(U16CPU src)
|
||||
{
|
||||
SkASSERT(src == SkToU16(src));
|
||||
|
||||
unsigned r = SkPacked16ToR32(src);
|
||||
unsigned g = SkPacked16ToG32(src);
|
||||
unsigned b = SkPacked16ToB32(src);
|
||||
|
||||
SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
|
||||
SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
|
||||
SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
|
||||
|
||||
return SkPackARGB32(0xFF, r, g, b);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef SkCornerPathEffect_DEFINED
|
||||
#define SkCornerPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkCornerPathEffect
|
||||
|
||||
SkCornerPathEffect is a subclass of SkPathEffect that can turn sharp corners
|
||||
into various treatments (e.g. rounded corners)
|
||||
*/
|
||||
class SkCornerPathEffect : public SkPathEffect {
|
||||
public:
|
||||
/** radius must be > 0 to have an effect. It specifies the distance from each corner
|
||||
that should be "rounded".
|
||||
*/
|
||||
SkCornerPathEffect(SkScalar radius);
|
||||
virtual ~SkCornerPathEffect();
|
||||
|
||||
// overrides for SkPathEffect
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkWBuffer&);
|
||||
|
||||
protected:
|
||||
SkCornerPathEffect(SkRBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar fRadius;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
|
||||
// illegal
|
||||
SkCornerPathEffect(const SkCornerPathEffect&);
|
||||
SkCornerPathEffect& operator=(const SkCornerPathEffect&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef SkCullPoints_DEFINED
|
||||
#define SkCullPoints_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkCullPoints {
|
||||
public:
|
||||
SkCullPoints();
|
||||
SkCullPoints(const SkRect16& r);
|
||||
|
||||
void reset(const SkRect16& r);
|
||||
|
||||
/** Start a contour at (x,y). Follow this with call(s) to lineTo(...)
|
||||
*/
|
||||
void moveTo(int x, int y);
|
||||
|
||||
enum LineToResult {
|
||||
kNo_Result, //!< line segment was completely clipped out
|
||||
kLineTo_Result, //!< path.lineTo(pts[1]);
|
||||
kMoveToLineTo_Result //!< path.moveTo(pts[0]); path.lineTo(pts[1]);
|
||||
};
|
||||
/** Connect a line to the previous call to lineTo (or moveTo).
|
||||
*/
|
||||
LineToResult lineTo(int x, int y, SkPoint16 pts[2]);
|
||||
|
||||
private:
|
||||
SkRect16 fR;
|
||||
SkPoint16 fAsQuad[4];
|
||||
SkPoint32 fPrevPt; // local state
|
||||
|
||||
bool sect_test(int x0, int y0, int x1, int y1) const;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkPath;
|
||||
|
||||
/** \class SkCullPointsPath
|
||||
|
||||
Similar to SkCullPoints, but this class handles the return values
|
||||
from lineTo, and automatically builds a SkPath with the result(s).
|
||||
*/
|
||||
class SkCullPointsPath {
|
||||
public:
|
||||
SkCullPointsPath();
|
||||
SkCullPointsPath(const SkRect16& r, SkPath* dst);
|
||||
|
||||
void reset(const SkRect16& r, SkPath* dst);
|
||||
|
||||
void moveTo(int x, int y);
|
||||
void lineTo(int x, int y);
|
||||
|
||||
private:
|
||||
SkCullPoints fCP;
|
||||
SkPath* fPath;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,83 @@
|
|||
#ifndef SkDOM_DEFINED
|
||||
#define SkDOM_DEFINED
|
||||
|
||||
#include "SkChunkAlloc.h"
|
||||
#include "SkMath.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
struct SkDOMNode;
|
||||
struct SkDOMAttr;
|
||||
|
||||
class SkDOM {
|
||||
public:
|
||||
SkDOM();
|
||||
~SkDOM();
|
||||
|
||||
typedef SkDOMNode Node;
|
||||
typedef SkDOMAttr Attr;
|
||||
|
||||
/** Returns nil on failure
|
||||
*/
|
||||
const Node* build(const char doc[], size_t len);
|
||||
const Node* copy(const SkDOM& dom, const Node* node);
|
||||
|
||||
const Node* getRootNode() const;
|
||||
|
||||
enum Type {
|
||||
kElement_Type,
|
||||
kText_Type
|
||||
};
|
||||
Type getType(const Node*) const;
|
||||
|
||||
const char* getName(const Node*) const;
|
||||
const Node* getFirstChild(const Node*, const char elem[] = nil) const;
|
||||
const Node* getNextSibling(const Node*, const char elem[] = nil) const;
|
||||
|
||||
const char* findAttr(const Node*, const char attrName[]) const;
|
||||
const Attr* getFirstAttr(const Node*) const;
|
||||
const Attr* getNextAttr(const Node*, const Attr*) const;
|
||||
const char* getAttrName(const Node*, const Attr*) const;
|
||||
const char* getAttrValue(const Node*, const Attr*) const;
|
||||
|
||||
// helpers for walking children
|
||||
int countChildren(const Node* node, const char elem[] = nil) const;
|
||||
|
||||
// helpers for calling SkParse
|
||||
bool findS32(const Node*, const char name[], int32_t* value) const;
|
||||
bool findScalars(const Node*, const char name[], SkScalar value[], int count) const;
|
||||
bool findHex(const Node*, const char name[], uint32_t* value) const;
|
||||
bool findBool(const Node*, const char name[], bool*) const;
|
||||
int findList(const Node*, const char name[], const char list[]) const;
|
||||
|
||||
bool findScalar(const Node* node, const char name[], SkScalar value[]) const
|
||||
{
|
||||
return this->findScalars(node, name, value, 1);
|
||||
}
|
||||
|
||||
bool hasAttr(const Node*, const char name[], const char value[]) const;
|
||||
bool hasS32(const Node*, const char name[], int32_t value) const;
|
||||
bool hasScalar(const Node*, const char name[], SkScalar value) const;
|
||||
bool hasHex(const Node*, const char name[], uint32_t value) const;
|
||||
bool hasBool(const Node*, const char name[], bool value) const;
|
||||
|
||||
class AttrIter {
|
||||
public:
|
||||
AttrIter(const class SkDOM&, const Node*);
|
||||
const char* next(const char** value);
|
||||
private:
|
||||
const Attr* fAttr;
|
||||
const Attr* fStop;
|
||||
};
|
||||
|
||||
SkDEBUGCODE(void dump(const Node* node = nil, int tabLevel = 0) const;)
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
|
||||
private:
|
||||
SkChunkAlloc fAlloc;
|
||||
Node* fRoot;
|
||||
friend class AttrIter;
|
||||
friend class SkDOMParser;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef SkDashPathEffect_DEFINED
|
||||
#define SkDashPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkDashPathEffect
|
||||
|
||||
SkDashPathEffect is a subclass of SkPathEffect that implements dashing
|
||||
*/
|
||||
class SkDashPathEffect : public SkPathEffect {
|
||||
public:
|
||||
/** The intervals array must contain an even number of entries (>=2), with the even
|
||||
indices specifying the "on" intervals, and the odd indices specifying the "off"
|
||||
intervals. phase is an offset into the intervals array (mod the sum of all of the
|
||||
intervals).
|
||||
Note: only affects framed paths
|
||||
*/
|
||||
SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase, bool scaleToFit = false);
|
||||
virtual ~SkDashPathEffect();
|
||||
|
||||
// overrides for SkPathEffect
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkWBuffer&);
|
||||
|
||||
protected:
|
||||
SkDashPathEffect(SkRBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar* fIntervals;
|
||||
int32_t fCount;
|
||||
// computed from phase
|
||||
SkScalar fInitialDashLength;
|
||||
int32_t fInitialDashIndex;
|
||||
SkScalar fIntervalLength;
|
||||
bool fScaleToFit;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
#ifndef SkTDeque_DEFINED
|
||||
#define SkTDeque_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
template <typename T> struct sk_trait_trivial_constructor { enum { value = false }; };
|
||||
template <typename T> struct sk_trait_trivial_destructor { enum { value = false }; };
|
||||
template <typename T> struct sk_trait_trivial_copy { enum { value = false }; };
|
||||
template <typename T> struct sk_trait_trivial_assign { enum { value = false }; };
|
||||
|
||||
template <typename T> struct sk_traits {
|
||||
enum {
|
||||
has_trivial_constructor = sk_trait_trivial_constructor<T>::value,
|
||||
has_trivial_destructor = sk_trait_trivial_destructor<T>::value,
|
||||
has_trivial_copy = sk_trait_trivial_copy<T>::value,
|
||||
has_trivial_assign = sk_trait_trivial_assign<T>::value
|
||||
};
|
||||
};
|
||||
|
||||
#define SK_SET_BASIC_TRAITS(T) \
|
||||
template <> struct sk_trait_trivial_constructor<T> { enum { value = true }; }; \
|
||||
template <> struct sk_trait_trivial_destructor<T> { enum { value = true }; }; \
|
||||
template <> struct sk_trait_trivial_copy<T> { enum { value = true }; }; \
|
||||
template <> struct sk_trait_trivial_assign<T> { enum { value = true }; }
|
||||
|
||||
#define SK_SET_TYPE_TRAITS(T, ctor, dtor, copy, asgn) \
|
||||
template <> struct sk_trait_trivial_constructor<T> { enum { value = ctor }; }; \
|
||||
template <> struct sk_trait_trivial_destructor<T> { enum { value = dtor }; }; \
|
||||
template <> struct sk_trait_trivial_copy<T> { enum { value = copy }; }; \
|
||||
template <> struct sk_trait_trivial_assign<T> { enum { value = asgn }; }
|
||||
|
||||
#include <new>
|
||||
|
||||
class SkDeque {
|
||||
public:
|
||||
SkDeque(size_t elemSize);
|
||||
SkDeque(size_t elemSize, void* storage, size_t storageSize);
|
||||
~SkDeque();
|
||||
|
||||
bool empty() const { return fCount == 0; }
|
||||
int count() const { return fCount; }
|
||||
|
||||
const void* front() const;
|
||||
const void* back() const;
|
||||
|
||||
void* front()
|
||||
{
|
||||
return (void*)((const SkDeque*)this)->front();
|
||||
}
|
||||
void* back()
|
||||
{
|
||||
return (void*)((const SkDeque*)this)->back();
|
||||
}
|
||||
|
||||
void* push_front();
|
||||
void* push_back();
|
||||
|
||||
void pop_front();
|
||||
void pop_back();
|
||||
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
|
||||
private:
|
||||
struct Head;
|
||||
|
||||
public:
|
||||
class Iter {
|
||||
public:
|
||||
Iter(const SkDeque& d);
|
||||
void* next();
|
||||
|
||||
private:
|
||||
SkDeque::Head* fHead;
|
||||
char* fPos;
|
||||
size_t fElemSize;
|
||||
};
|
||||
|
||||
private:
|
||||
Head* fFront;
|
||||
Head* fBack;
|
||||
size_t fElemSize;
|
||||
void* fInitialStorage;
|
||||
int fCount;
|
||||
|
||||
friend class Iter;
|
||||
};
|
||||
|
||||
template <typename T> class SkTDeque {
|
||||
public:
|
||||
SkTDeque() : fD(sizeof(T)) {}
|
||||
SkTDeque(T storage[], int count) : fD(sizeof(T), storage, count * sizeof(T)) {}
|
||||
inline ~SkTDeque();
|
||||
|
||||
bool empty() const { return fD.empty(); }
|
||||
int count() const { return fD.count(); }
|
||||
|
||||
T* front() { return (T*)fD.front(); }
|
||||
const T* front() const { return (const T*)fD.front(); }
|
||||
T* back() { return (T*)fD.back(); }
|
||||
const T* back() const { return (const T*)fD.back(); }
|
||||
|
||||
T* push_front()
|
||||
{
|
||||
T* front = (T*)fD.push_front();
|
||||
if (!sk_traits<T>::has_trivial_constructor) {
|
||||
new(front) T();
|
||||
}
|
||||
return front;
|
||||
}
|
||||
T* push_back()
|
||||
{
|
||||
T* back = (T*)fD.push_back();
|
||||
if (!sk_traits<T>::has_trivial_constructor) {
|
||||
new(back) T();
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
T* push_front(const T& value)
|
||||
{
|
||||
T* front = (T*)fD.push_front();
|
||||
if (sk_traits<T>::has_trivial_copy) {
|
||||
*front = value;
|
||||
}
|
||||
else {
|
||||
new(front) T(value);
|
||||
}
|
||||
return front;
|
||||
}
|
||||
T* push_back(const T& value)
|
||||
{
|
||||
T* back = (T*)fD.push_back();
|
||||
if (sk_traits<T>::has_trivial_copy) {
|
||||
*back = value;
|
||||
}
|
||||
else {
|
||||
new(back) T(value);
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
void pop_front()
|
||||
{
|
||||
if (!sk_traits<T>::has_trivial_destructor) {
|
||||
this->front()->~T();
|
||||
}
|
||||
fD.pop_front();
|
||||
}
|
||||
void pop_back()
|
||||
{
|
||||
if (!sk_traits<T>::has_trivial_destructor) {
|
||||
this->back()->~T();
|
||||
}
|
||||
fD.pop_back();
|
||||
}
|
||||
|
||||
class Iter : private SkDeque::Iter {
|
||||
public:
|
||||
Iter(const SkTDeque<T>& d) : SkDeque::Iter(d.fD) {}
|
||||
T* next() { return (T*)SkDeque::Iter::next(); }
|
||||
};
|
||||
|
||||
private:
|
||||
SkDeque fD;
|
||||
|
||||
friend class Iter;
|
||||
};
|
||||
|
||||
template <size_t COUNT, typename T> class SkSTDeque : public SkTDeque<T> {
|
||||
public:
|
||||
SkSTDeque() : SkTDeque<T>((T*)fStorage, COUNT) {}
|
||||
|
||||
private:
|
||||
uint32_t fStorage[SkAlign4(COUNT * sizeof(T))];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T> inline SkTDeque<T>::~SkTDeque()
|
||||
{
|
||||
if (!sk_traits<T>::has_trivial_destructor)
|
||||
{
|
||||
Iter iter(*this);
|
||||
T* t;
|
||||
while ((t = iter.next()) != nil) {
|
||||
t->~T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,158 @@
|
|||
#ifndef SkDescriptor_DEFINED
|
||||
#define SkDescriptor_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkDescriptor {
|
||||
public:
|
||||
static size_t ComputeOverhead(int entryCount)
|
||||
{
|
||||
SkASSERT(entryCount >= 0);
|
||||
return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
|
||||
}
|
||||
|
||||
static SkDescriptor* Alloc(size_t length)
|
||||
{
|
||||
SkASSERT(SkAlign4(length) == length);
|
||||
SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length);
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void Free(SkDescriptor* desc)
|
||||
{
|
||||
sk_free(desc);
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
fLength = sizeof(SkDescriptor);
|
||||
fCount = 0;
|
||||
}
|
||||
|
||||
U32 getLength() const { return fLength; }
|
||||
|
||||
void* addEntry(U32 tag, U32 length, const void* data = nil)
|
||||
{
|
||||
SkASSERT(tag);
|
||||
SkASSERT(SkAlign4(length) == length);
|
||||
SkASSERT(this->findEntry(tag, nil) == nil);
|
||||
|
||||
Entry* entry = (Entry*)((char*)this + fLength);
|
||||
entry->fTag = tag;
|
||||
entry->fLen = length;
|
||||
if (data)
|
||||
memcpy(entry + 1, data, length);
|
||||
|
||||
fCount += 1;
|
||||
fLength += sizeof(Entry) + length;
|
||||
return (entry + 1); // return its data
|
||||
}
|
||||
|
||||
void computeChecksum()
|
||||
{
|
||||
fChecksum = SkDescriptor::ComputeChecksum(this);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void assertChecksum() const
|
||||
{
|
||||
SkASSERT(fChecksum == SkDescriptor::ComputeChecksum(this));
|
||||
}
|
||||
#endif
|
||||
|
||||
const void* findEntry(U32 tag, U32* length) const
|
||||
{
|
||||
const Entry* entry = (const Entry*)(this + 1);
|
||||
int count = fCount;
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
if (entry->fTag == tag)
|
||||
{
|
||||
if (length)
|
||||
*length = entry->fLen;
|
||||
return entry + 1;
|
||||
}
|
||||
entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
SkDescriptor* copy() const
|
||||
{
|
||||
SkDescriptor* desc = SkDescriptor::Alloc(fLength);
|
||||
memcpy(desc, this, fLength);
|
||||
return desc;
|
||||
}
|
||||
|
||||
friend bool operator==(const SkDescriptor& a, const SkDescriptor& b)
|
||||
{
|
||||
return a.fChecksum == b.fChecksum &&
|
||||
a.fLength == b.fLength &&
|
||||
// this assumes that fCount is the beginning of the rest of the descriptor
|
||||
// (after fCheckSum and fLength)
|
||||
memcmp(&a.fCount, &b.fCount, a.fLength - 2*sizeof(U32)) == 0;
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
U32 fTag;
|
||||
U32 fLen;
|
||||
};
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
U32 getChecksum() const { return fChecksum; }
|
||||
U32 getCount() const { return fCount; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
U32 fChecksum; // must be first
|
||||
U32 fLength; // must be second
|
||||
U32 fCount;
|
||||
|
||||
static U32 ComputeChecksum(const SkDescriptor* desc)
|
||||
{
|
||||
const U32* ptr = (const U32*)desc + 1; // skip the checksum field
|
||||
const U32* stop = (const U32*)((const char*)desc + desc->fLength);
|
||||
U32 sum = 0;
|
||||
|
||||
SkASSERT(ptr < stop);
|
||||
do {
|
||||
sum = (sum << 1) | (sum >> 31);
|
||||
sum += *ptr++;
|
||||
} while (ptr < stop);
|
||||
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
#include "SkScalerContext.h"
|
||||
|
||||
class SkAutoDescriptor {
|
||||
public:
|
||||
SkAutoDescriptor(size_t size)
|
||||
{
|
||||
if (size <= kStorageSize)
|
||||
fDesc = (SkDescriptor*)fStorage;
|
||||
else
|
||||
fDesc = SkDescriptor::Alloc(size);
|
||||
}
|
||||
~SkAutoDescriptor()
|
||||
{
|
||||
if (fDesc != (SkDescriptor*)fStorage)
|
||||
SkDescriptor::Free(fDesc);
|
||||
}
|
||||
SkDescriptor* getDesc() const { return fDesc; }
|
||||
private:
|
||||
enum {
|
||||
kStorageSize = sizeof(SkDescriptor)
|
||||
+ sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec) // for rec
|
||||
+ sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface
|
||||
+ 32 // slop for occational small extras
|
||||
};
|
||||
SkDescriptor* fDesc;
|
||||
U32 fStorage[kStorageSize >> 2];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef SkDiscretePathEffect_DEFINED
|
||||
#define SkDiscretePathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkDiscretePathEffect
|
||||
|
||||
This path effect chops a path into discrete segments, and randomly displaces them.
|
||||
*/
|
||||
class SkDiscretePathEffect : public SkPathEffect {
|
||||
public:
|
||||
/** Break the path into segments of segLength length, and randomly move the endpoints
|
||||
away from the original path by a maximum of deviation.
|
||||
Note: works on filled or framed paths
|
||||
*/
|
||||
SkDiscretePathEffect(SkScalar segLength, SkScalar deviation);
|
||||
|
||||
// overrides for SkPathEffect
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkWBuffer&);
|
||||
|
||||
protected:
|
||||
SkDiscretePathEffect(SkRBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar fSegLength, fPerterb;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef SK_DRAW_EXTRA_PATH_EFFECT_H
|
||||
#define SK_DRAW_EXTRA_PATH_EFFECT_H
|
||||
class SkAnimator;
|
||||
void InitializeSkExtraPathEffects(SkAnimator* animator);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef SkEmbossMaskFilter_DEFINED
|
||||
#define SkEmbossMaskFilter_DEFINED
|
||||
|
||||
#include "SkMaskFilter.h"
|
||||
|
||||
/** \class SkEmbossMaskFilter
|
||||
|
||||
This mask filter creates a 3D emboss look, by specifying a light and blur amount.
|
||||
*/
|
||||
class SkEmbossMaskFilter : public SkMaskFilter {
|
||||
public:
|
||||
struct Light {
|
||||
SkScalar fDirection[3]; // x,y,z
|
||||
U16 fPad;
|
||||
U8 fAmbient;
|
||||
U8 fSpecular; // exponent, 4.4 right now
|
||||
};
|
||||
|
||||
SkEmbossMaskFilter(const Light& light, SkScalar blurRadius);
|
||||
|
||||
// overrides from SkMaskFilter
|
||||
// This method is not exported to java.
|
||||
virtual SkMask::Format getFormat();
|
||||
// This method is not exported to java.
|
||||
virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkPoint16* margin);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkWBuffer&);
|
||||
|
||||
protected:
|
||||
SkEmbossMaskFilter(SkRBuffer&);
|
||||
|
||||
private:
|
||||
Light fLight;
|
||||
SkScalar fBlurRadius;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
|
||||
typedef SkMaskFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
#ifndef SkEvent_DEFINED
|
||||
#define SkEvent_DEFINED
|
||||
|
||||
#include "SkDOM.h"
|
||||
#include "SkMetaData.h"
|
||||
#include "SkString.h"
|
||||
|
||||
//class SkOSWindow;
|
||||
|
||||
/** Unique 32bit id used to identify an instance of SkEventSink. When events are
|
||||
posted, they are posted to a specific sinkID. When it is time to dispatch the
|
||||
event, the sinkID is used to find the specific SkEventSink object. If it is found,
|
||||
its doEvent() method is called with the event.
|
||||
*/
|
||||
typedef U32 SkEventSinkID;
|
||||
|
||||
/** \class SkEvent
|
||||
|
||||
SkEvents are used to communicate type-safe information to SkEventSinks.
|
||||
SkEventSinks (including SkViews) each have a unique ID, which is stored
|
||||
in an event. This ID is used to target the event once it has been "posted".
|
||||
*/
|
||||
class SkEvent {
|
||||
public:
|
||||
/** Default construct, creating an empty event.
|
||||
*/
|
||||
SkEvent();
|
||||
/** Construct a new event with the specified type.
|
||||
*/
|
||||
explicit SkEvent(const SkString& type);
|
||||
/** Construct a new event with the specified type.
|
||||
*/
|
||||
explicit SkEvent(const char type[]);
|
||||
/** Construct a new event by copying the fields from the src event.
|
||||
*/
|
||||
SkEvent(const SkEvent& src);
|
||||
~SkEvent();
|
||||
|
||||
// /** Return the event's type (will never be nil) */
|
||||
// const char* getType() const;
|
||||
/** Copy the event's type into the specified SkString parameter */
|
||||
void getType(SkString* str) const;
|
||||
/** Returns true if the event's type matches exactly the specified type (case sensitive) */
|
||||
bool isType(const SkString& str) const;
|
||||
/** Returns true if the event's type matches exactly the specified type (case sensitive) */
|
||||
bool isType(const char type[], size_t len = 0) const;
|
||||
/** Set the event's type to the specified string.
|
||||
In XML, use the "type" attribute.
|
||||
*/
|
||||
void setType(const SkString&);
|
||||
/** Set the event's type to the specified string.
|
||||
In XML, use the "type" attribute.
|
||||
*/
|
||||
void setType(const char type[], size_t len = 0);
|
||||
|
||||
/** Return the event's unnamed 32bit field. Default value is 0 */
|
||||
U32 getFast32() const { return f32; }
|
||||
/** Set the event's unnamed 32bit field. In XML, use
|
||||
the subelement <data fast32=... />
|
||||
*/
|
||||
void setFast32(uint32_t x) { f32 = x; }
|
||||
|
||||
/** Return true if the event contains the named 32bit field, and return the field
|
||||
in value (if value is non-nil). If there is no matching named field, return false
|
||||
and ignore the value parameter.
|
||||
*/
|
||||
bool findS32(const char name[], int32_t* value = nil) const { return fMeta.findS32(name, value); }
|
||||
/** Return true if the event contains the named SkScalar field, and return the field
|
||||
in value (if value is non-nil). If there is no matching named field, return false
|
||||
and ignore the value parameter.
|
||||
*/
|
||||
bool findScalar(const char name[], SkScalar* value = nil) const { return fMeta.findScalar(name, value); }
|
||||
/** Return true if the event contains the named SkScalar field, and return the fields
|
||||
in value[] (if value is non-nil), and return the number of SkScalars in count (if count is non-nil).
|
||||
If there is no matching named field, return false and ignore the value and count parameters.
|
||||
*/
|
||||
const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = nil) const { return fMeta.findScalars(name, count, values); }
|
||||
/** Return the value of the named string field, or if no matching named field exists, return nil.
|
||||
*/
|
||||
const char* findString(const char name[]) const { return fMeta.findString(name); }
|
||||
/** Return true if the event contains the named pointer field, and return the field
|
||||
in value (if value is non-nil). If there is no matching named field, return false
|
||||
and ignore the value parameter.
|
||||
*/
|
||||
bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); }
|
||||
bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); }
|
||||
|
||||
/** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */
|
||||
bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); }
|
||||
/** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */
|
||||
bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); }
|
||||
/** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */
|
||||
bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); }
|
||||
/** Returns true if ethe event contains the named pointer field, and if it equals the specified value */
|
||||
bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); }
|
||||
bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); }
|
||||
|
||||
/** Add/replace the named 32bit field to the event. In XML use the subelement <data name=... s32=... /> */
|
||||
void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); }
|
||||
/** Add/replace the named SkScalar field to the event. In XML use the subelement <data name=... scalar=... /> */
|
||||
void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); }
|
||||
/** Add/replace the named SkScalar[] field to the event. */
|
||||
SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nil) { return fMeta.setScalars(name, count, values); }
|
||||
/** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
|
||||
void setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); }
|
||||
/** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
|
||||
void setString(const char name[], const char value[]) { fMeta.setString(name, value); }
|
||||
/** Add/replace the named pointer field to the event. There is no XML equivalent for this call */
|
||||
void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); }
|
||||
void setBool(const char name[], bool value) { fMeta.setBool(name, value); }
|
||||
|
||||
/** Return the underlying metadata object */
|
||||
SkMetaData& getMetaData() { return fMeta; }
|
||||
/** Return the underlying metadata object */
|
||||
const SkMetaData& getMetaData() const { return fMeta; }
|
||||
|
||||
void tron() { SkDEBUGCODE(fDebugTrace = true;) }
|
||||
void troff() { SkDEBUGCODE(fDebugTrace = false;) }
|
||||
bool isDebugTrace() const
|
||||
{
|
||||
#ifdef SK_DEBUG
|
||||
return fDebugTrace;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Call this to initialize the event from the specified XML node */
|
||||
void inflate(const SkDOM&, const SkDOM::Node*);
|
||||
|
||||
SkDEBUGCODE(void dump(const char title[] = nil);)
|
||||
|
||||
/** Post the specified event to the event queue, targeting the specified eventsink, with an optional
|
||||
delay. The event must be dynamically allocated for this. It cannot be a global or on the stack.
|
||||
After this call, ownership is transfered to the system, so the caller must not retain
|
||||
the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
|
||||
*/
|
||||
static bool Post(SkEvent* evt, SkEventSinkID targetID, SkMSec delay = 0);
|
||||
/** Post the specified event to the event queue, targeting the specified eventsink, to be delivered on/after the
|
||||
specified millisecond time. The event must be dynamically allocated for this. It cannot be a global or on the stack.
|
||||
After this call, ownership is transfered to the system, so the caller must not retain
|
||||
the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
|
||||
*/
|
||||
static bool PostTime(SkEvent* evt, SkEventSinkID targetID, SkMSec time);
|
||||
|
||||
/** Helper method for calling SkEvent::PostTime(this, ...), where the caller specifies a delay.
|
||||
The real "time" will be computed automatically by sampling the clock and adding its value
|
||||
to delay.
|
||||
*/
|
||||
bool post(SkEventSinkID sinkID, SkMSec delay = 0)
|
||||
{
|
||||
return SkEvent::Post(this, sinkID, delay);
|
||||
}
|
||||
|
||||
void postTime(SkEventSinkID sinkID, SkMSec time)
|
||||
{
|
||||
SkEvent::PostTime(this, sinkID, time);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
/** Porting layer must call these functions **/
|
||||
///////////////////////////////////////////////
|
||||
|
||||
/** Global initialization function for the SkEvent system. Should be called exactly
|
||||
once before any other event method is called, and should be called after the
|
||||
call to SkGraphics::Init().
|
||||
*/
|
||||
static void Init();
|
||||
/** Global cleanup function for the SkEvent system. Should be called exactly once after
|
||||
all event methods have been called, and should be called before calling SkGraphics::Term().
|
||||
*/
|
||||
static void Term();
|
||||
|
||||
/** Call this to process one event from the queue. If it returns true, there are more events
|
||||
to process.
|
||||
*/
|
||||
static bool ProcessEvent();
|
||||
/** Call this whenever the requested timer has expired (requested by a call to SetQueueTimer).
|
||||
It will post any delayed events whose time as "expired" onto the event queue.
|
||||
It may also call SignalQueueTimer() and SignalNonEmptyQueue().
|
||||
*/
|
||||
static void ServiceQueueTimer();
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
/** Porting layer must implement these functions **/
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
/** Called whenever an SkEvent is posted to an empty queue, so that the OS
|
||||
can be told to later call Dequeue().
|
||||
*/
|
||||
static void SignalNonEmptyQueue();
|
||||
/** Called whenever the delay until the next delayed event changes. If zero is
|
||||
passed, then there are no more queued delay events.
|
||||
*/
|
||||
static void SignalQueueTimer(SkMSec delay);
|
||||
|
||||
#ifndef SK_USE_WXWIDGETS
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
#elif defined(SK_BUILD_FOR_UNIXx)
|
||||
static U32 HandleTimer(U32, void*);
|
||||
static bool WndProc(Display*, Window, XEvent&);
|
||||
#endif
|
||||
#else
|
||||
// Don't know yet what this will be
|
||||
//static bool CustomEvent();
|
||||
#endif
|
||||
|
||||
private:
|
||||
SkMetaData fMeta;
|
||||
mutable char* fType; // may be characters with low bit set to know that it is not a pointer
|
||||
U32 f32;
|
||||
SkDEBUGCODE(bool fDebugTrace;)
|
||||
|
||||
// these are for our implementation of the event queue
|
||||
SkEventSinkID fTargetID;
|
||||
SkMSec fTime;
|
||||
SkEvent* fNextEvent; // either in the delay or normal event queue
|
||||
void initialize(const char* type, size_t typeLen);
|
||||
|
||||
static bool Enqueue(SkEvent* evt);
|
||||
static SkMSec EnqueueTime(SkEvent* evt, SkMSec time);
|
||||
static SkEvent* Dequeue(SkEventSinkID* targetID);
|
||||
static bool QHasEvents();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef SkEventSink_DEFINED
|
||||
#define SkEventSink_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkEvent.h"
|
||||
|
||||
struct SkTagList;
|
||||
|
||||
/** \class SkEventSink
|
||||
|
||||
SkEventSink is the base class for all objects that receive SkEvents.
|
||||
*/
|
||||
class SkEventSink : public SkRefCnt {
|
||||
public:
|
||||
SkEventSink();
|
||||
virtual ~SkEventSink();
|
||||
|
||||
/** Returns this eventsink's unique ID. Use this to post SkEvents to
|
||||
this eventsink.
|
||||
*/
|
||||
SkEventSinkID getSinkID() const { return fID; }
|
||||
|
||||
/** Call this to pass an event to this object for processing. Returns true if the
|
||||
event was handled.
|
||||
*/
|
||||
bool doEvent(const SkEvent&);
|
||||
/** Returns true if the sink (or one of its subclasses) understands the event as a query.
|
||||
If so, the sink may modify the event to communicate its "answer".
|
||||
*/
|
||||
bool doQuery(SkEvent* query);
|
||||
|
||||
/** Add sinkID to the list of listeners, to receive events from calls to sendToListeners()
|
||||
and postToListeners(). If sinkID already exists in the listener list, no change is made.
|
||||
*/
|
||||
void addListenerID(SkEventSinkID sinkID);
|
||||
/** Copy listeners from one event sink to another, typically from parent to child.
|
||||
@param from the event sink to copy the listeners from
|
||||
*/
|
||||
void copyListeners(const SkEventSink& from);
|
||||
/** Remove sinkID from the list of listeners. If sinkID does not appear in the list,
|
||||
no change is made.
|
||||
*/
|
||||
void removeListenerID(SkEventSinkID);
|
||||
/** Returns true if there are 1 or more listeners attached to this eventsink
|
||||
*/
|
||||
bool hasListeners() const;
|
||||
/** Posts a copy of evt to each of the eventsinks in the lisener list.
|
||||
*/
|
||||
void postToListeners(const SkEvent& evt, SkMSec delay = 0);
|
||||
|
||||
enum EventResult {
|
||||
kHandled_EventResult, //!< the eventsink returned true from its doEvent method
|
||||
kNotHandled_EventResult, //!< the eventsink returned false from its doEvent method
|
||||
kSinkNotFound_EventResult //!< no matching eventsink was found for the event's getSink().
|
||||
};
|
||||
/** DoEvent handles searching for an eventsink object that matches the targetID.
|
||||
If one is found, it calls the sink's doEvent method, returning
|
||||
either kHandled_EventResult or kNotHandled_EventResult. If no matching
|
||||
eventsink is found, kSinkNotFound_EventResult is returned.
|
||||
*/
|
||||
static EventResult DoEvent(const SkEvent&, SkEventSinkID targetID);
|
||||
|
||||
/** Returns the matching eventsink, or nil if not found
|
||||
*/
|
||||
static SkEventSink* FindSink(SkEventSinkID);
|
||||
|
||||
protected:
|
||||
/** Override this to handle events in your subclass. Be sure to call the inherited version
|
||||
for events that you don't handle.
|
||||
*/
|
||||
virtual bool onEvent(const SkEvent&);
|
||||
virtual bool onQuery(SkEvent*);
|
||||
|
||||
SkTagList* findTagList(U8CPU tag) const;
|
||||
void addTagList(SkTagList*);
|
||||
void removeTagList(U8CPU tag);
|
||||
|
||||
private:
|
||||
SkEventSinkID fID;
|
||||
SkTagList* fTagHead;
|
||||
|
||||
// for our private link-list
|
||||
SkEventSink* fNextSink;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef SkFlattenable_DEFINED
|
||||
#define SkFlattenable_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBuffer.h"
|
||||
|
||||
/** \class SkFlattenable
|
||||
|
||||
SkFlattenable is the base class for objects that need to be flattened
|
||||
into a data stream for either transport or as part of the key to the
|
||||
font cache.
|
||||
*/
|
||||
// This class is not exported to java.
|
||||
class SkFlattenable : public SkRefCnt {
|
||||
public:
|
||||
typedef SkFlattenable* (*Factory)(SkRBuffer&);
|
||||
|
||||
virtual Factory getFactory();
|
||||
virtual void flatten(SkWBuffer&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef SkFontCodec_DEFINED
|
||||
#define SkFontCodec_DEFINED
|
||||
|
||||
#include "SkSFNT.h"
|
||||
|
||||
class SkFontCodec {
|
||||
public:
|
||||
static void Compress(SkSFNT& font, const char fileName[]);
|
||||
|
||||
/* Format is [count] + [instruction, bitcount] * count
|
||||
Allocated with sk_malloc()
|
||||
*/
|
||||
static U8* BuildInstrHuffmanTable(SkSFNT&);
|
||||
static U8* BuildOutlineHuffmanTable(SkSFNT& font);
|
||||
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef SkFontHost_DEFINED
|
||||
#define SkFontHost_DEFINED
|
||||
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
class SkDescriptor;
|
||||
|
||||
/** \class SkFontHost
|
||||
|
||||
This class is ported to each environment. It is responsible for bridging the gap
|
||||
between SkTypeface and the resulting platform-specific instance of SkScalerContext.
|
||||
*/
|
||||
class SkFontHost {
|
||||
public:
|
||||
/** Return a subclass of SkTypeface, one that can be used by your scalaracontext
|
||||
(returned by SkFontHost::CreateScalarContext).
|
||||
1) If family is nil, use name.
|
||||
2) If name is nil, use family.
|
||||
3) If both are nil, use default family.
|
||||
*/
|
||||
static SkTypeface* CreateTypeface(const SkTypeface* family, const char name[], SkTypeface::Style);
|
||||
/** Given a typeface (or nil), return the number of bytes needed to flatten it
|
||||
into a buffer, for the purpose of communicating information to the
|
||||
scalercontext. If buffer is nil, then ignore it but still return the number
|
||||
of bytes that would be written.
|
||||
*/
|
||||
static uint32_t FlattenTypeface(const SkTypeface* face, void* buffer);
|
||||
/** Return a subclass of SkScalarContext
|
||||
*/
|
||||
static SkScalerContext* CreateScalerContext(const SkDescriptor* desc);
|
||||
|
||||
enum ScalerContextID {
|
||||
kMissing_ScalerContextID = SK_UnknownAuxScalerContextID,
|
||||
kMax_ScalerContextID = SK_MaxAuxScalerContextID
|
||||
};
|
||||
static ScalerContextID FindScalerContextIDForUnichar(int32_t unichar);
|
||||
|
||||
static SkScalerContext* CreateScalerContextFromID(ScalerContextID, const SkScalerContext::Rec&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef SkGlobals_DEFINED
|
||||
#define SkGlobals_DEFINED
|
||||
|
||||
#include "SkThread.h"
|
||||
|
||||
class SkGlobals {
|
||||
public:
|
||||
class Rec {
|
||||
public:
|
||||
virtual ~Rec();
|
||||
private:
|
||||
Rec* fNext;
|
||||
U32 fTag;
|
||||
|
||||
friend class SkGlobals;
|
||||
};
|
||||
|
||||
/** Look for a matching Rec for the specified tag. If one is found, return it.
|
||||
If one is not found, if create_proc is nil, return nil, else
|
||||
call the proc, and if it returns a Rec, add it to the global list
|
||||
and return it.
|
||||
|
||||
create_proc can NOT call back into SkGlobals::Find (it would deadlock)
|
||||
*/
|
||||
static Rec* Find(U32 tag, Rec* (*create_proc)());
|
||||
/** Helper for Find, when you want to assert that the Rec is already in the list
|
||||
*/
|
||||
static Rec* Get(U32 tag)
|
||||
{
|
||||
Rec* rec = SkGlobals::Find(tag, nil);
|
||||
SkASSERT(rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
// used by porting layer
|
||||
struct BootStrap {
|
||||
SkMutex fMutex;
|
||||
Rec* fHead;
|
||||
};
|
||||
|
||||
private:
|
||||
static void Init();
|
||||
static void Term();
|
||||
friend class SkGraphics;
|
||||
|
||||
// This last function is implemented in the porting layer
|
||||
static BootStrap& GetBootStrap();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef SkGradientShader_DEFINED
|
||||
#define SkGradientShader_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkUnitMapper;
|
||||
|
||||
/** \class SkGradientShader
|
||||
|
||||
SkGradientShader hosts factories for creating subclasses of SkShader that
|
||||
render linear and radial gradients.
|
||||
*/
|
||||
class SkGradientShader : public SkShader {
|
||||
public:
|
||||
/** Returns a shader that generates a linear gradient between the two
|
||||
specified points.
|
||||
<p />
|
||||
CreateLinear returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for count to be < 2.
|
||||
@param pts The start and end points for the gradient.
|
||||
@param colors The array[count] of colors, to be distributed between the two points
|
||||
@param pos May be NULL. array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the start and end point.
|
||||
@param count Must be >=2. The number of colors (and pos if not NULL) entries.
|
||||
@param mode The tiling mode
|
||||
@param mapper May be NULL. Callback to modify the spread of the colors.
|
||||
*/
|
||||
static SkShader* CreateLinear( const SkPoint pts[2],
|
||||
const SkColor colors[], const SkScalar pos[], int count,
|
||||
TileMode mode,
|
||||
SkUnitMapper* mapper = NULL);
|
||||
|
||||
/** Returns a shader that generates a radial gradient given the center and radius.
|
||||
<p />
|
||||
CreateRadial returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for colorCount to be < 2, or for radius to be <= 0.
|
||||
@param center The center of the circle for this gradient
|
||||
@param radius Must be positive. The radius of the circle for this gradient
|
||||
@param colors The array[count] of colors, to be distributed between the center and edge of the circle
|
||||
@param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the center and edge of the circle.
|
||||
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
|
||||
@param mode The tiling mode
|
||||
@param mapper May be NULL. Callback to modify the spread of the colors.
|
||||
*/
|
||||
static SkShader* CreateRadial( const SkPoint& center, SkScalar radius,
|
||||
const SkColor colors[], const SkScalar pos[], int count,
|
||||
TileMode mode,
|
||||
SkUnitMapper* mapper = NULL);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef SkGraphics_DEFINED
|
||||
#define SkGraphics_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkGraphics {
|
||||
public:
|
||||
static void Init(bool runUnitTests);
|
||||
static void Term();
|
||||
|
||||
/** Call this if the heap that the graphics engine uses is low on memory.
|
||||
It will attempt to free some of its caches. Returns true if it was
|
||||
able to, or false if it could do nothing.
|
||||
|
||||
This may be called from any thread, and guarantees not to call
|
||||
new or sk_malloc (though it will hopefully call delete and/or sk_free).
|
||||
It also will never throw an exception.
|
||||
*/
|
||||
static bool FreeCaches(size_t bytesNeeded);
|
||||
|
||||
private:
|
||||
/** This is automatically called by SkGraphics::Init(), and must be
|
||||
implemented by the host OS. This allows the host OS to register a callback
|
||||
with the C++ runtime to call SkGraphics::FreeCaches()
|
||||
*/
|
||||
static void InstallNewHandler();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
#ifndef SkImageDecoder_DEFINED
|
||||
#define SkImageDecoder_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkBitmapRef.h"
|
||||
|
||||
class SkStream;
|
||||
|
||||
/** \class SkImageDecoder
|
||||
|
||||
Base class for decoding compressed images into a SkBitmap
|
||||
*/
|
||||
class SkImageDecoder {
|
||||
public:
|
||||
virtual ~SkImageDecoder();
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
static bool DecodeFile(const char file[], SkBitmap* bitmap,
|
||||
SkBitmap::Config pref = SkBitmap::kNo_Config);
|
||||
/** 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.
|
||||
*/
|
||||
static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap,
|
||||
SkBitmap::Config pref = SkBitmap::kNo_Config);
|
||||
/** 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.
|
||||
*/
|
||||
static bool DecodeStream(SkStream*, SkBitmap* bitmap,
|
||||
SkBitmap::Config pref = SkBitmap::kNo_Config);
|
||||
|
||||
/** Decode the image stored at the specified URL, and store the result
|
||||
in bitmap. Return true for success or false on failure. The URL restrictions
|
||||
are device dependent. On Win32 and WinCE, the URL may be ftp, http or
|
||||
https.
|
||||
|
||||
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.
|
||||
*/
|
||||
static bool DecodeURL(const char url[], SkBitmap* bitmap,
|
||||
SkBitmap::Config pref = SkBitmap::kNo_Config);
|
||||
|
||||
/** 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:
|
||||
SkImageDecoder();
|
||||
|
||||
/** Given a stream, decode it into the specified bitmap.
|
||||
If the decoder can decompress the image, it should call setConfig() on the bitmap,
|
||||
and then call allocPixels(), which will allocated offscreen memory for the pixels.
|
||||
It can then set the pixels with the decompressed image. If the image cannot be
|
||||
decompressed, return false and leave the bitmap unchanged.
|
||||
*/
|
||||
virtual bool onDecode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref) = 0;
|
||||
|
||||
private:
|
||||
static SkImageDecoder* Factory(SkStream*);
|
||||
};
|
||||
|
||||
#ifdef SK_SUPPORT_IMAGE_ENCODE
|
||||
|
||||
class SkWStream;
|
||||
|
||||
class SkImageEncoder {
|
||||
public:
|
||||
enum Type {
|
||||
kJPEG_Type,
|
||||
kPNG_Type
|
||||
};
|
||||
static SkImageEncoder* Create(Type);
|
||||
|
||||
virtual ~SkImageEncoder();
|
||||
|
||||
/* Quality ranges from 0..100 */
|
||||
|
||||
bool encodeFile(const char file[], const SkBitmap&, int quality = 80);
|
||||
bool encodeStream(SkWStream*, const SkBitmap&, int quality = 80);
|
||||
|
||||
protected:
|
||||
virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0;
|
||||
};
|
||||
|
||||
#endif /* SK_SUPPORT_IMAGE_ENCODE */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef SkImageView_DEFINED
|
||||
#define SkImageView_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
#include "SkString.h"
|
||||
|
||||
class SkAnimator;
|
||||
class SkBitmap;
|
||||
struct 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; // nil or copy of caller's matrix ,,,,,
|
||||
union {
|
||||
SkAnimator* fAnim;
|
||||
SkBitmap* fBitmap;
|
||||
} fData;
|
||||
U8 fScaleType;
|
||||
SkBool8 fDataIsAnim; // as opposed to bitmap
|
||||
SkBool8 fUriIsValid;
|
||||
|
||||
void onUriChange();
|
||||
bool getDataBounds(SkRect* bounds);
|
||||
bool freeData();
|
||||
bool ensureUriIsLoaded();
|
||||
|
||||
typedef SkView INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef SkInterpolator_DEFINED
|
||||
#define SkInterpolator_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
|
||||
class SkInterpolatorBase {
|
||||
public:
|
||||
enum Result {
|
||||
kNormal_Result,
|
||||
kFreezeStart_Result,
|
||||
kFreezeEnd_Result
|
||||
};
|
||||
static SkScalar Blend(SkScalar t, SkScalar blend);
|
||||
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 no nil, returns the time (in milliseconds) of the
|
||||
first keyframe. If there are no keyframes, this parameter
|
||||
is ignored (left unchanged).
|
||||
@param endTime If no nil, 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 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 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
|
||||
};
|
||||
static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime, SkMSec nextTime, SkScalar blend);
|
||||
S16 fFrameCount;
|
||||
U8 fElemCount;
|
||||
U8 fFlags;
|
||||
SkScalar fRepeat;
|
||||
struct SkTimeCode {
|
||||
SkMSec fTime;
|
||||
SkScalar fBlend;
|
||||
};
|
||||
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[], SkScalar blend = SK_Scalar1);
|
||||
Result timeToValues(SkMSec time, SkScalar values[]) const;
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
private:
|
||||
SkScalar* fValues; // pointer into fStorage
|
||||
#ifdef SK_DEBUG
|
||||
SkScalar(* fScalarsArray)[10];
|
||||
#endif
|
||||
typedef SkInterpolatorBase INHERITED;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#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;
|
||||
};
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#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
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#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);
|
||||
}
|
||||
void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual Factory getFactory();
|
||||
virtual void flatten(SkWBuffer&);
|
||||
|
||||
protected:
|
||||
SkLayerRasterizer(SkRBuffer&);
|
||||
|
||||
// override from SkRasterizer
|
||||
virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
|
||||
const SkRect16* clipBounds,
|
||||
SkMask* mask, SkMask::CreateMode mode);
|
||||
|
||||
private:
|
||||
SkDeque fLayers;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
|
||||
typedef SkRasterizer INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,65 @@
|
|||
#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
|
||||
};
|
||||
|
||||
uint8_t* fImage;
|
||||
SkRect16 fBounds;
|
||||
uint16_t fRowBytes;
|
||||
uint8_t fFormat; // Format
|
||||
|
||||
/** Return the byte size of the mask, assuming only 1 plane.
|
||||
Does not account for k3D_Format. For that, use computeFormatImageSize()
|
||||
*/
|
||||
size_t computeImageSize() const;
|
||||
/** Return the byte size of the mask, taking into account
|
||||
any extra planes (e.g. k3D_Format).
|
||||
*/
|
||||
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 != nil);
|
||||
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 != nil);
|
||||
return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
|
||||
}
|
||||
|
||||
static uint8_t* AllocImage(size_t bytes);
|
||||
static void FreeImage(uint8_t* 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
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
#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 == nil, 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 == nil, dst should not allocate its image
|
||||
@param src the original image to be filtered.
|
||||
@param matrix the CTM
|
||||
@param margin if not nil, 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.
|
||||
@return true if the dst mask was correctly created.
|
||||
*/
|
||||
virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, SkPoint16* 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);
|
||||
|
||||
protected:
|
||||
// empty for now, but lets get our subclass to remember to init us for the future
|
||||
SkMaskFilter(SkRBuffer&) {}
|
||||
};
|
||||
|
||||
/** \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
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
#ifndef SkMetaData_DEFINED
|
||||
#define SkMetaData_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
|
||||
class SkMetaData {
|
||||
public:
|
||||
SkMetaData();
|
||||
SkMetaData(const SkMetaData& src);
|
||||
~SkMetaData();
|
||||
|
||||
SkMetaData& operator=(const SkMetaData& src);
|
||||
|
||||
void reset();
|
||||
|
||||
bool findS32(const char name[], int32_t* value = nil) const;
|
||||
bool findScalar(const char name[], SkScalar* value = nil) const;
|
||||
const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = nil) const;
|
||||
const char* findString(const char name[]) const;
|
||||
bool findPtr(const char name[], void** value = nil) const;
|
||||
bool findBool(const char name[], bool* value = nil) const;
|
||||
|
||||
bool hasS32(const char name[], int32_t value) const
|
||||
{
|
||||
int32_t v;
|
||||
return this->findS32(name, &v) && v == value;
|
||||
}
|
||||
bool hasScalar(const char name[], SkScalar value) const
|
||||
{
|
||||
SkScalar v;
|
||||
return this->findScalar(name, &v) && v == value;
|
||||
}
|
||||
bool hasString(const char name[], const char value[]) const
|
||||
{
|
||||
const char* v = this->findString(name);
|
||||
return v == nil && value == nil ||
|
||||
v != nil && value != nil && !strcmp(v, value);
|
||||
}
|
||||
bool hasPtr(const char name[], void* value) const
|
||||
{
|
||||
void* v;
|
||||
return this->findPtr(name, &v) && v == value;
|
||||
}
|
||||
bool hasBool(const char name[], bool value) const
|
||||
{
|
||||
bool v;
|
||||
return this->findBool(name, &v) && v == value;
|
||||
}
|
||||
|
||||
void setS32(const char name[], int32_t value);
|
||||
void setScalar(const char name[], SkScalar value);
|
||||
SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nil);
|
||||
void setString(const char name[], const char value[]);
|
||||
void setPtr(const char name[], void* value);
|
||||
void setBool(const char name[], bool value);
|
||||
|
||||
bool removeS32(const char name[]);
|
||||
bool removeScalar(const char name[]);
|
||||
bool removeString(const char name[]);
|
||||
bool removePtr(const char name[]);
|
||||
bool removeBool(const char name[]);
|
||||
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
|
||||
enum Type {
|
||||
kS32_Type,
|
||||
kScalar_Type,
|
||||
kString_Type,
|
||||
kPtr_Type,
|
||||
kBool_Type,
|
||||
|
||||
kTypeCount
|
||||
};
|
||||
|
||||
struct Rec;
|
||||
class Iter;
|
||||
friend class Iter;
|
||||
|
||||
class Iter {
|
||||
public:
|
||||
Iter() : fRec(nil) {}
|
||||
Iter(const SkMetaData&);
|
||||
|
||||
/** Reset the iterator, so that calling next() will return the first
|
||||
data element. This is done implicitly in the constructor.
|
||||
*/
|
||||
void reset(const SkMetaData&);
|
||||
|
||||
/** Each time next is called, it returns the name of the next data element,
|
||||
or nil when there are no more elements. If non-nil is returned, then the
|
||||
element's type is returned (if not nil), and the number of data values
|
||||
is returned in count (if not nil).
|
||||
*/
|
||||
const char* next(Type*, int* count);
|
||||
|
||||
private:
|
||||
Rec* fRec;
|
||||
};
|
||||
|
||||
public:
|
||||
struct Rec {
|
||||
Rec* fNext;
|
||||
uint16_t fDataCount; // number of elements
|
||||
uint8_t fDataLen; // sizeof a single element
|
||||
#ifdef SK_DEBUG
|
||||
Type fType;
|
||||
#else
|
||||
uint8_t fType;
|
||||
#endif
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
const char* fName;
|
||||
union {
|
||||
int32_t fS32;
|
||||
SkScalar fScalar;
|
||||
const char* fString;
|
||||
void* fPtr;
|
||||
bool fBool;
|
||||
} fData;
|
||||
#endif
|
||||
|
||||
const void* data() const { return (this + 1); }
|
||||
void* data() { return (this + 1); }
|
||||
const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
|
||||
char* name() { return (char*)this->data() + fDataLen * fDataCount; }
|
||||
|
||||
static Rec* Alloc(size_t);
|
||||
static void Free(Rec*);
|
||||
};
|
||||
Rec* fRec;
|
||||
|
||||
const Rec* find(const char name[], Type) const;
|
||||
void* set(const char name[], const void* data, size_t len, Type, int count);
|
||||
bool remove(const char name[], Type);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef SkNinePatch_DEFINED
|
||||
#define SkNinePatch_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
|
||||
class SkNinePatch {
|
||||
public:
|
||||
static void Draw(SkCanvas* canvas, const SkRect& dst,
|
||||
const SkBitmap& bitmap, const SkRect16& margin,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
static void Draw(SkCanvas* canvas, const SkRect& dst,
|
||||
const SkBitmap& bitmap, int cx, int cy,
|
||||
const SkPaint* paint = NULL);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright Skia Inc. 2004 - 2005
|
||||
//
|
||||
#ifndef SkOSFile_DEFINED
|
||||
#define SkOSFile_DEFINED
|
||||
|
||||
#include "SkString.h"
|
||||
|
||||
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
struct SkFILE;
|
||||
|
||||
enum SkFILE_Flags {
|
||||
kRead_SkFILE_Flag = 0x01,
|
||||
kWrite_SkFILE_Flag = 0x02
|
||||
};
|
||||
|
||||
SkFILE* sk_fopen(const char path[], SkFILE_Flags);
|
||||
void sk_fclose(SkFILE*);
|
||||
|
||||
size_t sk_fgetsize(SkFILE*);
|
||||
/** Return true if the file could seek back to the beginning
|
||||
*/
|
||||
bool sk_frewind(SkFILE*);
|
||||
|
||||
size_t sk_fread(void* buffer, size_t byteCount, SkFILE*);
|
||||
size_t sk_fwrite(const void* buffer, size_t byteCount, SkFILE*);
|
||||
void sk_fflush(SkFILE*);
|
||||
|
||||
int sk_fseek( SkFILE*, size_t, int );
|
||||
size_t sk_ftell( SkFILE* );
|
||||
|
||||
class SkOSFile {
|
||||
public:
|
||||
class Iter {
|
||||
public:
|
||||
Iter();
|
||||
Iter(const char path[], const char suffix[] = nil);
|
||||
~Iter();
|
||||
|
||||
void reset(const char path[], const char suffix[] = nil);
|
||||
bool next(SkString* name, bool getDir = false);
|
||||
|
||||
private:
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
HANDLE fHandle;
|
||||
U16* fPath16;
|
||||
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
|
||||
DIR* fDIR;
|
||||
SkString fPath, fSuffix;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
class SkUTF16_Str {
|
||||
public:
|
||||
SkUTF16_Str(const char src[]);
|
||||
~SkUTF16_Str()
|
||||
{
|
||||
sk_free(fStr);
|
||||
}
|
||||
const U16* get() const { return fStr; }
|
||||
|
||||
private:
|
||||
U16* fStr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef SkOSMenu_DEFINED
|
||||
#define SkOSMenu_DEFINED
|
||||
|
||||
#include "SkEvent.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkOSMenu {
|
||||
public:
|
||||
explicit SkOSMenu(const char title[]);
|
||||
~SkOSMenu();
|
||||
|
||||
const char* getTitle() const { return fTitle; }
|
||||
|
||||
void appendItem(const char title[], const char eventType[], S32 eventData);
|
||||
|
||||
// called by SkOSWindow when it receives an OS menu event
|
||||
int countItems() const;
|
||||
const char* getItem(int index, U32* cmdID) const;
|
||||
|
||||
SkEvent* createEvent(U32 os_cmd);
|
||||
|
||||
private:
|
||||
const char* fTitle;
|
||||
|
||||
struct Item {
|
||||
const char* fTitle;
|
||||
const char* fEventType;
|
||||
U32 fEventData;
|
||||
U32 fOSCmd; // internal
|
||||
};
|
||||
SkTDArray<Item> fItems;
|
||||
|
||||
// illegal
|
||||
SkOSMenu(const SkOSMenu&);
|
||||
SkOSMenu& operator=(const SkOSMenu&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef SkOSSound_DEFINED
|
||||
#define SkOSSound_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkOSSound {
|
||||
public:
|
||||
static void Play(const char path[]);
|
||||
static void Pause();
|
||||
static void Resume();
|
||||
static bool TogglePause(); // returns true if we are now playing, or false if we're now paused
|
||||
static void Stop();
|
||||
|
||||
// volume runs from 0 (silent) to 0xFF (max-volume)
|
||||
static U8 GetVolume();
|
||||
static void SetVolume(U8CPU volume);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef SkOSWindow_Mac_DEFINED
|
||||
#define SkOSWindow_Mac_DEFINED
|
||||
|
||||
#include "SkWindow.h"
|
||||
|
||||
class SkOSWindow : public SkWindow {
|
||||
public:
|
||||
SkOSWindow(void* hwnd);
|
||||
|
||||
void* getHWND() const { return fHWND; }
|
||||
void updateSize();
|
||||
|
||||
static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
|
||||
|
||||
static pascal OSStatus SkOSWindow::EventHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* userData );
|
||||
|
||||
protected:
|
||||
// overrides from SkWindow
|
||||
virtual void onHandleInval(const SkRect16&);
|
||||
// overrides from SkView
|
||||
virtual void onAddMenu(const SkOSMenu*);
|
||||
|
||||
private:
|
||||
void* fHWND;
|
||||
|
||||
void doPaint(void* ctx);
|
||||
|
||||
typedef SkWindow INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef SkOSWindow_Unix_DEFINED
|
||||
#define SkOSWindow_Unix_DEFINED
|
||||
|
||||
#include "SkWindow.h"
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
struct SkUnixWindow {
|
||||
Display* fDisplay;
|
||||
Window fWin;
|
||||
size_t fOSWin;
|
||||
};
|
||||
|
||||
class SkOSWindow : public SkWindow {
|
||||
public:
|
||||
SkOSWindow(Display* display, Window win);
|
||||
|
||||
void* getHWND() const { return (void*)fUnixWindow.fWin; }
|
||||
void* getDisplay() const { return (void*)fUnixWindow.fDisplay; }
|
||||
void* getUnixWindow() const { return (void*)&fUnixWindow; }
|
||||
void setSize(int width, int height);
|
||||
void updateSize();
|
||||
|
||||
static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
|
||||
|
||||
static bool WndProc(SkUnixWindow* w, XEvent &e);
|
||||
|
||||
protected:
|
||||
// overrides from SkWindow
|
||||
virtual void onHandleInval(const SkRect16&);
|
||||
// overrides from SkView
|
||||
virtual void onAddMenu(const SkOSMenu*);
|
||||
|
||||
private:
|
||||
SkUnixWindow fUnixWindow;
|
||||
|
||||
void doPaint();
|
||||
|
||||
void* fMBar;
|
||||
|
||||
typedef SkWindow INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef SkOSWindow_Win_DEFINED
|
||||
#define SkOSWindow_Win_DEFINED
|
||||
|
||||
#include "SkWindow.h"
|
||||
|
||||
class SkOSWindow : public SkWindow {
|
||||
public:
|
||||
SkOSWindow(void* hwnd);
|
||||
|
||||
void* getHWND() const { return fHWND; }
|
||||
void setSize(int width, int height);
|
||||
void updateSize();
|
||||
|
||||
static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
|
||||
|
||||
static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
static bool SkOSWindow::QuitOnDeactivate(HWND hWnd);
|
||||
|
||||
enum {
|
||||
SK_WM_SkEvent = WM_APP + 1000,
|
||||
SK_WM_SkTimerID = 0xFFFF // just need a non-zero value
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual bool quitOnDeactivate() { return true; }
|
||||
|
||||
// overrides from SkWindow
|
||||
virtual void onHandleInval(const SkRect16&);
|
||||
// overrides from SkView
|
||||
virtual void onAddMenu(const SkOSMenu*);
|
||||
|
||||
private:
|
||||
void* fHWND;
|
||||
|
||||
void doPaint(void* ctx);
|
||||
|
||||
HMENU fMBar;
|
||||
|
||||
typedef SkWindow INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* SkOSWindow_wxwidgets.h
|
||||
* wxwidgets
|
||||
*
|
||||
* Created by phanna on 12/14/05.
|
||||
* Copyright 2005 __MyCompanyName__. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SkOSWindow_wxwidgets_DEFINED
|
||||
#define SkOSWindow_wxwidgets_DEFINED
|
||||
|
||||
#include "SkWindow.h"
|
||||
#include "wx/frame.h"
|
||||
|
||||
class SkOSWindow: public SkWindow
|
||||
{
|
||||
public:
|
||||
SkOSWindow();
|
||||
SkOSWindow(const wxString& title, int x, int y, int width, int height);
|
||||
~SkOSWindow();
|
||||
|
||||
wxFrame* getWXFrame() const { return fFrame; }
|
||||
|
||||
void updateSize();
|
||||
|
||||
protected:
|
||||
virtual void onHandleInval(const SkRect16&);
|
||||
virtual void onAddMenu(const SkOSMenu*);
|
||||
|
||||
private:
|
||||
wxFrame* fFrame;
|
||||
typedef SkWindow INHERITED;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,630 @@
|
|||
#ifndef SkPaint_DEFINED
|
||||
#define SkPaint_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkMath.h"
|
||||
#include "SkPorterDuff.h"
|
||||
|
||||
class SkColorFilter;
|
||||
class SkGlyphCache;
|
||||
class SkMaskFilter;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkPathEffect;
|
||||
class SkRasterizer;
|
||||
class SkShader;
|
||||
class SkTextLayout;
|
||||
class SkTypeface;
|
||||
class SkXfermode;
|
||||
|
||||
typedef SkUnichar (*SkUnicodeWalkerProc)(const char** text);
|
||||
|
||||
/** \class SkPaint
|
||||
|
||||
The SkPaint class holds the style and color information about how to draw geometries, text and bitmaps.
|
||||
*/
|
||||
class SkPaint {
|
||||
public:
|
||||
SkPaint();
|
||||
SkPaint(const SkPaint& paint);
|
||||
~SkPaint();
|
||||
|
||||
SkPaint& operator=(const SkPaint&);
|
||||
|
||||
friend int operator==(const SkPaint& a, const SkPaint& b);
|
||||
friend int operator!=(const SkPaint& a, const SkPaint& b) { return !(a == b); }
|
||||
|
||||
/** Restores the paint to its initial settings.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** FlagShift enum specifies the amount to bit-shift for a given flag setting.
|
||||
Can be used to slide a boolean value into the correct position (e.g.
|
||||
flags |= isAntiAlias << kAntiAlias_Shift;
|
||||
*/
|
||||
enum FlagShift {
|
||||
kAntiAlias_Shift, //!< bit position for the flag enabling antialiasing
|
||||
kLinearText_Shift , //!< bit position for the flag enabling linear-text (no gridding)
|
||||
kUnderlineText_Shift, //!< bit position for the flag enabling underline text
|
||||
kStrikeThruText_Shift, //!< bit position for the flag enabling strike-thru text
|
||||
kFakeBoldText_Shift, //!< bit position for the flag enabling fake-bold text
|
||||
|
||||
kFlagShiftCount
|
||||
};
|
||||
|
||||
/** FlagMask enum specifies the bit values that are stored in the paint's flags.
|
||||
*/
|
||||
enum FlagMask {
|
||||
kAntiAlias_Mask = 1 << kAntiAlias_Shift, //!< bit mask for the flag enabling antialiasing
|
||||
kLinearText_Mask = 1 << kLinearText_Shift, //!< bit mask for the flag enabling linear-text (no gridding)
|
||||
kUnderlineText_Mask = 1 << kUnderlineText_Shift, //!< bit mask for the flag enabling underline text
|
||||
kStrikeThruText_Mask= 1 << kStrikeThruText_Shift, //!< bit mask for the flag enabling strike-thru text
|
||||
kFakeBoldText_Mask = 1 << kFakeBoldText_Shift, //!< bit mask for the flag enabling fake-bold text
|
||||
|
||||
kAllFlagMasks = (1 << kFlagShiftCount) - 1
|
||||
};
|
||||
|
||||
/** Return the paint's flags. Use the FlagMask enum to test flag values.
|
||||
@return the paint's flags (see enums ending in _Mask for bit masks)
|
||||
*/
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
/** Set the paint's flags. Use the FlagMask enum to specific flag values.
|
||||
@param flags The new flag bits for the paint (see enums ending in _Mask for bit masks)
|
||||
*/
|
||||
void setFlags(uint32_t flags);
|
||||
|
||||
/** Helper for getFlags(), returning true if kAntiAlias_Mask bit is set
|
||||
@return true if the antialias bit is set in the paint's flags.
|
||||
*/
|
||||
bool isAntiAliasOn() const { return SkToBool(this->getFlags() & kAntiAlias_Mask); }
|
||||
/** Helper for setFlags(), setting or clearing the kAntiAlias_Mask bit
|
||||
@param aa true to set the antialias bit in the flags, false to clear it
|
||||
*/
|
||||
void setAntiAliasOn(bool aa);
|
||||
/** Helper for getFlags(), returning true if kLinearText_Mask bit is set
|
||||
@return true if the lineartext bit is set in the paint's flags
|
||||
*/
|
||||
bool isLinearTextOn() const { return SkToBool(this->getFlags() & kLinearText_Mask); }
|
||||
/** Helper for setFlags(), setting or clearing the kLinearText_Mask bit
|
||||
@param linearText true to set the linearText bit in the paint's flags, false to clear it.
|
||||
*/
|
||||
void setLinearTextOn(bool linearText);
|
||||
/** Helper for getFlags(), returning true if kUnderlineText_Mask bit is set
|
||||
@return true if the underlineText bit is set in the paint's flags.
|
||||
*/
|
||||
bool isUnderlineTextOn() const { return SkToBool(this->getFlags() & kUnderlineText_Mask); }
|
||||
/** Helper for setFlags(), setting or clearing the kUnderlineText_Mask bit
|
||||
@param underlineText true to set the underlineText bit in the paint's flags, false to clear it.
|
||||
*/
|
||||
void setUnderlineTextOn(bool underlineText);
|
||||
/** Helper for getFlags(), returning true if kStrikeThruText_Mask bit is set
|
||||
@return true if the strikeThruText bit is set in the paint's flags.
|
||||
*/
|
||||
bool isStrikeThruTextOn() const { return SkToBool(this->getFlags() & kStrikeThruText_Mask); }
|
||||
/** Helper for setFlags(), setting or clearing the kStrikeThruText_Mask bit
|
||||
@param strikeThruText true to set the strikeThruText bit in the paint's flags, false to clear it.
|
||||
*/
|
||||
void setStrikeThruTextOn(bool strikeThruText);
|
||||
/** Helper for getFlags(), returning true if kFakeBoldText_Mask bit is set
|
||||
@return true if the fakeBoldText bit is set in the paint's flags.
|
||||
*/
|
||||
bool isFakeBoldTextOn() const { return SkToBool(this->getFlags() & kFakeBoldText_Mask); }
|
||||
/** Helper for setFlags(), setting or clearing the kStrikeThruText_Mask bit
|
||||
@param fakeBoldText true to set the fakeBoldText bit in the paint's flags, false to clear it.
|
||||
*/
|
||||
void setFakeBoldTextOn(bool fakeBoldText);
|
||||
|
||||
/** Styles apply to rect, oval, path, and text.
|
||||
Bitmaps are always drawn in "fill", and lines are always drawn in "stroke"
|
||||
*/
|
||||
enum Style {
|
||||
kFill_Style, //!< fill with the paint's color
|
||||
kStroke_Style, //!< stroke with the paint's color
|
||||
kStrokeAndFill_Style, //!< fill and stroke with the paint's color
|
||||
|
||||
kStyleCount,
|
||||
kDefault_Style = kFill_Style, //!< the default style setting in the paint
|
||||
};
|
||||
/** Return the paint's style, used for controlling how primitives'
|
||||
geometries are interpreted (except for drawBitmap, which always assumes
|
||||
kFill_Style).
|
||||
@return the paint's style setting (Fill, Stroke, StrokeAndFill)
|
||||
*/
|
||||
Style getStyle() const { return (Style)fStyle; }
|
||||
/** Set the paint's style, used for controlling how primitives'
|
||||
geometries are interpreted (except for drawBitmap, which always assumes
|
||||
Fill).
|
||||
@param style The new style to set in the paint (Fill, Stroke, StrokeAndFill)
|
||||
*/
|
||||
void setStyle(Style style);
|
||||
|
||||
/** Return the paint's color. Note that the color is a 32bit value containing alpha
|
||||
as well as r,g,b. This 32bit value is not premultiplied, meaning that
|
||||
its alpha can be any value, regardless of the values of r,g,b.
|
||||
@return the paint's color (and alpha).
|
||||
*/
|
||||
SkColor getColor() const { return fColor; }
|
||||
/** Helper to getColor() that just returns the color's alpha value.
|
||||
@return the alpha component of the paint's color.
|
||||
*/
|
||||
uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
|
||||
/** Set the paint's color. Note that the color is a 32bit value containing alpha
|
||||
as well as r,g,b. This 32bit value is not premultiplied, meaning that
|
||||
its alpha can be any value, regardless of the values of r,g,b.
|
||||
@param color The new color (including alpha) to set in the paint.
|
||||
*/
|
||||
void setColor(SkColor color);
|
||||
/** Helper to setColor(), that only assigns the color's alpha value, leaving its
|
||||
r,g,b values unchanged.
|
||||
@param a set the alpha component (0..255) of the paint's color.
|
||||
*/
|
||||
void setAlpha(U8CPU a);
|
||||
/** Helper to setColor(), that takes a,r,g,b and constructs the color value using SkColorSetARGB()
|
||||
@param a The new alpha component (0..255) of the paint's color.
|
||||
@param r The new red component (0..255) of the paint's color.
|
||||
@param g The new green component (0..255) of the paint's color.
|
||||
@param b The new blue component (0..255) of the paint's color.
|
||||
*/
|
||||
void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
|
||||
/** Return the width for stroking.
|
||||
<p />
|
||||
A value of 0 strokes in hairline mode.
|
||||
Hairlines always draws a single pixel independent of the canva's matrix.
|
||||
@return the paint's stroke width, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
SkScalar getStrokeWidth() const { return fWidth; }
|
||||
/** Set the width for stroking.
|
||||
Pass 0 to stroke in hairline mode.
|
||||
Hairlines always draws a single pixel independent of the canva's matrix.
|
||||
@param width set the paint's stroke width, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeWidth(SkScalar width);
|
||||
|
||||
/** Return the paint's stroke miter value. This is used to control the behavior
|
||||
of miter joins when the joins angle is sharp.
|
||||
@return the paint's miter limit, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
SkScalar getStrokeMiter() const { return fMiterLimit; }
|
||||
/** Set the paint's stroke miter value. This is used to control the behavior
|
||||
of miter joins when the joins angle is sharp. This value must be >= 0.
|
||||
@param miter set the miter limit on the paint, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeMiter(SkScalar miter);
|
||||
|
||||
/** Cap enum specifies the settings for the paint's strokecap. This is the treatment
|
||||
that is applied to the beginning and end of each non-closed contour (e.g. lines).
|
||||
*/
|
||||
enum Cap {
|
||||
kButt_Cap, //!< begin and end a contour with no extension
|
||||
kRound_Cap, //!< begin and end a contour with a semi-circle extension
|
||||
kSquare_Cap, //!< begin and end a contour with a half square extension
|
||||
|
||||
kCapCount,
|
||||
kDefault_Cap = kButt_Cap
|
||||
};
|
||||
|
||||
/** Join enum specifies the settings for the paint's strokejoin. This is the treatment
|
||||
that is applied to corners in paths and rectangles.
|
||||
*/
|
||||
enum Join {
|
||||
kMiter_Join, //!< connect path segments with a sharp join (respects miter-limit)
|
||||
kRound_Join, //!< connect path segments with a round join
|
||||
kBevel_Join, //!< connect path segments with a flat bevel join
|
||||
|
||||
kJoinCount,
|
||||
kDefault_Join = kMiter_Join
|
||||
};
|
||||
|
||||
/** Return the paint's stroke cap type, controlling how the start and end of stroked lines and paths
|
||||
are treated.
|
||||
@return the line cap style for the paint, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
Cap getStrokeCap() const { return (Cap)fCapType; }
|
||||
/** Set the paint's stroke cap type.
|
||||
@param cap set the paint's line cap style, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeCap(Cap cap);
|
||||
|
||||
/** Return the paint's stroke join type.
|
||||
@return the paint's line join style, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
Join getStrokeJoin() const { return (Join)fJoinType; }
|
||||
/** Set the paint's stroke join type.
|
||||
@param join set the paint's line join style, used whenever the paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeJoin(Join join);
|
||||
|
||||
enum FilterType {
|
||||
kNo_FilterType, //!< draw bitmaps using nearest-neighbor sampling
|
||||
kBilinear_FilterType, //!< draw bitmaps using bilinear sampling
|
||||
|
||||
kFilterTypeCount
|
||||
};
|
||||
/** Return the paint's bitmap filter type. This setting affects drawBitmap() and bitmaps
|
||||
that appear inside a bitmap shader.
|
||||
@return the paint's filter type, used when drawing bitmaps.
|
||||
*/
|
||||
FilterType getFilterType() const { return (FilterType)fFilterType; }
|
||||
/** Set the paint's bitmap filter type. This setting affects drawBitmap() and bitmaps
|
||||
that appear inside a bitmap shader.
|
||||
@param filterType set the new filter type on the paint, used when drawing a bitmap
|
||||
*/
|
||||
void setFilterType(FilterType filterType);
|
||||
|
||||
/** Get the paint's shader object.
|
||||
<p />
|
||||
The shader's reference count is not affected.
|
||||
@return the paint's shader (or NULL)
|
||||
*/
|
||||
SkShader* getShader() const { return fShader; }
|
||||
/** Set or clear the shader object.
|
||||
<p />
|
||||
Pass NULL to clear any previous shader.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous shader exists, its reference count is decremented.
|
||||
If shader is not NULL, its reference count is incremented.
|
||||
@param shader May be NULL. the new shader to be installed in the paint
|
||||
@return shader
|
||||
*/
|
||||
SkShader* setShader(SkShader* shader);
|
||||
|
||||
/** Get the paint's colorfilter (or NULL). If there is a colorfilter, its reference
|
||||
count is not changed.
|
||||
@return the paint's colorfilter (or NULL)
|
||||
*/
|
||||
SkColorFilter* getColorFilter() const { return fColorFilter; }
|
||||
/** Set or clear the paint's colorfilter, returning the parameter.
|
||||
<p />
|
||||
If the paint already has a filter, its reference count is decremented.
|
||||
If filter is not NULL, its reference count is incremented.
|
||||
@param filter May be NULL. The new filter to be installed in the paint
|
||||
@return filter
|
||||
*/
|
||||
SkColorFilter* setColorFilter(SkColorFilter* filter);
|
||||
|
||||
/** Get the paint's xfermode object.
|
||||
<p />
|
||||
The xfermode's reference count is not affected.
|
||||
@return the paint's xfermode (or NULL)
|
||||
*/
|
||||
SkXfermode* getXfermode() const { return fXfermode; }
|
||||
/** Set or clear the xfermode object.
|
||||
<p />
|
||||
Pass NULL to clear any previous xfermode.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous xfermode exists, its reference count is decremented.
|
||||
If xfermode is not NULL, its reference count is incremented.
|
||||
@param xfermode May be NULL. The new xfermode to be installed in the paint
|
||||
@return xfermode
|
||||
*/
|
||||
SkXfermode* setXfermode(SkXfermode* xfermode);
|
||||
|
||||
/** Helper for setXfermode, passing the corresponding xfermode object returned from the
|
||||
PorterDuff factory.
|
||||
@param mode The porter-duff mode used to create an xfermode for the paint.
|
||||
@return the resulting xfermode object (or NULL if the mode is SrcOver)
|
||||
*/
|
||||
SkXfermode* setPorterDuffXfermode(SkPorterDuff::Mode mode);
|
||||
|
||||
/** Get the paint's patheffect object.
|
||||
<p />
|
||||
The patheffect reference count is not affected.
|
||||
@return the paint's patheffect (or NULL)
|
||||
*/
|
||||
SkPathEffect* getPathEffect() const { return fPathEffect; }
|
||||
/** Set or clear the patheffect object.
|
||||
<p />
|
||||
Pass NULL to clear any previous patheffect.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous patheffect exists, its reference count is decremented.
|
||||
If patheffect is not NULL, its reference count is incremented.
|
||||
@param effect May be NULL. The new patheffect to be installed in the paint
|
||||
@return effect
|
||||
*/
|
||||
SkPathEffect* setPathEffect(SkPathEffect* effect);
|
||||
|
||||
/** Get the paint's maskfilter object.
|
||||
<p />
|
||||
The maskfilter reference count is not affected.
|
||||
@return the paint's maskfilter (or NULL)
|
||||
*/
|
||||
SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
|
||||
/** Set or clear the maskfilter object.
|
||||
<p />
|
||||
Pass NULL to clear any previous maskfilter.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous maskfilter exists, its reference count is decremented.
|
||||
If maskfilter is not NULL, its reference count is incremented.
|
||||
@param maskfilter May be NULL. The new maskfilter to be installed in the paint
|
||||
@return maskfilter
|
||||
*/
|
||||
SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
|
||||
|
||||
// These attributes are for text/fonts
|
||||
|
||||
/** Get the paint's typeface object.
|
||||
<p />
|
||||
The typeface object identifies which font to use when drawing or measuring text.
|
||||
The typeface reference count is not affected.
|
||||
@return the paint's typeface (or NULL)
|
||||
*/
|
||||
SkTypeface* getTypeface() const { return fTypeface; }
|
||||
/** Set or clear the typeface object.
|
||||
<p />
|
||||
Pass NULL to clear any previous typeface.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous typeface exists, its reference count is decremented.
|
||||
If typeface is not NULL, its reference count is incremented.
|
||||
@param typeface May be NULL. The new typeface to be installed in the paint
|
||||
@return typeface
|
||||
*/
|
||||
SkTypeface* setTypeface(SkTypeface* typeface);
|
||||
|
||||
/** Get the paint's textlayout (or NULL).
|
||||
<p />
|
||||
The textlayout can modify the spacing between letters and words when measured/drawn.
|
||||
The textlayout reference count is not affected.
|
||||
@return the paint's textlayout (or NULL)
|
||||
*/
|
||||
SkTextLayout* getTextLayout() const { return fTextLayout; }
|
||||
/** Set or clear the textlayout object.
|
||||
<p />
|
||||
Pass NULL to clear any previous textlayout.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous layout exists in the paint, its reference count is decremented.
|
||||
If layout is not NULL, its reference count is incremented.
|
||||
@param layout May be NULL. The new layout to be installed in the paint.
|
||||
@return layout
|
||||
*/
|
||||
SkTextLayout* setTextLayout(SkTextLayout* layout);
|
||||
|
||||
/** Get the paint's rasterizer (or NULL).
|
||||
<p />
|
||||
The raster controls/modifies how paths/text are turned into alpha masks.
|
||||
@return the paint's rasterizer (or NULL)
|
||||
*/
|
||||
SkRasterizer* getRasterizer() const { return fRasterizer; }
|
||||
/** Set or clear the rasterizer object.
|
||||
<p />
|
||||
Pass NULL to clear any previous rasterizer.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous rasterizer exists in the paint, its reference count is decremented.
|
||||
If r is not NULL, its reference count is incremented.
|
||||
@param rasterizer May be NULL. The new rasterizer to be installed in the paint.
|
||||
@return rasterizer
|
||||
*/
|
||||
SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
|
||||
|
||||
enum Align {
|
||||
kLeft_Align,
|
||||
kCenter_Align,
|
||||
kRight_Align,
|
||||
|
||||
kAlignCount
|
||||
};
|
||||
/** Return the paint's Align value for drawing text.
|
||||
@return the paint's Align value for drawing text.
|
||||
*/
|
||||
Align getTextAlign() const { return (Align)fTextAlign; }
|
||||
/** Set the paint's text alignment.
|
||||
@param align set the paint's Align value for drawing text.
|
||||
*/
|
||||
void setTextAlign(Align align);
|
||||
|
||||
/** Return the paint's text size.
|
||||
@return the paint's text size.
|
||||
*/
|
||||
SkScalar getTextSize() const { return fTextSize; }
|
||||
/** Set the paint's text size. This value must be > 0
|
||||
@param textSize set the paint's text size.
|
||||
*/
|
||||
void setTextSize(SkScalar textSize);
|
||||
|
||||
/** Return the paint's horizontal scale factor for text. The default value
|
||||
is 1.0.
|
||||
@return the paint's scale factor in X for drawing/measuring text
|
||||
*/
|
||||
SkScalar getTextScaleX() const { return fTextScaleX; }
|
||||
/** Set the paint's horizontal scale factor for text. The default value
|
||||
is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
|
||||
stretch the text narrower.
|
||||
@param scaleX set the paint's scale factor in X for drawing/measuring text.
|
||||
*/
|
||||
void setTextScaleX(SkScalar scaleX);
|
||||
|
||||
/** Return the paint's horizontal skew factor for text. The default value
|
||||
is 0.
|
||||
@return the paint's skew factor in X for drawing text.
|
||||
*/
|
||||
SkScalar getTextSkewX() const { return fTextSkewX; }
|
||||
/** Set the paint's horizontal skew factor for text. The default value
|
||||
is 0. For approximating oblique text, use values around -0.25.
|
||||
@param skewX set the paint's skew factor in X for drawing text.
|
||||
*/
|
||||
void setTextSkewX(SkScalar skewX);
|
||||
|
||||
/** Return the width of the utf8 text.
|
||||
@param utf8 Address of the utf8 text
|
||||
@param length Number of bytes of utf8 text to measure
|
||||
@param above If not NULL, returns the distance above the baseline (ascent)
|
||||
@param below If not NULL, returns the distance below the baseline (descent)
|
||||
@return The width of the utf8 text
|
||||
*/
|
||||
SkScalar measureText(const char utf8[], size_t length,
|
||||
SkScalar* above, SkScalar* below) const;
|
||||
/** Return the width of the utf16 text.
|
||||
@param utf16 Address of the utf16 text
|
||||
@param numberOf16BitValues Number of 16bit values to measure
|
||||
@param above May be NULL. If not NULL, returns the distance above the baseline (ascent)
|
||||
@param below May be NULL. If not NULL, returns the distance below the baseline (descent)
|
||||
@return The width of the text
|
||||
*/
|
||||
SkScalar measureText16(const uint16_t utf16[], size_t numberOf16BitValues,
|
||||
SkScalar* above, SkScalar* below) const;
|
||||
/** Return the distance above (negative) the baseline (ascent) based on the current typeface and text size.
|
||||
@return the distance above (negative) the baseline (ascent) based on the current typeface and text size.
|
||||
*/
|
||||
SkScalar ascent() const;
|
||||
/** Return the distance below (positive) the baseline (descent) based on the current typeface and text size.
|
||||
@return the distance below (positive) the baseline (descent) based on the current typeface and text size.
|
||||
*/
|
||||
SkScalar descent() const;
|
||||
|
||||
/** Return the width of the utf8 text.
|
||||
@param text The utf8 text to measure
|
||||
@param byteLength The number of bytes of text to process
|
||||
@return the measured width of the specified text.
|
||||
*/
|
||||
SkScalar measureText(const char text[], size_t byteLength) const
|
||||
{
|
||||
return this->measureText(text, byteLength, NULL, NULL);
|
||||
}
|
||||
/** Return the width of the utf16 text.
|
||||
@param text The utf16 text to measure
|
||||
@param numberOf16BitValues The number of 16bit values in text to process
|
||||
@return the measured width of the specified text.
|
||||
*/
|
||||
SkScalar measureText16(const uint16_t text[], size_t numberOf16BitValues) const
|
||||
{
|
||||
return this->measureText16(text, numberOf16BitValues, NULL, NULL);
|
||||
}
|
||||
|
||||
/** Return the advance widths for the characters in the string.
|
||||
@param text UTF8 text
|
||||
@param byteLength number of bytes to read from the UTF8 text parameter
|
||||
@param widths array of SkScalars to receive the advance widths of the characters.
|
||||
May be NULL. If not NULL, must be at least a large as the number
|
||||
of unichars in the specified text.
|
||||
@return the number of unichars in the specified text.
|
||||
*/
|
||||
int getTextWidths(const char text[], size_t byteLength, SkScalar widths[]) const;
|
||||
/** Return the advance widths for the characters in the string.
|
||||
@param text UTF16 text
|
||||
@param numberOf16BitValues number of 16bit values to read from the UTF16 text parameter
|
||||
@param widths array of SkScalars to receive the advance widths of the characters.
|
||||
May be NULL. If not NULL, must be at least a large as the number
|
||||
of unichars in the specified text.
|
||||
@return the number of unichars in the specified text.
|
||||
*/
|
||||
int getTextWidths16(const uint16_t text[], size_t numberOf16BitValues, SkScalar widths[]) const;
|
||||
|
||||
/** Return the path (outline) for the specified text.
|
||||
Note: just like SkCanvas::drawText, this will respect the Align setting in the paint.
|
||||
*/
|
||||
void getTextPath(const char text[], size_t length, SkScalar x, SkScalar y, SkPath* path) const;
|
||||
|
||||
/** Return the path (outline) for the specified text.
|
||||
Note: just like SkCanvas::drawText, this will respect the Align setting in the paint.
|
||||
*/
|
||||
void getText16Path(const uint16_t text[], size_t numberOf16BitValues, SkScalar x, SkScalar y, SkPath* path) const;
|
||||
|
||||
/** Applies any/all effects (patheffect, stroking) to src, returning the result in dst.
|
||||
The result is that drawing src with this paint will be the same as drawing dst
|
||||
with a default paint (at least from the geometric perspective).
|
||||
@param src input path
|
||||
@param dst output path (may be the same as src)
|
||||
@return true if the path should be filled, or false if it should be drawn with a hairline (width == 0)
|
||||
*/
|
||||
bool getFillPath(const SkPath& src, SkPath* dst) const;
|
||||
|
||||
private:
|
||||
SkTypeface* fTypeface;
|
||||
SkScalar fTextSize;
|
||||
SkScalar fTextScaleX;
|
||||
SkScalar fTextSkewX;
|
||||
|
||||
SkPathEffect* fPathEffect;
|
||||
SkShader* fShader;
|
||||
SkXfermode* fXfermode;
|
||||
SkMaskFilter* fMaskFilter;
|
||||
SkColorFilter* fColorFilter;
|
||||
SkTextLayout* fTextLayout;
|
||||
SkRasterizer* fRasterizer;
|
||||
|
||||
SkColor fColor;
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
||||
unsigned fFlags : 5;
|
||||
unsigned fFilterType : 2;
|
||||
unsigned fTextAlign : 2;
|
||||
unsigned fCapType : 2;
|
||||
unsigned fJoinType : 2;
|
||||
unsigned fStyle : 2;
|
||||
|
||||
SkScalar privateMeasureText(SkUnicodeWalkerProc, const char text[], size_t byteLength,
|
||||
SkScalar* above, SkScalar* below) const;
|
||||
void privateGetTextPath(SkUnicodeWalkerProc, const char text[], size_t length,
|
||||
SkScalar x, SkScalar y, SkPath* path) const;
|
||||
int privateGetTextWidths(const char text[], size_t byteLength,
|
||||
SkScalar widths[], SkUnicodeWalkerProc textProc) const;
|
||||
|
||||
SkGlyphCache* detachCache(const SkMatrix*) const;
|
||||
|
||||
friend class SkGlyphCache;
|
||||
enum {
|
||||
kCanonicalTextSizeForPaths = 64
|
||||
};
|
||||
friend class SkDraw;
|
||||
friend class SkTextToPathIter;
|
||||
};
|
||||
|
||||
class SkAutoRestorePaintFlags {
|
||||
public:
|
||||
SkAutoRestorePaintFlags(const SkPaint& paint, uint32_t newFlags)
|
||||
{
|
||||
SkASSERT(&paint);
|
||||
fPaint = (SkPaint*)&paint; // remove constness
|
||||
fOldFlags = paint.getFlags();
|
||||
fPaint->setFlags(newFlags);
|
||||
}
|
||||
~SkAutoRestorePaintFlags()
|
||||
{
|
||||
fPaint->setFlags(fOldFlags);
|
||||
}
|
||||
private:
|
||||
SkPaint* fPaint;
|
||||
uint32_t fOldFlags;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkStrokePathEffect
|
||||
|
||||
SkStrokePathEffect simulates stroking inside a patheffect, allowing the caller to have explicit
|
||||
control of when to stroke a path. Typically this is used if the caller wants to stroke before
|
||||
another patheffect is applied (using SkComposePathEffect or SkSumPathEffect).
|
||||
*/
|
||||
class SkStrokePathEffect : public SkPathEffect {
|
||||
public:
|
||||
SkStrokePathEffect(const SkPaint&);
|
||||
SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join, SkPaint::Cap, SkScalar miterLimit = -1);
|
||||
|
||||
// overrides
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkWBuffer&);
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
|
||||
private:
|
||||
SkScalar fWidth, fMiter;
|
||||
uint8_t fStyle, fJoin, fCap;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
SkStrokePathEffect(SkRBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
|
||||
// illegal
|
||||
SkStrokePathEffect(const SkStrokePathEffect&);
|
||||
SkStrokePathEffect& operator=(const SkStrokePathEffect&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef SkParse_DEFINED
|
||||
#define SkParse_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkMath.h"
|
||||
|
||||
class SkParse {
|
||||
public:
|
||||
static int Count(const char str[]); // number of scalars or int values
|
||||
static int Count(const char str[], char separator);
|
||||
static const char* FindColor(const char str[], SkColor* value);
|
||||
static const char* FindHex(const char str[], uint32_t* value);
|
||||
static const char* FindMSec(const char str[], SkMSec* value);
|
||||
static const char* FindNamedColor(const char str[], size_t len, SkColor* color);
|
||||
static const char* FindS32(const char str[], int32_t* value);
|
||||
static const char* FindScalar(const char str[], SkScalar* value);
|
||||
static const char* FindScalars(const char str[], SkScalar value[], int count);
|
||||
|
||||
static bool FindBool(const char str[], bool* value);
|
||||
// return the index of str in list[], or -1 if not found
|
||||
static int FindList(const char str[], const char list[]);
|
||||
#ifdef SK_SUPPORT_UNITTEST
|
||||
static void TestColor();
|
||||
static void UnitTest();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef SkParsePaint_DEFINED
|
||||
#define SkParsePaint_DEFINED
|
||||
|
||||
#include "SkPaint.h"
|
||||
#include "SkDOM.h"
|
||||
|
||||
/** "color" color
|
||||
"opacity" scalar [0..1]
|
||||
"stroke-width" scalar (0...inf)
|
||||
"text-size" scalar (0..inf)
|
||||
"is-stroke" bool
|
||||
"is-antialias" bool
|
||||
"is-lineartext" bool
|
||||
*/
|
||||
void SkPaint_Inflate(SkPaint*, const SkDOM&, const SkDOM::Node*);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,373 @@
|
|||
#ifndef SkPath_DEFINED
|
||||
#define SkPath_DEFINED
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkString;
|
||||
|
||||
/** \class SkPath
|
||||
|
||||
The SkPath class encapsulates compound (multiple contour) geometric paths consisting
|
||||
of straight line segments, quadratic curves, and cubic curves.
|
||||
*/
|
||||
class SkPath {
|
||||
public:
|
||||
SkPath();
|
||||
SkPath(const SkPath&);
|
||||
~SkPath();
|
||||
|
||||
SkPath& operator=(const SkPath&);
|
||||
|
||||
enum FillType {
|
||||
kWinding_FillType, //!< Specifies that "inside" is computed by a non-zero sum of signed edge crossings
|
||||
kEvenOdd_FillType //!< Specifies that "inside" is computed by an odd number of edge crossings
|
||||
};
|
||||
/** Return the path's fill type. This is used to define how "inside" is computed.
|
||||
The default value is kWinding_FillType.
|
||||
@return the path's fill type
|
||||
*/
|
||||
FillType getFillType() const { return (FillType)fFillType; }
|
||||
/** Set the path's fill type. This is used to define how "inside" is computed.
|
||||
The default value is kWinding_FillType.
|
||||
@param ft The new fill type for this path
|
||||
*/
|
||||
void setFillType(FillType ft) { fFillType = SkToU8(ft); }
|
||||
|
||||
/** Clear any lines and curves from the path, making it empty.
|
||||
This does NOT change the fill-type setting.
|
||||
*/
|
||||
void reset();
|
||||
/** Returns true if the path is empty (contains no lines or curves)
|
||||
@return true if the path is empty (contains no lines or curves)
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
/** Returns true if the path specifies a rectangle. If so, and if rect is not nil,
|
||||
set rect to the bounds of the path. If the path does not specify a rectangle,
|
||||
return false and ignore rect.
|
||||
@param rect If not nil, returns the bounds of the path if it specifies a rectangle
|
||||
@return true if the path specifies a rectangle
|
||||
*/
|
||||
bool isRect(SkRect* rect) const;
|
||||
/** Returns the number of points in the path. Up to max points are copied.
|
||||
@param points If not null, receives up to max points
|
||||
@param max The maximum number of points to copy into points
|
||||
@return the actual number of points in the path
|
||||
*/
|
||||
int getPoints(SkPoint points[], int max) const;
|
||||
//! Swap contents of this and other. Guaranteed not to throw
|
||||
void swap(SkPath& other);
|
||||
|
||||
enum BoundsType {
|
||||
kFast_BoundsType, //!< compute the bounds of the path's control points, may be larger than with kExact_BoundsType, but may be faster to compute
|
||||
kExact_BoundsType //!< compute the exact bounds of the path, may be smaller than with kFast_BoundsType, but may be slower to compute
|
||||
};
|
||||
/** Compute the bounds of the path, and write the answer into bounds. If the path contains 0 or 1 points,
|
||||
the bounds is set to (0,0,0,0)
|
||||
@param bounds Returns the computed bounds of the path
|
||||
@param btype Specifies if the computed bounds should be exact (slower) or approximate (faster)
|
||||
*/
|
||||
void computeBounds(SkRect* bounds, BoundsType btype) const;
|
||||
|
||||
// Construction methods
|
||||
|
||||
/** Hint to the path to prepare for adding more points. This can allow the path to more efficiently grow its storage.
|
||||
@param extraPtCount The number of extra points that may be added to this path
|
||||
*/
|
||||
void incReserve(unsigned extraPtCount);
|
||||
|
||||
/** Set the beginning of the next contour to the point (x,y).
|
||||
@param x The x-coordinate of the start of a new contour
|
||||
@param y The y-coordinate of the start of a new contour
|
||||
*/
|
||||
void moveTo(SkScalar x, SkScalar y);
|
||||
/** Set the beginning of the next contour to the point
|
||||
@param p The start of a new contour
|
||||
*/
|
||||
void moveTo(const SkPoint& p)
|
||||
{
|
||||
this->moveTo(p.fX, p.fY);
|
||||
}
|
||||
/** Set the beginning of the next contour relative to the last point on the previous
|
||||
contour. If there is no previous contour, this is treated the same as moveTo().
|
||||
@param dx The amount to add to the x-coordinate of the end of the previous contour, to specify the start of a new contour
|
||||
@param dy The amount to add to the y-coordinate of the end of the previous contour, to specify the start of a new contour
|
||||
*/
|
||||
void rMoveTo(SkScalar dx, SkScalar dy);
|
||||
/** Add a line from the last point to the specified point (x,y).
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
@param x The x-coordinate of the end of a line
|
||||
@param y The y-coordinate of the end of a line
|
||||
*/
|
||||
void lineTo(SkScalar x, SkScalar y);
|
||||
/** Add a line from the last point to the specified point.
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
@param p The end of a line
|
||||
*/
|
||||
void lineTo(const SkPoint& p)
|
||||
{
|
||||
this->lineTo(p.fX, p.fY);
|
||||
}
|
||||
/** Same as lineTo, but the coordinates are considered relative to the last point on this
|
||||
contour. If there is no previous point, then a moveTo(0,0) is inserted automatically.
|
||||
@param dx The amount to add to the x-coordinate of the previous point on this contour, to specify a line
|
||||
@param dy The amount to add to the y-coordinate of the previous point on this contour, to specify a line
|
||||
*/
|
||||
void rLineTo(SkScalar dx, SkScalar dy);
|
||||
/** Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2).
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
@param x1 The x-coordinate of the control point on a quadratic curve
|
||||
@param y1 The y-coordinate of the control point on a quadratic curve
|
||||
@param x2 The x-coordinate of the end point on a quadratic curve
|
||||
@param y2 The y-coordinate of the end point on a quadratic curve
|
||||
*/
|
||||
void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
|
||||
/** Add a quadratic bezier from the last point, approaching control point p1, and ending at p2.
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
@param p1 The control point on a quadratic curve
|
||||
@param p2 The end point on a quadratic curve
|
||||
*/
|
||||
void quadTo(const SkPoint& p1, const SkPoint& p2)
|
||||
{
|
||||
this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
|
||||
}
|
||||
/** Same as quadTo, but the coordinates are considered relative to the last point on this
|
||||
contour. If there is no previous point, then a moveTo(0,0) is inserted automatically.
|
||||
@param dx1 The amount to add to the x-coordinate of the last point on this contour, to specify the control point of a quadratic curve
|
||||
@param dy1 The amount to add to the y-coordinate of the last point on this contour, to specify the control point of a quadratic curve
|
||||
@param dx2 The amount to add to the x-coordinate of the last point on this contour, to specify the end point of a quadratic curve
|
||||
@param dy2 The amount to add to the y-coordinate of the last point on this contour, to specify the end point of a quadratic curve
|
||||
*/
|
||||
void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
|
||||
/** Add a cubic bezier from the last point, approaching control points (x1,y1) and (x2,y2), and ending at (x3,y3).
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
@param x1 The x-coordinate of the 1st control point on a cubic curve
|
||||
@param y1 The y-coordinate of the 1st control point on a cubic curve
|
||||
@param x2 The x-coordinate of the 2nd control point on a cubic curve
|
||||
@param y2 The y-coordinate of the 2nd control point on a cubic curve
|
||||
@param x3 The x-coordinate of the end point on a cubic curve
|
||||
@param y3 The y-coordinate of the end point on a cubic curve
|
||||
*/
|
||||
void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3);
|
||||
/** Add a cubic bezier from the last point, approaching control points p1 and p2, and ending at p3.
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
@param p1 The 1st control point on a cubic curve
|
||||
@param p2 The 2nd control point on a cubic curve
|
||||
@param p3 The end point on a cubic curve
|
||||
*/
|
||||
void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3)
|
||||
{
|
||||
this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
|
||||
}
|
||||
/** Same as cubicTo, but the coordinates are considered relative to the current point on this
|
||||
contour. If there is no previous point, then a moveTo(0,0) is inserted automatically.
|
||||
@param dx1 The amount to add to the x-coordinate of the last point on this contour, to specify the 1st control point of a cubic curve
|
||||
@param dy1 The amount to add to the y-coordinate of the last point on this contour, to specify the 1st control point of a cubic curve
|
||||
@param dx2 The amount to add to the x-coordinate of the last point on this contour, to specify the 2nd control point of a cubic curve
|
||||
@param dy2 The amount to add to the y-coordinate of the last point on this contour, to specify the 2nd control point of a cubic curve
|
||||
@param dx3 The amount to add to the x-coordinate of the last point on this contour, to specify the end point of a cubic curve
|
||||
@param dy3 The amount to add to the y-coordinate of the last point on this contour, to specify the end point of a cubic curve
|
||||
*/
|
||||
void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3);
|
||||
/** Close the current contour. If the current point is not equal to the first point of the contour,
|
||||
a line segment is automatically added.
|
||||
*/
|
||||
void close();
|
||||
|
||||
enum Direction {
|
||||
kCW_Direction, //!< clockwise direction for adding closed contours
|
||||
kCCW_Direction //!< counter-clockwise direction for adding closed contours
|
||||
};
|
||||
/** Add a closed rectangle contour to the path
|
||||
@param rect The rectangle to add as a closed contour to the path
|
||||
@param dir The direction to wind the rectangle's contour
|
||||
*/
|
||||
void addRect(const SkRect& rect, Direction dir = kCW_Direction);
|
||||
/** Add a closed rectangle contour to the path
|
||||
@param left The left side of a rectangle to add as a closed contour to the path
|
||||
@param top The top of a rectangle to add as a closed contour to the path
|
||||
@param right The right side of a rectangle to add as a closed contour to the path
|
||||
@param bottom The bottom of a rectangle to add as a closed contour to the path
|
||||
@param dir The direction to wind the rectangle's contour
|
||||
*/
|
||||
void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom, Direction dir = kCW_Direction);
|
||||
/** Add a closed oval contour to the path
|
||||
@param oval The bounds of the oval to add as a closed contour to the path
|
||||
@param dir The direction to wind the oval's contour
|
||||
*/
|
||||
void addOval(const SkRect& oval, Direction dir = kCW_Direction);
|
||||
/** Add a closed circle contour to the path
|
||||
@param x The x-coordinate of the center of a circle to add as a closed contour to the path
|
||||
@param y The y-coordinate of the center of a circle to add as a closed contour to the path
|
||||
@param radius The radius of a circle to add as a closed contour to the path
|
||||
@param dir The direction to wind the circle's contour
|
||||
*/
|
||||
void addCircle(SkScalar x, SkScalar y, SkScalar radius, Direction dir = kCW_Direction);
|
||||
/** Add a closed round-rectangle contour to the path
|
||||
@param rect The bounds of a round-rectangle to add as a closed contour to the path
|
||||
@param rx The x-radius of the rounded corners on the round-rectangle
|
||||
@param ry The y-radius of the rounded corners on the round-rectangle
|
||||
@param dir The direction to wind the round-rectangle's contour
|
||||
*/
|
||||
void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, Direction dir = kCW_Direction);
|
||||
/** Add a copy of src to the path, offset by (dx,dy)
|
||||
@param src The path to add as a new contour
|
||||
@param dx The amount to translate the path in X as it is added
|
||||
@param dx The amount to translate the path in Y as it is added
|
||||
*/
|
||||
void addPath(const SkPath& src, SkScalar dx, SkScalar dy);
|
||||
/** Add a copy of src to the path
|
||||
*/
|
||||
void addPath(const SkPath& src) { SkMatrix m; m.reset(); this->addPath(src, m); }
|
||||
/** Add a copy of src to the path, transformed by matrix
|
||||
@param src The path to add as a new contour
|
||||
*/
|
||||
void addPath(const SkPath& src, const SkMatrix& matrix);
|
||||
|
||||
/** Offset the path by (dx,dy), returning true on success
|
||||
@param dx The amount in the X direction to offset the entire path
|
||||
@param dy The amount in the Y direction to offset the entire path
|
||||
@param dst The translated path is written here
|
||||
@return true
|
||||
*/
|
||||
bool offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
|
||||
/** Offset the path by (dx,dy), returning true on success
|
||||
@param dx The amount in the X direction to offset the entire path
|
||||
@param dy The amount in the Y direction to offset the entire path
|
||||
@return true
|
||||
*/
|
||||
bool offset(SkScalar dx, SkScalar dy)
|
||||
{
|
||||
return this->offset(dx, dy, this);
|
||||
}
|
||||
/** Transform the points in this path by matrix, and write the answer into dst.
|
||||
@param matrix The matrix to apply to the path
|
||||
@param dst The transformed path is written here
|
||||
@return true
|
||||
*/
|
||||
bool transform(const SkMatrix& matrix, SkPath* dst) const;
|
||||
/** Transform the points in this path by matrix, and write the answer into dst.
|
||||
@param matrix The matrix to apply to the path
|
||||
@return true
|
||||
*/
|
||||
bool transform(const SkMatrix& matrix)
|
||||
{
|
||||
return this->transform(matrix, this);
|
||||
}
|
||||
|
||||
/** Return the last point on the path. If no points have been added, (0,0) is returned.
|
||||
@param lastPt The last point on the path is returned here
|
||||
*/
|
||||
void getLastPt(SkPoint* lastPt) const;
|
||||
/** Set the last point on the path. If no points have been added, moveTo(x,y) is automatically called.
|
||||
@param x The new x-coordinate for the last point
|
||||
@param y The new y-coordinate for the last point
|
||||
*/
|
||||
void setLastPt(SkScalar x, SkScalar y);
|
||||
/** Set the last point on the path. If no points have been added, moveTo(p) is automatically called.
|
||||
@param p The new location for the last point
|
||||
*/
|
||||
void setLastPt(const SkPoint& p) { this->setLastPt(p.fX, p.fY); }
|
||||
|
||||
enum Verb {
|
||||
kMove_Verb, //!< iter.next returns 1 point
|
||||
kLine_Verb, //!< iter.next returns 2 points
|
||||
kQuad_Verb, //!< iter.next returns 3 points
|
||||
kCubic_Verb, //!< iter.next returns 4 points
|
||||
kClose_Verb, //!< iter.next returns 1 point (the last point)
|
||||
kDone_Verb //!< iter.next returns 0 points
|
||||
};
|
||||
/** Iterate through all of the segments (lines, quadratics, cubics) of
|
||||
each contours in a path.
|
||||
*/
|
||||
class Iter {
|
||||
public:
|
||||
Iter();
|
||||
Iter(const SkPath&, bool forceClose);
|
||||
void setPath(const SkPath&, bool forceClose);
|
||||
|
||||
/** Return the next verb in this iteration of the path. When all segments have been
|
||||
visited, return kDone_Verb.
|
||||
@param pts The point(s) representing the current verb and/or segment
|
||||
@return The verb for the current segment
|
||||
*/
|
||||
Verb next(SkPoint pts[4]);
|
||||
|
||||
/** If next() returns kLine_Verb, then this query returns
|
||||
true if the line was the result of a close() command
|
||||
(i.e. the end point is the initial moveto for this contour).
|
||||
If next() returned a different verb, this returns an
|
||||
undefined value.
|
||||
@return If the last call to next() returned kLine_Verb, return true if it was
|
||||
the result of an explicit close command.
|
||||
*/
|
||||
bool isCloseLine() const { return SkToBool(fCloseLine); }
|
||||
|
||||
/** Returns true if the current contour is closed (i.e. has a kClose_Verb)
|
||||
@return true if the current contour is closed (i.e. has a kClose_Verb)
|
||||
*/
|
||||
bool isClosedContour() const;
|
||||
|
||||
private:
|
||||
const SkPoint* fPts;
|
||||
const uint8_t* fVerbs;
|
||||
const uint8_t* fVerbStop;
|
||||
SkPoint fMoveTo;
|
||||
SkPoint fLastPt;
|
||||
SkBool8 fForceClose;
|
||||
SkBool8 fNeedClose;
|
||||
SkBool8 fNeedMoveTo;
|
||||
SkBool8 fCloseLine;
|
||||
|
||||
bool cons_moveTo(SkPoint pts[1]);
|
||||
Verb autoClose(SkPoint pts[2]);
|
||||
};
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** @cond UNIT_TEST */
|
||||
void dump(bool forceClose, const char title[] = nil) const;
|
||||
static void UnitTest();
|
||||
/** @endcond */
|
||||
#endif
|
||||
|
||||
/** Return the number of bytes (padded to a multiple of 4) needed to
|
||||
flatten the path into a block of memory. If bufferOrNil is not nil,
|
||||
the path is written into it. The format of the buffer is private,
|
||||
and can be used to create a new path by calling unflatten().
|
||||
*/
|
||||
uint32_t flatten(void* bufferOrNil) const;
|
||||
void unflatten(const void* buffer);
|
||||
|
||||
/** Subdivide the path so that no segment is longer that dist.
|
||||
If bendLines is true, then turn all line segments into curves.
|
||||
If dst == nil, then the original path itself is modified (not const!)
|
||||
*/
|
||||
void subdivide(SkScalar dist, bool bendLines, SkPath* dst = nil) const;
|
||||
|
||||
/** Return an SVG-compatible string of the path.
|
||||
*/
|
||||
void toString(SkString*) const;
|
||||
|
||||
private:
|
||||
SkTDArray<SkPoint> fPts;
|
||||
SkTDArray<uint8_t> fVerbs;
|
||||
uint8_t fFillType;
|
||||
|
||||
friend class Iter;
|
||||
void cons_moveto();
|
||||
|
||||
friend class SkPathStroker;
|
||||
/* Append the first contour of path, ignoring path's initial point.
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
*/
|
||||
void pathTo(const SkPath& path);
|
||||
/* Append, in reverse order, the first contour of path, ignoring path's last point.
|
||||
If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).
|
||||
*/
|
||||
void reversePathTo(const SkPath&);
|
||||
|
||||
friend const SkPoint* sk_get_path_points(const SkPath&, int index);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
#ifndef SkPathEffect_DEFINED
|
||||
#define SkPathEffect_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkPath;
|
||||
|
||||
/** \class SkPathEffect
|
||||
|
||||
SkPathEffect is the base class for objects in the SkPaint that affect
|
||||
the geometry of a drawing primitive before it is transformed by the
|
||||
canvas' matrix and drawn.
|
||||
|
||||
Dashing is implemented as a subclass of SkPathEffect.
|
||||
*/
|
||||
class SkPathEffect : public SkFlattenable {
|
||||
public:
|
||||
SkPathEffect() {}
|
||||
|
||||
/** Given a src path and a width value, return true if the patheffect
|
||||
has produced a new path (dst) and a new width value. If false is returned,
|
||||
ignore dst and width.
|
||||
On input, width >= 0 means the src should be stroked
|
||||
On output, width >= 0 means the dst should be stroked
|
||||
*/
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
/** overrides for SkFlattenable.
|
||||
Subclasses should override this to (re)create their subclass.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
|
||||
protected:
|
||||
// visible to our subclasses
|
||||
SkPathEffect(SkRBuffer&) {}
|
||||
|
||||
private:
|
||||
// illegal
|
||||
SkPathEffect(const SkPathEffect&);
|
||||
SkPathEffect& operator=(const SkPathEffect&);
|
||||
};
|
||||
|
||||
/** \class SkPairPathEffect
|
||||
|
||||
Common baseclass for Compose and Sum. This subclass manages two pathEffects,
|
||||
including flattening them. It does nothing in filterPath, and is only useful
|
||||
for managing the lifetimes of its two arguments.
|
||||
*/
|
||||
// This class is not exported to java.
|
||||
class SkPairPathEffect : public SkPathEffect {
|
||||
public:
|
||||
SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
|
||||
virtual ~SkPairPathEffect();
|
||||
|
||||
// overrides
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkWBuffer&);
|
||||
|
||||
protected:
|
||||
// these are visible to our subclasses
|
||||
SkPathEffect* fPE0, *fPE1;
|
||||
SkPairPathEffect(SkRBuffer&);
|
||||
|
||||
private:
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
/** \class SkComposePathEffect
|
||||
|
||||
This subclass of SkPathEffect composes its two arguments, to create
|
||||
a compound pathEffect.
|
||||
*/
|
||||
class SkComposePathEffect : public SkPairPathEffect {
|
||||
public:
|
||||
/** Construct a pathEffect whose effect is to apply first the inner pathEffect
|
||||
and the the outer pathEffect (e.g. outer(inner(path)))
|
||||
The reference counts for outer and inner are both incremented in the constructor,
|
||||
and decremented in the destructor.
|
||||
*/
|
||||
SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
|
||||
: SkPairPathEffect(outer, inner) {}
|
||||
|
||||
// overrides
|
||||
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
|
||||
private:
|
||||
SkPathEffect* fOuter, *fInner;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
SkComposePathEffect(SkRBuffer& buffer) : SkPairPathEffect(buffer) {}
|
||||
|
||||
// illegal
|
||||
SkComposePathEffect(const SkComposePathEffect&);
|
||||
SkComposePathEffect& operator=(const SkComposePathEffect&);
|
||||
|
||||
typedef SkPairPathEffect INHERITED;
|
||||
};
|
||||
|
||||
/** \class SkSumPathEffect
|
||||
|
||||
This subclass of SkPathEffect applies two pathEffects, one after the other.
|
||||
Its filterPath() returns true if either of the effects succeeded.
|
||||
*/
|
||||
class SkSumPathEffect : public SkPairPathEffect {
|
||||
public:
|
||||
/** Construct a pathEffect whose effect is to apply two effects, in sequence.
|
||||
(e.g. first(path) + second(path))
|
||||
The reference counts for first and second are both incremented in the constructor,
|
||||
and decremented in the destructor.
|
||||
*/
|
||||
SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
|
||||
: SkPairPathEffect(first, second) {}
|
||||
|
||||
// overrides
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
|
||||
private:
|
||||
SkPathEffect* fFirst, *fSecond;
|
||||
|
||||
static SkFlattenable* CreateProc(SkRBuffer&);
|
||||
SkSumPathEffect(SkRBuffer& buffer) : SkPairPathEffect(buffer) {}
|
||||
|
||||
// illegal
|
||||
SkSumPathEffect(const SkSumPathEffect&);
|
||||
SkSumPathEffect& operator=(const SkSumPathEffect&);
|
||||
|
||||
typedef SkPairPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
#ifndef SkPathMeasure_DEFINED
|
||||
#define SkPathMeasure_DEFINED
|
||||
|
||||
#include "SkPath.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkPathMeasure {
|
||||
public:
|
||||
SkPathMeasure();
|
||||
SkPathMeasure(const SkPath& path, bool forceClosed);
|
||||
~SkPathMeasure();
|
||||
|
||||
/** Assign a new path, or nil to have none.
|
||||
*/
|
||||
void setPath(const SkPath*, bool forceClosed);
|
||||
|
||||
/** Return the total length of the current contour, or 0 if no path
|
||||
is associated (e.g. resetPath(nil))
|
||||
*/
|
||||
SkScalar getLength();
|
||||
|
||||
/** Pins distance to 0 <= distance <= getLength(), and then computes
|
||||
the corresponding position and tangent.
|
||||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
position and tangent are unchanged.
|
||||
*/
|
||||
bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent);
|
||||
|
||||
enum MatrixFlags {
|
||||
kGetPosition_MatrixFlag = 0x01,
|
||||
kGetTangent_MatrixFlag = 0x02,
|
||||
kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
|
||||
};
|
||||
/** Pins distance to 0 <= distance <= getLength(), and then computes
|
||||
the corresponding matrix (by calling getPosTan).
|
||||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
matrix is unchanged.
|
||||
*/
|
||||
bool getMatrix(SkScalar distance, SkMatrix* matrix, MatrixFlags flags = kGetPosAndTan_MatrixFlag);
|
||||
/** Given a start and stop distance, return in dst the intervening segment(s).
|
||||
If the segment is zero-length, return false, else return true.
|
||||
startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
|
||||
then return false (and leave dst untouched).
|
||||
Begin the segment with a moveTo if startWithMoveTo is true
|
||||
*/
|
||||
bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
|
||||
|
||||
/** Return true if the current contour is closed()
|
||||
*/
|
||||
bool isClosed();
|
||||
|
||||
/** Move to the next contour in the path. Return true if one exists, or false if
|
||||
we're done with the path.
|
||||
*/
|
||||
bool nextContour();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void dump();
|
||||
static void UnitTest();
|
||||
#endif
|
||||
|
||||
private:
|
||||
SkPath::Iter fIter;
|
||||
const SkPath* fPath;
|
||||
SkScalar fLength; // relative to the current contour
|
||||
int fFirstPtIndex; // relative to the current contour
|
||||
bool fIsClosed; // relative to the current contour
|
||||
bool fForceClosed;
|
||||
|
||||
struct Segment {
|
||||
SkScalar fDistance; // total distance up to this point
|
||||
unsigned fPtIndex : 15;
|
||||
unsigned fTValue : 15;
|
||||
unsigned fType : 2;
|
||||
|
||||
SkScalar getScalarT() const;
|
||||
};
|
||||
SkTDArray<Segment> fSegments;
|
||||
|
||||
static const Segment* NextSegment(const Segment*);
|
||||
|
||||
void buildSegments();
|
||||
SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
|
||||
int mint, int maxt, int ptIndex);
|
||||
SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
|
||||
int mint, int maxt, int ptIndex);
|
||||
const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
|
||||
|
||||
// illegal (for now)
|
||||
SkPathMeasure(const SkPathMeasure&);
|
||||
SkPathMeasure& operator=(const SkPathMeasure&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef SkPorterDuff_DEFINED
|
||||
#define SkPorterDuff_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
|
||||
class SkXfermode;
|
||||
|
||||
class SkPorterDuff {
|
||||
public:
|
||||
/** List of predefined xfermodes. In general, the algebra for the modes
|
||||
uses the following symbols:
|
||||
Sa, Sc - source alpha and color
|
||||
Da, Dc - destination alpha and color (before compositing)
|
||||
[a, c] - Resulting (alpha, color) values
|
||||
For these equations, the colors are in premultiplied state.
|
||||
If no xfermode is specified, kSrcOver is assumed.
|
||||
*/
|
||||
enum Mode {
|
||||
kClear_Mode, //!< [0, 0]
|
||||
kSrc_Mode, //!< [Sa, Sc]
|
||||
kDst_Mode, //!< [Da, Dc]
|
||||
kSrcOver_Mode, //!< [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] this is the default mode
|
||||
kDstOver_Mode, //!< [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc]
|
||||
kSrcIn_Mode, //!< [Sa * Da, Sc * Da]
|
||||
kDstIn_Mode, //!< [Sa * Da, Sa * Dc]
|
||||
kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)]
|
||||
kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
|
||||
kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
|
||||
kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
|
||||
kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
|
||||
kDarken_Mode, //!< [Sa + Da - Sa\u00B7Da, Sc\u00B7(1 - Da) + Dc\u00B7(1 - Sa) + min(Sc, Dc)]
|
||||
kLighten_Mode, //!< [Sa + Da - Sa\u00B7Da, Sc\u00B7(1 - Da) + Dc\u00B7(1 - Sa) + max(Sc, Dc)]
|
||||
|
||||
kModeCount
|
||||
};
|
||||
/** Return an SkXfermode object for the specified mode.
|
||||
*/
|
||||
static SkXfermode* CreateXfermode(Mode mode);
|
||||
|
||||
/** Return a function pointer to a routine that applies the specified porter-duff
|
||||
transfer mode.
|
||||
*/
|
||||
static SkXfermodeProc GetXfermodeProc(Mode mode);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef SkPrefix_Debug_Fixed_DEFINED
|
||||
#define SkPrefix_Debug_Fixed_DEFINED
|
||||
|
||||
#define SK_DEBUG
|
||||
|
||||
/* define this to test fixed-point */
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
|
||||
/* these are for expat */
|
||||
#define MACOS_CLASSIC
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef SkPrefix_Release_Fixed_DEFINED
|
||||
|
||||
#define SkPrefix_Release_Fixed_DEFINED
|
||||
|
||||
/* this means we're a release build */
|
||||
|
||||
#define NDEBUG
|
||||
|
||||
|
||||
|
||||
/* define this to test fixed-point */
|
||||
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
|
||||
|
||||
|
||||
/* these are for expat */
|
||||
|
||||
#define MACOS_CLASSIC
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef SkProgressBarView_DEFINED
|
||||
#define SkProgressBarView_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
#include "SkWidgetViews.h"
|
||||
#include "SkAnimator.h"
|
||||
|
||||
class SkProgressBarView : public SkWidgetView {
|
||||
public:
|
||||
SkProgressBarView();
|
||||
//SkProgressBarView(int max);
|
||||
|
||||
//inflate: "sk-progress"
|
||||
|
||||
void reset(); //reset progress to zero
|
||||
void setProgress(int progress);
|
||||
void changeProgress(int diff);
|
||||
void setMax(int max);
|
||||
|
||||
int getProgress() const { return fProgress; }
|
||||
int getMax() const { return fMax; }
|
||||
|
||||
protected:
|
||||
//overrides
|
||||
virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
|
||||
virtual void onSizeChange();
|
||||
virtual void onDraw(SkCanvas* canvas);
|
||||
virtual bool onEvent(const SkEvent& evt);
|
||||
|
||||
private:
|
||||
SkAnimator fAnim;
|
||||
int fProgress;
|
||||
int fMax;
|
||||
|
||||
typedef SkWidgetView INHERITED;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef SkRasterizer_DEFINED
|
||||
#define SkRasterizer_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkMask.h"
|
||||
|
||||
class SkMaskFilter;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
struct SkRect16;
|
||||
|
||||
class SkRasterizer : public SkFlattenable {
|
||||
public:
|
||||
SkRasterizer() {}
|
||||
|
||||
/** Turn the path into a mask, respecting the specified local->device matrix.
|
||||
*/
|
||||
bool rasterize(const SkPath& path, const SkMatrix& matrix,
|
||||
const SkRect16* clipBounds, SkMaskFilter* filter,
|
||||
SkMask* mask, SkMask::CreateMode mode);
|
||||
|
||||
protected:
|
||||
SkRasterizer(SkRBuffer&);
|
||||
|
||||
virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
|
||||
const SkRect16* clipBounds,
|
||||
SkMask* mask, SkMask::CreateMode mode);
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef SkRefCnt_DEFINED
|
||||
#define SkRefCnt_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \class SkRefCnt
|
||||
|
||||
SkRefCnt is the base class for objects that may be shared by multiple objects.
|
||||
When a new owner wants a reference, it calls ref(). When an owner wants to release
|
||||
its reference, it calls unref(). When the shared object's reference count goes to
|
||||
zero as the result of an unref() call, its (virtual) destructor is called. It is
|
||||
an error for the destructor to be called explicitly (or via the object going out
|
||||
of scope on the stack or calling delete) if getRefCnt() > 1.
|
||||
*/
|
||||
class SkRefCnt {
|
||||
public:
|
||||
/** Default construct, initializing the reference count to 1.
|
||||
*/
|
||||
SkRefCnt() : fRefCnt(1) {}
|
||||
/** Destruct, asserting that the reference count is 1.
|
||||
*/
|
||||
virtual ~SkRefCnt() { SkASSERT(fRefCnt == 1); }
|
||||
|
||||
/** Return the reference count.
|
||||
*/
|
||||
int getRefCnt() const { return fRefCnt; }
|
||||
/** Increment the reference count. Must be balanced by a call to unref().
|
||||
*/
|
||||
void ref() const { SkASSERT(fRefCnt > 0); ++fRefCnt; }
|
||||
/** Decrement the reference count. If the reference count is 1 before the
|
||||
decrement, then call delete on the object. Note that if this is the case,
|
||||
then the object needs to have been allocated via new, and not on the stack.
|
||||
*/
|
||||
void unref() const
|
||||
{
|
||||
SkASSERT(fRefCnt > 0);
|
||||
if (fRefCnt == 1)
|
||||
delete this;
|
||||
else
|
||||
--fRefCnt;
|
||||
}
|
||||
|
||||
/** Helper version of ref(), that first checks to see if this is not nil.
|
||||
If this is nil, then do nothing.
|
||||
*/
|
||||
void safeRef() const { if (this) this->ref(); }
|
||||
/** Helper version of unref(), that first checks to see if this is not nil.
|
||||
If this is nil, then do nothing.
|
||||
*/
|
||||
void safeUnref() const { if (this) this->unref(); }
|
||||
|
||||
private:
|
||||
mutable int fRefCnt;
|
||||
};
|
||||
|
||||
/** \class SkAutoUnref
|
||||
|
||||
SkAutoUnref is a stack-helper class that will automatically call unref() on
|
||||
the object it points to when the SkAutoUnref object goes out of scope.
|
||||
*/
|
||||
class SkAutoUnref {
|
||||
public:
|
||||
SkAutoUnref(SkRefCnt* obj) : fObj(obj) {}
|
||||
~SkAutoUnref();
|
||||
|
||||
SkRefCnt* get() const { return fObj; }
|
||||
bool ref();
|
||||
bool unref();
|
||||
SkRefCnt* detach();
|
||||
|
||||
private:
|
||||
SkRefCnt* fObj;
|
||||
};
|
||||
|
||||
/** Helper macro to safely assign one SkRefCnt* to another, checking for
|
||||
nil in on each side of the assignment, and ensuring that ref() is called
|
||||
before unref(), in case the two pointers point to the same object.
|
||||
*/
|
||||
#define SkRefCnt_SafeAssign(dst, src) \
|
||||
do { \
|
||||
if (src) src->ref(); \
|
||||
if (dst) dst->unref(); \
|
||||
dst = src; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef SkSVGAttribute_DEFINED
|
||||
#define SkSVGAttribute_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
struct SkSVGAttribute {
|
||||
const char* fName;
|
||||
#ifdef SK_DEBUG
|
||||
size_t fOffset;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef SK_OFFSETOF
|
||||
#define SK_OFFSETOF(a, b) (((size_t) (&(((a*) 1)->b)))-1)
|
||||
#endif
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#define SVG_ATTRIBUTE(attr) { #attr, SK_OFFSETOF(BASE_CLASS, f_##attr) }
|
||||
#define SVG_LITERAL_ATTRIBUTE(svgAttr, cAttr) { #svgAttr, SK_OFFSETOF(BASE_CLASS, cAttr) }
|
||||
#else
|
||||
#define SVG_ATTRIBUTE(attr) { #attr }
|
||||
#define SVG_LITERAL_ATTRIBUTE(svgAttr, cAttr) { #svgAttr }
|
||||
#endif
|
||||
|
||||
#define SVG_ADD_ATTRIBUTE(attr) \
|
||||
if (f_##attr.size() > 0) \
|
||||
parser._addAttributeLen(#attr, f_##attr.c_str(), f_##attr.size())
|
||||
|
||||
#define SVG_ADD_ATTRIBUTE_ALIAS(attr, alias) \
|
||||
if (f_##alias.size() > 0) \
|
||||
parser._addAttributeLen(#attr, f_##alias.c_str(), f_##alias.size())
|
||||
|
||||
#endif // SkSVGAttribute_DEFINED
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef SkSVGBase_DEFINED
|
||||
#define SkSVGBase_DEFINED
|
||||
|
||||
#include "SkSVGAttribute.h"
|
||||
|
||||
class SkSVGParser;
|
||||
|
||||
class SkSVGBase {
|
||||
public:
|
||||
virtual ~SkSVGBase();
|
||||
virtual void addAttribute(SkSVGParser& parser, int attrIndex,
|
||||
const char* attrValue, size_t attrLength);
|
||||
virtual int getAttributes(const SkSVGAttribute** attrPtr) = 0;
|
||||
};
|
||||
|
||||
#endif // SkSVGBase_DEFINED
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef SkSVGPaintState_DEFINED
|
||||
#define SkSVGPaintState_DEFINED
|
||||
|
||||
#include "SkSVGBase.h"
|
||||
#include "SkString.h"
|
||||
|
||||
class SkSVGPaint : public SkSVGBase {
|
||||
public:
|
||||
enum Field {
|
||||
kInitial = -1,
|
||||
kClipPath,
|
||||
kClipRule,
|
||||
kEnableBackground,
|
||||
kFill,
|
||||
kFillRule,
|
||||
kFilter,
|
||||
kFontFamily,
|
||||
kFontSize,
|
||||
kLetterSpacing,
|
||||
kMask,
|
||||
kOpacity,
|
||||
kStopColor,
|
||||
kStopOpacity,
|
||||
kStroke,
|
||||
kStroke_Dasharray,
|
||||
kStroke_Linecap,
|
||||
kStroke_Linejoin,
|
||||
kStroke_Miterlimit,
|
||||
kStroke_Width,
|
||||
kStyle,
|
||||
kTransform,
|
||||
kTerminal
|
||||
};
|
||||
|
||||
SkSVGPaint();
|
||||
virtual void addAttribute(SkSVGParser& parser, int attrIndex,
|
||||
const char* attrValue, size_t attrLength);
|
||||
bool flush(SkSVGParser& , bool isFlushable, bool isDef);
|
||||
virtual int getAttributes(const SkSVGAttribute** attrPtr);
|
||||
static void Push(SkSVGPaint** head, SkSVGPaint* add);
|
||||
static void Pop(SkSVGPaint** head);
|
||||
SkString* operator[](int index);
|
||||
SkString fInitial;
|
||||
SkString f_clipPath;
|
||||
SkString f_clipRule;
|
||||
SkString f_enableBackground;
|
||||
SkString f_fill;
|
||||
SkString f_fillRule;
|
||||
SkString f_filter;
|
||||
SkString f_fontFamily;
|
||||
SkString f_fontSize;
|
||||
SkString f_letterSpacing;
|
||||
SkString f_mask;
|
||||
SkString f_opacity;
|
||||
SkString f_stopColor;
|
||||
SkString f_stopOpacity;
|
||||
SkString f_stroke;
|
||||
SkString f_strokeDasharray;
|
||||
SkString f_strokeLinecap;
|
||||
SkString f_strokeLinejoin;
|
||||
SkString f_strokeMiterlimit;
|
||||
SkString f_strokeWidth;
|
||||
SkString f_style; // unused, but allows array access to the rest
|
||||
SkString f_transform;
|
||||
#ifdef SK_DEBUG
|
||||
SkString fTerminal;
|
||||
#endif
|
||||
SkString fTransformID;
|
||||
static SkSVGAttribute gAttributes[];
|
||||
static const int kAttributesSize;
|
||||
private:
|
||||
void setSave(SkSVGParser& );
|
||||
bool writeChangedAttributes(SkSVGParser& , SkSVGPaint& , bool* changed);
|
||||
bool writeChangedElements(SkSVGParser& , SkSVGPaint& , bool* changed);
|
||||
SkSVGPaint* fNext;
|
||||
friend class SkSVGParser;
|
||||
typedef SkSVGPaint BASE_CLASS;
|
||||
};
|
||||
|
||||
#endif // SkSVGPaintState_DEFINED
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef SkSVGParser_DEFINED
|
||||
#define SkSVGParser_DEFINED
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkTDict.h"
|
||||
#include "SkTDStack.h"
|
||||
#include "SkSVGPaintState.h"
|
||||
#include "SkSVGTypes.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkString.h"
|
||||
#include "SkXMLParser.h"
|
||||
#include "SkXMLWriter.h"
|
||||
|
||||
class SkSVGBase;
|
||||
class SkSVGElement;
|
||||
|
||||
class SkSVGParser : public SkXMLParser {
|
||||
public:
|
||||
SkSVGParser();
|
||||
virtual ~SkSVGParser();
|
||||
void _addAttribute(const char* attrName, const char* attrValue) {
|
||||
fXMLWriter.addAttribute(attrName, attrValue); }
|
||||
void _addAttribute(const char* attrName, SkString& attrValue) {
|
||||
fXMLWriter.addAttribute(attrName, attrValue.c_str()); }
|
||||
void _addAttributeLen(const char* attrName, const char* attrValue, size_t len) {
|
||||
fXMLWriter.addAttributeLen(attrName, attrValue, len); }
|
||||
void _endElement() { fXMLWriter.endElement(); }
|
||||
int findAttribute(SkSVGBase* , const char* attrValue, size_t len, bool isPaint);
|
||||
const char* getFinal();
|
||||
SkTDict<SkSVGElement*>& getIDs() { return fIDs; }
|
||||
SkString& getPaintLast(SkSVGPaint::Field field);
|
||||
void _startElement(const char name[]) { fXMLWriter.startElement(name); }
|
||||
void translate(SkSVGElement*, bool isDef);
|
||||
void translateMatrix(SkString& , SkString* id);
|
||||
static void ConvertToArray(SkString& vals);
|
||||
protected:
|
||||
virtual bool onAddAttribute(const char name[], const char value[]);
|
||||
bool onAddAttributeLen(const char name[], const char value[], size_t len);
|
||||
virtual bool onEndElement(const char elem[]);
|
||||
virtual bool onStartElement(const char elem[]);
|
||||
bool onStartElementLen(const char elem[], size_t len);
|
||||
virtual bool onText(const char text[], int len);
|
||||
private:
|
||||
bool isStrokeAndFill(SkSVGPaint** stroke, SkSVGPaint** fill);
|
||||
static SkSVGElement* CreateElement(SkSVGTypes type, SkSVGElement* parent);
|
||||
static void Delete(SkTDArray<SkSVGElement*>& fChildren);
|
||||
static SkSVGTypes GetType(const char name[], size_t len);
|
||||
SkSVGPaint* fHead;
|
||||
SkSVGPaint fEmptyPaint;
|
||||
SkSVGPaint fLastFlush;
|
||||
SkString fLastColor;
|
||||
SkMatrix fLastTransform;
|
||||
SkTDArray<SkSVGElement*> fChildren;
|
||||
SkTDict<SkSVGElement*> fIDs;
|
||||
SkTDArray<SkSVGElement*> fParents;
|
||||
SkDynamicMemoryWStream fStream;
|
||||
SkXMLStreamWriter fXMLWriter;
|
||||
SkSVGElement* fCurrElement;
|
||||
SkBool8 fInSVG;
|
||||
SkBool8 fSuppressPaint;
|
||||
friend class SkSVGPaint;
|
||||
friend class SkSVGGradient;
|
||||
};
|
||||
|
||||
#endif // SkSVGParser_DEFINED
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef SkSVGTypes_DEFINED
|
||||
#define SkSVGTypes_DEFINED
|
||||
|
||||
enum SkSVGTypes {
|
||||
SkSVGType_Circle,
|
||||
SkSVGType_ClipPath,
|
||||
SkSVGType_Defs,
|
||||
SkSVGType_Ellipse,
|
||||
SkSVGType_FeColorMatrix,
|
||||
SkSVGType_Filter,
|
||||
SkSVGType_G,
|
||||
SkSVGType_Image,
|
||||
SkSVGType_Line,
|
||||
SkSVGType_LinearGradient,
|
||||
SkSVGType_Mask,
|
||||
SkSVGType_Metadata,
|
||||
SkSVGType_Path,
|
||||
SkSVGType_Polygon,
|
||||
SkSVGType_Polyline,
|
||||
SkSVGType_RadialGradient,
|
||||
SkSVGType_Rect,
|
||||
SkSVGType_SVG,
|
||||
SkSVGType_Stop,
|
||||
SkSVGType_Symbol,
|
||||
SkSVGType_Text,
|
||||
SkSVGType_Tspan,
|
||||
SkSVGType_Use
|
||||
};
|
||||
|
||||
#endif // SkSVGTypes_DEFINED
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef SkScalerContext_DEFINED
|
||||
#define SkScalerContext_DEFINED
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
class SkDescriptor;
|
||||
class SkMaskFilter;
|
||||
class SkPaint;
|
||||
class SkPathEffect;
|
||||
class SkRasterizer;
|
||||
|
||||
#define SK_UnknownAuxScalerContextID 0
|
||||
#define SK_MaxAuxScalerContextID 16
|
||||
|
||||
struct SkGlyph {
|
||||
void* fImage;
|
||||
SkPath* fPath;
|
||||
SkFixed fAdvanceX, fAdvanceY;
|
||||
|
||||
uint16_t fGlyphID;
|
||||
uint16_t fWidth, fHeight, fRowBytes;
|
||||
int16_t fTop, fLeft;
|
||||
|
||||
uint16_t fCharCode; // might go away with line layout. really wants 20bits
|
||||
uint8_t fMaskFormat;
|
||||
SkBool8 fUseAuxContext; // just need 1-bit for this field
|
||||
|
||||
size_t computeImageSize() const;
|
||||
};
|
||||
|
||||
class SkScalerContext {
|
||||
public:
|
||||
struct Rec {
|
||||
SkScalar fTextSize, fPreScaleX, fPreSkewX;
|
||||
SkScalar fPost2x2[2][2];
|
||||
SkScalar fFrameWidth, fMiterLimit;
|
||||
SkBool8 fUseHints;
|
||||
SkBool8 fFrameAndFill;
|
||||
SkBool8 fDoAA;
|
||||
uint8_t fStrokeJoin;
|
||||
|
||||
void getMatrixFrom2x2(SkMatrix*) const;
|
||||
void getLocalMatrix(SkMatrix*) const;
|
||||
void getSingleMatrix(SkMatrix*) const;
|
||||
};
|
||||
|
||||
SkScalerContext(const SkDescriptor* desc);
|
||||
virtual ~SkScalerContext();
|
||||
|
||||
void getMetrics(SkGlyph*);
|
||||
void getImage(const SkGlyph&);
|
||||
void getPath(const SkGlyph&, SkPath*);
|
||||
void getLineHeight(SkPoint* above, SkPoint* below);
|
||||
|
||||
static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
|
||||
static SkScalerContext* Create(const SkDescriptor*);
|
||||
|
||||
protected:
|
||||
Rec fRec;
|
||||
|
||||
virtual void generateMetrics(SkGlyph*) = 0;
|
||||
virtual void generateImage(const SkGlyph&) = 0;
|
||||
virtual void generatePath(const SkGlyph&, SkPath*) = 0;
|
||||
virtual void generateLineHeight(SkPoint* above, SkPoint* below) = 0;
|
||||
|
||||
private:
|
||||
SkPathEffect* fPathEffect;
|
||||
SkMaskFilter* fMaskFilter;
|
||||
SkRasterizer* fRasterizer;
|
||||
SkScalar fDevFrameWidth;
|
||||
|
||||
void internalGetPath(const SkGlyph& glyph, SkPath* fillPath, SkPath* devPath, SkMatrix* fillToDevMatrix);
|
||||
|
||||
// we index into this with scalerContextID-1
|
||||
SkScalerContext* fAuxContext[SK_MaxAuxScalerContextID];
|
||||
};
|
||||
|
||||
#define kRec_SkDescriptorTag SkSetFourByteTag('s', 'r', 'e', 'c')
|
||||
#define kTypeface_SkDescriptorTag SkSetFourByteTag('t', 'p', 'f', 'c')
|
||||
#define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e')
|
||||
#define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f')
|
||||
#define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't')
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef SkScrollBarView_DEFINED
|
||||
#define SkScrollBarView_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
#include "SkWidgetViews.h"
|
||||
#include "SkAnimator.h"
|
||||
|
||||
class SkScrollBarView : public SkWidgetView {
|
||||
public:
|
||||
SkScrollBarView();
|
||||
|
||||
unsigned getStart() const { return fStartPoint; }
|
||||
unsigned getShown() const { return fShownLength; }
|
||||
unsigned getTotal() const { return fTotalLength; }
|
||||
|
||||
void setStart(unsigned start);
|
||||
void setShown(unsigned shown);
|
||||
void setTotal(unsigned total);
|
||||
|
||||
protected:
|
||||
//overrides
|
||||
virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
|
||||
virtual void onSizeChange();
|
||||
virtual void onDraw(SkCanvas* canvas);
|
||||
virtual bool onEvent(const SkEvent& evt);
|
||||
|
||||
private:
|
||||
SkAnimator fAnim;
|
||||
unsigned fTotalLength, fStartPoint, fShownLength;
|
||||
|
||||
void adjust();
|
||||
|
||||
typedef SkWidgetView INHERITED;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,146 @@
|
|||
#ifndef SkShader_DEFINED
|
||||
#define SkShader_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkMask.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPaint.h"
|
||||
|
||||
class SkPath;
|
||||
|
||||
/** \class SkShader
|
||||
|
||||
SkShader is the based class for objects that return horizontal spans of colors during drawing.
|
||||
A subclass of SkShader is installed in a SkPaint calling paint.setShader(shader). After that
|
||||
any object (other than a bitmap) that is drawn with that paint will get its color(s) from the
|
||||
shader.
|
||||
*/
|
||||
class SkShader : public SkRefCnt {
|
||||
public:
|
||||
SkShader();
|
||||
virtual ~SkShader();
|
||||
|
||||
/** Return the shader's optional local matrix, or nil.
|
||||
*/
|
||||
const SkMatrix* getLocalMatrix() const { return fLocalMatrix; }
|
||||
/** Set the shader's optional local matrix. If the specified matrix is identity, then
|
||||
getLocalMatrix() will return nil.
|
||||
*/
|
||||
void setLocalMatrix(const SkMatrix&);
|
||||
|
||||
enum TileMode {
|
||||
kClamp_TileMode, //!< replicate the edge color if the shader draws outside of its original bounds
|
||||
kRepeat_TileMode, //!< repeat the shader's image horizontally and vertically
|
||||
kMirror_TileMode, //!< repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam
|
||||
|
||||
kTileModeCount
|
||||
};
|
||||
|
||||
// override these in your subclass
|
||||
|
||||
enum Flags {
|
||||
kOpaqueAlpha_Flag = 0x01, //!< set if all of the colors will be opaque (if so, kConstAlpha_Flag will not be set)
|
||||
kConstAlpha_Flag = 0x02, //!< set if all of the colors have the same (non-opaque) alpha
|
||||
kHasSpan16_Flag = 0x04, //!< set if this shader's shadeSpanOpaque16() method can be called
|
||||
|
||||
kFlagsMask = kOpaqueAlpha_Flag | kConstAlpha_Flag | kHasSpan16_Flag
|
||||
};
|
||||
|
||||
/** Called sometimes before drawing with this shader.
|
||||
Return the type of alpha your shader will return.
|
||||
The default implementation returns 0. Your subclass should override if it can
|
||||
(even sometimes) report a non-zero value, since that will enable various blitters
|
||||
to perform faster.
|
||||
*/
|
||||
virtual U32 getFlags();
|
||||
|
||||
/** Called once before drawing, with the current paint and
|
||||
device matrix. Return true if your shader supports these
|
||||
parameters, or false if not. If false is returned, nothing
|
||||
will be drawn.
|
||||
*/
|
||||
virtual bool setContext( const SkBitmap& device,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix& matrix);
|
||||
|
||||
/** Called for each span of the object being drawn. Your subclass
|
||||
should set the appropriate colors (with premultiplied alpha) that
|
||||
correspond to the specified device coordinates.
|
||||
*/
|
||||
virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
|
||||
/** Called only for 16bit devices when getFlags() returns kOpaqueAlphaFlag | kHasSpan16_Flag
|
||||
*/
|
||||
virtual void shadeSpanOpaque16(int x, int y, U16[], int count);
|
||||
/** Similar to shadeSpan, but only returns the alpha-channel for a span.
|
||||
The default implementation calls shadeSpan() and then extracts the alpha
|
||||
values from the returned colors.
|
||||
*/
|
||||
virtual void shadeSpanAlpha(int x, int y, U8 alpha[], int count);
|
||||
|
||||
/** Helper function that returns true if this shader's shadeSpanOpaque16() method can
|
||||
be called.
|
||||
*/
|
||||
bool canCallShadeSpanOpaque16()
|
||||
{
|
||||
return SkShader::CanCallShadeSpanOpaque16(this->getFlags());
|
||||
}
|
||||
|
||||
/** Helper to check the flags to know if it is legal to call shadeSpanOpaque16()
|
||||
*/
|
||||
static bool CanCallShadeSpanOpaque16(U32 flags)
|
||||
{
|
||||
return (flags & (kOpaqueAlpha_Flag | kHasSpan16_Flag)) == (kOpaqueAlpha_Flag | kHasSpan16_Flag);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Factory methods for stock shaders
|
||||
|
||||
/** Call this to create a new shader that will draw with the specified bitmap.
|
||||
@param src The bitmap to use inside the shader
|
||||
@param transferOwnershipOfPixels If true, the shader will call setOwnsPixels(true) on its private bitmap
|
||||
and setOwnsPixels(false) on the src bitmap, resulting in the bitmap's pixels
|
||||
being disposed when the shader is deleted.
|
||||
@param ft The filter type to be used when scaling or rotating the bitmap when it is drawn.
|
||||
@param tmx The tiling mode to use when sampling the bitmap in the x-direction.
|
||||
@param tmy The tiling mode to use when sampling the bitmap in the y-direction.
|
||||
@return Returns a new shader object. Note: this function never returns nil.
|
||||
*/
|
||||
static SkShader* CreateBitmapShader(const SkBitmap& src,
|
||||
bool transferOwnershipOfPixels,
|
||||
SkPaint::FilterType ft,
|
||||
TileMode tmx, TileMode tmy);
|
||||
|
||||
protected:
|
||||
enum MatrixClass {
|
||||
kLinear_MatrixClass, // no perspective
|
||||
kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each scanline
|
||||
kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
|
||||
};
|
||||
static MatrixClass ComputeMatrixClass(const SkMatrix&);
|
||||
|
||||
// These can be called by your subclass after setContext() has been called
|
||||
U8 getPaintAlpha() const { return fPaintAlpha; }
|
||||
SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
|
||||
const SkMatrix& getTotalInverse() const { return fTotalInverse; }
|
||||
MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
|
||||
SkMatrix::MapPtProc getInverseMapPtProc() const { return fInverseMapPtProc; }
|
||||
|
||||
private:
|
||||
SkMatrix* fLocalMatrix;
|
||||
SkMatrix fTotalInverse;
|
||||
SkMatrix::MapPtProc fInverseMapPtProc;
|
||||
U8 fPaintAlpha;
|
||||
U8 fDeviceConfig;
|
||||
U8 fTotalInverseClass;
|
||||
|
||||
static SkShader* CreateBitmapShader(const SkBitmap& src,
|
||||
bool transferOwnershipOfPixels,
|
||||
SkPaint::FilterType,
|
||||
TileMode, TileMode,
|
||||
void* storage, size_t storageSize);
|
||||
friend class SkAutoBitmapShaderInstall;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef SkShaderExtras_DEFINED
|
||||
#define SkShaderExtras_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkColorCombine : public SkRefCnt {
|
||||
public:
|
||||
/** Called with two scanlines of color. The implementation writes out its combination of
|
||||
those into the result[] scaline.
|
||||
*/
|
||||
virtual void combineSpan(const SkPMColor srcA[], const SkPMColor srcB[], int count, SkPMColor result[]) = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkComposeShader : public SkShader {
|
||||
public:
|
||||
SkComposeShader(SkShader* sA, SkShader* sB, SkColorCombine* combine);
|
||||
virtual ~SkComposeShader();
|
||||
|
||||
// override
|
||||
virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix);
|
||||
virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
|
||||
|
||||
private:
|
||||
enum {
|
||||
COUNT = 32
|
||||
};
|
||||
SkShader* fShaderA;
|
||||
SkShader* fShaderB;
|
||||
SkColorCombine* fCombine;
|
||||
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef SkStackViewLayout_DEFINED
|
||||
#define SkStackViewLayout_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
|
||||
class SkStackViewLayout : public SkView::Layout {
|
||||
public:
|
||||
SkStackViewLayout();
|
||||
|
||||
enum Orient {
|
||||
kHorizontal_Orient,
|
||||
kVertical_Orient,
|
||||
|
||||
kOrientCount
|
||||
};
|
||||
Orient getOrient() const { return (Orient)fOrient; }
|
||||
void setOrient(Orient);
|
||||
|
||||
void getMargin(SkRect*) const;
|
||||
void setMargin(const SkRect&);
|
||||
|
||||
SkScalar getSpacer() const { return fSpacer; }
|
||||
void setSpacer(SkScalar);
|
||||
|
||||
/** Controls the posititioning in the same direction as the orientation
|
||||
*/
|
||||
enum Pack {
|
||||
kStart_Pack,
|
||||
kCenter_Pack,
|
||||
kEnd_Pack,
|
||||
|
||||
kPackCount
|
||||
};
|
||||
Pack getPack() const { return (Pack)fPack; }
|
||||
void setPack(Pack);
|
||||
|
||||
/** Controls the posititioning at right angles to the orientation
|
||||
*/
|
||||
enum Align {
|
||||
kStart_Align,
|
||||
kCenter_Align,
|
||||
kEnd_Align,
|
||||
kStretch_Align,
|
||||
|
||||
kAlignCount
|
||||
};
|
||||
Align getAlign() const { return (Align)fAlign; }
|
||||
void setAlign(Align);
|
||||
|
||||
bool getRound() const { return SkToBool(fRound); }
|
||||
void setRound(bool);
|
||||
|
||||
protected:
|
||||
virtual void onLayoutChildren(SkView* parent);
|
||||
virtual void onInflate(const SkDOM&, const SkDOM::Node*);
|
||||
|
||||
private:
|
||||
SkRect fMargin;
|
||||
SkScalar fSpacer;
|
||||
U8 fOrient, fPack, fAlign, fRound;
|
||||
};
|
||||
|
||||
class SkFillViewLayout : public SkView::Layout {
|
||||
public:
|
||||
SkFillViewLayout();
|
||||
void getMargin(SkRect*) const;
|
||||
void setMargin(const SkRect&);
|
||||
|
||||
protected:
|
||||
// overrides;
|
||||
virtual void onLayoutChildren(SkView* parent);
|
||||
virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
|
||||
|
||||
private:
|
||||
SkRect fMargin;
|
||||
typedef SkView::Layout INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef SkStdLib_Redirect_DEFINED
|
||||
#define SkStdLib_Redirect_DEFINED
|
||||
|
||||
#error
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#define fread(buffer, count, size, file) sk_stdlib_fread(buffer, count, size, file)
|
||||
#define qsort
|
||||
#define tolower
|
||||
#define setjmp
|
||||
#define longjmp
|
||||
#define memmove
|
||||
#define malloc
|
||||
#define realloc
|
||||
#endif
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
#ifndef SkStream_DEFINED
|
||||
#define SkStream_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkStream {
|
||||
public:
|
||||
virtual ~SkStream() {}
|
||||
/** Called to rewind to the beginning of the stream. If this cannot be
|
||||
done, return false.
|
||||
*/
|
||||
virtual bool rewind() = 0;
|
||||
/** If this stream represents a file, this method returns the file's name.
|
||||
If it does not, it returns nil (the default behavior).
|
||||
*/
|
||||
virtual const char* getFileName();
|
||||
/** Called to read or skip size number of bytes. If buffer is nil, skip
|
||||
the bytes, else copy them into buffer. If this cannot be done, return false.
|
||||
If buffer is nil and size is zero, return the file length
|
||||
@param buffer If buffer is nil, ignore and just skip size bytes, otherwise copy size bytes into buffer
|
||||
@param size The number of bytes to skip or copy
|
||||
@return bytes read on success
|
||||
*/
|
||||
virtual size_t read(void* buffer, size_t size) = 0;
|
||||
static SkStream* GetURIStream(const char prefix[], const char path[]);
|
||||
static bool IsAbsoluteURI(const char path[]);
|
||||
};
|
||||
|
||||
class SkWStream {
|
||||
public:
|
||||
virtual ~SkWStream();
|
||||
|
||||
/** Called to write bytes to a SkWStream. Returns true on success
|
||||
@param buffer the address of at least size bytes to be written to the stream
|
||||
@param size The number of bytes in buffer to write to the stream
|
||||
@return true on success
|
||||
*/
|
||||
virtual bool write(const void* buffer, size_t size) = 0;
|
||||
virtual void newline();
|
||||
virtual void flush();
|
||||
|
||||
// helpers
|
||||
|
||||
bool writeText(const char text[]);
|
||||
bool writeDecAsText(S32);
|
||||
bool writeHexAsText(U32, int minDigits = 0);
|
||||
bool writeScalarAsText(SkScalar);
|
||||
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkString.h"
|
||||
|
||||
struct SkFILE;
|
||||
|
||||
class SkFILEStream : public SkStream {
|
||||
public:
|
||||
SkFILEStream(const char path[] = nil);
|
||||
virtual ~SkFILEStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFILE != nil; }
|
||||
/** Close the current file, and open a new file with the specified
|
||||
path. If path is nil, just close the current file.
|
||||
*/
|
||||
void setPath(const char path[]);
|
||||
|
||||
SkFILE* getSkFILE() const { return fFILE; }
|
||||
|
||||
virtual bool rewind();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
virtual const char* getFileName();
|
||||
|
||||
private:
|
||||
SkFILE* fFILE;
|
||||
SkString fName;
|
||||
};
|
||||
|
||||
class SkMemoryStream : public SkStream {
|
||||
public:
|
||||
SkMemoryStream(const void* src, size_t length);
|
||||
|
||||
virtual bool rewind();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
const void* fSrc;
|
||||
size_t fSize, fOffset;
|
||||
};
|
||||
|
||||
/** \class SkBufferStream
|
||||
This is a wrapper class that adds buffering to another stream.
|
||||
The caller can provide the buffer, or ask SkBufferStream to allocated/free
|
||||
it automatically.
|
||||
*/
|
||||
class SkBufferStream : public SkStream {
|
||||
public:
|
||||
/** Provide the stream to be buffered (proxy), and the size of the buffer that
|
||||
should be used. This will be allocated and freed automatically. If bufferSize is 0,
|
||||
a default buffer size will be used.
|
||||
*/
|
||||
SkBufferStream(SkStream& proxy, size_t bufferSize = 0);
|
||||
/** Provide the stream to be buffered (proxy), and a buffer and size to be used.
|
||||
This buffer is owned by the caller, and must be at least bufferSize bytes big.
|
||||
Passing nil for buffer will cause the buffer to be allocated/freed automatically.
|
||||
If buffer is not nil, it is an error for bufferSize to be 0.
|
||||
*/
|
||||
SkBufferStream(SkStream& proxy, void* buffer, size_t bufferSize);
|
||||
virtual ~SkBufferStream();
|
||||
|
||||
virtual bool rewind();
|
||||
virtual const char* getFileName();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
private:
|
||||
enum {
|
||||
kDefaultBufferSize = 128
|
||||
};
|
||||
// illegal
|
||||
SkBufferStream(const SkBufferStream&);
|
||||
SkBufferStream& operator=(const SkBufferStream&);
|
||||
|
||||
SkStream& fProxy;
|
||||
char* fBuffer;
|
||||
size_t fOrigBufferSize, fBufferSize, fBufferOffset;
|
||||
bool fWeOwnTheBuffer;
|
||||
|
||||
void init(void*, size_t);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkFILEWStream : public SkWStream {
|
||||
public:
|
||||
SkFILEWStream(const char path[]);
|
||||
virtual ~SkFILEWStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFILE != nil; }
|
||||
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
virtual void flush();
|
||||
private:
|
||||
SkFILE* fFILE;
|
||||
};
|
||||
|
||||
class SkMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SkMemoryWStream(void* buffer, size_t size);
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
char* fBuffer;
|
||||
size_t fMaxLength;
|
||||
size_t fBytesWritten;
|
||||
};
|
||||
|
||||
class SkDynamicMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SkDynamicMemoryWStream();
|
||||
virtual ~SkDynamicMemoryWStream();
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
// random access write
|
||||
// modifies stream and returns true if offset + size is less than or equal to getOffset()
|
||||
bool write(const void* buffer, size_t offset, size_t size);
|
||||
size_t getOffset() { return fBytesWritten; }
|
||||
|
||||
// copy what has been written to the stream into dst
|
||||
void copyTo(void* dst) const;
|
||||
/* return a cache of the flattened data returned by copyTo().
|
||||
This copy is only valid until the next call to write().
|
||||
The memory is managed by the stream class.
|
||||
*/
|
||||
const char* getStream() const;
|
||||
|
||||
private:
|
||||
struct Block;
|
||||
Block* fHead;
|
||||
Block* fTail;
|
||||
size_t fBytesWritten;
|
||||
mutable char* fCopyToCache;
|
||||
};
|
||||
|
||||
|
||||
class SkDebugWStream : public SkWStream {
|
||||
public:
|
||||
// overrides
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
virtual void newline();
|
||||
};
|
||||
|
||||
// for now
|
||||
typedef SkFILEStream SkURLStream;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef SkStream_Win_DEFINED
|
||||
#define SkStream_Win_DEFINED
|
||||
|
||||
#ifndef SK_BUILD_FOR_WIN
|
||||
#error "only valid for windows and wince builds"
|
||||
#endif
|
||||
|
||||
#ifndef SkStream_DEFINED
|
||||
#include "SkStream.h"
|
||||
#endif
|
||||
#include "SkString.h"
|
||||
#include "Wininet.h"
|
||||
|
||||
/** \cond ZERO */
|
||||
class SkURLStream : public SkStream {
|
||||
public:
|
||||
SkURLStream(const char url[] = nil);
|
||||
virtual ~SkURLStream();
|
||||
|
||||
/** Close the current URL, and open a new URL.
|
||||
If URL is nil, just close the current URL.
|
||||
*/
|
||||
void setURL(const char url[]);
|
||||
|
||||
// overrides
|
||||
virtual bool rewind();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
SkString fURL;
|
||||
HINTERNET fConnection;
|
||||
HINTERNET fURLStream;
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
#endif // SkStream_Win_DEFINED
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче