summaryrefslogtreecommitdiffstats
path: root/skia/include/corecg
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
commitae2c20f398933a9e86c387dcc465ec0f71065ffc (patch)
treede668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/include/corecg
parent09911bf300f1a419907a9412154760efd0b7abc3 (diff)
downloadchromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.zip
chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.gz
chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.bz2
Add skia to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/include/corecg')
-rw-r--r--skia/include/corecg/Sk64.h245
-rw-r--r--skia/include/corecg/SkBuffer.h142
-rw-r--r--skia/include/corecg/SkChunkAlloc.h62
-rw-r--r--skia/include/corecg/SkEndian.h99
-rw-r--r--skia/include/corecg/SkFDot6.h68
-rw-r--r--skia/include/corecg/SkFixed.h254
-rw-r--r--skia/include/corecg/SkFloatingPoint.h65
-rw-r--r--skia/include/corecg/SkInterpolator.h139
-rw-r--r--skia/include/corecg/SkMath.h230
-rw-r--r--skia/include/corecg/SkMatrix.h476
-rw-r--r--skia/include/corecg/SkPerspIter.h56
-rw-r--r--skia/include/corecg/SkPoint.h288
-rw-r--r--skia/include/corecg/SkPostConfig.h211
-rw-r--r--skia/include/corecg/SkPreConfig.h111
-rw-r--r--skia/include/corecg/SkRandom.h110
-rw-r--r--skia/include/corecg/SkRect.h426
-rw-r--r--skia/include/corecg/SkRegion.h339
-rw-r--r--skia/include/corecg/SkScalar.h261
-rw-r--r--skia/include/corecg/SkTSearch.h168
-rw-r--r--skia/include/corecg/SkTemplates.h188
-rw-r--r--skia/include/corecg/SkThread.h69
-rw-r--r--skia/include/corecg/SkThread_platform.h72
-rw-r--r--skia/include/corecg/SkTypes.h377
-rw-r--r--skia/include/corecg/SkUserConfig.h118
24 files changed, 4574 insertions, 0 deletions
diff --git a/skia/include/corecg/Sk64.h b/skia/include/corecg/Sk64.h
new file mode 100644
index 0000000..4d5343c
--- /dev/null
+++ b/skia/include/corecg/Sk64.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2006-2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef Sk64_DEFINED
+#define Sk64_DEFINED
+
+#include "SkFixed.h"
+#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);
+
+ /** return (this + other >> 16) as a 32bit result */
+ SkFixed addGetFixed(const Sk64& other) const {
+ return this->addGetFixed(other.fHi, other.fLo);
+ }
+
+ /** return (this + Sk64(hi, lo) >> 16) as a 32bit result */
+ 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;
+ hi += fHi + (sum < fLo);
+ lo = sum;
+
+ sum = lo + (1 << 15);
+ if (sum < lo)
+ hi += 1;
+
+ 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 SkLONGLONG
+ SkLONGLONG getLongLong() const;
+#endif
+
+#ifdef SK_DEBUG
+ /** @cond UNIT_TEST */
+ static void UnitTest();
+ /** @endcond */
+#endif
+};
+
+#endif
+
diff --git a/skia/include/corecg/SkBuffer.h b/skia/include/corecg/SkBuffer.h
new file mode 100644
index 0000000..b1cfefc
--- /dev/null
+++ b/skia/include/corecg/SkBuffer.h
@@ -0,0 +1,142 @@
+/* include/corecg/SkBuffer.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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 : SkNoncopyable {
+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); }
+ const void* skip(size_t size); // return start of skipped data
+ 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; }
+
+protected:
+ 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 : SkNoncopyable {
+public:
+ SkWBuffer() : fData(0), fPos(0), fStop(0) {}
+ SkWBuffer(void* data) { reset(data); }
+ SkWBuffer(void* data, size_t size) { reset(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* skip(size_t size); // return start of skipped data
+ 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); }
+
+protected:
+ void writeNoSizeCheck(const void* buffer, size_t size);
+
+ char* fData;
+ char* fPos;
+ char* fStop;
+};
+
+#endif
+
diff --git a/skia/include/corecg/SkChunkAlloc.h b/skia/include/corecg/SkChunkAlloc.h
new file mode 100644
index 0000000..aa4ebde
--- /dev/null
+++ b/skia/include/corecg/SkChunkAlloc.h
@@ -0,0 +1,62 @@
+/* include/corecg/SkChunkAlloc.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkChunkAlloc_DEFINED
+#define SkChunkAlloc_DEFINED
+
+#include "SkTypes.h"
+
+class SkChunkAlloc : SkNoncopyable {
+public:
+ SkChunkAlloc(size_t minSize);
+ ~SkChunkAlloc();
+
+ /** Free up all allocated blocks. This invalidates all returned
+ pointers.
+ */
+ void reset();
+
+ /** Reuse all allocated blocks. This invalidates all returned
+ pointers (like reset) but doesn't necessarily free up all
+ of the privately allocated blocks. This is more efficient
+ if you plan to reuse the allocator multiple times.
+ */
+ void reuse();
+
+ enum AllocFailType {
+ kReturnNil_AllocFailType,
+ kThrow_AllocFailType
+ };
+
+ void* alloc(size_t bytes, AllocFailType);
+ void* allocThrow(size_t bytes) {
+ return this->alloc(bytes, kThrow_AllocFailType);
+ }
+
+ size_t totalCapacity() const { return fTotalCapacity; }
+
+private:
+ struct Block;
+ Block* fBlock;
+ size_t fMinSize;
+ Block* fPool;
+ size_t fTotalCapacity;
+
+ Block* newBlock(size_t bytes, AllocFailType ftype);
+};
+
+#endif
diff --git a/skia/include/corecg/SkEndian.h b/skia/include/corecg/SkEndian.h
new file mode 100644
index 0000000..0897914
--- /dev/null
+++ b/skia/include/corecg/SkEndian.h
@@ -0,0 +1,99 @@
+/* include/corecg/SkEndian.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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 != NULL);
+
+ 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 != NULL);
+
+ 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
+
diff --git a/skia/include/corecg/SkFDot6.h b/skia/include/corecg/SkFDot6.h
new file mode 100644
index 0000000..57d4516
--- /dev/null
+++ b/skia/include/corecg/SkFDot6.h
@@ -0,0 +1,68 @@
+/* include/corecg/SkFDot6.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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
+
diff --git a/skia/include/corecg/SkFixed.h b/skia/include/corecg/SkFixed.h
new file mode 100644
index 0000000..e77d455
--- /dev/null
+++ b/skia/include/corecg/SkFixed.h
@@ -0,0 +1,254 @@
+/* include/corecg/SkFixed.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkFixed_DEFINED
+#define SkFixed_DEFINED
+
+#include "SkTypes.h"
+
+/** \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))
+
+ #define SkFixedToDouble(x) ((x) * 1.5258789e-5)
+ #define SkDoubleToFixed(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)
+
+SkFixed SkFixedMul_portable(SkFixed, SkFixed);
+SkFract SkFractMul_portable(SkFract, SkFract);
+inline SkFixed SkFixedSquare_portable(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);
+}
+
+#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)
+SkFixed SkFixedFastInvert(SkFixed n);
+#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* cosValueOrNull);
+#define SkFixedSin(radians) SkFixedSinCos(radians, NULL)
+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;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+// Now look for ASM overrides for our portable versions (should consider putting this in its own file)
+
+#ifdef SkLONGLONG
+ inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b)
+ {
+ return (SkFixed)((SkLONGLONG)a * b >> 16);
+ }
+ inline SkFract SkFractMul_longlong(SkFract a, SkFract b)
+ {
+ return (SkFixed)((SkLONGLONG)a * b >> 30);
+ }
+ inline SkFixed SkFixedSquare_longlong(SkFixed value)
+ {
+ return (SkFixed)((SkLONGLONG)value * value >> 16);
+ }
+ #define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
+ #define SkFractMul(a,b) SkFractMul_longlong(a,b)
+ #define SkFixedSquare(a) SkFixedSquare_longlong(a)
+#endif
+
+#if defined(__arm__) && !defined(__thumb__)
+ /* This guy does not handle NaN or other obscurities, but is faster than
+ than (int)(x*65536) when we only have software floats
+ */
+ inline SkFixed SkFloatToFixed_arm(float x)
+ {
+ register int32_t y, z;
+ asm("movs %1, %3, lsl #1 \n"
+ "mov %2, #0x8E \n"
+ "sub %1, %2, %1, lsr #24 \n"
+ "mov %2, %3, lsl #8 \n"
+ "orr %2, %2, #0x80000000 \n"
+ "mov %1, %2, lsr %1 \n"
+ "rsbcs %1, %1, #0 \n"
+ : "=r"(x), "=&r"(y), "=&r"(z)
+ : "r"(x)
+ : "cc"
+ );
+ return y;
+ }
+ inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y)
+ {
+ register int32_t t;
+ asm("smull %0, %2, %1, %3 \n"
+ "mov %0, %0, lsr #16 \n"
+ "orr %0, %0, %2, lsl #16 \n"
+ : "=r"(x), "=&r"(y), "=r"(t)
+ : "r"(x), "1"(y)
+ :
+ );
+ return x;
+ }
+ inline SkFixed SkFixedMulAdd_arm(SkFixed x, SkFixed y, SkFixed a)
+ {
+ register int32_t t;
+ asm("smull %0, %3, %1, %4 \n"
+ "add %0, %2, %0, lsr #16 \n"
+ "add %0, %0, %3, lsl #16 \n"
+ : "=r"(x), "=&r"(y), "=&r"(a), "=r"(t)
+ : "%r"(x), "1"(y), "2"(a)
+ :
+ );
+ return x;
+ }
+ inline SkFixed SkFractMul_arm(SkFixed x, SkFixed y)
+ {
+ register int32_t t;
+ asm("smull %0, %2, %1, %3 \n"
+ "mov %0, %0, lsr #30 \n"
+ "orr %0, %0, %2, lsl #2 \n"
+ : "=r"(x), "=&r"(y), "=r"(t)
+ : "r"(x), "1"(y)
+ :
+ );
+ return x;
+ }
+ #undef SkFixedMul
+ #undef SkFractMul
+ #define SkFixedMul(x, y) SkFixedMul_arm(x, y)
+ #define SkFractMul(x, y) SkFractMul_arm(x, y)
+ #define SkFixedMulAdd(x, y, a) SkFixedMulAdd_arm(x, y, a)
+
+ #undef SkFloatToFixed
+ #define SkFloatToFixed(x) SkFloatToFixed_arm(x)
+#endif
+
+/////////////////////// Now define our macros to the portable versions if they weren't overridden
+
+#ifndef SkFixedSquare
+ #define SkFixedSquare(x) SkFixedSquare_portable(x)
+#endif
+#ifndef SkFixedMul
+ #define SkFixedMul(x, y) SkFixedMul_portable(x, y)
+#endif
+#ifndef SkFractMul
+ #define SkFractMul(x, y) SkFractMul_portable(x, y)
+#endif
+#ifndef SkFixedMulAdd
+ #define SkFixedMulAdd(x, y, a) (SkFixedMul(x, y) + (a))
+#endif
+
+#endif
diff --git a/skia/include/corecg/SkFloatingPoint.h b/skia/include/corecg/SkFloatingPoint.h
new file mode 100644
index 0000000..b7c0435
--- /dev/null
+++ b/skia/include/corecg/SkFloatingPoint.h
@@ -0,0 +1,65 @@
+/* include/corecg/SkFloatingPoint.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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)
+ #define sk_float_floor(x) (float)::floor(x)
+ #define sk_float_ceil(x) (float)::ceil(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)
+ #define sk_float_floor(x) floorf(x)
+ #define sk_float_ceil(x) ceilf(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
diff --git a/skia/include/corecg/SkInterpolator.h b/skia/include/corecg/SkInterpolator.h
new file mode 100644
index 0000000..d98196d
--- /dev/null
+++ b/skia/include/corecg/SkInterpolator.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2006-2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkInterpolator_DEFINED
+#define SkInterpolator_DEFINED
+
+#include "SkScalar.h"
+
+class SkInterpolatorBase : SkNoncopyable {
+public:
+ enum Result {
+ kNormal_Result,
+ kFreezeStart_Result,
+ kFreezeEnd_Result
+ };
+protected:
+ SkInterpolatorBase();
+ ~SkInterpolatorBase();
+public:
+ void reset(int elemCount, int frameCount);
+
+ /** Return the start and end time for this interpolator.
+ If there are no key frames, return false.
+ @param startTime If not null, returns the time (in milliseconds) of the
+ first keyframe. If there are no keyframes, this param
+ is ignored (left unchanged).
+ @param endTime If not null, returns the time (in milliseconds) of the
+ last keyframe. If there are no keyframes, this parameter
+ is ignored (left unchanged).
+ @return True if there are key frames, or false if there are none.
+ */
+ bool getDuration(SkMSec* startTime, SkMSec* endTime) const;
+
+
+ /** Set the whether the repeat is mirrored.
+ @param mirror If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setMirror(bool mirror) {
+ fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror);
+ }
+
+ /** Set the repeat count. The repeat count may be fractional.
+ @param repeatCount Multiplies the total time by this scalar.
+ */
+ void setRepeatCount(SkScalar repeatCount) { fRepeat = repeatCount; }
+
+ /** Set the whether the repeat is mirrored.
+ @param reset If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setReset(bool reset) {
+ fFlags = SkToU8((fFlags & ~kReset) | (int)reset);
+ }
+
+ Result timeToT(SkMSec time, SkScalar* T, int* index, SkBool* exact) const;
+
+protected:
+ enum Flags {
+ kMirror = 1,
+ kReset = 2,
+ kHasBlend = 4
+ };
+ static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime,
+ SkMSec nextTime, const SkScalar blend[4] = NULL);
+ int16_t fFrameCount;
+ uint8_t fElemCount;
+ uint8_t fFlags;
+ SkScalar fRepeat;
+ struct SkTimeCode {
+ SkMSec fTime;
+ SkScalar fBlend[4];
+ };
+ SkTimeCode* fTimes; // pointer into fStorage
+ void* fStorage;
+#ifdef SK_DEBUG
+ SkTimeCode(* fTimesArray)[10];
+#endif
+};
+
+class SkInterpolator : public SkInterpolatorBase {
+public:
+ SkInterpolator();
+ SkInterpolator(int elemCount, int frameCount);
+ void reset(int elemCount, int frameCount);
+
+ /** Add or replace a key frame, copying the values[] data into the
+ interpolator.
+ @param index The index of this frame (frames must be ordered by time)
+ @param time The millisecond time for this frame
+ @param values The array of values [elemCount] for this frame. The data
+ is copied into the interpolator.
+ @param blend A positive scalar specifying how to blend between this
+ and the next key frame. [0...1) is a cubic lag/log/lag
+ blend (slow to change at the beginning and end)
+ 1 is a linear blend (default)
+ */
+ bool setKeyFrame(int index, SkMSec time, const SkScalar values[],
+ const SkScalar blend[4] = NULL);
+
+ /** Return the computed values given the specified time. Return whether
+ those values are the result of pinning to either the first
+ (kFreezeStart) or last (kFreezeEnd), or from interpolated the two
+ nearest key values (kNormal).
+ @param time The time to sample (in milliseconds)
+ @param (may be null) where to write the computed values.
+ */
+ Result timeToValues(SkMSec time, SkScalar values[] = NULL) const;
+
+ SkDEBUGCODE(static void UnitTest();)
+private:
+ SkScalar* fValues; // pointer into fStorage
+#ifdef SK_DEBUG
+ SkScalar(* fScalarsArray)[10];
+#endif
+ typedef SkInterpolatorBase INHERITED;
+};
+
+/** Given all the parameters are [0...1], apply the cubic specified by (0,0)
+ (bx,by) (cx,cy) (1,1) to value, returning the answer, also [0...1].
+*/
+SkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by,
+ SkScalar cx, SkScalar cy);
+
+#endif
+
diff --git a/skia/include/corecg/SkMath.h b/skia/include/corecg/SkMath.h
new file mode 100644
index 0000000..7519dee
--- /dev/null
+++ b/skia/include/corecg/SkMath.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2006-2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkMath_DEFINED
+#define SkMath_DEFINED
+
+#include "SkTypes.h"
+
+//! Returns the number of leading zero bits (0...32)
+int SkCLZ_portable(uint32_t);
+
+/** Computes the 64bit product of a * b, and then shifts the answer down by
+ shift bits, returning the low 32bits. shift must be [0..63]
+ e.g. to perform a fixedmul, call SkMulShift(a, b, 16)
+*/
+int32_t SkMulShift(int32_t a, int32_t b, unsigned shift);
+
+/** Computes numer1 * numer2 / denom in full 64 intermediate precision.
+ It is an error for denom to be 0. There is no special handling if
+ the result overflows 32bits.
+*/
+int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
+
+/** Computes (numer1 << shift) / denom in full 64 intermediate precision.
+ It is an error for denom to be 0. There is no special handling if
+ the result overflows 32bits.
+*/
+int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
+
+/** Return the integer square root of value, with a bias of bitBias
+*/
+int32_t SkSqrtBits(int32_t value, int bitBias);
+
+/** Return the integer square root of n, treated as a SkFixed (16.16)
+*/
+#define SkSqrt32(n) SkSqrtBits(n, 15)
+
+/** Return the integer cube root of value, with a bias of bitBias
+ */
+int32_t SkCubeRootBits(int32_t value, int bitBias);
+
+/** Returns -1 if n < 0, else returns 0
+*/
+#define SkExtractSign(n) ((int32_t)(n) >> 31)
+
+/** If sign == -1, returns -n, else sign must be 0, and returns n.
+ Typically used in conjunction with SkExtractSign().
+*/
+static inline int32_t SkApplySign(int32_t n, int32_t sign) {
+ SkASSERT(sign == 0 || sign == -1);
+ return (n ^ sign) - sign;
+}
+
+/** Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
+*/
+static inline int SkClampPos(int value) {
+ return value & ~(value >> 31);
+}
+
+/** Given an integer and a positive (max) integer, return the value
+ pinned against 0 and max, inclusive.
+ 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
+*/
+static 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
+*/
+static inline unsigned SkClampUMax(unsigned value, unsigned max) {
+#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
+ if (value > max) {
+ value = max;
+ }
+ return value;
+#else
+ int diff = max - value;
+ // clear diff if diff is positive
+ diff &= diff >> 31;
+
+ return value + diff;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(__arm__) && !defined(__thumb__)
+ #define SkCLZ(x) __builtin_clz(x)
+#endif
+
+#ifndef SkCLZ
+ #define SkCLZ(x) SkCLZ_portable(x)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** Returns the smallest power-of-2 that is >= the specified value. If value
+ is already a power of 2, then it is returned unchanged. It is undefined
+ if value is <= 0.
+*/
+static inline int SkNextPow2(int value) {
+ SkASSERT(value > 0);
+ return 1 << (32 - SkCLZ(value - 1));
+}
+
+/** Returns the log2 of the specified value, were that value to be rounded up
+ to the next power of 2. It is undefined to pass 0. Examples:
+ SkNextLog2(1) -> 0
+ SkNextLog2(2) -> 1
+ SkNextLog2(3) -> 2
+ SkNextLog2(4) -> 2
+ SkNextLog2(5) -> 3
+*/
+static inline int SkNextLog2(uint32_t value) {
+ SkASSERT(value != 0);
+ return 32 - SkCLZ(value - 1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
+ With this requirement, we can generate faster instructions on some
+ architectures.
+*/
+#if defined(__arm__) && !defined(__thumb__)
+ static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
+ SkASSERT((int16_t)x == x);
+ SkASSERT((int16_t)y == y);
+ int32_t product;
+ asm("smulbb %0, %1, %2 \n"
+ : "=r"(product)
+ : "r"(x), "r"(y)
+ :
+ );
+ return product;
+ }
+#else
+ #ifdef SK_DEBUG
+ static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
+ SkASSERT((int16_t)x == x);
+ SkASSERT((int16_t)y == y);
+ return x * y;
+ }
+ #else
+ #define SkMulS16(x, y) ((x) * (y))
+ #endif
+#endif
+
+/** Return a*b/255, truncating away any fractional bits. Only valid if both
+ a and b are 0..255
+*/
+static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
+ SkASSERT((uint8_t)a == a);
+ SkASSERT((uint8_t)b == b);
+ unsigned prod = SkMulS16(a, b) + 1;
+ return (prod + (prod >> 8)) >> 8;
+}
+
+/** Return a*b/255, rounding any fractional bits. Only valid if both
+ a and b are 0..255
+ */
+static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
+ SkASSERT((uint8_t)a == a);
+ SkASSERT((uint8_t)b == b);
+ unsigned prod = SkMulS16(a, b) + 128;
+ return (prod + (prod >> 8)) >> 8;
+}
+
+/** Return a*b/((1 << shift) - 1), rounding any fractional bits.
+ Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
+*/
+static unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
+ SkASSERT(a <= 32767);
+ SkASSERT(b <= 32767);
+ SkASSERT(shift > 0 && shift <= 8);
+ unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
+ return (prod + (prod >> shift)) >> shift;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_DEBUG
+ class SkMath {
+ public:
+ static void UnitTest();
+ };
+#endif
+
+#endif
+
diff --git a/skia/include/corecg/SkMatrix.h b/skia/include/corecg/SkMatrix.h
new file mode 100644
index 0000000..60fdd42
--- /dev/null
+++ b/skia/include/corecg/SkMatrix.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2006-2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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:
+ /** Enum of bit fields for the mask return by getType().
+ Use this to identify the complexity of the matrix.
+ */
+ enum TypeMask {
+ kIdentity_Mask = 0,
+ kTranslate_Mask = 0x01, //!< set if the matrix has translation
+ kScale_Mask = 0x02, //!< set if the matrix has X or Y scale
+ kAffine_Mask = 0x04, //!< set if the matrix skews or rotates
+ kPerspective_Mask = 0x08 //!< set if the matrix is in perspective
+ };
+
+ /** Returns a mask bitfield describing the types of transformations
+ that the matrix will perform. This information is used by routines
+ like mapPoints, to optimize its inner loops to only perform as much
+ arithmetic as is necessary.
+ */
+ TypeMask getType() const {
+ if (fTypeMask & kUnknown_Mask) {
+ fTypeMask = this->computeTypeMask();
+ }
+ // only return the public masks
+ return (TypeMask)(fTypeMask & 0xF);
+ }
+
+ /** Returns true if the matrix is identity.
+ */
+ bool isIdentity() const {
+ return this->getType() == 0;
+ }
+
+ /** Returns true if will map a rectangle to another rectangle. This can be
+ true if the matrix is identity, scale-only, or rotates a multiple of
+ 90 degrees.
+ */
+ bool rectStaysRect() const {
+ if (fTypeMask & kUnknown_Mask) {
+ fTypeMask = this->computeTypeMask();
+ }
+ return (fTypeMask & kRectStaysRect_Mask) != 0;
+ }
+
+ enum {
+ kMScaleX,
+ kMSkewX,
+ kMTransX,
+ kMSkewY,
+ kMScaleY,
+ kMTransY,
+ kMPersp0,
+ kMPersp1,
+ kMPersp2
+ };
+
+ SkScalar operator[](int index) const {
+ SkASSERT((unsigned)index < 9);
+ return fMat[index];
+ }
+
+ SkScalar get(int index) const {
+ SkASSERT((unsigned)index < 9);
+ return fMat[index];
+ }
+
+ SkScalar getScaleX() const { return fMat[kMScaleX]; }
+ SkScalar getScaleY() const { return fMat[kMScaleY]; }
+ SkScalar getSkewY() const { return fMat[kMSkewY]; }
+ SkScalar getSkewX() const { return fMat[kMSkewX]; }
+ SkScalar getTranslateX() const { return fMat[kMTransX]; }
+ SkScalar getTranslateY() const { return fMat[kMTransY]; }
+ SkScalar getPerspX() const { return fMat[kMPersp0]; }
+ SkScalar getPerspY() const { return fMat[kMPersp1]; }
+
+ void set(int index, SkScalar value) {
+ SkASSERT((unsigned)index < 9);
+ fMat[index] = value;
+ this->setTypeMask(kUnknown_Mask);
+ }
+
+ void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
+ void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
+ void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
+ void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
+ void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
+ void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
+ void setPerspX(SkScalar v) { this->set(kMPersp0, v); }
+ void setPerspY(SkScalar v) { this->set(kMPersp1, v); }
+
+ /** Set the matrix to identity
+ */
+ void reset();
+
+ /** Set the matrix to translate by (dx, dy).
+ */
+ void setTranslate(SkScalar dx, SkScalar dy);
+ /** Set the matrix to scale by sx and sy, with a pivot point at (px, py).
+ The pivot point is the coordinate that should remain unchanged by the
+ specified transformation.
+ */
+ void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Set the matrix to scale by sx and sy.
+ */
+ void setScale(SkScalar sx, SkScalar sy);
+ /** Set the matrix to rotate by the specified number of degrees, with a
+ pivot point at (px, py). The pivot point is the coordinate that should
+ remain unchanged by the specified transformation.
+ */
+ void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Set the matrix to rotate about (0,0) by the specified number of degrees.
+ */
+ void setRotate(SkScalar degrees);
+ /** Set the matrix to rotate by the specified sine and cosine values, with
+ a pivot point at (px, py). The pivot point is the coordinate that
+ should remain unchanged by the specified transformation.
+ */
+ void setSinCos(SkScalar sinValue, SkScalar cosValue,
+ SkScalar px, SkScalar py);
+ /** Set the matrix to rotate by the specified sine and cosine values.
+ */
+ void setSinCos(SkScalar sinValue, SkScalar cosValue);
+ /** Set the matrix to skew by sx and sy, with a pivot point at (px, py).
+ The pivot point is the coordinate that should remain unchanged by the
+ specified transformation.
+ */
+ void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Set the matrix to skew by sx and sy.
+ */
+ void setSkew(SkScalar kx, SkScalar ky);
+ /** Set the matrix to the concatenation of the two specified matrices,
+ returning true if the the result can be represented. Either of the
+ two matrices may also be the target matrix. *this = a * b;
+ */
+ bool setConcat(const SkMatrix& a, const SkMatrix& b);
+
+ /** Preconcats the matrix with the specified translation.
+ M' = M * T(dx, dy)
+ */
+ bool preTranslate(SkScalar dx, SkScalar dy);
+ /** Preconcats the matrix with the specified scale.
+ M' = M * S(sx, sy, px, py)
+ */
+ bool preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified scale.
+ M' = M * S(sx, sy)
+ */
+ bool preScale(SkScalar sx, SkScalar sy);
+ /** Preconcats the matrix with the specified rotation.
+ M' = M * R(degrees, px, py)
+ */
+ bool preRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified rotation.
+ M' = M * R(degrees)
+ */
+ bool preRotate(SkScalar degrees);
+ /** Preconcats the matrix with the specified skew.
+ M' = M * K(kx, ky, px, py)
+ */
+ bool preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified skew.
+ M' = M * K(kx, ky)
+ */
+ bool preSkew(SkScalar kx, SkScalar ky);
+ /** Preconcats the matrix with the specified matrix.
+ M' = M * other
+ */
+ bool preConcat(const SkMatrix& other);
+
+ /** Postconcats the matrix with the specified translation.
+ M' = T(dx, dy) * M
+ */
+ bool postTranslate(SkScalar dx, SkScalar dy);
+ /** Postconcats the matrix with the specified scale.
+ M' = S(sx, sy, px, py) * M
+ */
+ bool postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified scale.
+ M' = S(sx, sy) * M
+ */
+ bool postScale(SkScalar sx, SkScalar sy);
+ /** Postconcats the matrix by dividing it by the specified integers.
+ M' = S(1/divx, 1/divy, 0, 0) * M
+ */
+ bool postIDiv(int divx, int divy);
+ /** Postconcats the matrix with the specified rotation.
+ M' = R(degrees, px, py) * M
+ */
+ bool postRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified rotation.
+ M' = R(degrees) * M
+ */
+ bool postRotate(SkScalar degrees);
+ /** Postconcats the matrix with the specified skew.
+ M' = K(kx, ky, px, py) * M
+ */
+ bool postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified skew.
+ M' = K(kx, ky) * M
+ */
+ bool postSkew(SkScalar kx, SkScalar ky);
+ /** Postconcats the matrix with the specified matrix.
+ M' = other * M
+ */
+ bool postConcat(const SkMatrix& other);
+
+ enum ScaleToFit {
+ /**
+ * Scale in X and Y independently, so that src matches dst exactly.
+ * This may change the aspect ratio of the src.
+ */
+ kFill_ScaleToFit,
+ /**
+ * Compute a scale that will maintain the original src aspect ratio,
+ * but will also ensure that src fits entirely inside dst. At least one
+ * axis (X or Y) will fit exactly. kStart aligns the result to the
+ * left and top edges of dst.
+ */
+ kStart_ScaleToFit,
+ /**
+ * Compute a scale that will maintain the original src aspect ratio,
+ * but will also ensure that src fits entirely inside dst. At least one
+ * axis (X or Y) will fit exactly. The result is centered inside dst.
+ */
+ kCenter_ScaleToFit,
+ /**
+ * Compute a scale that will maintain the original src aspect ratio,
+ * but will also ensure that src fits entirely inside dst. At least one
+ * axis (X or Y) will fit exactly. kEnd aligns the result to the
+ * right and bottom edges of dst.
+ */
+ kEnd_ScaleToFit
+ };
+
+ /** Set the matrix to the scale and translate values that map the source
+ rectangle to the destination rectangle, returning true if the the result
+ can be represented.
+ @param src the source rectangle to map from.
+ @param dst the destination rectangle to map to.
+ @param stf the ScaleToFit option
+ @return true if the matrix can be represented by the rectangle mapping.
+ */
+ bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf);
+
+ /** Set the matrix such that the specified src points would map to the
+ specified dst points. count must be within [0..4].
+ @param src The array of src points
+ @param dst The array of dst points
+ @param count The number of points to use for the transformation
+ @return true if the matrix was set to the specified transformation
+ */
+ bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count);
+
+ /** If this matrix can be inverted, return true and if inverse is not null,
+ set inverse to be the inverse of this matrix. If this matrix cannot be
+ inverted, ignore inverse and return false
+ */
+ bool invert(SkMatrix* inverse) const;
+
+ /** Apply this matrix to the array of points specified by src, and write
+ the transformed points into the array of points specified by dst.
+ dst[] = M * src[]
+ @param dst Where the transformed coordinates are written. It must
+ contain at least count entries
+ @param src The original coordinates that are to be transformed. It
+ must contain at least count entries
+ @param count The number of points in src to read, and then transform
+ into dst.
+ */
+ void mapPoints(SkPoint dst[], const SkPoint src[], int count) const;
+
+ /** Apply this matrix to the array of points, overwriting it with the
+ transformed values.
+ dst[] = M * pts[]
+ @param pts The points to be transformed. It must contain at least
+ count entries
+ @param count The number of points in pts.
+ */
+ void mapPoints(SkPoint pts[], int count) const {
+ this->mapPoints(pts, pts, count);
+ }
+
+ void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
+ SkASSERT(result);
+ this->getMapXYProc()(*this, x, y, result);
+ }
+
+ /** Apply this matrix to the array of vectors specified by src, and write
+ the transformed vectors into the array of vectors specified by dst.
+ This is similar to mapPoints, but ignores any translation in the matrix.
+ @param dst Where the transformed coordinates are written. It must
+ contain at least count entries
+ @param src The original coordinates that are to be transformed. It
+ must contain at least count entries
+ @param count The number of vectors in src to read, and then transform
+ into dst.
+ */
+ void mapVectors(SkVector dst[], const SkVector src[], int count) const;
+
+ /** Apply this matrix to the array of vectors specified by src, and write
+ the transformed vectors into the array of vectors specified by dst.
+ This is similar to mapPoints, but ignores any translation in the matrix.
+ @param vecs The vectors to be transformed. It must contain at least
+ count entries
+ @param count The number of vectors in vecs.
+ */
+ void mapVectors(SkVector vecs[], int count) const {
+ this->mapVectors(vecs, vecs, count);
+ }
+
+ /** Apply this matrix to the src rectangle, and write the transformed
+ rectangle into dst. This is accomplished by transforming the 4 corners
+ of src, and then setting dst to the bounds of those points.
+ @param dst Where the transformed rectangle is written.
+ @param src The original rectangle to be transformed.
+ @return the result of calling rectStaysRect()
+ */
+ bool mapRect(SkRect* dst, const SkRect& src) const;
+
+ /** Apply this matrix to the rectangle, and write the transformed rectangle
+ back into it. This is accomplished by transforming the 4 corners of
+ rect, and then setting it to the bounds of those points
+ @param rect The rectangle to transform.
+ @return the result of calling rectStaysRect()
+ */
+ bool mapRect(SkRect* rect) const {
+ return this->mapRect(rect, *rect);
+ }
+
+ /** Return the mean radius of a circle after it has been mapped by
+ this matrix. NOTE: in perspective this value assumes the circle
+ has its center at the origin.
+ */
+ SkScalar mapRadius(SkScalar radius) const;
+
+ typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y,
+ SkPoint* result);
+
+ static MapXYProc GetMapXYProc(TypeMask mask) {
+ SkASSERT((mask & ~kAllMasks) == 0);
+ return gMapXYProcs[mask & kAllMasks];
+ }
+
+ MapXYProc getMapXYProc() const {
+ return GetMapXYProc(this->getType());
+ }
+
+ typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[],
+ const SkPoint src[], int count);
+
+ static MapPtsProc GetMapPtsProc(TypeMask mask) {
+ SkASSERT((mask & ~kAllMasks) == 0);
+ return gMapPtsProcs[mask & kAllMasks];
+ }
+
+ MapPtsProc getMapPtsProc() const {
+ return GetMapPtsProc(this->getType());
+ }
+
+ /** If the matrix can be stepped in X (not complex perspective)
+ then return true and if step[XY] is not null, return the step[XY] value.
+ If it cannot, return false and ignore step.
+ */
+ bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;
+
+ friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
+ return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) == 0;
+ }
+
+ friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
+ return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
+ }
+
+ void dump() const;
+
+#ifdef SK_DEBUG
+ /** @cond UNIT_TEST */
+
+ static void UnitTest();
+ /** @endcond */
+#endif
+
+private:
+ enum {
+ /** Set if the matrix will map a rectangle to another rectangle. This
+ can be true if the matrix is scale-only, or rotates a multiple of
+ 90 degrees. This bit is not set if the matrix is identity.
+
+ This bit will be set on identity matrices
+ */
+ kRectStaysRect_Mask = 0x10,
+
+ kUnknown_Mask = 0x80,
+
+ kAllMasks = kTranslate_Mask |
+ kScale_Mask |
+ kAffine_Mask |
+ kPerspective_Mask |
+ kRectStaysRect_Mask
+ };
+
+ SkScalar fMat[9];
+ mutable uint8_t fTypeMask;
+
+ uint8_t computeTypeMask() const;
+
+ void setTypeMask(int mask) {
+ // allow kUnknown or a valid mask
+ SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask);
+ fTypeMask = SkToU8(mask);
+ }
+
+ void clearTypeMask(int mask) {
+ // only allow a valid mask
+ SkASSERT((mask & kAllMasks) == mask);
+ fTypeMask &= ~mask;
+ }
+
+ static bool Poly2Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
+ static bool Poly3Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
+ static bool Poly4Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
+
+ static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+
+ static const MapXYProc gMapXYProcs[];
+
+ static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int);
+ static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+ static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+ static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
+ int count);
+ static void Rot_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+ static void RotTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
+ int count);
+ static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+
+ static const MapPtsProc gMapPtsProcs[];
+
+ friend class SkPerspIter;
+};
+
+#endif
+
diff --git a/skia/include/corecg/SkPerspIter.h b/skia/include/corecg/SkPerspIter.h
new file mode 100644
index 0000000..1a5d82f
--- /dev/null
+++ b/skia/include/corecg/SkPerspIter.h
@@ -0,0 +1,56 @@
+/* include/corecg/SkPerspIter.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkPerspIter_DEFINED
+#define SkPerspIter_DEFINED
+
+#include "SkMatrix.h"
+
+class SkPerspIter {
+public:
+ /** Iterate a line through the matrix [x,y] ... [x+count-1, y].
+ @param m The matrix we will be iterating a line through
+ @param x The initial X coordinate to be mapped through the matrix
+ @param y The initial Y coordinate to be mapped through the matrix
+ @param count The number of points (x,y) (x+1,y) (x+2,y) ... we will eventually map
+ */
+ SkPerspIter(const SkMatrix& m, SkScalar x, SkScalar y, int count);
+
+ /** Return the buffer of [x,y] fixed point values we will be filling.
+ This always returns the same value, so it can be saved across calls to
+ next().
+ */
+ const SkFixed* getXY() const { return fStorage; }
+
+ /** Return the number of [x,y] pairs that have been filled in the getXY() buffer.
+ When this returns 0, the iterator is finished.
+ */
+ int next();
+
+private:
+ enum {
+ kShift = 4,
+ kCount = (1 << kShift)
+ };
+ const SkMatrix& fMatrix;
+ SkFixed fStorage[kCount * 2];
+ SkFixed fX, fY;
+ SkScalar fSX, fSY;
+ int fCount;
+};
+
+#endif
diff --git a/skia/include/corecg/SkPoint.h b/skia/include/corecg/SkPoint.h
new file mode 100644
index 0000000..4493ce3
--- /dev/null
+++ b/skia/include/corecg/SkPoint.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2006-2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPoint_DEFINED
+#define SkPoint_DEFINED
+
+#include "SkMath.h"
+#include "SkScalar.h"
+
+/** \struct SkIPoint
+
+ SkIPoint holds two 32 bit integer coordinates
+*/
+struct SkIPoint {
+ int32_t fX, fY;
+
+ /** Set the x and y values of the point. */
+ void set(int32_t x, int32_t y) { fX = x; fY = y; }
+
+ /** Rotate the point clockwise, writing the new point into dst
+ It is legal for dst == this
+ */
+ void rotateCW(SkIPoint* 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(SkIPoint* 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
+ */
+ SkIPoint operator-() const {
+ SkIPoint neg;
+ neg.fX = -fX;
+ neg.fY = -fY;
+ return neg;
+ }
+
+ /** Add v's coordinates to this point's */
+ void operator+=(const SkIPoint& v) {
+ fX += v.fX;
+ fY += v.fY;
+ }
+
+ /** Subtract v's coordinates from this point's */
+ void operator-=(const SkIPoint& v) {
+ fX -= v.fX;
+ fY -= v.fY;
+ }
+
+ /** Returns true if the point's coordinates equal (x,y) */
+ bool equals(int32_t x, int32_t y) const {
+ return fX == x && fY == y;
+ }
+
+ friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
+ return a.fX == b.fX && a.fY == b.fY;
+ }
+
+ friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
+ return a.fX != b.fX || a.fY != b.fY;
+ }
+
+ /** Returns a new point whose coordinates are the difference between
+ a and b (i.e. a - b)
+ */
+ friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) {
+ SkIPoint 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 SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) {
+ SkIPoint 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 SkIPoint& a, const SkIPoint& 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 SkIPoint& a, const SkIPoint& b) {
+ return a.fX * b.fY - a.fY * b.fX;
+ }
+};
+
+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(int32_t x, int32_t 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 SkIPoint& 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 false, otherwise
+ return true.
+ */
+ bool normalize();
+
+ /** Set the point (vector) to be unit-length in the same direction as the
+ x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0)
+ then return false and do nothing, otherwise return true.
+ */
+ bool setNormalize(SkScalar x, SkScalar y);
+
+ /** Scale the point (vector) to have the specified length, and return that
+ length. If the original length is degenerately small (nearly zero),
+ do nothing and return false, otherwise return true.
+ */
+ bool setLength(SkScalar length);
+
+ /** Set the point (vector) to have the specified length in the same
+ direction as (x,y). If the vector (x,y) has a degenerate length
+ (i.e. nearly 0) then return false and do nothing, otherwise return true.
+ */
+ 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
+
diff --git a/skia/include/corecg/SkPostConfig.h b/skia/include/corecg/SkPostConfig.h
new file mode 100644
index 0000000..3ca5f75
--- /dev/null
+++ b/skia/include/corecg/SkPostConfig.h
@@ -0,0 +1,211 @@
+/* include/corecg/SkPostConfig.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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
+
+// ensure the port has defined all of these, or none of them
+#ifdef SK_A32_SHIFT
+ #if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
+ #error "all or none of the 32bit SHIFT amounts must be defined"
+ #endif
+#else
+ #if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
+ #error "all or none of the 32bit SHIFT amounts must be defined"
+ #endif
+#endif
+
+#ifndef SkNEW
+ #define SkNEW(type_name) new type_name
+ #define SkNEW_ARGS(type_name, args) new type_name args
+ #define SkNEW_ARRAY(type_name, count) new type_name[count]
+ #define SkDELETE(obj) delete obj
+ #define SkDELETE_ARRAY(array) delete[] array
+#endif
+
+#ifndef SK_CRASH
+#if 1 // set to 0 for infinite loop, which can help connecting gdb
+ #define SK_CRASH() *(int *)(uintptr_t)0xbbadbeef = 0
+#else
+ #define SK_CRASH() do {} while (true)
+#endif
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_BUILD_FOR_WIN
+ //////////////////////////////////////////////////////////////////////
+ // Begin Chrome-specific changes
+ // Chrome already defines WIN32_LEAN_AND_MEAN so no need to define it here.
+
+ #include <windows.h>
+ // End Chrome-specific changes
+
+ #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)
+ #ifndef SK_DEBUGBREAK
+ #define SK_DEBUGBREAK(cond) do { if (!(cond)) SK_CRASH(); } while (false)
+ #endif
+#else
+ #ifdef SK_DEBUG
+ #include <stdio.h>
+ #ifndef SK_DEBUGBREAK
+ #define SK_DEBUGBREAK(cond) do { if (cond) break; \
+ SkDebugf("%s:%d: failed assertion \"%s\"\n", \
+ __FILE__, __LINE__, #cond); SK_CRASH(); } while (false)
+ #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_DEBUGx
+#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
+
diff --git a/skia/include/corecg/SkPreConfig.h b/skia/include/corecg/SkPreConfig.h
new file mode 100644
index 0000000..c651dd4
--- /dev/null
+++ b/skia/include/corecg/SkPreConfig.h
@@ -0,0 +1,111 @@
+/* include/corecg/SkPreConfig.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkPreConfig_DEFINED
+#define SkPreConfig_DEFINED
+
+#ifdef ANDROID
+ #define SK_BUILD_FOR_UNIX
+ #define SkLONGLONG int64_t
+#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
+
+//////////////////////////////////////////////////////////////////////
+
+// define to blank or change this in SkUserConfig.h as needed
+#define SK_RESTRICT __restrict__
+
+//////////////////////////////////////////////////////////////////////
+
+#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
+ #ifndef SK_CAN_USE_FLOAT
+ #define SK_CAN_USE_FLOAT
+ #endif
+ #if !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
+ #define SK_SCALAR_IS_FIXED
+ #endif
+
+ #ifndef SkLONGLONG
+ #ifdef SK_BUILD_FOR_WIN32
+ #define SkLONGLONG __int64
+ #else
+ #define SkLONGLONG long long
+ #endif
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
+ #if defined (__ppc__) || defined(__ppc64__)
+ #define SK_CPU_BENDIAN
+ #else
+ #define SK_CPU_LENDIAN
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if (defined(__arm__) && !defined(__thumb__)) || 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
+
diff --git a/skia/include/corecg/SkRandom.h b/skia/include/corecg/SkRandom.h
new file mode 100644
index 0000000..8994fc4
--- /dev/null
+++ b/skia/include/corecg/SkRandom.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2006-2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkRandom_DEFINED
+#define SkRandom_DEFINED
+
+#include "Sk64.h"
+#include "SkScalar.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:
+ // See "Numerical Recipes in C", 1992 page 284 for these constants
+ enum {
+ kMul = 1664525,
+ kAdd = 1013904223
+ };
+ uint32_t fSeed;
+};
+
+#endif
+
diff --git a/skia/include/corecg/SkRect.h b/skia/include/corecg/SkRect.h
new file mode 100644
index 0000000..65a562e
--- /dev/null
+++ b/skia/include/corecg/SkRect.h
@@ -0,0 +1,426 @@
+/* include/corecg/SkRect.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkRect_DEFINED
+#define SkRect_DEFINED
+
+#include "SkPoint.h"
+
+/** \struct SkIRect
+
+ SkIRect holds four 32 bit integer coordinates for a rectangle
+*/
+struct SkIRect {
+ int32_t fLeft, fTop, fRight, fBottom;
+
+ /** Return true if the rectangle's width or height are <= 0
+ */
+ 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 SkIRect& a, const SkIRect& b)
+ {
+ return !memcmp(&a, &b, sizeof(a));
+ }
+ friend int operator!=(const SkIRect& a, const SkIRect& b)
+ {
+ return memcmp(&a, &b, sizeof(a));
+ }
+
+ /** Set the rectangle to (0,0,0,0)
+ */
+ void setEmpty() { memset(this, 0, sizeof(*this)); }
+
+ void set(int32_t left, int32_t top, int32_t right, int32_t bottom)
+ {
+ fLeft = left;
+ fTop = top;
+ fRight = right;
+ fBottom = bottom;
+ }
+
+ /** Offset set the rectangle by adding dx to its left and right,
+ and adding dy to its top and bottom.
+ */
+ void offset(int32_t dx, int32_t 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(int32_t dx, int32_t dy)
+ {
+ fLeft += dx;
+ fTop += dy;
+ fRight -= dx;
+ fBottom -= dy;
+ }
+ /** Returns true if (x,y) is inside the rectangle and the rectangle is not
+ empty. 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(int32_t x, int32_t 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.
+ If either rectangle is empty, contains() returns false.
+ */
+ bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const
+ {
+ return left < right && top < bottom && !this->isEmpty() && // check for empties
+ 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 SkIRect& r) const
+ {
+ return !r.isEmpty() && !this->isEmpty() && // check for empties
+ fLeft <= r.fLeft && fTop <= r.fTop &&
+ fRight >= r.fRight && fBottom >= r.fBottom;
+ }
+
+ /** Return true if this rectangle contains the specified rectangle.
+ For speed, this method does not check if either this or the specified
+ rectangles are empty, and if either is, its return value is undefined.
+ In the debugging build however, we assert that both this and the
+ specified rectangles are non-empty.
+ */
+ bool containsNoEmptyCheck(int32_t left, int32_t top,
+ int32_t right, int32_t bottom) const
+ {
+ SkASSERT(fLeft < fRight && fTop < fBottom);
+ SkASSERT(left < right && top < bottom);
+
+ return fLeft <= left && fTop <= top &&
+ fRight >= right && fBottom >= bottom;
+ }
+
+ /** If r intersects this rectangle, return true and set this rectangle to that
+ intersection, otherwise return false and do not change this rectangle.
+ If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(const SkIRect& r)
+ {
+ SkASSERT(&r);
+ return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ }
+
+ /** If rectangles a and b intersect, return true and set this rectangle to
+ that intersection, otherwise return false and do not change this
+ rectangle. If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(const SkIRect& a, const SkIRect& b)
+ {
+ SkASSERT(&a && &b);
+
+ if (!a.isEmpty() && !b.isEmpty() &&
+ a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom)
+ {
+ fLeft = SkMax32(a.fLeft, b.fLeft);
+ fTop = SkMax32(a.fTop, b.fTop);
+ fRight = SkMin32(a.fRight, b.fRight);
+ fBottom = SkMin32(a.fBottom, b.fBottom);
+ return true;
+ }
+ return false;
+ }
+
+ /** If rectangles a and b intersect, return true and set this rectangle to
+ that intersection, otherwise return false and do not change this
+ rectangle. For speed, no check to see if a or b are empty is performed.
+ If either is, then the return result is undefined. In the debug build,
+ we assert that both rectangles are non-empty.
+ */
+ bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b)
+ {
+ SkASSERT(&a && &b);
+ SkASSERT(!a.isEmpty() && !b.isEmpty());
+
+ if (a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom)
+ {
+ fLeft = SkMax32(a.fLeft, b.fLeft);
+ fTop = SkMax32(a.fTop, b.fTop);
+ fRight = SkMin32(a.fRight, b.fRight);
+ fBottom = SkMin32(a.fBottom, b.fBottom);
+ return true;
+ }
+ return false;
+ }
+
+ /** 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.
+ If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom)
+ {
+ if (left < right && top < bottom && !this->isEmpty() &&
+ fLeft < right && left < fRight && fTop < bottom && top < fBottom)
+ {
+ if (fLeft < left) fLeft = left;
+ if (fTop < top) fTop = top;
+ if (fRight > right) fRight = right;
+ if (fBottom > bottom) fBottom = bottom;
+ return true;
+ }
+ return false;
+ }
+
+ /** Returns true if a and b are not empty, and they intersect
+ */
+ static bool Intersects(const SkIRect& a, const SkIRect& b)
+ {
+ return !a.isEmpty() && !b.isEmpty() && // check for empties
+ a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom;
+ }
+
+ /** Update this rectangle to enclose itself and the specified rectangle.
+ If this rectangle is empty, just set it to the specified rectangle. If the specified
+ rectangle is empty, do nothing.
+ */
+ void join(int32_t left, int32_t top, int32_t right, int32_t bottom);
+
+ /** Update this rectangle to enclose itself and the specified rectangle.
+ If this rectangle is empty, just set it to the specified rectangle. If the specified
+ rectangle is empty, do nothing.
+ */
+ void join(const SkIRect& r)
+ {
+ this->join(r.fLeft, r.fTop, r.fRight, 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;
+
+ /** Return true if the rectangle's width or height are <= 0
+ */
+ 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 SkIRect& 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.
+ If either rectangle is empty, do nothing and return false.
+ */
+ 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.
+ If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
+
+ /** Return true if this rectangle is not empty, and the specified sides of
+ a rectangle are not empty, and they intersect.
+ */
+ bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const
+ {
+ return // first check that both are not empty
+ left < right && top < bottom &&
+ fLeft < fRight && fTop < fBottom &&
+ // now check for intersection
+ fLeft < right && left < fRight &&
+ fTop < bottom && top < fBottom;
+ }
+
+ /** Return true if rectangles a and b are not empty and intersect.
+ */
+ static bool Intersects(const SkRect& a, const SkRect& b)
+ {
+ return !a.isEmpty() && !b.isEmpty() && // check for empties
+ a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom;
+ }
+
+ /** Update this rectangle to enclose itself and the specified rectangle.
+ If this rectangle is empty, just set it to the specified rectangle. If the specified
+ rectangle is empty, do nothing.
+ */
+ void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
+
+ /** Update this rectangle to enclose itself and the specified rectangle.
+ If this rectangle is empty, just set it to the specified rectangle. If the specified
+ rectangle is empty, do nothing.
+ */
+ void join(const SkRect& r)
+ {
+ this->join(r.fLeft, r.fTop, r.fRight, r.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.
+ If this rectangle is empty, return false.
+ */
+ bool contains(const SkPoint& p) const
+ {
+ return !this->isEmpty() &&
+ 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.
+ If this rectangle is empty, return false.
+ */
+ bool contains(SkScalar x, SkScalar y) const
+ {
+ return !this->isEmpty() &&
+ fLeft <= x && x < fRight &&
+ fTop <= y && y < fBottom;
+ }
+
+ /** Return true if this rectangle contains r.
+ If either rectangle is empty, return false.
+ */
+ bool contains(const SkRect& r) const
+ {
+ return !r.isEmpty() && !this->isEmpty() && // check for empties
+ 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(SkIRect* 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(SkIRect* 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
+
diff --git a/skia/include/corecg/SkRegion.h b/skia/include/corecg/SkRegion.h
new file mode 100644
index 0000000..238524a
--- /dev/null
+++ b/skia/include/corecg/SkRegion.h
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2005-2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 int32_t RunType;
+ enum {
+ kRunTypeSentinel = 0x7FFFFFFF
+ };
+
+ SkRegion();
+ SkRegion(const SkRegion&);
+ explicit SkRegion(const SkIRect&);
+ ~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);
+ }
+
+ /** Replace this region with the specified region, and return true if the
+ resulting region is non-empty.
+ */
+ bool set(const SkRegion& src) {
+ SkASSERT(&src);
+ *this = src;
+ return !this->isEmpty();
+ }
+
+ /** 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 SkIRect& 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, since the resulting
+ region is empty
+ */
+ 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 SkIRect&);
+
+ /** 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(int32_t left, int32_t top, int32_t right, int32_t 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, clipped.
+ 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) with the specified clip.
+ */
+ bool setPath(const SkPath&, const SkRegion& clip);
+
+ /** Return true if the specified x,y coordinate is inside the region.
+ */
+ bool contains(int32_t x, int32_t y) const;
+
+ /** Return true if the specified rectangle is completely inside the region.
+ This works for simple (rectangular) and complex regions, and always
+ returns the correct result. Note: if either this region or the rectangle
+ is empty, contains() returns false.
+ */
+ bool contains(const SkIRect&) const;
+
+ /** Return true if the specified region is completely inside the region.
+ This works for simple (rectangular) and complex regions, and always
+ returns the correct result. Note: if either region is empty, contains()
+ returns false.
+ */
+ bool contains(const SkRegion&) 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 SkIRect& r) const {
+ return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ }
+
+ /** 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(int32_t left, int32_t top, int32_t right,
+ int32_t bottom) const {
+ SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
+
+ return left < right && top < bottom &&
+ fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect()
+ /* fBounds.contains(left, top, right, bottom); */
+ fBounds.fLeft <= left && fBounds.fTop <= top &&
+ fBounds.fRight >= right && fBounds.fBottom >= 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 SkIRect& rect) const
+ {
+ return this->isEmpty() || rect.isEmpty() ||
+ !SkIRect::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() ||
+ !SkIRect::Intersects(fBounds, rgn.fBounds);
+ }
+
+ /** Translate the region by the specified (dx, dy) amount.
+ */
+ void translate(int dx, int dy) { this->translate(dx, dy, this); }
+
+ /** Translate the region by the specified (dx, dy) amount, writing the
+ resulting region into dst. Note: it is legal to pass this region as the
+ dst parameter, effectively translating the region in place. If dst is
+ null, nothing happens.
+ */
+ void translate(int dx, int dy, SkRegion* dst) const;
+
+ /** The logical operations that can be performed when combining two regions.
+ */
+ enum Op {
+ kDifference_Op, //!< subtract the op region from the first region
+ kIntersect_Op, //!< intersect the two regions
+ kUnion_Op, //!< union (inclusive-or) the two regions
+ kXOR_Op, //!< exclusive-or the two regions
+ /** subtract the first region from the op region */
+ kReverseDifference_Op,
+ kReplace_Op //!< replace the dst region with the op region
+ };
+
+ /** Set this region to the result of applying the Op to this region and the
+ specified rectangle: this = (this op rect).
+ Return true if the resulting region is non-empty.
+ */
+ bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
+
+ /** Set this region to the result of applying the Op to this region and the
+ specified rectangle: this = (this op rect).
+ Return true if the resulting region is non-empty.
+ */
+ bool op(int left, int top, int right, int bottom, Op op) {
+ SkIRect rect;
+ rect.set(left, top, right, bottom);
+ return this->op(*this, rect, op);
+ }
+
+ /** Set this region to the result of applying the Op to this region and the
+ specified region: this = (this op rgn).
+ 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 Op to the specified
+ rectangle and region: this = (rect op rgn).
+ Return true if the resulting region is non-empty.
+ */
+ bool op(const SkIRect& rect, const SkRegion& rgn, Op);
+ /** Set this region to the result of applying the Op to the specified
+ region and rectangle: this = (rgn op rect).
+ Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRegion& rgn, const SkIRect& rect, Op);
+ /** Set this region to the result of applying the Op to the specified
+ regions: this = (rgna op rgnb).
+ Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
+
+ /** Returns the sequence of rectangles, sorted in Y and X, that make up
+ this region.
+ */
+ class Iterator {
+ public:
+ Iterator() : fRgn(NULL), fDone(true) {}
+ Iterator(const SkRegion&);
+ // if we have a region, reset to it and return true, else return false
+ bool rewind();
+ // reset the iterator, using the new region
+ void reset(const SkRegion&);
+ bool done() { return fDone; }
+ void next();
+ const SkIRect& rect() const { return fRect; }
+
+ private:
+ const SkRegion* fRgn;
+ const RunType* fRuns;
+ SkIRect fRect;
+ bool fDone;
+ };
+
+ /** Returns the sequence of rectangles, sorted in Y and X, that make up
+ this region intersected with the specified clip rectangle.
+ */
+ class Cliperator {
+ public:
+ Cliperator(const SkRegion&, const SkIRect& clip);
+ bool done() { return fDone; }
+ void next();
+ const SkIRect& rect() const { return fRect; }
+
+ private:
+ Iterator fIter;
+ SkIRect fClip;
+ SkIRect fRect;
+ bool fDone;
+ };
+
+ /** Returns the sequence of runs that make up this region for the specified
+ Y scanline, clipped to the specified left and right X values.
+ */
+ 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;
+ };
+
+ /** Write the region to the buffer, and return the number of bytes written.
+ If buffer is NULL, it still returns the number of bytes.
+ */
+ uint32_t flatten(void* buffer) const;
+ /** Initialized the region from the buffer, returning the number
+ of bytes actually read.
+ */
+ uint32_t unflatten(const void* buffer);
+
+ SkDEBUGCODE(void dump() const;)
+ SkDEBUGCODE(void validate() const;)
+ SkDEBUGCODE(static void UnitTest();)
+
+private:
+ enum {
+ kOpCount = kReplace_Op + 1
+ };
+
+ enum {
+ kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S]
+ };
+
+ friend class android::Region; // needed for marshalling efficiently
+ void allocateRuns(int count); // allocate space for count runs
+
+ struct RunHead;
+
+ SkIRect 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 BuildRectRuns(const SkIRect& bounds,
+ RunType runs[kRectRegionRuns]);
+ // returns true if runs are just a rect
+ static bool ComputeRunBounds(const RunType runs[], int count,
+ SkIRect* bounds);
+
+ friend struct RunHead;
+ friend class Iterator;
+ friend class Spanerator;
+ friend class SkRgnBuilder;
+ friend class SkFlatRegion;
+};
+
+
+#endif
+
diff --git a/skia/include/corecg/SkScalar.h b/skia/include/corecg/SkScalar.h
new file mode 100644
index 0000000..3e737ae
--- /dev/null
+++ b/skia/include/corecg/SkScalar.h
@@ -0,0 +1,261 @@
+/* include/corecg/SkScalar.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkScalar_DEFINED
+#define SkScalar_DEFINED
+
+#include "SkFixed.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*)(const void*)&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)
+ /** SkScalarToFixed(n) returns its SkScalar argument as an SkFixed
+ */
+ #define SkScalarToFixed(x) SkFloatToFixed(x)
+
+ #define SkScalarToFloat(n) (n)
+ #define SkFloatToScalar(n) (n)
+
+ #define SkScalarToDouble(n) (double)(n)
+ #define SkDoubleToScalar(n) (float)(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
+ */
+ #define SkScalarRound(x) (int)sk_float_floor((x) + 0.5f)
+ /** Returns the smallest integer that is >= the specified SkScalar
+ */
+ #define SkScalarCeil(x) (int)sk_float_ceil(x)
+ /** Returns the largest integer that is <= the specified SkScalar
+ */
+ #define SkScalarFloor(x) (int)sk_float_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) ((float)(a) * (b))
+ /** Returns the product of two SkScalars plus a third SkScalar
+ */
+ #define SkScalarMulAdd(a, b, c) ((float)(a) * (b) + (c))
+ /** Returns the product of a SkScalar and an int rounded to the nearest integer value
+ */
+ #define SkScalarMulRound(a, b) SkScalarRound((float)(a) * (b))
+ /** Returns the product of a SkScalar and an int promoted to the next larger int
+ */
+ #define SkScalarMulCeil(a, b) SkScalarCeil((float)(a) * (b))
+ /** Returns the product of a SkScalar and an int truncated to the next smaller int
+ */
+ #define SkScalarMulFloor(a, b) SkScalarFloor((float)(a) * (b))
+ /** Returns the quotient of two SkScalars (a/b)
+ */
+ #define SkScalarDiv(a, b) ((float)(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) ((float)(a) * (b) / (c))
+ /** Returns the multiplicative inverse of the SkScalar (1/x)
+ */
+ #define SkScalarInvert(x) (SK_Scalar1 / (x))
+ #define SkScalarFastInvert(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((float)(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
+ 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)
+
+ #define SkScalarToDouble(n) SkFixedToDouble(n)
+ #define SkDoubleToScalar(n) SkDoubleToFixed(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 SkScalarMulAdd(a, b, c) SkFixedMulAdd(a, b, c)
+ #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 SkScalarFastInvert(x) SkFixedFastInvert(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
+
+#ifndef SK_SCALAR_IS_FLOAT
+#define SK_ScalarNearlyZero SK_FixedNearlyZero
+#else
+/* Allow a little more flexibility for floating-point scalars
+ */
+#define SK_ScalarNearlyZero (SK_Scalar1 / (1<<15))
+#endif
+
+/* <= 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
+
diff --git a/skia/include/corecg/SkTSearch.h b/skia/include/corecg/SkTSearch.h
new file mode 100644
index 0000000..ca1e467
--- /dev/null
+++ b/skia/include/corecg/SkTSearch.h
@@ -0,0 +1,168 @@
+/* include/corecg/SkTSearch.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkTSearch_DEFINED
+#define SkTSearch_DEFINED
+
+#include "SkTypes.h"
+
+template <typename T>
+int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
+{
+ SkASSERT(count >= 0);
+ if (count <= 0)
+ return ~0;
+
+ SkASSERT(base != NULL); // base may be NULL if count is zero
+
+ int lo = 0;
+ int hi = count - 1;
+
+ while (lo < hi)
+ {
+ int mid = (hi + lo) >> 1;
+ const T* elem = (const T*)((const char*)base + mid * elemSize);
+
+ if (*elem < target)
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ const T* elem = (const T*)((const char*)base + hi * elemSize);
+ if (*elem != target)
+ {
+ if (*elem < target)
+ hi += 1;
+ hi = ~hi;
+ }
+ return hi;
+}
+
+template <typename T>
+int SkTSearch(const T* base, int count, const T& target, size_t elemSize,
+ int (*compare)(const T&, const T&))
+{
+ SkASSERT(count >= 0);
+ if (count <= 0) {
+ return ~0;
+ }
+
+ SkASSERT(base != NULL); // base may be NULL if count is zero
+
+ int lo = 0;
+ int hi = count - 1;
+
+ while (lo < hi) {
+ int mid = (hi + lo) >> 1;
+ const T* elem = (const T*)((const char*)base + mid * elemSize);
+
+ if ((*compare)(*elem, target) < 0)
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ const T* elem = (const T*)((const char*)base + hi * elemSize);
+ int pred = (*compare)(*elem, target);
+ if (pred != 0) {
+ if (pred < 0)
+ hi += 1;
+ hi = ~hi;
+ }
+ return hi;
+}
+
+template <typename T>
+int SkTSearch(const T** base, int count, const T* target, size_t elemSize,
+ int (*compare)(const T*, const T*))
+{
+ SkASSERT(count >= 0);
+ if (count <= 0)
+ return ~0;
+
+ SkASSERT(base != NULL); // base may be NULL if count is zero
+
+ int lo = 0;
+ int hi = count - 1;
+
+ while (lo < hi)
+ {
+ int mid = (hi + lo) >> 1;
+ const T* elem = *(const T**)((const char*)base + mid * elemSize);
+
+ if ((*compare)(elem, target) < 0)
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ const T* elem = *(const T**)((const char*)base + hi * elemSize);
+ int pred = (*compare)(elem, target);
+ if (pred != 0)
+ {
+ if (pred < 0)
+ hi += 1;
+ hi = ~hi;
+ }
+ return hi;
+}
+
+int SkStrSearch(const char*const* base, int count, const char target[],
+ size_t target_len, size_t elemSize);
+int SkStrSearch(const char*const* base, int count, const char target[],
+ size_t elemSize);
+
+/** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
+ base points to a table of lower-case strings.
+*/
+int SkStrLCSearch(const char*const* base, int count, const char target[],
+ size_t target_len, size_t elemSize);
+int SkStrLCSearch(const char*const* base, int count, const char target[],
+ size_t elemSize);
+
+/** Helper class to convert a string to lower-case, but only modifying the ascii
+ characters. This makes the routine very fast and never changes the string
+ length, but it is not suitable for linguistic purposes. Normally this is
+ used for buiding and searching string tables.
+*/
+class SkAutoAsciiToLC {
+public:
+ SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
+ ~SkAutoAsciiToLC();
+
+ const char* lc() const { return fLC; }
+ size_t length() const { return fLength; }
+
+private:
+ char* fLC; // points to either the heap or fStorage
+ size_t fLength;
+ enum {
+ STORAGE = 64
+ };
+ char fStorage[STORAGE+1];
+};
+
+extern "C" {
+ typedef int (*SkQSortCompareProc)(const void*, const void*);
+ void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc);
+}
+
+SkDEBUGCODE(void SkQSort_UnitTest();)
+
+#endif
+
diff --git a/skia/include/corecg/SkTemplates.h b/skia/include/corecg/SkTemplates.h
new file mode 100644
index 0000000..cfe42d9
--- /dev/null
+++ b/skia/include/corecg/SkTemplates.h
@@ -0,0 +1,188 @@
+/* include/corecg/SkTemplates.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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 SkAutoTCallVProc
+
+ Call a function when this goes out of scope. The template uses two
+ parameters, the object, and a function that is to be called in the destructor.
+ If detach() is called, the object reference is set to null. If the object
+ reference is null when the destructor is called, we do not call the
+ function.
+*/
+template <typename T, void (*P)(T*)> class SkAutoTCallVProc : SkNoncopyable {
+public:
+ SkAutoTCallVProc(T* obj): fObj(obj) {}
+ ~SkAutoTCallVProc() { if (fObj) P(fObj); }
+ T* detach() { T* obj = fObj; fObj = NULL; return obj; }
+private:
+ T* fObj;
+};
+
+/** \class SkAutoTCallIProc
+
+Call a function when this goes out of scope. The template uses two
+parameters, the object, and a function that is to be called in the destructor.
+If detach() is called, the object reference is set to null. If the object
+reference is null when the destructor is called, we do not call the
+function.
+*/
+template <typename T, int (*P)(T*)> class SkAutoTCallIProc : SkNoncopyable {
+public:
+ SkAutoTCallIProc(T* obj): fObj(obj) {}
+ ~SkAutoTCallIProc() { if (fObj) P(fObj); }
+ T* detach() { T* obj = fObj; fObj = NULL; return obj; }
+private:
+ T* fObj;
+};
+
+template <typename T> class SkAutoTDelete : SkNoncopyable {
+public:
+ SkAutoTDelete(T* obj) : fObj(obj) {}
+ ~SkAutoTDelete() { delete fObj; }
+
+ T* get() const { return fObj; }
+ void free() { delete fObj; fObj = NULL; }
+ T* detach() { T* obj = fObj; fObj = NULL; return obj; }
+
+private:
+ T* fObj;
+};
+
+template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
+public:
+ SkAutoTDeleteArray(T array[]) : fArray(array) {}
+ ~SkAutoTDeleteArray() { delete[] fArray; }
+
+ T* get() const { return fArray; }
+ void free() { delete[] fArray; fArray = NULL; }
+ T* detach() { T* array = fArray; fArray = NULL; return array; }
+
+private:
+ T* fArray;
+};
+
+template <typename T> class SkAutoTArray : SkNoncopyable {
+public:
+ SkAutoTArray(size_t count)
+ {
+ fArray = NULL; // 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 = NULL;
+ }
+ }
+
+ 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 : SkNoncopyable {
+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;
+};
+
+template <size_t N, typename T> class SkAutoSTMalloc : SkNoncopyable {
+public:
+ SkAutoSTMalloc(size_t count)
+ {
+ if (count <= N)
+ fPtr = fTStorage;
+ else
+ fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
+ }
+ ~SkAutoSTMalloc()
+ {
+ if (fPtr != fTStorage)
+ sk_free(fPtr);
+ }
+ T* get() const { return fPtr; }
+
+private:
+ T* fPtr;
+ union {
+ uint32_t fStorage32[(N*sizeof(T) + 3) >> 2];
+ T fTStorage[1]; // do NOT want to invoke T::T()
+ };
+};
+
+#endif
+
diff --git a/skia/include/corecg/SkThread.h b/skia/include/corecg/SkThread.h
new file mode 100644
index 0000000..8dc2402
--- /dev/null
+++ b/skia/include/corecg/SkThread.h
@@ -0,0 +1,69 @@
+/* include/corecg/SkThread.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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 : SkNoncopyable {
+public:
+ explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(&mutex)
+ {
+ SkASSERT(fMutex != NULL);
+ mutex.acquire();
+ }
+ /** If the mutex has not been release, release it now.
+ */
+ ~SkAutoMutexAcquire()
+ {
+ if (fMutex)
+ fMutex->release();
+ }
+ /** If the mutex has not been release, release it now.
+ */
+ void release()
+ {
+ if (fMutex)
+ {
+ fMutex->release();
+ fMutex = NULL;
+ }
+ }
+
+private:
+ SkMutex* fMutex;
+};
+
+#endif
diff --git a/skia/include/corecg/SkThread_platform.h b/skia/include/corecg/SkThread_platform.h
new file mode 100644
index 0000000..b94bc42
--- /dev/null
+++ b/skia/include/corecg/SkThread_platform.h
@@ -0,0 +1,72 @@
+/* include/corecg/SkThread_platform.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef 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:
+ // if isGlobal is true, then ignore any errors in the platform-specific
+ // destructor
+ SkMutex(bool isGlobal = true) {}
+ ~SkMutex() {}
+
+ void acquire() { this->lock(); }
+ void release() { this->unlock(); }
+};
+
+#else
+
+/** Implemented by the porting layer, this function adds 1 to the int specified
+ by the address (in a thread-safe manner), and returns the previous value.
+*/
+int32_t sk_atomic_inc(int32_t* addr);
+/** Implemented by the porting layer, this function subtracts 1 to the int
+ specified by the address (in a thread-safe manner), and returns the previous
+ value.
+*/
+int32_t sk_atomic_dec(int32_t* addr);
+
+class SkMutex {
+public:
+ // if isGlobal is true, then ignore any errors in the platform-specific
+ // destructor
+ SkMutex(bool isGlobal = true);
+ ~SkMutex();
+
+ void acquire();
+ void release();
+
+private:
+ bool fIsGlobal;
+ enum {
+ kStorageIntCount = 12
+ };
+ uint32_t fStorage[kStorageIntCount];
+};
+
+#endif
+
+#endif
diff --git a/skia/include/corecg/SkTypes.h b/skia/include/corecg/SkTypes.h
new file mode 100644
index 0000000..b67cf1d
--- /dev/null
+++ b/skia/include/corecg/SkTypes.h
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2006, Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkTypes_DEFINED
+#define SkTypes_DEFINED
+
+#include "SkPreConfig.h"
+#include "SkUserConfig.h"
+#include "SkPostConfig.h"
+
+#ifndef SK_IGNORE_STDINT_DOT_H
+ #include <stdint.h>
+#endif
+
+#include <stdio.h>
+
+/** \file SkTypes.h
+*/
+
+/*
+ memory wrappers to be implemented by the porting layer (platform)
+*/
+
+/** Called internally if we run out of memory. The platform implementation must
+ not return, but should either throw an exception or otherwise exit.
+*/
+extern void sk_out_of_memory(void);
+/** Called internally if we hit an unrecoverable error.
+ The platform implementation must not return, but should either throw
+ an exception or otherwise exit.
+*/
+extern void sk_throw(void);
+
+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 null (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 null 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 null.
+*/
+extern void sk_free(void*);
+
+///////////////////////////////////////////////////////////////////////
+
+#define SK_INIT_TO_AVOID_WARNING = 0
+
+#ifndef SkDebugf
+ void SkDebugf(const char format[], ...);
+#endif
+
+#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
+ #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
+
+///////////////////////////////////////////////////////////////////////
+
+/** 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 SkSetClearShift(uint32_t bits, bool cond, unsigned shift)
+{
+ SkASSERT((int)cond == 0 || (int)cond == 1);
+ return (bits & ~(1 << shift)) | ((int)cond << shift);
+}
+
+inline uint32_t SkSetClearMask(uint32_t bits, bool cond, uint32_t mask)
+{
+ return cond ? bits | mask : bits & ~mask;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/** \class SkNoncopyable
+
+SkNoncopyable is the base class for objects that may do not want to
+be copied. It hides its copy-constructor and its assignment-operator.
+*/
+class SkNoncopyable {
+public:
+ SkNoncopyable() {}
+
+private:
+ SkNoncopyable(const SkNoncopyable&);
+ SkNoncopyable& operator=(const SkNoncopyable&);
+};
+
+class SkAutoFree : SkNoncopyable {
+public:
+ SkAutoFree() : fPtr(NULL) {}
+ explicit SkAutoFree(void* ptr) : fPtr(ptr) {}
+ ~SkAutoFree() { sk_free(fPtr); }
+
+ /** Return the currently allocate buffer, or null
+ */
+ void* get() const { return fPtr; }
+
+ /** Assign a new ptr allocated with sk_malloc (or null), and return the
+ previous ptr. Note it is the caller's responsibility to sk_free the
+ returned ptr.
+ */
+ void* set(void* ptr) {
+ void* prev = fPtr;
+ fPtr = ptr;
+ return prev;
+ }
+
+ /** Transfer ownership of the current ptr to the caller, setting the
+ internal reference to null. Note the caller is reponsible for calling
+ sk_free on the returned address.
+ */
+ void* detach() { return this->set(NULL); }
+
+ /** Free the current buffer, and set the internal reference to NULL. Same
+ as calling sk_free(detach())
+ */
+ void free() {
+ sk_free(fPtr);
+ fPtr = NULL;
+ }
+
+private:
+ void* fPtr;
+ // illegal
+ SkAutoFree(const SkAutoFree&);
+ SkAutoFree& operator=(const SkAutoFree&);
+};
+
+class SkAutoMalloc : public SkAutoFree {
+public:
+ explicit SkAutoMalloc(size_t size)
+ : SkAutoFree(sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP)) {}
+
+ SkAutoMalloc(size_t size, unsigned flags)
+ : SkAutoFree(sk_malloc_flags(size, flags)) {}
+ SkAutoMalloc() {}
+
+ void* alloc(size_t size,
+ unsigned flags = (SK_MALLOC_THROW | SK_MALLOC_TEMP)) {
+ sk_free(set(sk_malloc_flags(size, flags)));
+ return get();
+ }
+};
+
+template <size_t kSize> class SkAutoSMalloc : SkNoncopyable {
+public:
+ explicit 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
+
diff --git a/skia/include/corecg/SkUserConfig.h b/skia/include/corecg/SkUserConfig.h
new file mode 100644
index 0000000..be7622f
--- /dev/null
+++ b/skia/include/corecg/SkUserConfig.h
@@ -0,0 +1,118 @@
+/* include/corecg/SkUserConfig.h
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef SkUserConfig_DEFINED
+#define SkUserConfig_DEFINED
+
+// remove the x if you want to force us into SK_DEBUG mode
+#ifdef SK_RELEASEx
+ #undef SK_RELEASE
+ #define SK_DEBUG
+#endif
+
+#ifdef ANDROID
+ #include <utils/misc.h>
+
+#if 0
+ // force fixed
+ #define SK_SCALAR_IS_FIXED
+ #undef SK_SCALAR_IS_FLOAT
+#else
+ // force floats
+ #ifdef SK_SCALAR_IS_FIXED
+ #undef SK_SCALAR_IS_FIXED
+ #endif
+ #define SK_SCALAR_IS_FLOAT
+#endif
+
+ #define SK_CAN_USE_FLOAT
+ #define SkLONGLONG int64_t
+
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ #define SK_CPU_BENDIAN
+ #undef SK_CPU_LENDIAN
+ #else
+ #define SK_CPU_LENDIAN
+ #undef SK_CPU_BENDIAN
+ #endif
+
+ // define SkDebugf to record file/line
+ #define SkDebugf(...) Android_SkDebugf(__FILE__, __LINE__, \
+ __FUNCTION__, __VA_ARGS__)
+ void Android_SkDebugf(const char* file, int line,
+ const char* function, const char* format, ...);
+#endif
+
+/* 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
+
+#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
+
+// ===== Begin Chrome-specific definitions =====
+
+#define SK_SCALAR_IS_FLOAT
+#undef SK_SCALAR_IS_FIXED
+
+#define SK_BUILD_FOR_WIN
+
+// VC8 doesn't support stdint.h, so we define those types here.
+#define SK_IGNORE_STDINT_DOT_H
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+
+// Don't use skia debug mode even when compiled as debug, because we don't
+// care about debugging this library, only our app.
+#undef SK_DEBUG
+#undef SK_SUPPORT_UNITTEST
+#define SK_RELEASE
+#undef SK_RESTRICT
+#define SK_RESTRICT
+// Skia uses this deprecated bzero function to fill zeros into a string.
+#define bzero(str, len) memset(str, 0, len)
+#define SkDebugf(...) ((void)0)
+#define SK_A32_SHIFT 24
+#define SK_R32_SHIFT 16
+#define SK_G32_SHIFT 8
+#define SK_B32_SHIFT 0
+
+// ===== End Chrome-specific definitions =====
+
+#endif
+