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:
croachrose 2006-09-20 15:47:42 +00:00
parent 586101c79b
commit 0f87cd842d
488 changed files with 79697 additions and 0 deletions

219
include/corecg/Sk64.h Normal file
View File

@ -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

135
include/corecg/SkBuffer.h Normal file
View File

@ -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

View File

@ -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

82
include/corecg/SkEndian.h Normal file
View File

@ -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

51
include/corecg/SkFDot6.h Normal file
View File

@ -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

159
include/corecg/SkFixed.h Normal file
View File

@ -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

View File

@ -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

132
include/corecg/SkMath.h Normal file
View File

@ -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

298
include/corecg/SkMatrix.h Normal file
View File

@ -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

244
include/corecg/SkPoint.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

85
include/corecg/SkRandom.h Normal file
View File

@ -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

266
include/corecg/SkRect.h Normal file
View File

@ -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

249
include/corecg/SkRegion.h Normal file
View File

@ -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

235
include/corecg/SkScalar.h Normal file
View File

@ -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

View File

@ -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

40
include/corecg/SkThread.h Normal file
View File

@ -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

View File

@ -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

299
include/corecg/SkTypes.h Normal file
View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
/** \mainpage notitle
* \htmlinclude "SGL Spec. rev 9.htm"
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

374
include/graphics/SkBitmap.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

470
include/graphics/SkCanvas.h Normal file
View File

@ -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

126
include/graphics/SkColor.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

83
include/graphics/SkDOM.h Normal file
View File

@ -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

View File

@ -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

191
include/graphics/SkDeque.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

228
include/graphics/SkEvent.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

31
include/graphics/SkJS.h Normal file
View File

@ -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;
};

47
include/graphics/SkKey.h Normal file
View File

@ -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

View File

@ -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

65
include/graphics/SkMask.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

630
include/graphics/SkPaint.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

373
include/graphics/SkPath.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

146
include/graphics/SkShader.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

199
include/graphics/SkStream.h Normal file
View File

@ -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

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More