diff options
author | Derek Sollenberger <djsollen@google.com> | 2011-04-14 09:57:06 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2011-04-14 15:01:11 -0400 |
commit | 87b8e645865f9633f410c02252a0fd3feb18f09b (patch) | |
tree | 21e2521ed6f69bf466849f7c9579c37aa6b22b06 /include | |
parent | 7f10e10e25231b613ebb242fa14ad8c924ce694f (diff) | |
download | external_skia-87b8e645865f9633f410c02252a0fd3feb18f09b.zip external_skia-87b8e645865f9633f410c02252a0fd3feb18f09b.tar.gz external_skia-87b8e645865f9633f410c02252a0fd3feb18f09b.tar.bz2 |
Skia Merge (revision 1116)
There is a companion change in external/webkit
Change-Id: I1c4110e7520bbef3f4e5f9551adb7ec79ac1e3ed
Diffstat (limited to 'include')
40 files changed, 1022 insertions, 423 deletions
diff --git a/include/config/SkUserConfig.h b/include/config/SkUserConfig.h index 13169ca..aa2e6cf 100644 --- a/include/config/SkUserConfig.h +++ b/include/config/SkUserConfig.h @@ -141,5 +141,14 @@ //#define SK_SUPPORT_UNITTEST #endif +/* Change the ordering to work in X windows. + */ +#ifdef SK_SAMPLES_FOR_X + #define SK_R32_SHIFT 16 + #define SK_G32_SHIFT 8 + #define SK_B32_SHIFT 0 + #define SK_A32_SHIFT 24 +#endif + #endif diff --git a/include/core/SkAdvancedTypefaceMetrics.h b/include/core/SkAdvancedTypefaceMetrics.h index 033e738..f536a56 100644 --- a/include/core/SkAdvancedTypefaceMetrics.h +++ b/include/core/SkAdvancedTypefaceMetrics.h @@ -76,6 +76,14 @@ public: SkIRect fBBox; // The bounding box of all glyphs (in font units). + // The type of advance data wanted. + enum PerGlyphInfo { + kNo_PerGlyphInfo = 0x0, // Don't populate any per glyph info. + kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data. + kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data. + kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only). + }; + template <typename Data> struct AdvanceMetric { enum MetricType { diff --git a/include/core/SkBounder.h b/include/core/SkBounder.h index bda5c97..fa4f7fb 100644 --- a/include/core/SkBounder.h +++ b/include/core/SkBounder.h @@ -36,6 +36,8 @@ class SkRegion; */ class SkBounder : public SkRefCnt { public: + SkBounder(); + /* Call to perform a clip test before calling onIRect. Returns the result from onIRect. */ diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 0a1b393..39fd998 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -78,12 +78,16 @@ public: /** If the Device supports GL viewports, return true and set size (if not null) to the size of the viewport. If it is not supported, ignore size and return false. + + DEPRECATED: the gpu-device backend takes care of managing the viewport */ virtual bool getViewport(SkIPoint* size) const; /** If the Device supports GL viewports, return true and set the viewport to the specified x and y dimensions. If it is not supported, ignore x and y and return false. + + DEPRECATED: the gpu-device backend takes care of managing the viewport */ virtual bool setViewport(int x, int y); @@ -99,6 +103,15 @@ public: */ SkDevice* setDevice(SkDevice* device); + /** + * saveLayer() can create another device (which is later drawn onto + * the previous device). getTopDevice() returns the top-most device current + * installed. Note that this can change on other calls like save/restore, + * so do not access this device after subsequent canvas calls. + * The reference count of the device is not changed. + */ + SkDevice* getTopDevice() const; + /** May be overridden by subclasses. This returns a compatible device for this canvas, with the specified config/width/height. If the device is raster, the pixels will be allocated automatically. diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 2f95015..8889fb4 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -21,13 +21,13 @@ #include "SkBitmap.h" #include "SkCanvas.h" #include "SkColor.h" -#include "SkRefDict.h" class SkClipStack; class SkDevice; class SkDraw; struct SkIRect; class SkMatrix; +class SkMetaData; class SkRegion; /** \class SkDeviceFactory @@ -36,7 +36,7 @@ class SkRegion; to pass into SkCanvas. Doing so will eliminate the need to extend SkCanvas as well. */ -class SkDeviceFactory { +class SK_API SkDeviceFactory { public: virtual ~SkDeviceFactory(); virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width, @@ -63,6 +63,7 @@ public: @param bitmap A copy of this bitmap is made and stored in the device */ SkDevice(SkCanvas*, const SkBitmap& bitmap, bool forOffscreen); + virtual ~SkDevice(); virtual SkDeviceFactory* getDeviceFactory() { return SkNEW(SkRasterDeviceFactory); @@ -180,6 +181,17 @@ public: const SkPoint[], const SkPaint& paint); virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint); + /** + * If pathIsMutable, then the implementation is allowed to cast path to a + * non-const pointer and modify it in place (as an optimization). Canvas + * may do this to implement helpers such as drawOval, by placing a temp + * path on the stack to hold the representation of the oval. + * + * If prePathMatrix is not null, it should logically be applied before any + * stroking or other effects. If there are no effects on the paint that + * affect the geometry/rasterization, then the pre matrix can just be + * pre-concated with the current matrix. + */ virtual void drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint, const SkMatrix* prePathMatrix = NULL, @@ -212,7 +224,7 @@ public: /////////////////////////////////////////////////////////////////////////// - SkRefDict& getRefDict() { return fRefDict; } + SkMetaData& getMetaData(); struct TextFlags { uint32_t fFlags; // SkPaint::getFlags() @@ -250,8 +262,8 @@ private: SkCanvas* fCanvas; SkBitmap fBitmap; - SkRefDict fRefDict; SkIPoint fOrigin; + SkMetaData* fMetaData; }; #endif diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h index 99ab342..b751be0 100644 --- a/include/core/SkDraw.h +++ b/include/core/SkDraw.h @@ -41,9 +41,15 @@ public: void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint&, bool forceUseDevice = false) const; void drawRect(const SkRect&, const SkPaint&) const; - /* To save on mallocs, we allow a flag that tells us that srcPath is - mutable, so that we don't have to make copies of it as we transform it. - */ + /** + * To save on mallocs, we allow a flag that tells us that srcPath is + * mutable, so that we don't have to make copies of it as we transform it. + * + * If prePathMatrix is not null, it should logically be applied before any + * stroking or other effects. If there are no effects on the paint that + * affect the geometry/rasterization, then the pre matrix can just be + * pre-concated with the current matrix. + */ void drawPath(const SkPath& srcPath, const SkPaint&, const SkMatrix* prePathMatrix, bool pathIsMutable) const; void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const; @@ -79,6 +85,24 @@ public: SkMaskFilter* filter, const SkMatrix* filterMatrix, SkMask* mask, SkMask::CreateMode mode); + enum RectType { + kHair_RectType, + kFill_RectType, + kStroke_RectType, + kPath_RectType + }; + + /** + * Based on the paint's style, strokeWidth, and the matrix, classify how + * to draw the rect. If no special-case is available, returns + * kPath_RectType. + * + * Iff RectType == kStroke_RectType, then strokeSize is set to the device + * width and height of the stroke. + */ + static RectType ComputeRectType(const SkPaint&, const SkMatrix&, + SkPoint* strokeSize); + private: void drawText_asPaths(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint&) const; diff --git a/include/core/SkDrawFilter.h b/include/core/SkDrawFilter.h index db5a685..c8af187 100644 --- a/include/core/SkDrawFilter.h +++ b/include/core/SkDrawFilter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,18 +19,15 @@ #include "SkRefCnt.h" -////////////////// EXPERIMENTAL ////////////////////////// - class SkCanvas; class SkPaint; -/** Right before something is being draw, filter() is called with the - current canvas and paint. If it returns true, then drawing proceeds - with the (possibly modified) canvas/paint, and then restore() is called - to restore the canvas/paint to their state before filter() was called. - If filter returns false, canvas/paint should not have been changed, and - restore() will not be called. -*/ +/** + * Right before something is being draw, filter() is called with the + * paint. The filter may modify the paint as it wishes, which will then be + * used for the actual drawing. Note: this modification only lasts for the + * current draw, as a temporary copy of the paint is used. + */ class SkDrawFilter : public SkRefCnt { public: enum Type { @@ -43,14 +40,11 @@ public: kText_Type }; - /** Return true to allow the draw to continue (with possibly modified - canvas/paint). If true is returned, then restore() will be called. - */ - virtual bool filter(SkCanvas*, SkPaint*, Type) = 0; - /** If filter() returned true, then restore() will be called to restore the - canvas/paint to their previous states - */ - virtual void restore(SkCanvas*, SkPaint*, Type) = 0; + /** + * Called with the paint that will be used to draw the specified type. + * The implementation may modify the paint as they wish. + */ + virtual void filter(SkPaint*, Type) = 0; }; #endif diff --git a/include/core/SkDrawLooper.h b/include/core/SkDrawLooper.h index 87eb5cb..270abc2 100644 --- a/include/core/SkDrawLooper.h +++ b/include/core/SkDrawLooper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,6 @@ #include "SkFlattenable.h" -////////////////// EXPERIMENTAL ////////////////////////// - class SkCanvas; class SkPaint; @@ -34,24 +32,25 @@ class SkPaint; */ class SK_API SkDrawLooper : public SkFlattenable { public: - /** Called right before something is being drawn to the specified canvas - with the specified paint. Subclass that want to modify either parameter - can do so now. - */ - virtual void init(SkCanvas*, SkPaint*) {} - /** Called in a loop (after init()). Each time true is returned, the object - is drawn (possibly with a modified canvas and/or paint). When false is - finally returned, drawing for the object stops. - */ - virtual bool next() { return false; } - /** Called after the looper has finally returned false from next(), allowing - the looper to restore the canvas/paint to their original states. - is this required, since the subclass knows when it is done??? - should we pass the canvas/paint here, and/or to the next call - so that subclasses don't need to retain pointers to them during the - loop? - */ - virtual void restore() {} + /** + * Called right before something is being drawn. This will be followed by + * calls to next() until next() returns false. + */ + virtual void init(SkCanvas*) = 0; + + /** + * Called in a loop (after init()). Each time true is returned, the object + * is drawn (possibly with a modified canvas and/or paint). When false is + * finally returned, drawing for the object stops. + * + * On each call, the paint will be in its original state, but the canvas + * will be as it was following the previous call to next() or init(). + * + * The implementation must ensure that, when next() finally returns false, + * that the canvas has been restored to the state it was initially, before + * init() was first called. + */ + virtual bool next(SkCanvas*, SkPaint* paint) = 0; protected: SkDrawLooper() {} diff --git a/include/core/SkEndian.h b/include/core/SkEndian.h index f08a9a9..a72dfe3 100644 --- a/include/core/SkEndian.h +++ b/include/core/SkEndian.h @@ -36,8 +36,7 @@ /** Swap the two bytes in the low 16bits of the parameters. e.g. 0x1234 -> 0x3412 */ -inline uint16_t SkEndianSwap16(U16CPU value) -{ +static inline uint16_t SkEndianSwap16(U16CPU value) { SkASSERT(value == (uint16_t)value); return (uint16_t)((value >> 8) | (value << 8)); } @@ -45,12 +44,10 @@ inline uint16_t SkEndianSwap16(U16CPU value) /** Vector version of SkEndianSwap16(), which swaps the low two bytes of each value in the array. */ -inline void SkEndianSwap16s(uint16_t array[], int count) -{ +static inline void SkEndianSwap16s(uint16_t array[], int count) { SkASSERT(count == 0 || array != NULL); - while (--count >= 0) - { + while (--count >= 0) { *array = SkEndianSwap16(*array); array += 1; } @@ -59,8 +56,7 @@ inline void SkEndianSwap16s(uint16_t array[], int count) /** Reverse all 4 bytes in a 32bit value. e.g. 0x12345678 -> 0x78563412 */ -inline uint32_t SkEndianSwap32(uint32_t value) -{ +static inline uint32_t SkEndianSwap32(uint32_t value) { return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0xFF0000) >> 8) | @@ -70,12 +66,10 @@ inline uint32_t SkEndianSwap32(uint32_t value) /** Vector version of SkEndianSwap16(), which swaps the bytes of each value in the array. */ -inline void SkEndianSwap32s(uint32_t array[], int count) -{ +static inline void SkEndianSwap32s(uint32_t array[], int count) { SkASSERT(count == 0 || array != NULL); - while (--count >= 0) - { + while (--count >= 0) { *array = SkEndianSwap32(*array); array += 1; } diff --git a/include/core/SkFDot6.h b/include/core/SkFDot6.h index a4b9cf7..9d56116 100644 --- a/include/core/SkFDot6.h +++ b/include/core/SkFDot6.h @@ -21,12 +21,11 @@ typedef int32_t SkFDot6; -#define SK_FDot61 (64) +#define SK_FDot6One (64) #define SK_FDot6Half (32) #ifdef SK_DEBUG - inline SkFDot6 SkIntToFDot6(S16CPU x) - { + inline SkFDot6 SkIntToFDot6(S16CPU x) { SkASSERT(SkToS16(x) == x); return x << 6; } @@ -40,8 +39,7 @@ typedef int32_t SkFDot6; #define SkFixedToFDot6(x) ((x) >> 10) -inline SkFixed SkFDot6ToFixed(SkFDot6 x) -{ +inline SkFixed SkFDot6ToFixed(SkFDot6 x) { SkASSERT((x << 10 >> 10) == x); return x << 10; @@ -53,14 +51,14 @@ inline SkFixed SkFDot6ToFixed(SkFDot6 x) #define SkScalarToFDot6(x) ((x) >> 10) #endif -inline SkFixed SkFDot6Div(SkFDot6 a, SkFDot6 b) -{ +inline SkFixed SkFDot6Div(SkFDot6 a, SkFDot6 b) { SkASSERT(b != 0); - if (a == (int16_t)a) + if (a == (int16_t)a) { return (a << 16) / b; - else + } else { return SkFixedDiv(a, b); + } } #endif diff --git a/include/core/SkFlate.h b/include/core/SkFlate.h index c496b6f..b606742 100644 --- a/include/core/SkFlate.h +++ b/include/core/SkFlate.h @@ -40,9 +40,6 @@ public: putting the result into dst. Returns false if an error occurs. */ static bool Inflate(SkStream* src, SkDynamicMemoryWStream* dst); - -private: - static const size_t kBufferSize; }; #endif diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h index 3c69251..72faed7 100644 --- a/include/core/SkFontHost.h +++ b/include/core/SkFontHost.h @@ -177,14 +177,14 @@ public: /////////////////////////////////////////////////////////////////////////// /** Retrieve detailed typeface metrics. Used by the PDF backend. - @param perGlyphInfo Indicate if the glyph specific information. - @param perGlyphInfo Indicate if the glyph specific information (advances - and names) should be populated. + @param perGlyphInfo Indicate what glyph specific information (advances, + names, etc.) should be populated. @return The returned object has already been referenced. NULL is returned if the font is not found. */ static SkAdvancedTypefaceMetrics* GetAdvancedTypefaceMetrics( - SkFontID fontID, bool perGlyphInfo); + SkFontID fontID, + SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo); /** Return the number of tables in the font */ diff --git a/include/core/SkGeometry.h b/include/core/SkGeometry.h index d4b13fb..000ca73 100644 --- a/include/core/SkGeometry.h +++ b/include/core/SkGeometry.h @@ -32,7 +32,8 @@ typedef SkPoint SkXRay; one of the endpoints' y coordinates, indicating that another query y coordinate is preferred for robustness. */ -bool SkXRayCrossesLine(const SkXRay& pt, const SkPoint pts[2], bool* ambiguous = NULL); +bool SkXRayCrossesLine(const SkXRay& pt, const SkPoint pts[2], + bool* ambiguous = NULL); /** Given a quadratic equation Ax^2 + Bx + C = 0, return 0, 1, 2 roots for the equation. @@ -44,8 +45,10 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]); /** Set pt to the point on the src quadratic specified by t. t must be 0 <= t <= 1.0 */ -void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tangent = NULL); -void SkEvalQuadAtHalf(const SkPoint src[3], SkPoint* pt, SkVector* tangent = NULL); +void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, + SkVector* tangent = NULL); +void SkEvalQuadAtHalf(const SkPoint src[3], SkPoint* pt, + SkVector* tangent = NULL); /** Given a src quadratic bezier, chop it at the specified t value, where 0 < t < 1, and return the two new quadratics in dst: @@ -92,7 +95,7 @@ int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]); */ SK_API void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]); -//////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// /** Convert from parametric from (pts) to polynomial coefficients coeff[0]*T^3 + coeff[1]*T^2 + coeff[2]*T + coeff[3] @@ -102,14 +105,16 @@ void SkGetCubicCoeff(const SkPoint pts[4], SkScalar cx[4], SkScalar cy[4]); /** Set pt to the point on the src cubic specified by t. t must be 0 <= t <= 1.0 */ -void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* locOrNull, SkVector* tangentOrNull, SkVector* curvatureOrNull); +void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* locOrNull, + SkVector* tangentOrNull, SkVector* curvatureOrNull); /** Given a src cubic bezier, chop it at the specified t value, where 0 < t < 1, and return the two new cubics in dst: dst[0..3] and dst[3..6] */ void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t); -void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], const SkScalar t[], int t_count); +void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], const SkScalar t[], + int t_count); /** Given a src cubic bezier, chop it at the specified t == 1/2, The new cubics are returned in dst[0..3] and dst[3..6] @@ -125,7 +130,8 @@ void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]); 1 0 < tValues[0] < 1 2 0 < tValues[0] < tValues[1] < 1 */ -int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar tValues[2]); +int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, + SkScalar tValues[2]); /** Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that the resulting beziers are monotonic in Y. This is called by the scan converter. @@ -149,7 +155,8 @@ int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[2]); int SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10]); int SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3]); -int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], SkScalar tValues[3] = NULL); +int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], + SkScalar tValues[3] = NULL); /** Given a monotonic cubic bezier, determine whether an xray intersects the cubic. @@ -163,7 +170,8 @@ int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], SkScalar tV coordinates, indicating that another query y coordinate is preferred for robustness. */ -bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4], bool* ambiguous = NULL); +bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4], + bool* ambiguous = NULL); /** Given an arbitrary cubic bezier, return the number of times an xray crosses the cubic. Valid return values are [0..3] @@ -177,9 +185,10 @@ bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4], bool* coordinates or at a tangent point, indicating that another query y coordinate is preferred for robustness. */ -int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4], bool* ambiguous = NULL); +int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4], + bool* ambiguous = NULL); -/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// enum SkRotationDirection { kCW_SkRotationDirection, @@ -197,7 +206,7 @@ enum SkRotationDirection { matrix, if not null, is appled to the points before they are returned. */ -int SkBuildQuadArc(const SkVector& unitStart, const SkVector& unitStop, SkRotationDirection, - const SkMatrix* matrix, SkPoint quadPoints[]); +int SkBuildQuadArc(const SkVector& unitStart, const SkVector& unitStop, + SkRotationDirection, const SkMatrix*, SkPoint quadPoints[]); #endif diff --git a/include/core/SkMallocPixelRef.h b/include/core/SkMallocPixelRef.h index 7022ba2..edaab94 100644 --- a/include/core/SkMallocPixelRef.h +++ b/include/core/SkMallocPixelRef.h @@ -54,6 +54,7 @@ protected: void* fStorage; private: + size_t fSize; SkColorTable* fCTable; diff --git a/include/core/SkMath.h b/include/core/SkMath.h index af19083..3e72904 100644 --- a/include/core/SkMath.h +++ b/include/core/SkMath.h @@ -77,7 +77,6 @@ static inline int SkClampPos(int value) { /** 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 @@ -85,10 +84,6 @@ static inline int SkClampPos(int 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; } @@ -96,15 +91,6 @@ static inline int SkClampMax(int value, int 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 diff --git a/include/core/SkMetaData.h b/include/core/SkMetaData.h new file mode 100644 index 0000000..ee2fa2b --- /dev/null +++ b/include/core/SkMetaData.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * 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 SkMetaData_DEFINED +#define SkMetaData_DEFINED + +#include "SkScalar.h" + +class SkRefCnt; + +class SkMetaData { +public: + /** + * Used to manage the life-cycle of a ptr in the metadata. This is option + * in setPtr, and is only invoked when either copying one metadata to + * another, or when the metadata is destroyed. + * + * setPtr(name, ptr, proc) { + * fPtr = proc(ptr, true); + * } + * + * copy: A = B { + * A.fPtr = B.fProc(B.fPtr, true); + * } + * + * ~SkMetaData { + * fProc(fPtr, false); + * } + */ + typedef void* (*PtrProc)(void* ptr, bool doRef); + + /** + * Implements PtrProc for SkRefCnt pointers + */ + static void* RefCntProc(void* ptr, bool doRef); + + SkMetaData(); + SkMetaData(const SkMetaData& src); + ~SkMetaData(); + + SkMetaData& operator=(const SkMetaData& src); + + void reset(); + + bool findS32(const char name[], int32_t* value = NULL) const; + bool findScalar(const char name[], SkScalar* value = NULL) const; + const SkScalar* findScalars(const char name[], int* count, + SkScalar values[] = NULL) const; + const char* findString(const char name[]) const; + bool findPtr(const char name[], void** value = NULL, PtrProc* = NULL) const; + bool findBool(const char name[], bool* value = NULL) const; + const void* findData(const char name[], size_t* byteCount = NULL) const; + + bool hasS32(const char name[], int32_t value) const { + int32_t v; + return this->findS32(name, &v) && v == value; + } + bool hasScalar(const char name[], SkScalar value) const { + SkScalar v; + return this->findScalar(name, &v) && v == value; + } + bool hasString(const char name[], const char value[]) const { + const char* v = this->findString(name); + return (v == NULL && value == NULL) || + (v != NULL && value != NULL && !strcmp(v, value)); + } + bool hasPtr(const char name[], void* value) const { + void* v; + return this->findPtr(name, &v) && v == value; + } + bool hasBool(const char name[], bool value) const { + bool v; + return this->findBool(name, &v) && v == value; + } + bool hasData(const char name[], const void* data, size_t byteCount) const { + size_t len; + const void* ptr = this->findData(name, &len); + return NULL != ptr && len == byteCount && !memcmp(ptr, data, len); + } + + void setS32(const char name[], int32_t value); + void setScalar(const char name[], SkScalar value); + SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL); + void setString(const char name[], const char value[]); + void setPtr(const char name[], void* value, PtrProc proc = NULL); + void setBool(const char name[], bool value); + // the data is copied from the input pointer. + void setData(const char name[], const void* data, size_t byteCount); + + bool removeS32(const char name[]); + bool removeScalar(const char name[]); + bool removeString(const char name[]); + bool removePtr(const char name[]); + bool removeBool(const char name[]); + bool removeData(const char name[]); + + // helpers for SkRefCnt + bool findRefCnt(const char name[], SkRefCnt** ptr = NULL) { + return this->findPtr(name, reinterpret_cast<void**>(ptr)); + } + bool hasRefCnt(const char name[], SkRefCnt* ptr) { + return this->hasPtr(name, ptr); + } + void setRefCnt(const char name[], SkRefCnt* ptr) { + this->setPtr(name, ptr, RefCntProc); + } + bool removeRefCnt(const char name[]) { + return this->removePtr(name); + } + + enum Type { + kS32_Type, + kScalar_Type, + kString_Type, + kPtr_Type, + kBool_Type, + kData_Type, + + kTypeCount + }; + + struct Rec; + class Iter; + friend class Iter; + + class Iter { + public: + Iter() : fRec(NULL) {} + Iter(const SkMetaData&); + + /** Reset the iterator, so that calling next() will return the first + data element. This is done implicitly in the constructor. + */ + void reset(const SkMetaData&); + + /** Each time next is called, it returns the name of the next data element, + or null when there are no more elements. If non-null is returned, then the + element's type is returned (if not null), and the number of data values + is returned in count (if not null). + */ + const char* next(Type*, int* count); + + private: + Rec* fRec; + }; + +public: + struct Rec { + Rec* fNext; + uint16_t fDataCount; // number of elements + uint8_t fDataLen; // sizeof a single element + uint8_t fType; + + const void* data() const { return (this + 1); } + void* data() { return (this + 1); } + const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; } + char* name() { return (char*)this->data() + fDataLen * fDataCount; } + + static Rec* Alloc(size_t); + static void Free(Rec*); + }; + Rec* fRec; + + const Rec* find(const char name[], Type) const; + void* set(const char name[], const void* data, size_t len, Type, int count); + bool remove(const char name[], Type); +}; + +#endif + diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index eec11cf..f4b325f 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -89,12 +89,7 @@ public: return static_cast<Hinting>(fHinting); } - void setHinting(Hinting hintingLevel) { - if ((unsigned) hintingLevel != fHinting) { - fGenerationID++; - fHinting = hintingLevel; - } - } + void setHinting(Hinting hintingLevel); /** Specifies the bit values that are stored in the paint's flags. */ @@ -820,10 +815,12 @@ public: void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y, SkPath* path) const; +#ifdef ANDROID const SkGlyph& getUnicharMetrics(SkUnichar); const void* findImage(const SkGlyph&); uint32_t getGenerationID() const; +#endif private: SkTypeface* fTypeface; @@ -849,7 +846,9 @@ private: unsigned fStyle : 2; unsigned fTextEncoding : 2; // 3 values unsigned fHinting : 2; +#ifdef ANDROID uint32_t fGenerationID; +#endif SkDrawCacheProc getDrawCacheProc() const; SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir, diff --git a/include/core/SkPath.h b/include/core/SkPath.h index 24e260b..d9a7093 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -20,6 +20,14 @@ #include "SkMatrix.h" #include "SkTDArray.h" +#ifdef ANDROID +#define GEN_ID_INC fGenerationID++ +#define GEN_ID_PTR_INC(ptr) ptr->fGenerationID++ +#else +#define GEN_ID_INC +#define GEN_ID_PTR_INC(ptr) +#endif + class SkFlattenableReadBuffer; class SkFlattenableWriteBuffer; class SkAutoPathBoundsUpdate; @@ -74,7 +82,7 @@ public: */ void setFillType(FillType ft) { fFillType = SkToU8(ft); - fGenerationID++; + GEN_ID_INC; } /** Returns true if the filltype is one of the Inverse variants */ @@ -85,7 +93,7 @@ public: */ void toggleInverseFillType() { fFillType ^= 2; - fGenerationID++; + GEN_ID_INC; } /** Returns true if the path is flagged as being convex. This is not a @@ -100,7 +108,7 @@ public: */ void setIsConvex(bool isConvex) { fIsConvex = (isConvex != 0); - fGenerationID++; + GEN_ID_INC; } /** Clear any lines and curves from the path, making it empty. This frees up @@ -580,7 +588,9 @@ public: */ void subdivide(SkScalar dist, bool bendLines, SkPath* dst = NULL) const; +#ifdef ANDROID uint32_t getGenerationID() const; +#endif SkDEBUGCODE(void validate() const;) @@ -591,7 +601,9 @@ private: mutable uint8_t fBoundsIsDirty; uint8_t fFillType; uint8_t fIsConvex; +#ifdef ANDROID uint32_t fGenerationID; +#endif // called, if dirty, by getBounds() void computeBounds() const; diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h index 177ecec..8fb368a 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -20,7 +20,9 @@ #include "SkRefCnt.h" #include "SkString.h" +class SkBitmap; class SkColorTable; +struct SkIRect; class SkMutex; class SkFlattenableReadBuffer; class SkFlattenableWriteBuffer; @@ -112,6 +114,8 @@ public: */ virtual SkGpuTexture* getTexture() { return NULL; } + bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL); + // serialization typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&); @@ -157,6 +161,14 @@ protected: */ virtual void onUnlockPixels() = 0; + /** + * For pixelrefs that don't have access to their raw pixels, they may be + * able to make a copy of them (e.g. if the pixels are on the GPU). + * + * The base class implementation returns false; + */ + virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull); + /** Return the mutex associated with this pixelref. This value is assigned in the constructor, and cannot change during the lifetime of the object. */ diff --git a/include/core/SkPoint.h b/include/core/SkPoint.h index c89f080..52dbd51 100644 --- a/include/core/SkPoint.h +++ b/include/core/SkPoint.h @@ -149,6 +149,9 @@ struct SK_API SkPoint { return pt; } + SkScalar x() const { return fX; } + SkScalar y() const { return fY; } + /** Set the point's X and Y coordinates */ void set(SkScalar x, SkScalar y) { fX = x; fY = y; } diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h index 4cda2cd..1dace59 100644 --- a/include/core/SkRegion.h +++ b/include/core/SkRegion.h @@ -47,118 +47,148 @@ public: ~SkRegion(); SkRegion& operator=(const SkRegion&); - - friend int operator==(const SkRegion& a, const SkRegion& b); - friend int operator!=(const SkRegion& a, const SkRegion& b) { + + /** + * 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); + + /** + * Return true if the two regions are not equal. + */ + friend bool 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. - */ + /** + * 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&); + /** + * 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; } + 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; } + 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. - */ + 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. - */ + /** + * Returns true if the region is non-empty, and if so, sets the specified + * path to the boundary(s) of the region. If the region is empty, then + * this returns false, and path is left unmodified. + */ bool getBoundaryPath(SkPath* path) const; - /** Set the region to be empty, and return false, since the resulting - region is empty - */ - bool setEmpty(); + /** + * 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 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); + /** + * 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 union of an array of rects. This is generally - faster than calling region.op(rect, kUnion_Op) in a loop. If count is - 0, then this region is set to the empty region. - @return true if the resulting region is non-empty + /** + * Set this region to the union of an array of rects. This is generally + * faster than calling region.op(rect, kUnion_Op) in a loop. If count is + * 0, then this region is set to the empty region. + * @return true if the resulting region is non-empty */ bool setRects(const SkIRect rects[], int count); - /** 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); + /** + * 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); - /** Returns true if the specified rectangle has a non-empty intersection - with this region. - */ - bool intersects(const SkIRect&) const; + /** + * Returns true if the specified rectangle has a non-empty intersection + * with this region. + */ + bool intersects(const SkIRect&) const; - /** Returns true if the specified region has a non-empty intersection - with this region. - */ - bool intersects(const SkRegion&) const; - - /** 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. - */ + /** + * Returns true if the specified region has a non-empty intersection + * with this region. + */ + bool intersects(const SkRegion&) const; + + /** + * 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. - */ + /** + * 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 @@ -170,38 +200,40 @@ public: 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 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. - */ + /** + * 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. - */ + /** 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. - */ + /** + * 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. - */ + /** + * 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 @@ -212,41 +244,50 @@ public: 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. - */ + /** + * 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. - */ + /** + * 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. - */ + /** + * 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. - */ + + /** + * 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. - */ + + /** + * 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. - */ + + /** + * 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); #ifdef ANDROID @@ -255,9 +296,10 @@ public: char* toString(); #endif - /** Returns the sequence of rectangles, sorted in Y and X, that make up - this region. - */ + /** + * Returns the sequence of rectangles, sorted in Y and X, that make up + * this region. + */ class SK_API Iterator { public: Iterator() : fRgn(NULL), fDone(true) {} @@ -271,6 +313,7 @@ public: const SkIRect& rect() const { return fRect; } // may return null const SkRegion* rgn() const { return fRgn; } + private: const SkRegion* fRgn; const RunType* fRuns; @@ -278,14 +321,15 @@ public: bool fDone; }; - /** Returns the sequence of rectangles, sorted in Y and X, that make up - this region intersected with the specified clip rectangle. - */ + /** + * Returns the sequence of rectangles, sorted in Y and X, that make up + * this region intersected with the specified clip rectangle. + */ class SK_API Cliperator { public: Cliperator(const SkRegion&, const SkIRect& clip); - bool done() { return fDone; } - void next(); + bool done() { return fDone; } + void next(); const SkIRect& rect() const { return fRect; } private: @@ -295,13 +339,14 @@ public: 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. - */ + /** + * 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); + bool next(int* left, int* right); private: const SkRegion::RunType* fRuns; @@ -309,15 +354,24 @@ public: 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. - */ + /** + * 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. - */ + + /** + * Initialized the region from the buffer, returning the number + * of bytes actually read. + */ uint32_t unflatten(const void* buffer); - + + /** + * Returns a reference to a global empty region. Just a convenience for + * callers that need a const empty region. + */ + static const SkRegion& GetEmptyRegion(); + SkDEBUGCODE(void dump() const;) SkDEBUGCODE(void validate() const;) SkDEBUGCODE(static void UnitTest();) @@ -361,6 +415,4 @@ private: friend class SkFlatRegion; }; - #endif - diff --git a/include/core/SkRelay.h b/include/core/SkRelay.h new file mode 100644 index 0000000..9361482 --- /dev/null +++ b/include/core/SkRelay.h @@ -0,0 +1,50 @@ +/* + Copyright 2010 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 SkTRelay_DEFINED +#define SkTRelay_DEFINED + +#include "SkRefCnt.h" + +/** + * Similar to a weakptr in java, a Relay allows for a back-ptr to an + * object to be "safe", without using a hard reference-count. + * + * Typically, the target creates a Relay with a pointer to itself. Whenever it + * wants to have another object maintain a safe-ptr to it, it gives them a + * Relay, which they ref()/unref(). Through the Relay each external object can + * retrieve a pointer to the Target. However, when the Target goes away, it + * clears the Relay pointer to it (relay->set(NULL)) and then unref()s the + * Relay. The other objects still have a ref on the Relay, but now when they + * call get() the receive a NULL. + */ +template <template T> class SkTRelay : public SkRefCnt { +public: + SkTRelay(T* ptr) : fPtr(ptr) {} + + // consumers call this + T* get() const { return fPtr; } + + // producer calls this + void set(T* ptr) { fPtr = ptr; } + + void clear() { this->set(NULL); } + +private: + T* fPtr; +}; + +#endif diff --git a/include/core/SkScalar.h b/include/core/SkScalar.h index 09f24b5..4fca656 100644 --- a/include/core/SkScalar.h +++ b/include/core/SkScalar.h @@ -50,10 +50,10 @@ #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) + #define SK_ScalarMax (3.402823466e+38f) /** SK_ScalarMin is defined to be the smallest value representable as an SkScalar */ - #define SK_ScalarMin (1.1754944e-38f) + #define SK_ScalarMin (1.175494351e-38f) /** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar */ #define SK_ScalarNaN (*(const float*)(const void*)&gIEEENotANumber) diff --git a/include/core/SkScan.h b/include/core/SkScan.h index 037dc09..31d4845 100644 --- a/include/core/SkScan.h +++ b/include/core/SkScan.h @@ -1,6 +1,6 @@ /* libs/graphics/sgl/SkScan.h ** -** Copyright 2006, The Android Open Source Project +** Copyright 2011, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -42,10 +42,9 @@ public: #else static void FillRect(const SkRect&, const SkRegion* clip, SkBlitter*); #endif - - static void FillTriangle(const SkPoint pts[], const SkRegion*, SkBlitter*); static void FillPath(const SkPath&, const SkRegion& clip, SkBlitter*); + static void FillTriangle(const SkPoint pts[], const SkRegion*, SkBlitter*); static void FillTriangle(const SkPoint& a, const SkPoint& b, const SkPoint& c, const SkRegion* clip, SkBlitter* blitter) { @@ -56,12 +55,11 @@ public: FillTriangle(pts, clip, blitter); } - static void HairLine(const SkPoint&, const SkPoint&, const SkRegion* clip, SkBlitter*); + static void HairLine(const SkPoint&, const SkPoint&, const SkRegion*, + SkBlitter*); static void HairRect(const SkRect&, const SkRegion* clip, SkBlitter*); static void HairPath(const SkPath&, const SkRegion* clip, SkBlitter*); - static void FrameRect(const SkRect&, SkScalar width, const SkRegion* clip, SkBlitter*); - static void AntiFillXRect(const SkXRect&, const SkRegion* clip, SkBlitter*); #ifdef SK_SCALAR_IS_FIXED static void AntiFillRect(const SkRect& rect, const SkRegion* clip, @@ -74,9 +72,16 @@ public: static void AntiFillPath(const SkPath&, const SkRegion& clip, SkBlitter*); - static void AntiHairLine(const SkPoint&, const SkPoint&, const SkRegion* clip, SkBlitter*); + static void AntiHairLine(const SkPoint&, const SkPoint&, const SkRegion*, + SkBlitter*); static void AntiHairRect(const SkRect&, const SkRegion* clip, SkBlitter*); static void AntiHairPath(const SkPath&, const SkRegion* clip, SkBlitter*); + + // draws with a miter-join + static void FrameRect(const SkRect&, const SkPoint& strokeSize, + const SkRegion*, SkBlitter*); + static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize, + const SkRegion*, SkBlitter*); }; /** Assign an SkXRect from a SkIRect, by promoting the src rect's coordinates diff --git a/include/core/SkShader.h b/include/core/SkShader.h index d837284..cf1d4e9 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -26,28 +26,33 @@ class SkPath; /** \class SkShader - - SkShader is the based class for objects that return horizontal spans of colors during drawing. - A subclass of SkShader is installed in a SkPaint calling paint.setShader(shader). After that - any object (other than a bitmap) that is drawn with that paint will get its color(s) from the - shader. -*/ + * + * SkShader is the based class for objects that return horizontal spans of + * colors during drawing. A subclass of SkShader is installed in a SkPaint + * calling paint.setShader(shader). After that any object (other than a bitmap) + * that is drawn with that paint will get its color(s) from the shader. + */ class SK_API SkShader : public SkFlattenable { public: SkShader(); virtual ~SkShader(); - /** Return true if the shader has a non-identity local matrix. - @param localM Optional: If not null, return the shader's local matrix - @return true if the shader has a non-identity local matrix. - */ + /** + * Return true if the shader has a non-identity local matrix. + * @param localM Optional: If not null, return the shader's local matrix + * @return true if the shader has a non-identity local matrix. + */ bool getLocalMatrix(SkMatrix* localM) const; - /** Set the shader's local matrix. - @param localM The shader's new local matrix. - */ + + /** + * Set the shader's local matrix. + * @param localM The shader's new local matrix. + */ void setLocalMatrix(const SkMatrix& localM); - /** Reset the shader's local matrix to identity. - */ + + /** + * Reset the shader's local matrix to identity. + */ void resetLocalMatrix(); enum TileMode { @@ -89,59 +94,69 @@ public: kConstInY16_Flag = 0x10 }; - /** Called sometimes before drawing with this shader. - Return the type of alpha your shader will return. - The default implementation returns 0. Your subclass should override if it can - (even sometimes) report a non-zero value, since that will enable various blitters - to perform faster. - */ + /** + * Called sometimes before drawing with this shader. Return the type of + * alpha your shader will return. The default implementation returns 0. + * Your subclass should override if it can (even sometimes) report a + * non-zero value, since that will enable various blitters to perform + * faster. + */ virtual uint32_t getFlags() { return 0; } - /** Return the alpha associated with the data returned by shadeSpan16(). If - kHasSpan16_Flag is not set, this value is meaningless. - */ + /** + * Return the alpha associated with the data returned by shadeSpan16(). If + * kHasSpan16_Flag is not set, this value is meaningless. + */ virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; } - /** Called once before drawing, with the current paint and - device matrix. Return true if your shader supports these - parameters, or false if not. If false is returned, nothing - will be drawn. - */ + /** + * Called once before drawing, with the current paint and device matrix. + * Return true if your shader supports these parameters, or false if not. + * If false is returned, nothing will be drawn. + */ virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix); - /** Called for each span of the object being drawn. Your subclass - should set the appropriate colors (with premultiplied alpha) that - correspond to the specified device coordinates. - */ + /** + * Called for each span of the object being drawn. Your subclass should + * set the appropriate colors (with premultiplied alpha) that correspond + * to the specified device coordinates. + */ virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0; - /** Called only for 16bit devices when getFlags() returns - kOpaqueAlphaFlag | kHasSpan16_Flag - */ + + /** + * Called only for 16bit devices when getFlags() returns + * kOpaqueAlphaFlag | kHasSpan16_Flag + */ virtual void shadeSpan16(int x, int y, uint16_t[], int count); - /** Similar to shadeSpan, but only returns the alpha-channel for a span. - The default implementation calls shadeSpan() and then extracts the alpha - values from the returned colors. - */ + + /** + * Similar to shadeSpan, but only returns the alpha-channel for a span. + * The default implementation calls shadeSpan() and then extracts the alpha + * values from the returned colors. + */ virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); - /** Helper function that returns true if this shader's shadeSpan16() method can - be called. - */ + /** + * Helper function that returns true if this shader's shadeSpan16() method + * can be called. + */ bool canCallShadeSpan16() { return SkShader::CanCallShadeSpan16(this->getFlags()); } - /** Helper to check the flags to know if it is legal to call shadeSpan16() - */ + /** + * Helper to check the flags to know if it is legal to call shadeSpan16() + */ static bool CanCallShadeSpan16(uint32_t flags) { return (flags & kHasSpan16_Flag) != 0; } - /** Called before a session using the shader begins. Some shaders override - this to defer some of their work (like calling bitmap.lockPixels()). - Must be balanced by a call to endSession. - */ + /** + * Called before a session using the shader begins. Some shaders override + * this to defer some of their work (like calling bitmap.lockPixels()). + * Must be balanced by a call to endSession. + */ virtual void beginSession(); virtual void endSession(); @@ -195,7 +210,7 @@ public: about the first point. */ virtual BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, - TileMode xy[2], SkScalar* twoPointRadialParams) const; + TileMode xy[2], SkScalar* twoPointRadialParams) const; /** * If the shader subclass can be represented as a gradient, asAGradient diff --git a/include/core/SkStream.h b/include/core/SkStream.h index b02d482..3886b09 100644 --- a/include/core/SkStream.h +++ b/include/core/SkStream.h @@ -70,7 +70,7 @@ public: size_t readPackedUInt(); }; -class SkWStream : SkNoncopyable { +class SK_API SkWStream : SkNoncopyable { public: virtual ~SkWStream(); @@ -269,7 +269,7 @@ private: size_t fBytesWritten; }; -class SkDynamicMemoryWStream : public SkWStream { +class SK_API SkDynamicMemoryWStream : public SkWStream { public: SkDynamicMemoryWStream(); virtual ~SkDynamicMemoryWStream(); diff --git a/include/core/SkString.h b/include/core/SkString.h index eb25e15..38604dd 100644 --- a/include/core/SkString.h +++ b/include/core/SkString.h @@ -78,25 +78,21 @@ public: const char* c_str() const { return fRec->data(); } char operator[](size_t n) const { return this->c_str()[n]; } - bool equals(const SkString&) const; - bool equals(const char text[]) const; - bool equals(const char text[], size_t len) const; + bool equals(const SkString&) const; + bool equals(const char text[]) const; + bool equals(const char text[], size_t len) const; - bool startsWith(const char prefix[]) const - { + bool startsWith(const char prefix[]) const { return SkStrStartsWith(fRec->data(), prefix); } - bool endsWith(const char suffix[]) const - { + bool endsWith(const char suffix[]) const { return SkStrEndsWith(fRec->data(), suffix); } - friend int operator==(const SkString& a, const SkString& b) - { + friend int operator==(const SkString& a, const SkString& b) { return a.equals(b); } - friend int operator!=(const SkString& a, const SkString& b) - { + friend int operator!=(const SkString& a, const SkString& b) { return !a.equals(b); } @@ -107,51 +103,52 @@ public: char* writable_str(); char& operator[](size_t n) { return this->writable_str()[n]; } - void reset(); - void resize(size_t len) { this->set(NULL, len); } - void set(const SkString& src) { *this = src; } - void set(const char text[]); - void set(const char text[], size_t len); - void setUTF16(const uint16_t[]); - void setUTF16(const uint16_t[], size_t len); - - void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); } - void insert(size_t offset, const char text[]); - void insert(size_t offset, const char text[], size_t len); - void insertUnichar(size_t offset, SkUnichar); - void insertS32(size_t offset, int32_t value); - void insertS64(size_t offset, int64_t value, int minDigits = 0); - void insertHex(size_t offset, uint32_t value, int minDigits = 0); - void insertScalar(size_t offset, SkScalar); - - void append(const SkString& str) { this->insert((size_t)-1, str); } - void append(const char text[]) { this->insert((size_t)-1, text); } - void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); } - void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); } - void appendS32(int32_t value) { this->insertS32((size_t)-1, value); } - void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); } - void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); } - void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); } - - void prepend(const SkString& str) { this->insert(0, str); } - void prepend(const char text[]) { this->insert(0, text); } - void prepend(const char text[], size_t len) { this->insert(0, text, len); } - void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); } - void prependS32(int32_t value) { this->insertS32(0, value); } - void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); } - void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); } - void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); } - - void printf(const char format[], ...); - void appendf(const char format[], ...); - void prependf(const char format[], ...); - - void remove(size_t offset, size_t length); - - /** Swap contents between this and other. This function is guaranteed - to never fail or throw. - */ - void swap(SkString& other); + void reset(); + void resize(size_t len) { this->set(NULL, len); } + void set(const SkString& src) { *this = src; } + void set(const char text[]); + void set(const char text[], size_t len); + void setUTF16(const uint16_t[]); + void setUTF16(const uint16_t[], size_t len); + + void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); } + void insert(size_t offset, const char text[]); + void insert(size_t offset, const char text[], size_t len); + void insertUnichar(size_t offset, SkUnichar); + void insertS32(size_t offset, int32_t value); + void insertS64(size_t offset, int64_t value, int minDigits = 0); + void insertHex(size_t offset, uint32_t value, int minDigits = 0); + void insertScalar(size_t offset, SkScalar); + + void append(const SkString& str) { this->insert((size_t)-1, str); } + void append(const char text[]) { this->insert((size_t)-1, text); } + void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); } + void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); } + void appendS32(int32_t value) { this->insertS32((size_t)-1, value); } + void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); } + void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); } + void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); } + + void prepend(const SkString& str) { this->insert(0, str); } + void prepend(const char text[]) { this->insert(0, text); } + void prepend(const char text[], size_t len) { this->insert(0, text, len); } + void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); } + void prependS32(int32_t value) { this->insertS32(0, value); } + void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); } + void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); } + void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); } + + void printf(const char format[], ...); + void appendf(const char format[], ...); + void prependf(const char format[], ...); + + void remove(size_t offset, size_t length); + + /** + * Swap contents between this and other. This function is guaranteed + * to never fail or throw. + */ + void swap(SkString& other); private: struct Rec { @@ -185,6 +182,7 @@ public: /** This returns the number of ucs2 characters */ int count() const { return fCount; } + /** This returns a null terminated ucs2 string */ const uint16_t* getUCS2() const { return fUCS2; } diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h new file mode 100644 index 0000000..fecc975 --- /dev/null +++ b/include/core/SkTLazy.h @@ -0,0 +1,91 @@ +/* + Copyright 2011 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 SkTLazy_DEFINED +#define SkTLazy_DEFINED + +#include "SkTypes.h" + +/** + * Efficient way to defer allocating/initializing a class until it is needed + * (if ever). + */ +template <typename T> class SkTLazy { +public: + SkTLazy() : fPtr(NULL) {} + + explicit SkTLazy(const T* src) : fPtr(NULL) { + if (src) { + fPtr = new (fStorage) T(*src); + } + } + + SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) { + const T* ptr = src.get(); + if (ptr) { + fPtr = new (fStorage) T(*ptr); + } + } + + ~SkTLazy() { + if (fPtr) { + fPtr->~T(); + } + } + + /** + * Return a pointer to a default-initialized instance of the class. If a + * previous instance had been initialzied (either from init() or set()) it + * will first be destroyed, so that a freshly initialized instance is + * always returned. + */ + T* init() { + if (fPtr) { + fPtr->~T(); + } + fPtr = new (fStorage) T; + return fPtr; + } + + /** + * Copy src into this, and return a pointer to a copy of it. Note this + * will always return the same pointer, so if it is called on a lazy that + * has already been initialized, then this will copy over the previous + * contents. + */ + T* set(const T& src) { + if (fPtr) { + *fPtr = src; + } else { + fPtr = new (fStorage) T(src); + } + return fPtr; + } + + /** + * Returns either NULL, or a copy of the object that was passed to + * set() or the constructor. + */ + T* get() const { return fPtr; } + +private: + T* fPtr; // NULL or fStorage + char fStorage[sizeof(T)]; +}; + +#endif + diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h index c3b0f50..c415329 100644 --- a/include/core/SkTypeface.h +++ b/include/core/SkTypeface.h @@ -17,6 +17,7 @@ #ifndef SkTypeface_DEFINED #define SkTypeface_DEFINED +#include "SkAdvancedTypefaceMetrics.h" #include "SkRefCnt.h" class SkStream; @@ -136,12 +137,12 @@ public: static SkTypeface* Deserialize(SkStream*); /** Retrieve detailed typeface metrics. Used by the PDF backend. - @param perGlyphInfo Indicate if the glyph specific information (advances - and names) should be populated. + @param perGlyphInfo Indicate what glyph specific information (advances, + names, etc.) should be populated. @return The returned object has already been referenced. */ SkAdvancedTypefaceMetrics* getAdvancedTypefaceMetrics( - bool perGlyphInfo) const; + SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) const; protected: /** uniqueID must be unique (please!) and non-zero diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h index 1290935..1a3a2e5 100644 --- a/include/core/SkTypes.h +++ b/include/core/SkTypes.h @@ -318,6 +318,13 @@ static inline uint32_t SkSetClearMask(uint32_t bits, bool cond, /////////////////////////////////////////////////////////////////////////////// +/** Use to combine multiple bits in a bitmask in a type safe way. + */ +template <typename T> +T SkTBitOr(T a, T b) { + return (T)(a | b); +} + /** * Use to cast a pointer to a different type, and maintaining strict-aliasing */ diff --git a/include/core/SkUserConfig.h b/include/core/SkUserConfig.h index 2140a15..29e64f2 100644 --- a/include/core/SkUserConfig.h +++ b/include/core/SkUserConfig.h @@ -163,5 +163,14 @@ void Android_SkDebugf(const char* file, int line, #define SK_SUPPORT_UNITTEST #endif +/* Change the ordering to work in X windows. + */ +#ifdef SK_SAMPLES_FOR_X + #define SK_R32_SHIFT 16 + #define SK_G32_SHIFT 8 + #define SK_B32_SHIFT 0 + #define SK_A32_SHIFT 24 +#endif + #endif diff --git a/include/core/SkUtils.h b/include/core/SkUtils.h index 7cb2066..a346d48 100644 --- a/include/core/SkUtils.h +++ b/include/core/SkUtils.h @@ -19,7 +19,7 @@ #include "SkTypes.h" -/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// /** Similar to memset(), but it assigns a 16bit value into the buffer. @param buffer The memory to have value copied into it @@ -54,7 +54,7 @@ extern SkMemset16Proc sk_memset16; extern SkMemset32Proc sk_memset32; #endif -/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// #define kMaxBytesInUTF8Sequence 4 @@ -64,8 +64,7 @@ extern SkMemset32Proc sk_memset32; #define SkUTF8_LeadByteToCount(c) ((((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1) #endif -inline int SkUTF8_CountUTF8Bytes(const char utf8[]) -{ +inline int SkUTF8_CountUTF8Bytes(const char utf8[]) { SkASSERT(utf8); return SkUTF8_LeadByteToCount(*(const uint8_t*)utf8); } diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h index 101d24e..846048c 100644 --- a/include/effects/SkBlurDrawLooper.h +++ b/include/effects/SkBlurDrawLooper.h @@ -48,9 +48,8 @@ public: virtual ~SkBlurDrawLooper(); // overrides from SkDrawLooper - virtual void init(SkCanvas*, SkPaint*); - virtual bool next(); - virtual void restore(); + virtual void init(SkCanvas*); + virtual bool next(SkCanvas*, SkPaint* paint); static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(SkBlurDrawLooper, (buffer)); @@ -64,14 +63,10 @@ protected: virtual Factory getFactory() { return CreateProc; } private: - SkCanvas* fCanvas; - SkPaint* fPaint; SkMaskFilter* fBlur; SkColorFilter* fColorFilter; SkScalar fDx, fDy; SkColor fBlurColor; - SkColor fSavedColor; // remember the original - int fSaveCount; uint32_t fBlurFlags; enum State { diff --git a/include/effects/SkLayerDrawLooper.h b/include/effects/SkLayerDrawLooper.h index 670ac23..b487a88 100644 --- a/include/effects/SkLayerDrawLooper.h +++ b/include/effects/SkLayerDrawLooper.h @@ -2,6 +2,7 @@ #define SkLayerDrawLooper_DEFINED #include "SkDrawLooper.h" +#include "SkXfermode.h" struct SkPoint; @@ -9,23 +10,83 @@ class SkLayerDrawLooper : public SkDrawLooper { public: SkLayerDrawLooper(); virtual ~SkLayerDrawLooper(); - - /** Call for each layer you want to add (from top to bottom). - This returns a paint you can modify, but that ptr is only valid until - the next call made to this object. + + /** + * Bits specifies which aspects of the layer's paint should replace the + * corresponding aspects on the draw's paint. + * kEntirePaint_Bits means use the layer's paint completely. + * 0 means ignore the layer's paint. + */ + enum Bits { + kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings + kTextSkewX_Bit = 1 << 1, //!< use this layer's textskewx + kPathEffect_Bit = 1 << 2, //!< use this layer's patheffect + kMaskFilter_Bit = 1 << 3, //!< use this layer's maskfilter + kShader_Bit = 1 << 4, //!< use this layer's shader + kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter + kXfermode_Bit = 1 << 6, //!< use this layer's xfermode + + kEntirePaint_Bits = -1, //!< use this layer's paint entirely + }; + typedef int32_t BitFlags; + + /** + * Info for how to apply the layer's paint and offset. + * + * fColorMode controls how we compute the final color for the layer: + * The layer's paint's color is treated as the SRC + * The draw's paint's color is treated as the DST + * final-color = Mode(layers-color, draws-color); + * Any SkXfermode::Mode will work. Two common choices are: + * kSrc_Mode: to use the layer's color, ignoring the draw's + * kDst_Mode: to just keep the draw's color, ignoring the layer's + */ + struct LayerInfo { + BitFlags fPaintBits; + SkXfermode::Mode fColorMode; + SkVector fOffset; + bool fPostTranslate; //!< applies to fOffset + + /** + * Initial the LayerInfo. Defaults to settings that will draw the + * layer with no changes: e.g. + * fPaintBits == 0 + * fColorMode == kDst_Mode + * fOffset == (0, 0) + */ + LayerInfo(); + }; + + /** + * Call for each layer you want to add (from top to bottom). + * This returns a paint you can modify, but that ptr is only valid until + * the next call made to this object. + */ + SkPaint* addLayer(const LayerInfo&); + + /** + * Call for each layer you want to add (from top to bottom). + * This returns a paint you can modify, but that ptr is only valid until + * the next call made to this object. + * The returned paint will be ignored, and only the offset will be applied + * + * DEPRECATED: call addLayer(const LayerInfo&) */ SkPaint* addLayer(SkScalar dx, SkScalar dy); - /** Helper for addLayer() which passes (0, 0) for the offset parameters + /** + * Helper for addLayer() which passes (0, 0) for the offset parameters. + * This layer will not affect the drawing in any way. + * + * DEPRECATED: call addLayer(const LayerInfo&) */ SkPaint* addLayer() { return this->addLayer(0, 0); } // overrides from SkDrawLooper - virtual void init(SkCanvas*, SkPaint*); - virtual bool next(); - virtual void restore(); + virtual void init(SkCanvas*); + virtual bool next(SkCanvas*, SkPaint* paint); // must be public for Registrar :( static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { @@ -43,21 +104,19 @@ private: struct Rec { Rec* fNext; SkPaint fPaint; - SkPoint fOffset; - + LayerInfo fInfo; + static Rec* Reverse(Rec*); }; Rec* fRecs; int fCount; - - struct Iter { - SkPaint fSavedPaint; - SkPaint* fPaint; - SkCanvas* fCanvas; - Rec* fRec; - }; - Iter fIter; - + + // state-machine during the init/next cycle + Rec* fCurrRec; + + static void ApplyBits(SkPaint* dst, const SkPaint& src, BitFlags, + SkXfermode::Mode); + class MyRegistrar : public SkFlattenable::Registrar { public: MyRegistrar(); diff --git a/include/effects/SkPaintFlagsDrawFilter.h b/include/effects/SkPaintFlagsDrawFilter.h index 941be24..e4ec466 100644 --- a/include/effects/SkPaintFlagsDrawFilter.h +++ b/include/effects/SkPaintFlagsDrawFilter.h @@ -24,8 +24,7 @@ public: SkPaintFlagsDrawFilter(uint32_t clearFlags, uint32_t setFlags); // overrides - virtual bool filter(SkCanvas*, SkPaint*, Type); - virtual void restore(SkCanvas*, SkPaint*, Type); + virtual void filter(SkPaint*, Type); private: uint32_t fPrevFlags; // local cache for filter/restore diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h index 8852803..fbe5929 100644 --- a/include/gpu/SkGpuDevice.h +++ b/include/gpu/SkGpuDevice.h @@ -30,7 +30,7 @@ class GrTextContext; * Subclass of SkDevice, which directs all drawing to the GrGpu owned by the * canvas. */ -class SkGpuDevice : public SkDevice { +class SK_API SkGpuDevice : public SkDevice { public: /** * The SkGpuDevice will render to the GrRenderTarget, or if the paremeter is diff --git a/include/gpu/SkGpuDeviceFactory.h b/include/gpu/SkGpuDeviceFactory.h index 5dcba6a..6f62ad6 100644 --- a/include/gpu/SkGpuDeviceFactory.h +++ b/include/gpu/SkGpuDeviceFactory.h @@ -21,7 +21,7 @@ class GrContext; -class SkGpuDeviceFactory : public SkDeviceFactory { +class SK_API SkGpuDeviceFactory : public SkDeviceFactory { public: /** * The constructor will ref() the context, passing it to each device @@ -34,6 +34,14 @@ public: * construction. */ SkGpuDeviceFactory(GrContext*, GrRenderTarget* rootRenderTarget); + + /** + * When the root layer is both a GrRenderTarget and a GrTexture it + * is handy to have the factory hang on to a ref to the GrTexture object. + * This is because the GrTexture has a ref to the GrRenderTarget but not + * vice-versa. + */ + SkGpuDeviceFactory(GrContext*, GrTexture* rootRenderTargetTexture); virtual ~SkGpuDeviceFactory(); @@ -43,6 +51,7 @@ public: private: GrContext* fContext; GrRenderTarget* fRootRenderTarget; + GrTexture* fRootTexture; }; #endif diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h index 7221213..10f1bd0 100644 --- a/include/gpu/SkGr.h +++ b/include/gpu/SkGr.h @@ -129,10 +129,10 @@ public: * Convert the SkBitmap::Config to the corresponding PixelConfig, or * kUnknown_PixelConfig if the conversion cannot be done. */ - static GrTexture::PixelConfig BitmapConfig2PixelConfig(SkBitmap::Config, - bool isOpaque); + static GrPixelConfig BitmapConfig2PixelConfig(SkBitmap::Config, + bool isOpaque); - static GrTexture::PixelConfig Bitmap2PixelConfig(const SkBitmap& bm) { + static GrPixelConfig Bitmap2PixelConfig(const SkBitmap& bm) { return BitmapConfig2PixelConfig(bm.config(), bm.isOpaque()); } @@ -156,14 +156,6 @@ public: unsigned a = SkGetPackedA32(pm); return GrColorPackRGBA(r, g, b, a); } - - /** - * This abandons all texture caches (for bitmaps and text) associated with - * the gpu, and frees any associated skia caches. It differs from - * deleteAllTextures in that it assumes that the gpu has lots its context, - * and thus the associated HW textures are no longer valid - */ - static void AbandonAllTextures(GrContext*); }; //////////////////////////////////////////////////////////////////////////////// @@ -207,7 +199,11 @@ public: virtual GrSetOp getOp() const; virtual void getRect(GrRect* rect) const { - *rect = Sk2Gr(*fCurr->fRect); + if (!fCurr->fRect) { + rect->setEmpty(); + } else { + *rect = Sk2Gr(*fCurr->fRect); + } } virtual GrPathIter* getPathIter() { diff --git a/include/gpu/SkGrTexturePixelRef.h b/include/gpu/SkGrTexturePixelRef.h index 1f5133f..5bc64f5 100644 --- a/include/gpu/SkGrTexturePixelRef.h +++ b/include/gpu/SkGrTexturePixelRef.h @@ -40,11 +40,38 @@ protected: // override from SkPixelRef virtual void onUnlockPixels() {} + virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset); private: GrTexture* fTexture; typedef SkPixelRef INHERITED; }; +class SkGrRenderTargetPixelRef : public SkPixelRef { +public: + SkGrRenderTargetPixelRef(GrRenderTarget* rt); + virtual ~SkGrRenderTargetPixelRef(); + + // override from SkPixelRef + virtual SkGpuTexture* getTexture(); + +protected: + // override from SkPixelRef + virtual void* onLockPixels(SkColorTable** ptr) { + if (ptr) { + *ptr = NULL; + } + return NULL; + } + + // override from SkPixelRef + virtual void onUnlockPixels() {} + virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset); + +private: + GrRenderTarget* fRenderTarget; + typedef SkPixelRef INHERITED; +}; + #endif diff --git a/include/ports/SkTypeface_mac.h b/include/ports/SkTypeface_mac.h new file mode 100644 index 0000000..61b226b --- /dev/null +++ b/include/ports/SkTypeface_mac.h @@ -0,0 +1,32 @@ +/* + Copyright 2011 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 SkTypeface_mac_DEFINED +#define SkTypeface_mac_DEFINED + +#include "SkTypeface.h" +#include <Carbon/Carbon.h> + +/** + * Like the other Typeface create methods, this returns a new reference to the + * corresponding typeface for the specified CTFontRef. The caller must call + * unref() when it is finished. + */ +SK_API extern SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef); + +#endif + |