aboutsummaryrefslogtreecommitdiffstats
path: root/include/core
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2012-03-06 09:06:43 -0500
committerDerek Sollenberger <derek@android.com>2012-03-06 09:44:47 -0500
commit4f1dae40e24d57d647db01443b8bf2410514b8b5 (patch)
tree594df3f3fc6c1d90a76691a75763ae1beacfdf98 /include/core
parent1cab2921ab279367f8206cdadc9259d12e603548 (diff)
downloadexternal_skia-4f1dae40e24d57d647db01443b8bf2410514b8b5.zip
external_skia-4f1dae40e24d57d647db01443b8bf2410514b8b5.tar.gz
external_skia-4f1dae40e24d57d647db01443b8bf2410514b8b5.tar.bz2
Skia Merge (revision 3312)
This CL also includes changes made to Android's copy of Skia in their J release branch. Change-Id: Ib2baecf48004951a3ad4a1574cdc38790c814cbc
Diffstat (limited to 'include/core')
-rw-r--r--include/core/SkCanvas.h41
-rw-r--r--include/core/SkColorPriv.h162
-rw-r--r--include/core/SkDevice.h25
-rw-r--r--include/core/SkDeviceProfile.h95
-rw-r--r--include/core/SkEndian.h56
-rw-r--r--include/core/SkFlattenable.h5
-rw-r--r--include/core/SkFontHost.h6
-rw-r--r--include/core/SkImageFilter.h16
-rw-r--r--include/core/SkPaint.h5
-rw-r--r--include/core/SkPath.h14
-rw-r--r--include/core/SkPathMeasure.h4
-rw-r--r--include/core/SkPixelRef.h10
-rw-r--r--include/core/SkPoint.h4
-rw-r--r--include/core/SkRegion.h6
-rw-r--r--include/core/SkScalerContext.h40
-rw-r--r--include/core/SkStream.h3
-rw-r--r--include/core/SkStroke.h4
-rw-r--r--include/core/SkThread.h4
-rw-r--r--include/core/SkThread_platform.h64
-rw-r--r--include/core/SkUserConfig.h7
20 files changed, 489 insertions, 82 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 24e4141..1b9f055 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -62,6 +62,11 @@ public:
///////////////////////////////////////////////////////////////////////////
/**
+ * Trigger the immediate execution of all pending draw operations.
+ */
+ void flush();
+
+ /**
* Return the width/height of the underlying device. The current drawable
* area may be small (due to clipping or saveLayer). For a canvas with
* no device, 0,0 will be returned.
@@ -78,7 +83,7 @@ public:
reference count is incremented. If the canvas was already holding a
device, its reference count is decremented. The new device is returned.
*/
- SkDevice* setDevice(SkDevice* device);
+ virtual SkDevice* setDevice(SkDevice* device);
/**
* saveLayer() can create another device (which is later drawn onto
@@ -99,7 +104,7 @@ public:
* Shortcut for getDevice()->createCompatibleDevice(...).
* If getDevice() == NULL, this method does nothing, and returns NULL.
*/
- SkDevice* createCompatibleDevice(SkBitmap::Config config,
+ SkDevice* createCompatibleDevice(SkBitmap::Config config,
int width, int height,
bool isOpaque);
@@ -152,7 +157,7 @@ public:
* kARGB_8888_Config as SkPMColor
*
* If the bitmap has pixels already allocated, the canvas pixels will be
- * written there. If not, bitmap->allocPixels() will be called
+ * written there. If not, bitmap->allocPixels() will be called
* automatically. If the bitmap is backed by a texture readPixels will
* fail.
*
@@ -290,7 +295,7 @@ public:
/** Returns true if drawing is currently going to a layer (from saveLayer)
* rather than to the root device.
*/
- bool isDrawingToLayer() const;
+ virtual bool isDrawingToLayer() const;
/** Preconcat the current matrix with the specified translation
@param dx The distance to translate in X
@@ -424,7 +429,16 @@ public:
@return true if the horizontal band is completely clipped out (i.e. does
not intersect the current clip)
*/
- bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const;
+ bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const {
+ SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom));
+ const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(et);
+ // In the case where the clip is empty and we are provided with a
+ // negative top and positive bottom parameter then this test will return
+ // false even though it will be clipped. We have chosen to exclude that
+ // check as it is rare and would result double the comparisons.
+ return SkScalarToCompareType(top) >= clipR.fBottom
+ || SkScalarToCompareType(bottom) <= clipR.fTop;
+ }
/** Return the bounds of the current clip (in local coordinates) in the
bounds parameter, and return true if it is non-empty. This can be useful
@@ -438,7 +452,7 @@ public:
then taking its bounds.
*/
bool getClipDeviceBounds(SkIRect* bounds) const;
-
+
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
specified ARGB color, using the specified mode.
@@ -921,10 +935,21 @@ public:
};
protected:
+ // Returns the canvas to be used by DrawIter. Default implementation
+ // returns this. Subclasses that encapsulate an indirect canvas may
+ // need to overload this method. The impl must keep track of this, as it
+ // is not released or deleted by the caller.
+ virtual SkCanvas* canvasForDrawIter();
+
// all of the drawBitmap variants call this guy
virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*,
const SkMatrix&, const SkPaint& paint);
+ // Clip rectangle bounds. Called internally by saveLayer.
+ // returns false if the entire rectangle is entirely clipped out
+ bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
+ SkIRect* intersection);
+
private:
class MCRec;
@@ -947,7 +972,7 @@ private:
friend class SkDrawIter; // needs setupDrawForLayerDevice()
- SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
+ SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
bool isOpaque);
SkDevice* init(SkDevice*);
@@ -962,7 +987,7 @@ private:
const SkRect& dst, const SkPaint* paint);
void internalDrawPaint(const SkPaint& paint);
-
+
void drawDevice(SkDevice*, int x, int y, const SkPaint*);
// shared by save() and saveLayer()
int internalSave(SaveFlags flags);
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h
index 714e845..e51b0b9 100644
--- a/include/core/SkColorPriv.h
+++ b/include/core/SkColorPriv.h
@@ -216,6 +216,57 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
}
/**
+ * Abstract 4-byte interpolation, implemented on top of SkPMColor
+ * utility functions. Third parameter controls blending of the first two:
+ * (src, dst, 0) returns dst
+ * (src, dst, 0xFF) returns src
+ */
+static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst,
+ U8CPU srcWeight) {
+ unsigned scale = SkAlpha255To256(srcWeight);
+
+ unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale);
+ unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
+ unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
+ unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
+
+ return SkPackARGB32(a, r, g, b);
+}
+
+/**
+ * 32b optimized version; currently appears to be 10% faster even on 64b
+ * architectures than an equivalent 64b version and 30% faster than
+ * SkFourByteInterp(). Third parameter controls blending of the first two:
+ * (src, dst, 0) returns dst
+ * (src, dst, 0xFF) returns src
+ * ** Does not match the results of SkFourByteInterp() because we use
+ * a more accurate scale computation!
+ * TODO: migrate Skia function to using an accurate 255->266 alpha
+ * conversion.
+ */
+static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
+ SkPMColor dst,
+ U8CPU srcWeight) {
+ SkASSERT(srcWeight < 256);
+
+ // Reorders ARGB to AG-RB in order to reduce the number of operations.
+ const uint32_t mask = 0xFF00FF;
+ uint32_t src_rb = src & mask;
+ uint32_t src_ag = (src >> 8) & mask;
+ uint32_t dst_rb = dst & mask;
+ uint32_t dst_ag = (dst >> 8) & mask;
+
+ // scale = srcWeight + (srcWeight >> 7) is more accurate than
+ // scale = srcWeight + 1, but 7% slower
+ int scale = srcWeight + (srcWeight >> 7);
+
+ uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
+ uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
+
+ return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8);
+}
+
+/**
* Same as SkPackARGB32, but this version guarantees to not check that the
* values are premultiplied in the debug version.
*/
@@ -663,5 +714,116 @@ static inline uint32_t SkExpand32_4444(SkPMColor c) {
// used for cheap 2x2 dithering when the colors are opaque
void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n);
+///////////////////////////////////////////////////////////////////////////////
+
+static inline int SkUpscale31To32(int value) {
+ SkASSERT((unsigned)value <= 31);
+ return value + (value >> 4);
+}
+
+static inline int SkBlend32(int src, int dst, int scale) {
+ SkASSERT((unsigned)src <= 0xFF);
+ SkASSERT((unsigned)dst <= 0xFF);
+ SkASSERT((unsigned)scale <= 32);
+ return dst + ((src - dst) * scale >> 5);
+}
+
+static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB,
+ SkPMColor dst, uint16_t mask) {
+ if (mask == 0) {
+ return dst;
+ }
+
+ /* We want all of these in 5bits, hence the shifts in case one of them
+ * (green) is 6bits.
+ */
+ int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
+ int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
+ int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
+
+ // Now upscale them to 0..32, so we can use blend32
+ maskR = SkUpscale31To32(maskR);
+ maskG = SkUpscale31To32(maskG);
+ maskB = SkUpscale31To32(maskB);
+
+ // srcA has been upscaled to 256 before passed into this function
+ maskR = maskR * srcA >> 8;
+ maskG = maskG * srcA >> 8;
+ maskB = maskB * srcA >> 8;
+
+ int dstR = SkGetPackedR32(dst);
+ int dstG = SkGetPackedG32(dst);
+ int dstB = SkGetPackedB32(dst);
+
+ // LCD blitting is only supported if the dst is known/required
+ // to be opaque
+ return SkPackARGB32(0xFF,
+ SkBlend32(srcR, dstR, maskR),
+ SkBlend32(srcG, dstG, maskG),
+ SkBlend32(srcB, dstB, maskB));
+}
+
+static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB,
+ SkPMColor dst, uint16_t mask,
+ SkPMColor opaqueDst) {
+ if (mask == 0) {
+ return dst;
+ }
+
+ if (0xFFFF == mask) {
+ return opaqueDst;
+ }
+
+ /* We want all of these in 5bits, hence the shifts in case one of them
+ * (green) is 6bits.
+ */
+ int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
+ int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
+ int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
+
+ // Now upscale them to 0..32, so we can use blend32
+ maskR = SkUpscale31To32(maskR);
+ maskG = SkUpscale31To32(maskG);
+ maskB = SkUpscale31To32(maskB);
+
+ int dstR = SkGetPackedR32(dst);
+ int dstG = SkGetPackedG32(dst);
+ int dstB = SkGetPackedB32(dst);
+
+ // LCD blitting is only supported if the dst is known/required
+ // to be opaque
+ return SkPackARGB32(0xFF,
+ SkBlend32(srcR, dstR, maskR),
+ SkBlend32(srcG, dstG, maskG),
+ SkBlend32(srcB, dstB, maskB));
+}
+
+static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t src[],
+ SkColor color, int width, SkPMColor) {
+ int srcA = SkColorGetA(color);
+ int srcR = SkColorGetR(color);
+ int srcG = SkColorGetG(color);
+ int srcB = SkColorGetB(color);
+
+ srcA = SkAlpha255To256(srcA);
+
+ for (int i = 0; i < width; i++) {
+ dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], src[i]);
+ }
+}
+
+static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t src[],
+ SkColor color, int width,
+ SkPMColor opaqueDst) {
+ int srcR = SkColorGetR(color);
+ int srcG = SkColorGetG(color);
+ int srcB = SkColorGetB(color);
+
+ for (int i = 0; i < width; i++) {
+ dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], src[i],
+ opaqueDst);
+ }
+}
+
#endif
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index c026a4b..3303981 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -62,7 +62,7 @@ public:
* draw into this device such that all of the pixels will
* be opaque.
*/
- SkDevice* createCompatibleDevice(SkBitmap::Config config,
+ SkDevice* createCompatibleDevice(SkBitmap::Config config,
int width, int height,
bool isOpaque);
@@ -258,7 +258,7 @@ protected:
* kARGB_8888_Config as SkPMColor
*
* If the bitmap has pixels already allocated, the device pixels will be
- * written there. If not, bitmap->allocPixels() will be called
+ * written there. If not, bitmap->allocPixels() will be called
* automatically. If the bitmap is backed by a texture readPixels will
* fail.
*
@@ -279,11 +279,14 @@ protected:
///////////////////////////////////////////////////////////////////////////
- /** Update as needed the pixel value in the bitmap, so that the caller can access
- the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
- must remain unchanged.
+ /** Update as needed the pixel value in the bitmap, so that the caller can
+ access the pixels directly. Note: only the pixels field should be
+ altered. The config/width/height/rowbytes must remain unchanged.
+ @param bitmap The device's bitmap
+ @return Echo the bitmap parameter, or an alternate (shadow) bitmap
+ maintained by the subclass.
*/
- virtual void onAccessBitmap(SkBitmap*);
+ virtual const SkBitmap& onAccessBitmap(SkBitmap*);
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
// just for subclasses, to assign a custom pixelref
@@ -291,7 +294,7 @@ protected:
fBitmap.setPixelRef(pr, offset);
return pr;
}
-
+
/**
* Implements readPixels API. The caller will ensure that:
* 1. bitmap has pixel config kARGB_8888_Config.
@@ -327,7 +330,7 @@ protected:
const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset);
- // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if
+ // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if
// either is identical to kNative_Premul_Config8888. Otherwise, -1.
static const SkCanvas::Config8888 kPMColorAlias;
@@ -342,15 +345,15 @@ private:
// just called by SkCanvas when built as a layer
void setOrigin(int x, int y) { fOrigin.set(x, y); }
// just called by SkCanvas for saveLayer
- SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
+ SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
int width, int height,
bool isOpaque);
/**
* Subclasses should override this to implement createCompatibleDevice.
*/
- virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
- int width, int height,
+ virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
bool isOpaque,
Usage usage);
diff --git a/include/core/SkDeviceProfile.h b/include/core/SkDeviceProfile.h
new file mode 100644
index 0000000..46b9781
--- /dev/null
+++ b/include/core/SkDeviceProfile.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDeviceProfile_DEFINED
+#define SkDeviceProfile_DEFINED
+
+#include "SkRefCnt.h"
+
+class SkDeviceProfile : public SkRefCnt {
+public:
+ enum LCDConfig {
+ kNone_LCDConfig, // disables LCD text rendering, uses A8 instead
+ kRGB_Horizontal_LCDConfig,
+ kBGR_Horizontal_LCDConfig,
+ kRGB_Vertical_LCDConfig,
+ kBGR_Vertical_LCDConfig,
+ };
+
+ enum FontHintLevel {
+ kNone_FontHintLevel,
+ kSlight_FontHintLevel,
+ kNormal_FontHintLevel,
+ kFull_FontHintLevel,
+ kAuto_FontHintLevel,
+ };
+
+ /**
+ * gammaExp is typically between 1.0 and 2.2. For no gamma adjustment,
+ * specify 1.0
+ *
+ * contrastScale will be pinned between 0.0 and 1.0. For no contrast
+ * adjustment, specify 0.0
+ *
+ * @param config Describes the LCD layout for this device. If this is set
+ * to kNone, then all requests for LCD text will be
+ * devolved to A8 antialiasing.
+ *
+ * @param level The hinting level to be used, IF the paint specifies
+ * "default". Otherwise the paint's hinting level will be
+ * respected.
+ */
+ static SkDeviceProfile* Create(float gammaExp,
+ float contrastScale,
+ LCDConfig,
+ FontHintLevel);
+
+ /**
+ * Returns the global default profile, that is used if no global profile is
+ * specified with SetGlobal(), or if NULL is specified to SetGlobal().
+ * The references count is *not* incremented, and the caller should not
+ * call unref().
+ */
+ static SkDeviceProfile* GetDefault();
+
+ /**
+ * Return the current global profile (or the default if no global had yet
+ * been set) and increment its reference count. The call *must* call unref()
+ * when it is done using it.
+ */
+ static SkDeviceProfile* RefGlobal();
+
+ /**
+ * Make the specified profile be the global value for all subsequently
+ * instantiated devices. Does not affect any existing devices.
+ * Increments the reference count on the profile.
+ * Specify NULL for the "identity" profile (where there is no gamma or
+ * contrast correction).
+ */
+ static void SetGlobal(SkDeviceProfile*);
+
+ float getFontGammaExponent() const { return fGammaExponent; }
+ float getFontContrastScale() const { return fContrastScale; }
+
+ /**
+ * Given a luminance byte (0 for black, 0xFF for white), generate a table
+ * that applies the gamma/contrast settings to linear coverage values.
+ */
+ void generateTableForLuminanceByte(U8CPU lumByte, uint8_t table[256]) const;
+
+private:
+ SkDeviceProfile(float gammaExp, float contrastScale, LCDConfig,
+ FontHintLevel);
+
+ float fGammaExponent;
+ float fContrastScale;
+ LCDConfig fLCDConfig;
+ FontHintLevel fFontHintLevel;
+};
+
+#endif
+
diff --git a/include/core/SkEndian.h b/include/core/SkEndian.h
index 3eb67da..910cf1e 100644
--- a/include/core/SkEndian.h
+++ b/include/core/SkEndian.h
@@ -31,8 +31,11 @@
*/
static inline uint16_t SkEndianSwap16(U16CPU value) {
SkASSERT(value == (uint16_t)value);
- return (uint16_t)((value >> 8) | (value << 8));
+ return static_cast<uint16_t>((value >> 8) | (value << 8));
}
+template<uint16_t N> struct SkTEndianSwap16 {
+ static const uint16_t value = static_cast<uint16_t>((N >> 8) | ((N & 0xFF) << 8));
+};
/** Vector version of SkEndianSwap16(), which swaps the
low two bytes of each value in the array.
@@ -55,6 +58,12 @@ static inline uint32_t SkEndianSwap32(uint32_t value) {
((value & 0xFF0000) >> 8) |
(value >> 24);
}
+template<uint32_t N> struct SkTEndianSwap32 {
+ static const uint32_t value = ((N & 0xFF) << 24) |
+ ((N & 0xFF00) << 8) |
+ ((N & 0xFF0000) >> 8) |
+ (N >> 24);
+};
/** Vector version of SkEndianSwap16(), which swaps the
bytes of each value in the array.
@@ -73,11 +82,21 @@ static inline void SkEndianSwap32s(uint32_t array[], int count) {
#define SkEndian_SwapBE32(n) SkEndianSwap32(n)
#define SkEndian_SwapLE16(n) (n)
#define SkEndian_SwapLE32(n) (n)
+
+ #define SkTEndian_SwapBE16(n) SkTEndianSwap16<n>::value
+ #define SkTEndian_SwapBE32(n) SkTEndianSwap32<n>::value
+ #define SkTEndian_SwapLE16(n) (n)
+ #define SkTEndian_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)
+
+ #define SkTEndian_SwapBE16(n) (n)
+ #define SkTEndian_SwapBE32(n) (n)
+ #define SkTEndian_SwapLE16(n) SkTEndianSwap16<n>::value
+ #define SkTEndian_SwapLE32(n) SkTEndianSwap32<n>::value
#endif
// When a bytestream is embedded in a 32-bit word, how far we need to
@@ -94,5 +113,40 @@ static inline void SkEndianSwap32s(uint32_t array[], int count) {
#define SkEndian_Byte3Shift 0
#endif
+
+#if defined(SK_UINT8_BITFIELD_LENDIAN) && defined(SK_UINT8_BITFIELD_BENDIAN)
+ #error "can't have both bitfield LENDIAN and BENDIAN defined"
+#endif
+
+#if !defined(SK_UINT8_BITFIELD_LENDIAN) && !defined(SK_UINT8_BITFIELD_BENDIAN)
+ #ifdef SK_CPU_LENDIAN
+ #define SK_UINT8_BITFIELD_LENDIAN
+ #else
+ #define SK_UINT8_BITFIELD_BENDIAN
+ #endif
+#endif
+
+#ifdef SK_UINT8_BITFIELD_LENDIAN
+ #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \
+ SK_OT_BYTE f0 : 1; \
+ SK_OT_BYTE f1 : 1; \
+ SK_OT_BYTE f2 : 1; \
+ SK_OT_BYTE f3 : 1; \
+ SK_OT_BYTE f4 : 1; \
+ SK_OT_BYTE f5 : 1; \
+ SK_OT_BYTE f6 : 1; \
+ SK_OT_BYTE f7 : 1;
+#else
+ #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \
+ SK_OT_BYTE f7 : 1; \
+ SK_OT_BYTE f6 : 1; \
+ SK_OT_BYTE f5 : 1; \
+ SK_OT_BYTE f4 : 1; \
+ SK_OT_BYTE f3 : 1; \
+ SK_OT_BYTE f2 : 1; \
+ SK_OT_BYTE f1 : 1; \
+ SK_OT_BYTE f0 : 1;
+#endif
+
#endif
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h
index a66638e..34ca34e 100644
--- a/include/core/SkFlattenable.h
+++ b/include/core/SkFlattenable.h
@@ -161,6 +161,9 @@ public:
void* readFunctionPtr();
SkFlattenable* readFlattenable();
+ void setPictureVersion(uint32_t version) { fPictureVersion = version; }
+ uint32_t getPictureVersion() { return fPictureVersion; }
+
private:
SkRefCnt** fRCArray;
int fRCCount;
@@ -172,6 +175,8 @@ private:
SkFlattenable::Factory* fFactoryArray;
int fFactoryCount;
+ uint32_t fPictureVersion;
+
typedef SkReader32 INHERITED;
};
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h
index c549519..25c9ecb 100644
--- a/include/core/SkFontHost.h
+++ b/include/core/SkFontHost.h
@@ -84,12 +84,6 @@ public:
///////////////////////////////////////////////////////////////////////////
- /** Returns true if the specified unique ID matches an existing font.
- Returning false is similar to calling OpenStream with an invalid ID,
- which will return NULL in that case.
- */
- static bool ValidFontID(SkFontID uniqueID);
-
/** Return a new stream to read the font data, or null if the uniqueID does
not match an existing typeface. .The caller must call stream->unref()
when it is finished reading the data.
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index 22b9569..7d7c140 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -80,6 +80,22 @@ public:
*/
virtual bool asABlur(SkSize* sigma) const;
+ /**
+ * Experimental.
+ *
+ * If the filter can be expressed as an erode, return true and
+ * set the radius in X and Y.
+ */
+ virtual bool asAnErode(SkISize* radius) const;
+
+ /**
+ * Experimental.
+ *
+ * If the filter can be expressed as a dilation, return true and
+ * set the radius in X and Y.
+ */
+ virtual bool asADilate(SkISize* radius) const;
+
protected:
SkImageFilter() {}
explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 445f7eb..31bc30b 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -100,11 +100,12 @@ public:
kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
kVerticalText_Flag = 0x1000,
+ kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it
// when adding extra flags, note that the fFlags member is specified
// with a bit-width and you'll have to expand it.
- kAllFlags = 0x1FFF
+ kAllFlags = 0x3FFF
};
/** Return the paint's flags. Use the Flag enum to test flag values.
@@ -880,7 +881,7 @@ private:
SkColor fColor;
SkScalar fWidth;
SkScalar fMiterLimit;
- unsigned fFlags : 14;
+ unsigned fFlags : 15;
unsigned fTextAlign : 2;
unsigned fCapType : 2;
unsigned fJoinType : 2;
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index 859486c..957d50e 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -732,6 +732,8 @@ public:
#ifdef SK_BUILD_FOR_ANDROID
uint32_t getGenerationID() const;
+ const SkPath* getSourcePath() const;
+ void setSourcePath(const SkPath* path);
#endif
SkDEBUGCODE(void validate() const;)
@@ -740,19 +742,20 @@ private:
SkTDArray<SkPoint> fPts;
SkTDArray<uint8_t> fVerbs;
mutable SkRect fBounds;
+ int fLastMoveToIndex;
uint8_t fFillType;
uint8_t fSegmentMask;
mutable uint8_t fBoundsIsDirty;
mutable uint8_t fConvexity;
#ifdef SK_BUILD_FOR_ANDROID
uint32_t fGenerationID;
+ const SkPath* fSourcePath;
#endif
// called, if dirty, by getBounds()
void computeBounds() const;
friend class Iter;
- void cons_moveto();
friend class SkPathStroker;
/* Append the first contour of path, ignoring path's initial point. If no
@@ -767,7 +770,14 @@ private:
*/
void reversePathTo(const SkPath&);
- friend const SkPoint* sk_get_path_points(const SkPath&, int index);
+ // called before we add points for lineTo, quadTo, cubicTo, checking to see
+ // if we need to inject a leading moveTo first
+ //
+ // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0)
+ // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
+ //
+ inline void injectMoveToIfNeeded();
+
friend class SkAutoPathBoundsUpdate;
};
diff --git a/include/core/SkPathMeasure.h b/include/core/SkPathMeasure.h
index ec43834..6fb4482 100644
--- a/include/core/SkPathMeasure.h
+++ b/include/core/SkPathMeasure.h
@@ -85,13 +85,14 @@ private:
struct Segment {
SkScalar fDistance; // total distance up to this point
- unsigned fPtIndex : 15;
+ unsigned fPtIndex : 15; // index into the fPts array
unsigned fTValue : 15;
unsigned fType : 2;
SkScalar getScalarT() const;
};
SkTDArray<Segment> fSegments;
+ SkTDArray<SkPoint> fPts; // Points used to define the segments
static const Segment* NextSegment(const Segment*);
@@ -104,4 +105,3 @@ private:
};
#endif
-
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index e247479..d5f6ab2 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -50,9 +50,9 @@ class SkGpuTexture;
This class can be shared/accessed between multiple threads.
*/
-class SkPixelRef : public SkRefCnt {
+class SK_API SkPixelRef : public SkRefCnt {
public:
- explicit SkPixelRef(SkMutex* mutex = NULL);
+ explicit SkPixelRef(SkBaseMutex* mutex = NULL);
/** Return the pixel memory returned from lockPixels, or null if the
lockCount is 0.
@@ -201,16 +201,16 @@ protected:
/** Return the mutex associated with this pixelref. This value is assigned
in the constructor, and cannot change during the lifetime of the object.
*/
- SkMutex* mutex() const { return fMutex; }
+ SkBaseMutex* mutex() const { return fMutex; }
- SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
+ SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*);
private:
#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
static void InitializeFlattenables();
#endif
- SkMutex* fMutex; // must remain in scope for the life of this object
+ SkBaseMutex* fMutex; // must remain in scope for the life of this object
void* fPixels;
SkColorTable* fColorTable; // we do not track ownership, subclass does
int fLockCount;
diff --git a/include/core/SkPoint.h b/include/core/SkPoint.h
index de7c0ef..d371e64 100644
--- a/include/core/SkPoint.h
+++ b/include/core/SkPoint.h
@@ -442,11 +442,11 @@ struct SK_API SkPoint {
void setOrthog(const SkPoint& vec, Side side = kLeft_Side) {
// vec could be this
SkScalar tmp = vec.fX;
- if (kLeft_Side == side) {
+ if (kRight_Side == side) {
fX = -vec.fY;
fY = tmp;
} else {
- SkASSERT(kRight_Side == side);
+ SkASSERT(kLeft_Side == side);
fX = vec.fY;
fY = -tmp;
}
diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h
index 9d89d94..7623b82 100644
--- a/include/core/SkRegion.h
+++ b/include/core/SkRegion.h
@@ -45,13 +45,13 @@ public:
* Return true if the two regions are equal. i.e. The enclose exactly
* the same area.
*/
- friend bool operator==(const SkRegion& a, const SkRegion& b);
+ bool operator==(const SkRegion& other) const;
/**
* Return true if the two regions are not equal.
*/
- friend bool operator!=(const SkRegion& a, const SkRegion& b) {
- return !(a == b);
+ bool operator!=(const SkRegion& other) const {
+ return !(*this == other);
}
/**
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h
index e7dd7d4..29679d6 100644
--- a/include/core/SkScalerContext.h
+++ b/include/core/SkScalerContext.h
@@ -16,6 +16,8 @@
#include "SkPath.h"
#include "SkPoint.h"
+//#define SK_USE_COLOR_LUMINANCE
+
class SkDescriptor;
class SkMaskFilter;
class SkPathEffect;
@@ -175,16 +177,27 @@ public:
kLCD_Vertical_Flag = 0x0200, // else Horizontal
kLCD_BGROrder_Flag = 0x0400, // else RGB order
+ // Generate A8 from LCD source (for GDI), only meaningful if fMaskFormat is kA8
+ // Perhaps we can store this (instead) in fMaskFormat, in hight bit?
+ kGenA8FromLCD_Flag = 0x0800,
+
+#ifdef SK_USE_COLOR_LUMINANCE
+ kLuminance_Bits = 3,
+#else
// luminance : 0 for black text, kLuminance_Max for white text
- kLuminance_Shift = 11, // to shift into the other flags above
+ kLuminance_Shift = 13, // shift to land in the high 3-bits of Flags
kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits
+#endif
};
// computed values
enum {
kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
+#ifdef SK_USE_COLOR_LUMINANCE
+#else
kLuminance_Max = (1 << kLuminance_Bits) - 1,
kLuminance_Mask = kLuminance_Max << kLuminance_Shift,
+#endif
};
struct Rec {
@@ -193,6 +206,9 @@ public:
SkScalar fTextSize, fPreScaleX, fPreSkewX;
SkScalar fPost2x2[2][2];
SkScalar fFrameWidth, fMiterLimit;
+#ifdef SK_USE_COLOR_LUMINANCE
+ uint32_t fLumBits;
+#endif
uint8_t fMaskFormat;
uint8_t fStrokeJoin;
uint16_t fFlags;
@@ -213,7 +229,20 @@ public:
void setHinting(SkPaint::Hinting hinting) {
fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift);
}
-
+
+ SkMask::Format getFormat() const {
+ return static_cast<SkMask::Format>(fMaskFormat);
+ }
+
+#ifdef SK_USE_COLOR_LUMINANCE
+ SkColor getLuminanceColor() const {
+ return fLumBits;
+ }
+
+ void setLuminanceColor(SkColor c) {
+ fLumBits = c;
+ }
+#else
unsigned getLuminanceBits() const {
return (fFlags & kLuminance_Mask) >> kLuminance_Shift;
}
@@ -230,10 +259,7 @@ public:
lum |= (lum << kLuminance_Bits*2);
return lum >> (4*kLuminance_Bits - 8);
}
-
- SkMask::Format getFormat() const {
- return static_cast<SkMask::Format>(fMaskFormat);
- }
+#endif
};
SkScalerContext(const SkDescriptor* desc);
@@ -277,6 +303,8 @@ public:
#endif
static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
+ static inline void PostMakeRec(Rec*);
+
static SkScalerContext* Create(const SkDescriptor*);
protected:
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
index 90d2357..67512d7 100644
--- a/include/core/SkStream.h
+++ b/include/core/SkStream.h
@@ -272,7 +272,8 @@ class SkMemoryWStream : public SkWStream {
public:
SkMemoryWStream(void* buffer, size_t size);
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
-
+ size_t bytesWritten() const { return fBytesWritten; }
+
private:
char* fBuffer;
size_t fMaxLength;
diff --git a/include/core/SkStroke.h b/include/core/SkStroke.h
index d055b83..e5d69c4 100644
--- a/include/core/SkStroke.h
+++ b/include/core/SkStroke.h
@@ -16,10 +16,6 @@
struct SkRect;
class SkPath;
-#define SK_DefaultStrokeWidth SK_Scalar1
-#define SK_DefaultMiterLimit SkIntToScalar(4)
-
-
/** \class SkStroke
SkStroke is the utility class that constructs paths by stroking
geometries (lines, rects, ovals, roundrects, paths). This is
diff --git a/include/core/SkThread.h b/include/core/SkThread.h
index 5f2da4a..1495a16 100644
--- a/include/core/SkThread.h
+++ b/include/core/SkThread.h
@@ -31,7 +31,7 @@ public:
class SkAutoMutexAcquire : SkNoncopyable {
public:
- explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(&mutex)
+ explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex)
{
SkASSERT(fMutex != NULL);
mutex.acquire();
@@ -55,7 +55,7 @@ public:
}
private:
- SkMutex* fMutex;
+ SkBaseMutex* fMutex;
};
#endif
diff --git a/include/core/SkThread_platform.h b/include/core/SkThread_platform.h
index d83f3ed..863f6e3 100644
--- a/include/core/SkThread_platform.h
+++ b/include/core/SkThread_platform.h
@@ -53,38 +53,44 @@ SK_API int32_t sk_atomic_dec(int32_t* addr);
#endif // !SK_BUILD_FOR_ANDROID
-#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
+#ifdef SK_USE_POSIX_THREADS
+
+#include <pthread.h>
+
+// A SkBaseMutex is a POD structure that can be directly initialized
+// at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the
+// generation of a static initializer in the final machine code (and
+// a corresponding static finalizer).
+//
+struct SkBaseMutex {
+ void acquire() { pthread_mutex_lock(&fMutex); }
+ void release() { pthread_mutex_unlock(&fMutex); }
+ pthread_mutex_t fMutex;
+};
-#include <utils/threads.h>
+// Using POD-style initialization prevents the generation of a static initializer
+// and keeps the acquire() implementation small and fast.
+#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER }
-class SkMutex : android::Mutex {
-public:
- // if isGlobal is true, then ignore any errors in the platform-specific
- // destructor
- SkMutex(bool isGlobal = true) {}
- ~SkMutex() {}
+// Special case used when the static mutex must be available globally.
+#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER }
- void acquire() { this->lock(); }
- void release() { this->unlock(); }
+// A normal mutex that requires to be initialized through normal C++ construction,
+// i.e. when it's a member of another class, or allocated on the heap.
+class SkMutex : public SkBaseMutex, SkNoncopyable {
+public:
+ SkMutex();
+ ~SkMutex();
};
-#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.
-*/
-SK_API 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.
-*/
-SK_API int32_t sk_atomic_dec(int32_t* addr);
+#else // !SK_USE_POSIX_THREADS
-class SkMutex {
+// In the generic case, SkBaseMutex and SkMutex are the same thing, and we
+// can't easily get rid of static initializers.
+//
+class SkMutex : SkNoncopyable {
public:
- // if isGlobal is true, then ignore any errors in the platform-specific
- // destructor
- SkMutex(bool isGlobal = true);
+ SkMutex();
~SkMutex();
void acquire();
@@ -98,6 +104,12 @@ private:
uint32_t fStorage[kStorageIntCount];
};
-#endif
+typedef SkMutex SkBaseMutex;
+
+#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name
+#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name
+
+#endif // !SK_USE_POSIX_THREADS
+
#endif
diff --git a/include/core/SkUserConfig.h b/include/core/SkUserConfig.h
index b409e82..ef75114 100644
--- a/include/core/SkUserConfig.h
+++ b/include/core/SkUserConfig.h
@@ -41,11 +41,16 @@
// ANDROID Specific changes - NO NOT CHECK BACK INTO code.google.com/p/skia
//
+#define PICTURE_VERSION_ICS 1 // r1562 of Skia
+#define PICTURE_VERSION_JB 2
+
// do this build check for other tools that still read this header
#ifdef ANDROID
#include <utils/misc.h>
#endif
+#define SK_USE_POSIX_THREADS
+
/* Scalars (the fractional value type in skia) can be implemented either as
floats or 16.16 integers (fixed). Exactly one of these two symbols must be
defined.
@@ -111,7 +116,7 @@
printf conventions (e.g. const char* format, ...). If you want to redirect
this to something other than printf, define yours here
*/
-//#define SkDebugf(...) MyFunction(__VA_ARGS__)
+//#define SkDebugf(...) MyFunction(__VA_ARGS__)
/*
* To specify a different default font cache limit, define this. If this is