diff options
author | Derek Sollenberger <djsollen@google.com> | 2012-03-06 09:06:43 -0500 |
---|---|---|
committer | Derek Sollenberger <derek@android.com> | 2012-03-06 09:44:47 -0500 |
commit | 4f1dae40e24d57d647db01443b8bf2410514b8b5 (patch) | |
tree | 594df3f3fc6c1d90a76691a75763ae1beacfdf98 /include/core | |
parent | 1cab2921ab279367f8206cdadc9259d12e603548 (diff) | |
download | external_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.h | 41 | ||||
-rw-r--r-- | include/core/SkColorPriv.h | 162 | ||||
-rw-r--r-- | include/core/SkDevice.h | 25 | ||||
-rw-r--r-- | include/core/SkDeviceProfile.h | 95 | ||||
-rw-r--r-- | include/core/SkEndian.h | 56 | ||||
-rw-r--r-- | include/core/SkFlattenable.h | 5 | ||||
-rw-r--r-- | include/core/SkFontHost.h | 6 | ||||
-rw-r--r-- | include/core/SkImageFilter.h | 16 | ||||
-rw-r--r-- | include/core/SkPaint.h | 5 | ||||
-rw-r--r-- | include/core/SkPath.h | 14 | ||||
-rw-r--r-- | include/core/SkPathMeasure.h | 4 | ||||
-rw-r--r-- | include/core/SkPixelRef.h | 10 | ||||
-rw-r--r-- | include/core/SkPoint.h | 4 | ||||
-rw-r--r-- | include/core/SkRegion.h | 6 | ||||
-rw-r--r-- | include/core/SkScalerContext.h | 40 | ||||
-rw-r--r-- | include/core/SkStream.h | 3 | ||||
-rw-r--r-- | include/core/SkStroke.h | 4 | ||||
-rw-r--r-- | include/core/SkThread.h | 4 | ||||
-rw-r--r-- | include/core/SkThread_platform.h | 64 | ||||
-rw-r--r-- | include/core/SkUserConfig.h | 7 |
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 |