diff options
author | Derek Sollenberger <djsollen@google.com> | 2011-01-07 13:32:14 -0500 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2011-02-23 14:59:05 -0500 |
commit | 40528743dbb9ce7f39f093e0cdc47849ac8887cf (patch) | |
tree | 9f27d91d1210746846b76e2ab85a82258243fe1f /include | |
parent | dd3f189dfde60f95f6be0517f1c28ad2879973a1 (diff) | |
download | external_skia-40528743dbb9ce7f39f093e0cdc47849ac8887cf.zip external_skia-40528743dbb9ce7f39f093e0cdc47849ac8887cf.tar.gz external_skia-40528743dbb9ce7f39f093e0cdc47849ac8887cf.tar.bz2 |
Skia Merge (revision 808)
This merge has companion changes in the following projects in order
to be compatible with changes to skia interfaces and practices:
1. /frameworks/base
2. /external/webkit
Change-Id: I54092971305579e81a8fdb27bbe04ec340792e3b
Diffstat (limited to 'include')
67 files changed, 1866 insertions, 436 deletions
diff --git a/include/config/SkUserConfig.h b/include/config/SkUserConfig.h new file mode 100644 index 0000000..c0bbb4b --- /dev/null +++ b/include/config/SkUserConfig.h @@ -0,0 +1,140 @@ +/* + * 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 SkUserConfig_DEFINED +#define SkUserConfig_DEFINED + +/* SkTypes.h, the root of the public header files, does the following trick: + + #include "SkPreConfig.h" + #include "SkUserConfig.h" + #include "SkPostConfig.h" + + SkPreConfig.h runs first, and it is responsible for initializing certain + skia defines. + + SkPostConfig.h runs last, and its job is to just check that the final + defines are consistent (i.e. that we don't have mutually conflicting + defines). + + SkUserConfig.h (this file) runs in the middle. It gets to change or augment + the list of flags initially set in preconfig, and then postconfig checks + that everything still makes sense. + + Below are optional defines that add, subtract, or change default behavior + in Skia. Your port can locally edit this file to enable/disable flags as + you choose, or these can be delared on your command line (i.e. -Dfoo). + + By default, this include file will always default to having all of the flags + commented out, so including it will have no effect. +*/ + +/////////////////////////////////////////////////////////////////////////////// + +/* 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. +*/ +//#define SK_SCALAR_IS_FLOAT +//#define SK_SCALAR_IS_FIXED + + +/* Somewhat independent of how SkScalar is implemented, Skia also wants to know + if it can use floats at all. Naturally, if SK_SCALAR_IS_FLOAT is defined, + then so muse SK_CAN_USE_FLOAT, but if scalars are fixed, SK_CAN_USE_FLOAT + can go either way. + */ +//#define SK_CAN_USE_FLOAT + +/* For some performance-critical scalar operations, skia will optionally work + around the standard float operators if it knows that the CPU does not have + native support for floats. If your environment uses software floating point, + define this flag. + */ +//#define SK_SOFTWARE_FLOAT + + +/* Skia has lots of debug-only code. Often this is just null checks or other + parameter checking, but sometimes it can be quite intrusive (e.g. check that + each 32bit pixel is in premultiplied form). This code can be very useful + during development, but will slow things down in a shipping product. + + By default, these mutually exclusive flags are defined in SkPreConfig.h, + based on the presence or absence of NDEBUG, but that decision can be changed + here. + */ +//#define SK_DEBUG +//#define SK_RELEASE + + +/* If, in debugging mode, Skia needs to stop (presumably to invoke a debugger) + it will call SK_CRASH(). If this is not defined it, it is defined in + SkPostConfig.h to write to an illegal address + */ +//#define SK_CRASH() *(int *)(uintptr_t)0 = 0 + + +/* preconfig will have attempted to determine the endianness of the system, + but you can change these mutually exclusive flags here. + */ +//#define SK_CPU_BENDIAN +//#define SK_CPU_LENDIAN + + +/* Some compilers don't support long long for 64bit integers. If yours does + not, define this to the appropriate type. + */ +//#define SkLONGLONG int64_t + + +/* Some envorinments do not suport writable globals (eek!). If yours does not, + define this flag. + */ +//#define SK_USE_RUNTIME_GLOBALS + + +/* To write debug messages to a console, skia will call SkDebugf(...) following + 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__) + +/* To enable additional blitters (and fontscaler code) to support separate + alpha channels for R G B channels, define SK_SUPPORT_LCDTEXT + */ +//#define SK_SUPPORT_LCDTEXT + +/* If zlib is available and you want to support the flate compression + algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the + include path. + */ +//#define SK_ZLIB_INCLUDE <zlib.h> + +/* Define this to remove dimension checks on bitmaps. Not all blits will be + correct yet, so this is mostly for debugging the implementation. + */ +//#define SK_ALLOW_OVER_32K_BITMAPS + +/* If SK_DEBUG is defined, then you can optionally define SK_SUPPORT_UNITTEST + which will run additional self-tests at startup. These can take a long time, + so this flag is optional. + */ +#ifdef SK_DEBUG +//#define SK_SUPPORT_UNITTEST +#endif + +#endif + diff --git a/include/config/sk_stdint.h b/include/config/sk_stdint.h new file mode 100644 index 0000000..9a5f5ca --- /dev/null +++ b/include/config/sk_stdint.h @@ -0,0 +1,13 @@ +#ifndef sk_stdint_DEFINED
+#define sk_stdint_DEFINED
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+#endif
diff --git a/include/core/SkAdvancedTypefaceMetrics.h b/include/core/SkAdvancedTypefaceMetrics.h new file mode 100644 index 0000000..033e738 --- /dev/null +++ b/include/core/SkAdvancedTypefaceMetrics.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 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 SkAdvancedTypefaceMetrics_DEFINED +#define SkAdvancedTypefaceMetrics_DEFINED + +#include "SkRect.h" +#include "SkRefCnt.h" +#include "SkString.h" +#include "SkTDArray.h" +#include "SkTemplates.h" +#include "SkTScopedPtr.h" + +/** \class SkAdvancedTypefaceMetrics + + The SkAdvancedTypefaceMetrics class is used by the PDF backend to correctly + embed typefaces. This class is filled in with information about a given + typeface by the SkFontHost class. +*/ + +class SkAdvancedTypefaceMetrics : public SkRefCnt { +public: + SkString fFontName; + + enum FontType { + kType1_Font, + kType1CID_Font, + kCFF_Font, + kTrueType_Font, + kOther_Font, + kNotEmbeddable_Font, + }; + // The type of the underlying font program. This field determines which + // of the following fields are valid. If it is kOther_Font or + // kNotEmbeddable_Font, the per glyph information will never be populated. + FontType fType; + + // fMultiMaster may be true for Type1_Font or CFF_Font. + bool fMultiMaster; + uint16_t fLastGlyphID; // The last valid glyph ID in the font. + uint16_t fEmSize; // The size of the em box (defines font units). + + // These enum values match the values used in the PDF file format. + enum StyleFlags { + kFixedPitch_Style = 0x00001, + kSerif_Style = 0x00002, + kSymbolic_Style = 0x00004, + kScript_Style = 0x00008, + kNonsymbolic_Style = 0x00020, + kItalic_Style = 0x00040, + kAllCaps_Style = 0x10000, + kSmallCaps_Style = 0x20000, + kForceBold_Style = 0x40000, + }; + uint16_t fStyle; // Font style characteristics. + int16_t fItalicAngle; // Counterclockwise degrees from vertical of the + // dominant vertical stroke for an Italic face. + // The following fields are all in font units. + int16_t fAscent; // Max height above baseline, not including accents. + int16_t fDescent; // Max depth below baseline (negative). + int16_t fStemV; // Thickness of dominant vertical stem. + int16_t fCapHeight; // Height (from baseline) of top of flat capitals. + + SkIRect fBBox; // The bounding box of all glyphs (in font units). + + template <typename Data> + struct AdvanceMetric { + enum MetricType { + kDefault, // Default advance: fAdvance.count = 1 + kRange, // Advances for a range: fAdvance.count = fEndID-fStartID + kRun, // fStartID-fEndID have same advance: fAdvance.count = 1 + }; + MetricType fType; + uint16_t fStartId; + uint16_t fEndId; + SkTDArray<Data> fAdvance; + SkTScopedPtr<AdvanceMetric<Data> > fNext; + }; + + struct VerticalMetric { + int16_t fVerticalAdvance; + int16_t fOriginXDisp; // Horiz. displacement of the secondary origin. + int16_t fOriginYDisp; // Vert. displacement of the secondary origin. + }; + typedef AdvanceMetric<int16_t> WidthRange; + typedef AdvanceMetric<VerticalMetric> VerticalAdvanceRange; + + // This is indexed by glyph id. + SkTScopedPtr<WidthRange> fGlyphWidths; + // Only used for Vertical CID fonts. + SkTScopedPtr<VerticalAdvanceRange> fVerticalMetrics; + + // The names of each glyph, only populated for postscript fonts. + SkTScopedPtr<SkAutoTArray<SkString> > fGlyphNames; +}; + +namespace skia_advanced_typeface_metrics_utils { + +template <typename Data> +void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range, + int startId); + +template <typename Data> +SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange( + SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot, + int startId); + +template <typename Data> +void finishRange( + SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range, + int endId, + typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType + type); + +template <typename Data, typename FontHandle> +SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData( + FontHandle fontHandle, + int num_glyphs, + bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)); + +} // namespace skia_advanced_typeface_metrics_utils + +#endif diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h index 1def198..a38cafa 100644 --- a/include/core/SkBitmap.h +++ b/include/core/SkBitmap.h @@ -30,6 +30,9 @@ class SkRegion; class SkFlattenableReadBuffer; class SkFlattenableWriteBuffer; +// This is an opaque class, not interpreted by skia +class SkGpuTexture; + /** \class SkBitmap The SkBitmap class specifies a raster bitmap. A bitmap has an integer width @@ -43,12 +46,22 @@ public: enum Config { kNo_Config, //!< bitmap has not been configured - kA1_Config, //!< 1-bit per pixel, (0 is transparent, 1 is opaque) + /** + * 1-bit per pixel, (0 is transparent, 1 is opaque) + * Valid as a destination (target of a canvas), but not valid as a src. + * i.e. you can draw into a 1-bit bitmap, but you cannot draw from one. + */ + kA1_Config, kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque) kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing) kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing) kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing) + /** + * Custom compressed format, not supported on all platforms. + * Cannot be used as a destination (target of a canvas). + * i.e. you may be able to draw from one, but you cannot draw into one. + */ kRLE_Index8_Config, kConfigCount @@ -129,6 +142,12 @@ public: */ size_t getSize() const { return fHeight * fRowBytes; } + /** Return the number of bytes from the pointer returned by getPixels() + to the end of the allocated space in the buffer. Required in + cases where extractBitmap has been called. + */ + size_t getSafeSize() const ; + /** Return the byte size of the pixels, based on the height and rowBytes. This routine is slightly slower than getSize(), but does not truncate the answer to 32bits. @@ -139,6 +158,10 @@ public: return size; } + /** Same as getSafeSize(), but does not truncate the answer to 32bits. + */ + Sk64 getSafeSize64() const ; + /** Returns true if the bitmap is opaque (has no translucent/transparent pixels). */ bool isOpaque() const; @@ -189,6 +212,44 @@ public: */ void setPixels(void* p, SkColorTable* ctable = NULL); + /** Copies the bitmap's pixels to the location pointed at by dst and returns + true if possible, returns false otherwise. + + In the event that the bitmap's stride is equal to dstRowBytes, and if + it is greater than strictly required by the bitmap's current config + (this may happen if the bitmap is an extracted subset of another), then + this function will copy bytes past the eand of each row, excluding the + last row. No copies are made outside of the declared size of dst, + however. + + Always returns false for RLE formats. + + @param dst Location of destination buffer. + @param dstSize Size of destination buffer. Must be large enough to hold + pixels using indicated stride. + @param dstRowBytes Width of each line in the buffer. If -1, uses + bitmap's internal stride. + */ + bool copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes = -1) + const; + + /** Copies the pixels at location src to the bitmap's pixel buffer. + Returns true if copy if possible (bitmap buffer is large enough), + false otherwise. + + Like copyPixelsTo, this function may write values beyond the end of + each row, although never outside the defined buffer. + + Always returns false for RLE formats. + + @param src Location of the source buffer. + @param srcSize Height of source buffer in pixels. + @param srcRowBytes Width of each line in the buffer. If -1, uses i + bitmap's internal stride. + */ + bool copyPixelsFrom(const void* const src, size_t srcSize, + int srcRowBytes = -1); + /** Use the standard HeapAllocator to create the pixelref that manages the pixel memory. It will be sized based on the current width/height/config. If this is called multiple times, a new pixelref object will be created @@ -227,7 +288,7 @@ public: */ bool allocPixels(Allocator* allocator, SkColorTable* ctable); - /** Return the current pixelref object, of any + /** Return the current pixelref object, if any */ SkPixelRef* pixelRef() const { return fPixelRef; } /** Return the offset into the pixelref, if any. Will return 0 if there is @@ -258,10 +319,15 @@ public: */ bool readyToDraw() const { return this->getPixels() != NULL && - ((this->config() != kIndex8_Config && this->config() != kRLE_Index8_Config) || + ((this->config() != kIndex8_Config && + this->config() != kRLE_Index8_Config) || fColorTable != NULL); } + /** Returns the pixelRef's texture, or NULL + */ + SkGpuTexture* getTexture() const; + /** Return the bitmap's colortable (if any). Does not affect the colortable's reference count. */ @@ -477,6 +543,17 @@ private: uint8_t fFlags; uint8_t fBytesPerPixel; // based on config + /* Internal computations for safe size. + */ + static Sk64 ComputeSafeSize64(Config config, + uint32_t width, + uint32_t height, + uint32_t rowBytes); + static size_t ComputeSafeSize(Config config, + uint32_t width, + uint32_t height, + uint32_t rowBytes); + /* Unreference any pixelrefs or colortables */ void freePixels(); diff --git a/include/core/SkBlitRow.h b/include/core/SkBlitRow.h new file mode 100644 index 0000000..2b652c2 --- /dev/null +++ b/include/core/SkBlitRow.h @@ -0,0 +1,87 @@ +#ifndef SkBlitRow_DEFINED +#define SkBlitRow_DEFINED + +#include "SkBitmap.h" +#include "SkColor.h" + +class SkBlitRow { +public: + enum Flags16 { + //! If set, the alpha parameter will be != 255 + kGlobalAlpha_Flag = 0x01, + //! If set, the src colors may have alpha != 255 + kSrcPixelAlpha_Flag = 0x02, + //! If set, the resulting 16bit colors should be dithered + kDither_Flag = 0x04 + }; + + /** Function pointer that reads a scanline of src SkPMColors, and writes + a corresponding scanline of 16bit colors (specific format based on the + config passed to the Factory. + + The x,y params are useful just for dithering + + @param alpha A global alpha to be applied to all of the src colors + @param x The x coordinate of the beginning of the scanline + @param y THe y coordinate of the scanline + */ + typedef void (*Proc)(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y); + + /** Function pointer that blends a single color with a row of 32-bit colors + onto a 32-bit destination + */ + typedef void (*ColorProc)(SkPMColor* dst, const SkPMColor* src, int count, + SkPMColor color); + + //! Public entry-point to return a blit function ptr + static Proc Factory(unsigned flags, SkBitmap::Config); + + ///////////// D32 version + + enum Flags32 { + kGlobalAlpha_Flag32 = 1 << 0, + kSrcPixelAlpha_Flag32 = 1 << 1, + }; + + /** Function pointer that blends 32bit colors onto a 32bit destination. + @param dst array of dst 32bit colors + @param src array of src 32bit colors (w/ or w/o alpha) + @param count number of colors to blend + @param alpha global alpha to be applied to all src colors + */ + typedef void (*Proc32)(uint32_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha); + + static Proc32 Factory32(unsigned flags32); + + /** Blend a single color onto a row of S32 pixels, writing the result + into a row of D32 pixels. src and dst may be the same memory, but + if they are not, they may not overlap. + */ + static void Color32(SkPMColor dst[], const SkPMColor src[], + int count, SkPMColor color); + + static ColorProc ColorProcFactory(); + + /** These static functions are called by the Factory and Factory32 + functions, and should return either NULL, or a + platform-specific function-ptr to be used in place of the + system default. + */ + + static Proc32 PlatformProcs32(unsigned flags); + static Proc PlatformProcs565(unsigned flags); + static Proc PlatformProcs4444(unsigned flags); + static ColorProc PlatformColorProc(); + +private: + enum { + kFlags16_Mask = 7, + kFlags32_Mask = 3 + }; +}; + +#endif diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index b5ccca6..b2a9fa9 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -98,12 +98,46 @@ public: */ SkDevice* setDevice(SkDevice* device); - /** Deprecated - Specify a bitmap for the canvas to draw into. This is a - helper method for setDevice(), and it creates a device for the bitmap by - calling createDevice(). The structure of the bitmap is copied into the - device. - */ - virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap); + /** 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. + */ + virtual SkDevice* createDevice(SkBitmap::Config, int width, int height, + bool isOpaque, bool forLayer = false); + + /** + * Create a new raster device and make it current. This also returns + * the new device. + */ + SkDevice* setBitmapDevice(const SkBitmap& bitmap, bool forLayer = false); + + /** + * Return the current device factory, or NULL. + */ + SkDeviceFactory* getDeviceFactory() const { return fDeviceFactory; } + + /** + * Replace any existing factory with the specified factory. + */ + SkDeviceFactory* setDeviceFactory(SkDeviceFactory*); + + /////////////////////////////////////////////////////////////////////////// + + /** + * Copy the pixels from the device into bitmap. Returns true on success. + * If false is returned, then the bitmap parameter is left unchanged. + * The bitmap parameter is treated as output-only, and will be completely + * overwritten (if the method returns true). + */ + bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); + bool readPixels(SkBitmap* bitmap); + + /** + * Similar to draw sprite, this method will copy the pixels in bitmap onto + * the device, with the top/left corner specified by (x, y). The pixel + * values in the device are completely replaced: there is no blending. + */ + void writePixels(const SkBitmap& bitmap, int x, int y); /////////////////////////////////////////////////////////////////////////// @@ -139,8 +173,10 @@ public: offscreen bitmap. All drawing calls are directed there, and only when the balancing call to restore() is made is that offscreen transfered to the canvas (or the previous layer). - @param bounds (may be null) the maximum size the offscreen bitmap needs - to be (in local coordinates) + @param bounds (may be null) This rect, if non-null, is used as a hint to + limit the size of the offscreen, and thus drawing may be + clipped to it, though that clipping is not guaranteed to + happen. If exact clipping is desired, use clipRect(). @param paint (may be null) This is copied, and is applied to the offscreen when restore() is called @param flags LayerFlags @@ -153,8 +189,10 @@ public: offscreen bitmap. All drawing calls are directed there, and only when the balancing call to restore() is made is that offscreen transfered to the canvas (or the previous layer). - @param bounds (may be null) the maximum size the offscreen bitmap needs - to be (in local coordinates) + @param bounds (may be null) This rect, if non-null, is used as a hint to + limit the size of the offscreen, and thus drawing may be + clipped to it, though that clipping is not guaranteed to + happen. If exact clipping is desired, use clipRect(). @param alpha This is applied to the offscreen when restore() is called. @param flags LayerFlags @return The value to pass to restoreToCount() to balance this save() @@ -213,12 +251,12 @@ public: @return true if the operation succeeded (e.g. did not overflow) */ virtual bool concat(const SkMatrix& matrix); - + /** Replace the current matrix with a copy of the specified matrix. @param matrix The matrix that will be copied into the current matrix. */ virtual void setMatrix(const SkMatrix& matrix); - + /** Helper for setMatrix(identity). Sets the current matrix to identity. */ void resetMatrix(); @@ -382,7 +420,7 @@ public: details. */ void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint); - + /** Draws a single pixel in the specified color. @param x The X coordinate of which pixel to draw @param y The Y coordiante of which pixel to draw @@ -420,7 +458,7 @@ public: r.set(rect); // promotes the ints to scalars this->drawRect(r, paint); } - + /** Draw the specified rectangle using the specified paint. The rectangle will be filled or framed based on the Style in the paint. @param left The left side of the rectangle to be drawn @@ -508,7 +546,7 @@ public: virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, const SkPaint* paint = NULL); - + /** Draw the specified bitmap, with its top/left corner at (x,y), NOT transformed by the current matrix. Note: if the paint contains a maskfilter that generates a mask which extends beyond the @@ -535,7 +573,7 @@ public: SkScalar y, const SkPaint& paint); /** Draw the text, with each character/glyph origin specified by the pos[] - array. The origin is interpreted by the Align setting in the paint. + array. The origin is interpreted by the Align setting in the paint. @param text The text to be drawn @param byteLength The number of bytes to read from the text parameter @param pos Array of positions, used to position each character @@ -543,10 +581,10 @@ public: */ virtual void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint); - + /** Draw the text, with each character/glyph origin specified by the x coordinate taken from the xpos[] array, and the y from the constY param. - The origin is interpreted by the Align setting in the paint. + The origin is interpreted by the Align setting in the paint. @param text The text to be drawn @param byteLength The number of bytes to read from the text parameter @param xpos Array of x-positions, used to position each character @@ -556,7 +594,7 @@ public: virtual void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint); - + /** Draw the text, with origin at (x,y), using the specified paint, along the specified path. The paint's Align setting determins where along the path to start the text. @@ -610,7 +648,7 @@ public: canvas. */ virtual void drawPicture(SkPicture& picture); - + /** Draws the specified shape */ virtual void drawShape(SkShape*); @@ -620,7 +658,7 @@ public: kTriangleStrip_VertexMode, kTriangleFan_VertexMode }; - + /** Draw the array of vertices, interpreted as triangles (based on mode). @param vmode How to interpret the array of vertices @param vertexCount The number of points in the vertices array (and @@ -637,7 +675,7 @@ public: @param indices If not null, array of indices to reference into the vertex (texs, colors) array. @param indexCount number of entries in the indices array (if not null) - @param paint Specifies the shader/texture if present. + @param paint Specifies the shader/texture if present. */ virtual void drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[], @@ -654,7 +692,7 @@ public: virtual void drawData(const void* data, size_t length); ////////////////////////////////////////////////////////////////////////// - + /** Get the current bounder object. The bounder's reference count is unchaged. @return the canva's bounder (or NULL). @@ -670,13 +708,13 @@ public: @return the set bounder object */ virtual SkBounder* setBounder(SkBounder* bounder); - + /** Get the current filter object. The filter's reference count is not affected. The filter is saved/restored, just like the matrix and clip. @return the canvas' filter (or NULL). */ SkDrawFilter* getDrawFilter() const; - + /** Set the new filter (or NULL). Pass NULL to clear any existing filter. As a convenience, the parameter is returned. If an existing filter exists, its refcnt is decrement. If the new filter is not null, its @@ -701,16 +739,7 @@ public: */ const SkRegion& getTotalClip() const; - /** May be overridden by subclasses. This returns a compatible device - for this canvas, with the specified config/width/height. If isOpaque - is true, then the underlying bitmap is optimized to assume that every - pixel will be drawn to, and thus it does not need to clear the alpha - channel ahead of time (assuming the specified config supports per-pixel - alpha.) If isOpaque is false, then the bitmap should clear its alpha - channel. - */ - virtual SkDevice* createDevice(SkBitmap::Config, int width, int height, - bool isOpaque, bool isForLayer); + void setExternalMatrix(const SkMatrix* = NULL); /////////////////////////////////////////////////////////////////////////// @@ -725,12 +754,12 @@ public: /** Initialize iterator with canvas, and set values for 1st device */ LayerIter(SkCanvas*, bool skipEmptyClips); ~LayerIter(); - + /** Return true if the iterator is done */ bool done() const { return fDone; } /** Cycle to the next device */ void next(); - + // These reflect the current device in the iterator SkDevice* device() const; @@ -739,14 +768,14 @@ public: const SkPaint& paint() const; int x() const; int y() const; - + private: // used to embed the SkDrawIter object directly in our instance, w/o // having to expose that class def to the public. There is an assert // in our constructor to ensure that fStorage is large enough // (though needs to be a compile-time-assert!). We use intptr_t to work // safely with 32 and 64 bit machines (to ensure the storage is enough) - intptr_t fStorage[12]; + intptr_t fStorage[32]; class SkDrawIter* fImpl; // this points at fStorage SkPaint fDefaultPaint; bool fDone; @@ -754,9 +783,9 @@ public: protected: // all of the drawBitmap variants call this guy - virtual void commonDrawBitmap(const SkBitmap&, const SkMatrix& m, - const SkPaint& paint); - + virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*, + const SkMatrix&, const SkPaint& paint); + private: class MCRec; @@ -770,21 +799,21 @@ private: SkDevice* fLastDeviceToGainFocus; SkDeviceFactory* fDeviceFactory; - void prepareForDeviceDraw(SkDevice*); - + void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&); + bool fDeviceCMDirty; // cleared by updateDeviceCMCache() void updateDeviceCMCache(); friend class SkDrawIter; // needs setupDrawForLayerDevice() SkDevice* init(SkDevice*); - void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, + void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m, const SkPaint* paint); void drawDevice(SkDevice*, int x, int y, const SkPaint*); // shared by save() and saveLayer() int internalSave(SaveFlags flags); void internalRestore(); - + /* These maintain a cache of the clip bounds in local coordinates, (converted to 2s-compliment if floats are slow). */ @@ -816,6 +845,9 @@ private: } } void computeLocalClipBoundsCompareType(EdgeType et) const; + + SkMatrix fExternalMatrix, fExternalInverse; + bool fUseExternalMatrix; }; /** Stack helper class to automatically call restoreToCount() on the canvas diff --git a/include/core/SkChunkAlloc.h b/include/core/SkChunkAlloc.h index 810e7b6..ba9e2c9 100644 --- a/include/core/SkChunkAlloc.h +++ b/include/core/SkChunkAlloc.h @@ -55,7 +55,14 @@ public: size_t unalloc(void* ptr); size_t totalCapacity() const { return fTotalCapacity; } - + + /** + * Returns true if the specified address is within one of the chunks, and + * has at least 1-byte following the address (i.e. if addr points to the + * end of a chunk, then contains() will return false). + */ + bool contains(const void* addr) const; + private: struct Block; Block* fBlock; diff --git a/include/core/SkColor.h b/include/core/SkColor.h index c97a8ec..c17068f 100644 --- a/include/core/SkColor.h +++ b/include/core/SkColor.h @@ -36,13 +36,30 @@ typedef uint32_t SkColor; /** Return a SkColor value from 8 bit component values */ -static inline SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) +static inline SkColor SkColorSetARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { SkASSERT(a <= 255 && r <= 255 && g <= 255 && b <= 255); return (a << 24) | (r << 16) | (g << 8) | (b << 0); } +#define SkColorSetARGBMacro(a, r, g, b) \ + static_cast<SkColor>( \ + (static_cast<U8CPU>(a) << 24) | \ + (static_cast<U8CPU>(r) << 16) | \ + (static_cast<U8CPU>(g) << 8) | \ + (static_cast<U8CPU>(b) << 0)) + +/** gcc will generate static initializers for code of this form: + * static const SkColor kMyColor = SkColorSetARGB(0xFF, 0x01, 0x02, 0x03) + * if SkColorSetARGB() is a static inline, but not if it's a macro. + */ +#if defined(NDEBUG) +#define SkColorSetARGB(a, r, g, b) SkColorSetARGBMacro(a, r, g, b) +#else +#define SkColorSetARGB(a, r, g, b) SkColorSetARGBInline(a, r, g, b) +#endif + /** Return a SkColor value from 8 bit component values, with an implied value of 0xFF for alpha (fully opaque) */ diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h index 7c6b7d1..bd407da 100644 --- a/include/core/SkColorPriv.h +++ b/include/core/SkColorPriv.h @@ -28,7 +28,7 @@ /** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a byte into a scale value, so that we can say scale * value >> 8 instead of alpha * value / 255. - + In debugging, asserts that alpha is 0..255 */ static inline unsigned SkAlpha255To256(U8CPU alpha) { @@ -133,7 +133,7 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], int srcScale, int count) { SkASSERT(count > 0); SkASSERT((unsigned)srcScale <= 256); - + srcScale >>= 3; do { @@ -148,7 +148,7 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK); SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK); SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK); - + return a + b; } #else @@ -201,7 +201,7 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], unsigned r = SkGetPackedR32(c); unsigned g = SkGetPackedG32(c); unsigned b = SkGetPackedB32(c); - + SkA32Assert(a); SkASSERT(r <= a); SkASSERT(g <= a); @@ -211,6 +211,10 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], #define SkPMColorAssert(c) #endif +/** + * Pack the components into a SkPMColor, checking (in the debug version) that + * the components are 0..255, and are already premultiplied (i.e. alpha >= color) + */ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { SkA32Assert(a); SkASSERT(r <= a); @@ -221,6 +225,15 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); } +/** + * Same as SkPackARGB32, but this version guarantees to not check that the + * values are premultiplied in the debug version. + */ +static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | + (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); +} + extern const uint32_t gMask_00FF00FF; static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) { @@ -299,7 +312,7 @@ static inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) { r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS); g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS); b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS); - + return SkPackRGB16(r, g, b); } @@ -318,7 +331,7 @@ static inline uint32_t SkPMColorToExpanded16x5(SkPMColor c) { unsigned sr = SkPacked32ToR16(c); unsigned sg = SkPacked32ToG16(c); unsigned sb = SkPacked32ToB16(c); - + sr = (sr << 5) | sr; sg = (sg << 5) | (sg >> 1); sb = (sb << 5) | sb; @@ -332,17 +345,17 @@ static inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) { unsigned sr = SkGetPackedR32(src); unsigned sg = SkGetPackedG32(src); unsigned sb = SkGetPackedB32(src); - + unsigned dr = SkGetPackedR16(dst); unsigned dg = SkGetPackedG16(dst); unsigned db = SkGetPackedB16(dst); - + unsigned isa = 255 - SkGetPackedA32(src); - + dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS); dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS); db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS); - + return SkPackRGB16(dr, dg, db); } @@ -382,15 +395,15 @@ static inline SkPMColor SkPixel16ToPixel32(U16CPU src) { // similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor static inline SkColor SkPixel16ToColor(U16CPU src) { SkASSERT(src == SkToU16(src)); - + unsigned r = SkPacked16ToR32(src); unsigned g = SkPacked16ToG32(src); unsigned b = SkPacked16ToB32(src); - + SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); - + return SkColorSetRGB(r, g, b); } @@ -435,7 +448,7 @@ static inline void SkPMColor16Assert(U16CPU c) { unsigned r = SkGetPackedR4444(c); unsigned g = SkGetPackedG4444(c); unsigned b = SkGetPackedB4444(c); - + SkASSERT(a <= 0xF); SkASSERT(r <= a); SkASSERT(g <= a); @@ -480,7 +493,7 @@ static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r, SkASSERT(r <= a); SkASSERT(g <= a); SkASSERT(b <= a); - + return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) | (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); } @@ -491,7 +504,7 @@ static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { SkASSERT(scale <= 16); const unsigned mask = 0xF0F; //gMask_0F0F; - + #if 0 unsigned rb = ((c & mask) * scale) >> 4; unsigned ag = ((c >> 4) & mask) * scale; @@ -508,7 +521,7 @@ static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { */ static inline uint32_t SkExpand_4444(U16CPU c) { SkASSERT(c == (uint16_t)c); - + const unsigned mask = 0xF0F; //gMask_0F0F; return (c & mask) | ((c & ~mask) << 12); } @@ -541,7 +554,7 @@ static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale); unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale); unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale); - + #if 0 if (sg + dg > 63) { SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg); @@ -552,13 +565,13 @@ static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16) { SkASSERT((unsigned)scale16 <= 16); - + return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); } static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) { SkASSERT((unsigned)scale16 <= 16); - + uint32_t src32 = SkExpand_4444(src) * scale16; // the scaled srcAlpha is the bottom byte #ifdef SK_DEBUG @@ -600,7 +613,7 @@ static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4; g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4; b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4; - + return SkPackARGB4444(a, r, g, b); } diff --git a/include/core/SkColorShader.h b/include/core/SkColorShader.h index 7c5f941..44a6148 100644 --- a/include/core/SkColorShader.h +++ b/include/core/SkColorShader.h @@ -29,14 +29,16 @@ public: /** Create a ColorShader that will inherit its color from the Paint at draw time. */ - SkColorShader() : fFlags(0), fInheritColor(true) {} + SkColorShader(); /** Create a ColorShader that ignores the color in the paint, and uses the specified color. Note: like all shaders, at draw time the paint's alpha will be respected, and is applied to the specified color. */ - SkColorShader(SkColor c) : fColor(c), fFlags(0), fInheritColor(false) {} - + SkColorShader(SkColor c); + + virtual ~SkColorShader(); + virtual uint32_t getFlags() { return fFlags; } virtual uint8_t getSpan16Alpha() const; virtual bool setContext(const SkBitmap& device, const SkPaint& paint, @@ -45,6 +47,10 @@ public: virtual void shadeSpan16(int x, int y, uint16_t span[], int count); virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); + virtual BitmapType asABitmap(SkBitmap* outTexture, + SkMatrix* outMatrix, + TileMode xy[2], + SkScalar* twoPointRadialParams); protected: SkColorShader(SkFlattenableReadBuffer& ); virtual void flatten(SkFlattenableWriteBuffer& ); @@ -59,6 +65,9 @@ private: uint16_t fColor16; // cached after setContext() SkBool8 fInheritColor; + // deferred allocation, used for asABitmap() + SkPixelRef* fAsABitmapPixelRef; + typedef SkShader INHERITED; }; diff --git a/include/core/SkDescriptor.h b/include/core/SkDescriptor.h index 8074cff..09397b7 100644 --- a/include/core/SkDescriptor.h +++ b/include/core/SkDescriptor.h @@ -120,13 +120,14 @@ public: return true; } + uint32_t getChecksum() const { return fChecksum; } + struct Entry { uint32_t fTag; uint32_t fLen; }; #ifdef SK_DEBUG - uint32_t getChecksum() const { return fChecksum; } uint32_t getCount() const { return fCount; } #endif diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index dbc8fcf..1b4630d 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -21,6 +21,7 @@ #include "SkBitmap.h" #include "SkCanvas.h" #include "SkColor.h" +#include "SkRefDict.h" class SkDevice; class SkDraw; @@ -37,26 +38,30 @@ class SkRegion; class SkDeviceFactory { public: virtual ~SkDeviceFactory(); - virtual SkDevice* newDevice(SkBitmap::Config config, int width, int height, - bool isOpaque, bool isForLayer) = 0; + virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width, + int height, bool isOpaque, bool isLayer) = 0; }; class SkRasterDeviceFactory : public SkDeviceFactory { public: - virtual SkDevice* newDevice(SkBitmap::Config config, int width, int height, - bool isOpaque, bool isForLayer); + virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width, + int height, bool isOpaque, bool isLayer); }; class SkDevice : public SkRefCnt { public: - SkDevice(); - /** Construct a new device, extracting the width/height/config/isOpaque - values from the bitmap. Subclasses may override the destructor, which - is virtual, even though this class doesn't have one. SkRefCnt does. + SkDevice(SkCanvas*); + /** Construct a new device, extracting the width/height/config/isOpaque values from + the bitmap. If transferPixelOwnership is true, and the bitmap claims to own its + own pixels (getOwnsPixels() == true), then transfer this responsibility to the + device, and call setOwnsPixels(false) on the bitmap. + + Subclasses may override the destructor, which is virtual, even though this class + doesn't have one. SkRefCnt does. @param bitmap A copy of this bitmap is made and stored in the device */ - SkDevice(const SkBitmap& bitmap); + SkDevice(SkCanvas*, const SkBitmap& bitmap, bool forOffscreen); virtual SkDeviceFactory* getDeviceFactory() { return SkNEW(SkRasterDeviceFactory); @@ -71,10 +76,10 @@ public: /** Return the width of the device (in pixels). */ - int width() const { return fBitmap.width(); } + virtual int width() const { return fBitmap.width(); } /** Return the height of the device (in pixels). */ - int height() const { return fBitmap.height(); } + virtual int height() const { return fBitmap.height(); } /** Return the bitmap config of the device's pixels */ SkBitmap::Config config() const { return fBitmap.getConfig(); } @@ -82,11 +87,11 @@ public: implicitly opaque. */ bool isOpaque() const { return fBitmap.isOpaque(); } - + /** Return the bounds of the device */ void getBounds(SkIRect* bounds) const; - + /** Return true if the specified rectangle intersects the bounds of the device. If sect is not NULL and there is an intersection, sect returns the intersection. @@ -112,6 +117,11 @@ public: virtual void lockPixels(); virtual void unlockPixels(); + /** Return the device's associated texture, or NULL. If returned, it may be + drawn into another device + */ + virtual SkGpuTexture* accessTexture() { return NULL; } + /** Called with the correct matrix and clip before this device is drawn to using those settings. If your subclass overrides this, be sure to call through to the base class as well. @@ -121,7 +131,26 @@ public: /** Called when this device gains focus (i.e becomes the current device for drawing). */ - virtual void gainFocus(SkCanvas*) {} + virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&) {} + + /** Causes any deferred drawing to the device to be completed. + */ + virtual void flush() {} + + /** + * Copy the pixels from the device into bitmap. Returns true on success. + * If false is returned, then the bitmap parameter is left unchanged. + * The bitmap parameter is treated as output-only, and will be completely + * overwritten (if the method returns true). + */ + virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); + + /** + * Similar to draw sprite, this method will copy the pixels in bitmap onto + * the device, with the top/left corner specified by (x, y). The pixel + * values in the device are completely replaced: there is no blending. + */ + virtual void writePixels(const SkBitmap& bitmap, int x, int y); /** These are called inside the per-device-layer loop for each draw call. When these are called, we have already applied any saveLayer operations, @@ -134,8 +163,11 @@ public: virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint); virtual void drawPath(const SkDraw&, const SkPath& path, - const SkPaint& paint); + const SkPaint& paint, + const SkMatrix* prePathMatrix = NULL, + bool pathIsMutable = false); virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, + const SkIRect* srcRectOrNull, const SkMatrix& matrix, const SkPaint& paint); virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y, const SkPaint& paint); @@ -158,6 +190,10 @@ public: virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, const SkPaint&); + /////////////////////////////////////////////////////////////////////////// + + SkRefDict& getRefDict() { return fRefDict; } + 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 @@ -165,8 +201,17 @@ protected: */ virtual void onAccessBitmap(SkBitmap*); + SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } + // just for subclasses, to assign a custom pixelref + SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) { + fBitmap.setPixelRef(pr, offset); + return pr; + } + private: - SkBitmap fBitmap; + SkCanvas* fCanvas; + SkBitmap fBitmap; + SkRefDict fRefDict; }; #endif diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h index a86ef67..fb2f292 100644 --- a/include/core/SkDraw.h +++ b/include/core/SkDraw.h @@ -33,12 +33,12 @@ struct SkDrawProcs; class SkDraw { public: - SkDraw() : fDevice(NULL), fBounder(NULL), fProcs(NULL) {} + SkDraw(); SkDraw(const SkDraw& src); void drawPaint(const SkPaint&) const; void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[], - const SkPaint&) const; + 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. @@ -86,12 +86,18 @@ public: const SkBitmap* fBitmap; // required const SkMatrix* fMatrix; // required const SkRegion* fClip; // required + SkDevice* fDevice; // optional SkBounder* fBounder; // optional SkDrawProcs* fProcs; // optional + const SkMatrix* fMVMatrix; // optional + const SkMatrix* fExtMatrix; // optional + #ifdef SK_DEBUG - void validate() const; + void validate() const; +#else + void validate() const {} #endif }; diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h index be4bf99..2a2456e 100644 --- a/include/core/SkFixed.h +++ b/include/core/SkFixed.h @@ -17,7 +17,7 @@ #ifndef SkFixed_DEFINED #define SkFixed_DEFINED -#include "SkTypes.h" +#include "SkMath.h" /** \file SkFixed.h @@ -39,7 +39,15 @@ typedef int32_t SkFixed; #ifdef SK_CAN_USE_FLOAT #define SkFixedToFloat(x) ((x) * 1.5258789e-5f) +#if 1 #define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1)) +#else + // pins over/under flows to max/min int32 (slower than just a cast) + static inline SkFixed SkFloatToFixed(float x) { + int64_t n = x * SK_Fixed1; + return (SkFixed)n; + } +#endif #define SkFixedToDouble(x) ((x) * 1.5258789e-5) #define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1)) diff --git a/include/core/SkFlate.h b/include/core/SkFlate.h new file mode 100644 index 0000000..c496b6f --- /dev/null +++ b/include/core/SkFlate.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 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 SkFlate_DEFINED +#define SkFlate_DEFINED + +#include "SkTypes.h" + +class SkDynamicMemoryWStream; +class SkStream; + +/** \class SkFlate + A class to provide access to the flate compression algorithm. +*/ +class SkFlate { +public: + /** Indicates if the flate algorithm is available. + */ + static bool HaveFlate(); + + /** Use the flate compression algorithm to compress the data in src, + putting the result into dst. Returns false if an error occurs. + */ + static bool Deflate(SkStream* src, SkDynamicMemoryWStream* dst); + + /** Use the flate compression algorithm to decompress the data in src, + 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 84e575f..d70ba65 100644 --- a/include/core/SkFontHost.h +++ b/include/core/SkFontHost.h @@ -59,14 +59,16 @@ typedef uint32_t SkFontTableTag; class SkFontHost { public: /** Return a new, closest matching typeface given either an existing family - (specified by a typeface in that family) or by a familyName, and a - requested style. - 1) If familyFace is null, use famillyName. - 2) If famillyName is null, use familyFace. - 3) If both are null, return the default font that best matches style + (specified by a typeface in that family) or by a familyName and a + requested style, or by a set of Unicode codepoitns to cover in a given + style. + 1) If familyFace is null, use familyName. + 2) If familyName is null, use data (UTF-16 to cover). + 3) If all are null, return the default font that best matches style */ static SkTypeface* CreateTypeface(const SkTypeface* familyFace, - const char famillyName[], + const char familyName[], + const void* data, size_t bytelength, SkTypeface::Style style); /** Return a new typeface given the data buffer. If the data does not @@ -174,6 +176,16 @@ 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. + @return The returned object has already been referenced. NULL is + returned if the font is not found. + */ + static SkAdvancedTypefaceMetrics* GetAdvancedTypefaceMetrics( + SkFontID fontID, bool perGlyphInfo); + /** Return the number of tables in the font */ static int CountTables(SkFontID); diff --git a/include/core/SkGeometry.h b/include/core/SkGeometry.h index b8ab74c..a209783 100644 --- a/include/core/SkGeometry.h +++ b/include/core/SkGeometry.h @@ -26,10 +26,13 @@ */ typedef SkPoint SkXRay; -/** Given a line segment from pts[0] to pts[1], and ax xray, return true if - they intersect. +/** Given a line segment from pts[0] to pts[1], and an xray, return true if + they intersect. Optional outgoing "ambiguous" argument indicates + whether the answer is ambiguous because the query occurred exactly at + 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 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. @@ -155,8 +158,12 @@ int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], SkScalar tV left of the curve, the line is not considered to cross the curve, but if it is equal to cubic[3].fY then it is considered to cross. + Optional outgoing "ambiguous" argument indicates whether the answer is + ambiguous because the query occurred exactly at one of the endpoints' y + coordinates, indicating that another query y coordinate is preferred + for robustness. */ -bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4]); +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] @@ -165,8 +172,12 @@ bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4]); left of the curve, the line is not considered to cross the curve, but if it is equal to cubic[3].fY then it is considered to cross. + Optional outgoing "ambiguous" argument indicates whether the answer is + ambiguous because the query occurred exactly at one of the endpoints' y + 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]); +int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4], bool* ambiguous = NULL); /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/core/SkMallocPixelRef.h b/include/core/SkMallocPixelRef.h index 1c36b74..7022ba2 100644 --- a/include/core/SkMallocPixelRef.h +++ b/include/core/SkMallocPixelRef.h @@ -25,13 +25,15 @@ class SkMallocPixelRef : public SkPixelRef { public: /** Allocate the specified buffer for pixels. The memory is freed when the - last owner of this pixelref is gone. + last owner of this pixelref is gone. If addr is NULL, sk_malloc_throw() + is called to allocate it. */ SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable); virtual ~SkMallocPixelRef(); //! Return the allocation size for the pixels size_t getSize() const { return fSize; } + void* getAddr() const { return fStorage; } // overrides from SkPixelRef virtual void flatten(SkFlattenableWriteBuffer&) const; @@ -58,4 +60,5 @@ private: typedef SkPixelRef INHERITED; }; + #endif diff --git a/include/core/SkMask.h b/include/core/SkMask.h index 608010d..58a2493 100644 --- a/include/core/SkMask.h +++ b/include/core/SkMask.h @@ -44,8 +44,9 @@ struct SkMask { edges. kVerticalLCD_Format has an extra row at the top and bottom. */ - kHorizontalLCD_Format, //!< 4 bytes/pixel: a/r/g/b - kVerticalLCD_Format, //!< 4 bytes/pixel: a/r/g/b + kHorizontalLCD_Format, //!< 4 bytes/pixel: a/r/g/b + kVerticalLCD_Format, //!< 4 bytes/pixel: a/r/g/b + kARGB32_Format, //!< SkPMColor }; enum { diff --git a/include/core/SkMath.h b/include/core/SkMath.h index e0f2361..af19083 100644 --- a/include/core/SkMath.h +++ b/include/core/SkMath.h @@ -161,6 +161,13 @@ static inline int SkNextLog2(uint32_t value) { return 32 - SkCLZ(value - 1); } +/** Returns true if value is a power of 2. Does not explicitly check for + value <= 0. + */ +static inline bool SkIsPow2(int value) { + return (value & (value - 1)) == 0; +} + /////////////////////////////////////////////////////////////////////////////// /** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t. @@ -213,6 +220,16 @@ static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) { return (prod + (prod >> 8)) >> 8; } +/** Return (a*b)/255, taking the ceiling of any fractional bits. Only valid if + both a and b are 0..255. The expected result equals (a * b + 254) / 255. + */ +static inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) { + SkASSERT((uint8_t)a == a); + SkASSERT((uint8_t)b == b); + unsigned prod = SkMulS16(a, b) + 255; + return (prod + (prod >> 8)) >> 8; +} + /** Return a*b/((1 << shift) - 1), rounding any fractional bits. Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8 */ diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h index 7ef7d8c..5c82d78 100644 --- a/include/core/SkMatrix.h +++ b/include/core/SkMatrix.h @@ -292,6 +292,13 @@ public: */ bool invert(SkMatrix* inverse) const; + /** Fills the passed array with the tranform values in the right order + for PDFs. If the matrix is a perspective transform, returns false + and fills the array with an identity transform. + @param transform The array to fill in. + */ + bool pdfTransform(SkScalar transform[6]) const; + /** Apply this matrix to the array of points specified by src, and write the transformed points into the array of points specified by dst. dst[] = M * src[] diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index f2df226..3c847de 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -113,10 +113,11 @@ public: kDevKernText_Flag = 0x100, //!< mask to enable device kerning text kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes + kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter // when adding extra flags, note that the fFlags member is specified // with a bit-width and you'll have to expand it. - kAllFlags = 0x7FF + kAllFlags = 0xFFF }; /** Return the paint's flags. Use the Flag enum to test flag values. @@ -205,6 +206,18 @@ public: */ void setEmbeddedBitmapText(bool useEmbeddedBitmapText); + bool isAutohinted() const + { + return SkToBool(this->getFlags() & kAutoHinting_Flag); + } + + /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit + @param useAutohinter true to set the kEmbeddedBitmapText bit in the + paint's flags, + false to clear it. + */ + void setAutohinted(bool useAutohinter); + /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set @return true if the underlineText bit is set in the paint's flags. */ @@ -831,7 +844,7 @@ private: SkColor fColor; SkScalar fWidth; SkScalar fMiterLimit; - unsigned fFlags : 11; + unsigned fFlags : 12; unsigned fTextAlign : 2; unsigned fCapType : 2; unsigned fJoinType : 2; @@ -859,9 +872,10 @@ private: enum { kCanonicalTextSizeForPaths = 64 }; + friend class SkAutoGlyphCache; friend class SkCanvas; friend class SkDraw; - friend class SkAutoGlyphCache; + friend class SkPDFDevice; friend class SkTextToPathIter; }; diff --git a/include/core/SkPictureFlat.h b/include/core/SkPictureFlat.h deleted file mode 100644 index 2c0af5a..0000000 --- a/include/core/SkPictureFlat.h +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef SkPictureFlat_DEFINED -#define SkPictureFlat_DEFINED - -#include "SkChunkAlloc.h" -#include "SkBitmap.h" -#include "SkPicture.h" -#include "SkMatrix.h" -#include "SkPaint.h" -#include "SkPath.h" -#include "SkRegion.h" - -enum DrawType { - UNUSED, - CLIP_PATH, - CLIP_REGION, - CLIP_RECT, - CONCAT, - DRAW_BITMAP, - DRAW_BITMAP_MATRIX, - DRAW_BITMAP_RECT, - DRAW_DATA, - DRAW_PAINT, - DRAW_PATH, - DRAW_PICTURE, - DRAW_POINTS, - DRAW_POS_TEXT, - DRAW_POS_TEXT_H, - DRAW_POS_TEXT_H_TOP_BOTTOM, // fast variant of DRAW_POS_TEXT_H - DRAW_RECT, - DRAW_SHAPE, - DRAW_SPRITE, - DRAW_TEXT, - DRAW_TEXT_ON_PATH, - DRAW_TEXT_TOP_BOTTOM, // fast variant of DRAW_TEXT - DRAW_VERTICES, - RESTORE, - ROTATE, - SAVE, - SAVE_LAYER, - SCALE, - SET_MATRIX, - SKEW, - TRANSLATE -}; - -enum DrawVertexFlags { - DRAW_VERTICES_HAS_TEXS = 0x01, - DRAW_VERTICES_HAS_COLORS = 0x02, - DRAW_VERTICES_HAS_INDICES = 0x04 -}; - -class SkRefCntPlayback { -public: - SkRefCntPlayback(); - virtual ~SkRefCntPlayback(); - - int count() const { return fCount; } - - void reset(const SkRefCntRecorder*); - - void setCount(int count); - SkRefCnt* set(int index, SkRefCnt*); - - virtual void setupBuffer(SkFlattenableReadBuffer& buffer) const { - buffer.setRefCntArray(fArray, fCount); - } - -protected: - int fCount; - SkRefCnt** fArray; -}; - -class SkTypefacePlayback : public SkRefCntPlayback { -public: - virtual void setupBuffer(SkFlattenableReadBuffer& buffer) const { - buffer.setTypefaceArray((SkTypeface**)fArray, fCount); - } -}; - -class SkFactoryPlayback { -public: - SkFactoryPlayback(int count) : fCount(count) { - fArray = SkNEW_ARRAY(SkFlattenable::Factory, count); - } - - ~SkFactoryPlayback() { - SkDELETE_ARRAY(fArray); - } - - SkFlattenable::Factory* base() const { return fArray; } - - void setupBuffer(SkFlattenableReadBuffer& buffer) const { - buffer.setFactoryPlayback(fArray, fCount); - } - -private: - int fCount; - SkFlattenable::Factory* fArray; -}; - -class SkFlatData { -public: - static int Compare(const SkFlatData* a, const SkFlatData* b) { - return memcmp(&a->fAllocSize, &b->fAllocSize, a->fAllocSize); - } - - int index() const { return fIndex; } - -#ifdef SK_DEBUG_SIZE - size_t size() const { return sizeof(fIndex) + fAllocSize; } -#endif - -protected: - static SkFlatData* Alloc(SkChunkAlloc* heap, int32_t size, int index); - - int fIndex; - int32_t fAllocSize; -}; - -class SkFlatBitmap : public SkFlatData { -public: - static SkFlatBitmap* Flatten(SkChunkAlloc*, const SkBitmap&, int index, - SkRefCntRecorder*); - - void unflatten(SkBitmap* bitmap, SkRefCntPlayback* rcp) const { - SkFlattenableReadBuffer buffer(fBitmapData); - if (rcp) { - rcp->setupBuffer(buffer); - } - bitmap->unflatten(buffer); - } - -#ifdef SK_DEBUG_VALIDATE - void validate() const { - // to be written - } -#endif - -private: - char fBitmapData[1]; - typedef SkFlatData INHERITED; -}; - -class SkFlatMatrix : public SkFlatData { -public: - static SkFlatMatrix* Flatten(SkChunkAlloc* heap, const SkMatrix& matrix, int index); - - void unflatten(SkMatrix* result) const { - memcpy(result, fMatrixData, sizeof(SkMatrix)); - } - -#ifdef SK_DEBUG_DUMP - void dump() const; -#endif - -#ifdef SK_DEBUG_VALIDATE - void validate() const { - // to be written - } -#endif - -private: - char fMatrixData[1]; - typedef SkFlatData INHERITED; -}; - -class SkFlatPaint : public SkFlatData { -public: - static SkFlatPaint* Flatten(SkChunkAlloc* heap, const SkPaint& paint, - int index, SkRefCntRecorder*, - SkRefCntRecorder* faceRecorder); - - void unflatten(SkPaint* result, SkRefCntPlayback* rcp, - SkTypefacePlayback* facePlayback) const { - Read(fPaintData, result, rcp, facePlayback); - } - - static void Read(const void* storage, SkPaint* paint, SkRefCntPlayback*, - SkTypefacePlayback* facePlayback); - -#ifdef SK_DEBUG_DUMP - void dump() const; -#endif - -private: - char fPaintData[1]; - typedef SkFlatData INHERITED; -}; - -class SkFlatRegion : public SkFlatData { -public: - static SkFlatRegion* Flatten(SkChunkAlloc* heap, const SkRegion& region, int index); - - void unflatten(SkRegion* result) const { - result->unflatten(fRegionData); - } - -#ifdef SK_DEBUG_VALIDATE - void validate() const { - // to be written - } -#endif - -private: - char fRegionData[1]; - typedef SkFlatData INHERITED; -}; - -#endif diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h index f1dab36..c0259af 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -25,6 +25,9 @@ class SkMutex; class SkFlattenableReadBuffer; class SkFlattenableWriteBuffer; +// this is an opaque class, not interpreted by skia +class SkGpuTexture; + /** \class SkPixelRef This class is the smart container for pixel memory, and is used with @@ -105,6 +108,10 @@ public: */ void setURI(const SkString& uri) { fURI = uri; } + /** Are we really wrapping a texture instead of a bitmap? + */ + virtual SkGpuTexture* getTexture() { return NULL; } + // serialization typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&); diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h index cb6473c..57cc368 100644 --- a/include/core/SkPostConfig.h +++ b/include/core/SkPostConfig.h @@ -107,8 +107,16 @@ #endif #ifndef SK_DEBUGBREAK - #define SK_DEBUGBREAK(cond) do { if (!(cond)) DebugBreak(); } while (false) + #define SK_DEBUGBREAK(cond) do { if (!(cond)) __debugbreak(); } while (false) #endif + + #ifndef SK_A32_SHIFT + #define SK_A32_SHIFT 24 + #define SK_R32_SHIFT 16 + #define SK_G32_SHIFT 8 + #define SK_B32_SHIFT 0 + #endif + #elif defined(SK_BUILD_FOR_MAC) #ifndef SK_DEBUGBREAK #define SK_DEBUGBREAK(cond) do { if (!(cond)) SK_CRASH(); } while (false) diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h index 0a5170c..f907578 100644 --- a/include/core/SkPreConfig.h +++ b/include/core/SkPreConfig.h @@ -17,9 +17,17 @@ #ifndef SkPreConfig_DEFINED #define SkPreConfig_DEFINED +#ifdef WEBKIT_VERSION_MIN_REQUIRED + #include "config.h" +#endif + ////////////////////////////////////////////////////////////////////// -#if !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) +#if !defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW) + + #ifdef __APPLE__ + #include "TargetConditionals.h" + #endif #if defined(PALMOS_SDK_VERSION) #define SK_BUILD_FOR_PALM @@ -31,6 +39,12 @@ #define SK_BUILD_FOR_WIN32 #elif defined(linux) #define SK_BUILD_FOR_UNIX + #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + #define SK_BUILD_FOR_IOS + #elif defined(ANDROID_NDK) + #define SK_BUILD_FOR_ANDROID_NDK + #elif defined(ANROID) + #define SK_BUILD_FOR_ANDROID #else #define SK_BUILD_FOR_MAC #endif diff --git a/include/core/SkRect.h b/include/core/SkRect.h index fbd9f7f..b6caad5 100644 --- a/include/core/SkRect.h +++ b/include/core/SkRect.h @@ -27,6 +27,36 @@ struct SkIRect { int32_t fLeft, fTop, fRight, fBottom; + static SkIRect MakeEmpty() { + SkIRect r; + r.setEmpty(); + return r; + } + + static SkIRect MakeWH(int32_t w, int32_t h) { + SkIRect r; + r.set(0, 0, w, h); + return r; + } + + static SkIRect MakeSize(const SkISize& size) { + SkIRect r; + r.set(0, 0, size.width(), size.height()); + return r; + } + + static SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) { + SkIRect rect; + rect.set(l, t, r, b); + return rect; + } + + static SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) { + SkIRect r; + r.set(x, y, x + w, y + h); + return r; + } + /** Return true if the rectangle's width or height are <= 0 */ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } @@ -266,6 +296,7 @@ struct SkRect { /** Return true if the rectangle's width or height are <= 0 */ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } + bool hasValidCoordinates() const; SkScalar width() const { return fRight - fLeft; } SkScalar height() const { return fBottom - fTop; } SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); } diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h index 7e325e0..f109ead 100644 --- a/include/core/SkRefCnt.h +++ b/include/core/SkRefCnt.h @@ -62,24 +62,6 @@ public: SkDELETE(this); } } - - /** Helper version of ref(), that first checks to see if this is not null. - If this is null, then do nothing. - */ - void safeRef() const { - if (this) { - this->ref(); - } - } - - /** Helper version of unref(), that first checks to see if this is not null. - If this is null, then do nothing. - */ - void safeUnref() const { - if (this) { - this->unref(); - } - } private: mutable int32_t fRefCnt; @@ -147,5 +129,51 @@ template <typename T> static inline void SkSafeUnref(T* obj) { } } +/** Wrapper class for SkRefCnt pointers. This manages ref/unref of a pointer to + a SkRefCnt (or subclass) object. + */ +template <typename T> class SkRefPtr { +public: + SkRefPtr() : fObj(NULL) {} + SkRefPtr(T* obj) : fObj(obj) { SkSafeRef(fObj); } + SkRefPtr(const SkRefPtr& o) : fObj(o.fObj) { SkSafeRef(fObj); } + ~SkRefPtr() { SkSafeUnref(fObj); } + + SkRefPtr& operator=(const SkRefPtr& rp) { + SkRefCnt_SafeAssign(fObj, rp.fObj); + return *this; + } + SkRefPtr& operator=(T* obj) { + SkRefCnt_SafeAssign(fObj, obj); + return *this; + } + + bool operator==(const SkRefPtr& rp) const { return fObj == rp.fObj; } + bool operator==(const T* obj) const { return fObj == obj; } + bool operator!=(const SkRefPtr& rp) const { return fObj != rp.fObj; } + bool operator!=(const T* obj) const { return fObj != obj; } + + T* get() const { return fObj; } + T& operator*() const { return *fObj; } + T* operator->() const { return fObj; } + bool operator!() const { return !fObj; } + + typedef T* SkRefPtr::*unspecified_bool_type; + operator unspecified_bool_type() const { return fObj ? &SkRefPtr::fObj : NULL; } + +private: + T* fObj; +}; + +template <typename T> +inline bool operator==(T* obj, const SkRefPtr<T>& rp) { + return obj == rp.get(); +} + +template <typename T> +inline bool operator!=(T* obj, const SkRefPtr<T>& rp) { + return obj != rp.get(); +} + #endif diff --git a/include/core/SkRefDict.h b/include/core/SkRefDict.h new file mode 100644 index 0000000..3ee27d9 --- /dev/null +++ b/include/core/SkRefDict.h @@ -0,0 +1,61 @@ +/* + 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 SkRefDict_DEFINED +#define SkRefDict_DEFINED + +#include "SkRefCnt.h" + +/** + * A dictionary of string,refcnt pairs. The dictionary is also an owner of the + * refcnt objects while they are contained. + */ +class SkRefDict : SkNoncopyable { +public: + SkRefDict(); + ~SkRefDict(); + + /** + * Return the data associated with name[], or NULL if no matching entry + * is found. The reference-count of the entry is not affected. + */ + SkRefCnt* find(const char name[]) const; + + /** + * If data is NULL, remove (if present) the entry matching name and call + * prev_data->unref() on the data for the matching entry. + * If data is not-NULL, replace the existing entry matching name and + * call (prev_data->unref()), or add a new one. In either case, + * data->ref() is called. + */ + void set(const char name[], SkRefCnt* data); + + /** + * Remove the matching entry (if found) and unref its data. + */ + void remove(const char name[]) { this->set(name, NULL); } + + /** + * Remove all entries, and unref() their associated data. + */ + void removeAll(); + +private: + struct Impl; + Impl* fImpl; +}; + +#endif diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h index 09b835d..d8c4e00 100644 --- a/include/core/SkRegion.h +++ b/include/core/SkRegion.h @@ -98,6 +98,13 @@ public: */ 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 + */ + 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&); @@ -260,7 +267,8 @@ public: bool done() { return fDone; } void next(); const SkIRect& rect() const { return fRect; } - + // may return null + const SkRegion* rgn() const { return fRgn; } private: const SkRegion* fRgn; const RunType* fRuns; diff --git a/include/core/SkScalar.h b/include/core/SkScalar.h index 9130a7c..09f24b5 100644 --- a/include/core/SkScalar.h +++ b/include/core/SkScalar.h @@ -60,6 +60,12 @@ /** SkScalarIsNaN(n) returns true if argument is not a number */ static inline bool SkScalarIsNaN(float x) { return x != x; } + /** Returns true if x is not NaN and not infinite */ + static inline bool SkScalarIsFinite(float x) { + uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts + int exponent = bits << 1 >> 24; + return exponent != 0xFF; + } /** SkIntToScalar(n) returns its integer argument as an SkScalar */ #define SkIntToScalar(n) ((float)(n)) @@ -177,6 +183,8 @@ #define SK_ScalarMin SK_FixedMin #define SK_ScalarNaN SK_FixedNaN #define SkScalarIsNaN(x) ((x) == SK_FixedNaN) + #define SkScalarIsFinite(x) ((x) != SK_FixedNaN) + #define SkIntToScalar(n) SkIntToFixed(n) #define SkFixedToScalar(x) (x) #define SkScalarToFixed(x) (x) @@ -253,5 +261,18 @@ static inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) { return A + SkScalarMul(B - A, t); } +/** Interpolate along the function described by (keys[length], values[length]) + for the passed searchKey. SearchKeys outside the range keys[0]-keys[Length] + clamp to the min or max value. This function was inspired by a desire + to change the multiplier for thickness in fakeBold; therefore it assumes + the number of pairs (length) will be small, and a linear search is used. + Repeated keys are allowed for discontinuous functions (so long as keys is + monotonically increasing), and if key is the value of a repeated scalar in + keys, the first one will be used. However, that may change if a binary + search is used. +*/ +SkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[], + const SkScalar values[], int length); + #endif diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h index 59d7125..0c93e2e 100644 --- a/include/core/SkScalerContext.h +++ b/include/core/SkScalerContext.h @@ -29,7 +29,10 @@ class SkPathEffect; class SkRasterizer; // needs to be != to any valid SkMask::Format -#define MASK_FORMAT_JUST_ADVANCE (0xFF) +#define MASK_FORMAT_UNKNOWN (0xFF) +#define MASK_FORMAT_JUST_ADVANCE MASK_FORMAT_UNKNOWN + +#define kMaxGlyphWidth (1<<13) struct SkGlyph { void* fImage; @@ -42,25 +45,38 @@ struct SkGlyph { uint8_t fMaskFormat; int8_t fRsbDelta, fLsbDelta; // used by auto-kerning - + + void init(uint32_t id) { + fID = id; + fImage = NULL; + fPath = NULL; + fMaskFormat = MASK_FORMAT_UNKNOWN; +#ifdef SK_GPU_AWARE_GLYPHCACHE + fGLCacheOffset = SKGLYPH_GLCACHEOFFSET_INVALID; + fGLStrikePtr = NULL; +#endif + } + unsigned rowBytes() const { unsigned rb = fWidth; if (SkMask::kBW_Format == fMaskFormat) { rb = (rb + 7) >> 3; + } else if (SkMask::kARGB32_Format == fMaskFormat) { + rb <<= 2; } else { rb = SkAlign4(rb); } return rb; } - + bool isJustAdvance() const { return MASK_FORMAT_JUST_ADVANCE == fMaskFormat; } - + bool isFullMetrics() const { return MASK_FORMAT_JUST_ADVANCE != fMaskFormat; } - + uint16_t getGlyphID() const { return ID2Code(fID); } @@ -70,27 +86,27 @@ struct SkGlyph { SkASSERT(code >= baseGlyphCount); return code - baseGlyphCount; } - + unsigned getSubX() const { return ID2SubX(fID); } - + SkFixed getSubXFixed() const { return SubToFixed(ID2SubX(fID)); } - + SkFixed getSubYFixed() const { return SubToFixed(ID2SubY(fID)); } - + size_t computeImageSize() const; - + /** Call this to set all of the metrics fields to 0 (e.g. if the scaler encounters an error measuring a glyph). Note: this does not alter the fImage, fPath, fID, fMaskFormat fields. */ void zeroMetrics(); - + enum { kSubBits = 2, kSubMask = ((1 << kSubBits) - 1), @@ -104,28 +120,28 @@ struct SkGlyph { static unsigned ID2Code(uint32_t id) { return id & kCodeMask; } - + static unsigned ID2SubX(uint32_t id) { return id >> (kSubShift + kSubShiftX); } - + static unsigned ID2SubY(uint32_t id) { return (id >> (kSubShift + kSubShiftY)) & kSubMask; } - + static unsigned FixedToSub(SkFixed n) { return (n >> (16 - kSubBits)) & kSubMask; } - + static SkFixed SubToFixed(unsigned sub) { SkASSERT(sub <= kSubMask); return sub << (16 - kSubBits); } - + static uint32_t MakeID(unsigned code) { return code; } - + static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) { SkASSERT(code <= kCodeMask); x = FixedToSub(x); @@ -134,7 +150,7 @@ struct SkGlyph { (y << (kSubShift + kSubShiftY)) | code; } - + void toMask(SkMask* mask) const; /** Given a glyph which is has a mask format of LCD or VerticalLCD, take @@ -156,6 +172,8 @@ public: kHintingBit2_Flag = 0x20, kEmbeddedBitmapText_Flag = 0x40, kEmbolden_Flag = 0x80, + kSubpixelPositioning_Flag = 0x100, + kAutohinting_Flag = 0x200, }; private: enum { @@ -167,10 +185,9 @@ public: SkScalar fTextSize, fPreScaleX, fPreSkewX; SkScalar fPost2x2[2][2]; SkScalar fFrameWidth, fMiterLimit; - bool fSubpixelPositioning; uint8_t fMaskFormat; uint8_t fStrokeJoin; - uint8_t fFlags; + uint16_t fFlags; // Warning: when adding members note that the size of this structure // must be a multiple of 4. SkDescriptor requires that its arguments be // multiples of four and this structure is put in an SkDescriptor in diff --git a/include/core/SkShader.h b/include/core/SkShader.h index f3d4856..1cdbf17 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -145,12 +145,56 @@ public: virtual void beginSession(); virtual void endSession(); + /** + Gives method bitmap should be read to implement a shader. + Also determines number and interpretation of "extra" parameters returned + by asABitmap + */ + enum BitmapType { + kNone_BitmapType, //<! Shader is not represented as a bitmap + kDefault_BitmapType,//<! Access bitmap using local coords transformed + // by matrix. No extras + kRadial_BitmapType, //<! Access bitmap by transforming local coordinates + // by the matrix and taking the distance of result + // from (0,0) as bitmap column. Bitmap is 1 pixel + // tall. No extras + kSweep_BitmapType, //<! Access bitmap by transforming local coordinates + // by the matrix and taking the angle of result + // to (0,0) as bitmap x coord, where angle = 0 is + // bitmap left edge of bitmap = 2pi is the + // right edge. Bitmap is 1 pixel tall. No extras + kTwoPointRadial_BitmapType + //<! Matrix transforms to space where (0,0) is + // the center of the starting circle. The second + // circle will be centered (x, 0) where x may be + // 0. The post-matrix space is normalized such + // that 1 is the second radius - first radius. + // Three extra parameters are returned: + // 0: x-offset of second circle center + // to first. + // 1: radius of first circle in post-matrix + // space + // 2: the second radius minus the first radius + // in pre-transformed space. + + }; /** Optional methods for shaders that can pretend to be a bitmap/texture - to play along with opengl. Default just returns false and ignores - the out parameters. + to play along with opengl. Default just returns kNone_BitmapType and + ignores the out parameters. + + @param outTexture if non-NULL will be the bitmap representing the shader + after return. + @param outMatrix if non-NULL will be the matrix to apply to vertices + to access the bitmap after return. + @param xy if non-NULL will be the tile modes that should be + used to access the bitmap after return. + @param twoPointRadialParams Two extra return values needed for two point + radial bitmaps. The first is the x-offset of + the second point and the second is the radius + about the first point. */ - virtual bool asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, - TileMode xy[2]); + virtual BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, + TileMode xy[2], SkScalar* twoPointRadialParams); ////////////////////////////////////////////////////////////////////////// // Factory methods for stock shaders diff --git a/include/core/SkSize.h b/include/core/SkSize.h index 9df9508..8371c9b 100644 --- a/include/core/SkSize.h +++ b/include/core/SkSize.h @@ -83,19 +83,19 @@ struct SkSize : public SkTSize<SkScalar> { return *this; } - SkISize round() const { + SkISize toRound() const { SkISize s; s.set(SkScalarRound(fWidth), SkScalarRound(fHeight)); return s; } - - SkISize ceil() const { + + SkISize toCeil() const { SkISize s; s.set(SkScalarCeil(fWidth), SkScalarCeil(fHeight)); return s; } - SkISize floor() const { + SkISize toFloor() const { SkISize s; s.set(SkScalarFloor(fWidth), SkScalarFloor(fHeight)); return s; diff --git a/include/core/SkStream.h b/include/core/SkStream.h index 798c6be..b02d482 100644 --- a/include/core/SkStream.h +++ b/include/core/SkStream.h @@ -91,6 +91,7 @@ public: bool writeText(const char text[]); bool writeDecAsText(int32_t); + bool writeBigDecAsText(int64_t, int minDigits = 0); bool writeHexAsText(uint32_t, int minDigits = 0); bool writeScalarAsText(SkScalar); @@ -176,7 +177,11 @@ public: */ virtual void setMemory(const void* data, size_t length, bool copyData = false); - virtual void setMemoryOwned(const void* src, size_t size); + /** Replace any memory buffer with the specified buffer. The caller + must have allocated data with sk_malloc or sk_realloc, since it + will be freed with sk_free. + */ + void setMemoryOwned(const void* data, size_t length); void skipToAlign4(); virtual bool rewind(); virtual size_t read(void* buffer, size_t size); @@ -273,7 +278,7 @@ public: // modifies stream and returns true if offset + size is less than or equal to getOffset() bool write(const void* buffer, size_t offset, size_t size); bool read(void* buffer, size_t offset, size_t size); - size_t getOffset() { return fBytesWritten; } + size_t getOffset() const { return fBytesWritten; } // copy what has been written to the stream into dst void copyTo(void* dst) const; @@ -309,4 +314,3 @@ public: typedef SkFILEStream SkURLStream; #endif - diff --git a/include/core/SkString.h b/include/core/SkString.h index 5ecfb1e..4498bba 100644 --- a/include/core/SkString.h +++ b/include/core/SkString.h @@ -28,6 +28,8 @@ int SkStrStartsWithOneOf(const char string[], const char prefixes[]); #define SkStrAppendS32_MaxSize 11 char* SkStrAppendS32(char buffer[], int32_t); +#define SkStrAppendS64_MaxSize 20 +char* SkStrAppendS64(char buffer[], int64_t, int minDigits); #define SkStrAppendScalar_MaxSize 11 char* SkStrAppendScalar(char buffer[], SkScalar); @@ -93,6 +95,7 @@ public: 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); @@ -101,6 +104,7 @@ public: 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); } @@ -109,6 +113,7 @@ public: 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); } @@ -165,4 +170,3 @@ private: }; #endif - diff --git a/include/core/SkTScopedPtr.h b/include/core/SkTScopedPtr.h new file mode 100644 index 0000000..1e5d4c4 --- /dev/null +++ b/include/core/SkTScopedPtr.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 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 SkTScopedPtr_DEFINED +#define SkTScopedPtr_DEFINED + +#include "SkTypes.h" + +/** \class SkTScopedPtr + A SkTScopedPtr<T> is like a T*, except that the destructor of SkTScopedPtr<T> + automatically deletes the pointer it holds (if any). That is, SkTScopedPtr<T> + owns the T object that it points to. Like a T*, a SkTScopedPtr<T> may hold + either NULL or a pointer to a T object. Also like T*, SkTScopedPtr<T> is + thread-compatible, and once you dereference it, you get the threadsafety + guarantees of T. + + The size of a SkTScopedPtr is small: sizeof(SkTScopedPtr<T>) == sizeof(T*) +*/ +template <typename T> class SkTScopedPtr : SkNoncopyable { +public: + explicit SkTScopedPtr(T* o = NULL) : fObj(o) {} + ~SkTScopedPtr() { + enum { kTypeMustBeComplete = sizeof(T) }; + delete fObj; + } + + /** Delete the current object, if any. Then take ownership of the + passed object. + */ + void reset(T* o = NULL) { + if (o != fObj) { + enum { kTypeMustBeComplete = sizeof(T) }; + delete fObj; + fObj = o; + } + } + + /** Without deleting the current object, return it and forget about it. + Similar to calling get() and reset(), but the object is not deleted. + */ + T* release() { + T* retVal = fObj; + fObj = NULL; + return retVal; + } + + T& operator*() const { + SkASSERT(fObj != NULL); + return *fObj; + } + T* operator->() const { + SkASSERT(fObj != NULL); + return fObj; + } + T* get() const { return fObj; } + + bool operator==(T* o) const { return fObj == o; } + bool operator!=(T* o) const { return fObj != o; } + +private: + T* fObj; + + // Forbid comparison of SkTScopedPtr types. If T2 != T, it doesn't make + // sense, and if T2 == T, it still doesn't make sense because the same + // object can't be owned by two different scoped_ptrs. + template <class T2> bool operator==(SkTScopedPtr<T2> const& o2) const; + template <class T2> bool operator!=(SkTScopedPtr<T2> const& o2) const; +}; + +#endif diff --git a/include/core/SkTemplates.h b/include/core/SkTemplates.h index d484389..55109bf 100644 --- a/include/core/SkTemplates.h +++ b/include/core/SkTemplates.h @@ -59,12 +59,13 @@ private: T* fObj; }; +// See also SkTScopedPtr. template <typename T> class SkAutoTDelete : SkNoncopyable { public: SkAutoTDelete(T* obj, bool deleteWhenDone = true) : fObj(obj) { - this->deleteWhenDone = deleteWhenDone; + fDeleteWhenDone = deleteWhenDone; } - ~SkAutoTDelete() { if (deleteWhenDone) delete fObj; } + ~SkAutoTDelete() { if (fDeleteWhenDone) delete fObj; } T* get() const { return fObj; } void free() { delete fObj; fObj = NULL; } @@ -72,7 +73,7 @@ public: private: T* fObj; - bool deleteWhenDone; + bool fDeleteWhenDone; }; template <typename T> class SkAutoTDeleteArray : SkNoncopyable { diff --git a/include/core/SkThread_platform.h b/include/core/SkThread_platform.h index 825b737..c6fd058 100644 --- a/include/core/SkThread_platform.h +++ b/include/core/SkThread_platform.h @@ -17,7 +17,7 @@ #ifndef SkThread_platform_DEFINED #define SkThread_platform_DEFINED -#ifdef ANDROID +#if defined(ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) #include <utils/threads.h> #include <utils/Atomic.h> @@ -61,7 +61,7 @@ public: private: bool fIsGlobal; enum { - kStorageIntCount = 12 + kStorageIntCount = 64 }; uint32_t fStorage[kStorageIntCount]; }; diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h index bf783a3..cea6ab1 100644 --- a/include/core/SkTypeface.h +++ b/include/core/SkTypeface.h @@ -20,6 +20,7 @@ #include "SkRefCnt.h" class SkStream; +class SkAdvancedTypefaceMetrics; class SkWStream; /** \class SkTypeface @@ -83,6 +84,18 @@ public: */ static SkTypeface* CreateFromName(const char familyName[], Style style); + /** Return a new reference to the typeface that covers a set of Unicode + code points with the specified Style. Use this call if you want to + pick any font that covers a given string of text. + + @param data UTF-16 characters + @param bytelength length of data, in bytes + @return reference to the closest-matching typeface. Call must call + unref() when they are done. + */ + static SkTypeface* CreateForChars(const void* data, size_t bytelength, + Style s); + /** Return a new reference to the typeface that most closely matches the requested typeface and specified Style. Use this call if you want to pick a new style from the same family of the existing typeface. @@ -118,6 +131,14 @@ 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. + @return The returned object has already been referenced. + */ + SkAdvancedTypefaceMetrics* getAdvancedTypefaceMetrics( + bool perGlyphInfo) const; + protected: /** uniqueID must be unique (please!) and non-zero */ diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h index 1f8ecaa..8dbd51b 100644 --- a/include/core/SkTypes.h +++ b/include/core/SkTypes.h @@ -103,27 +103,53 @@ static inline void sk_bzero(void* buffer, size_t size) { #define SkAssertResult(cond) cond #endif +namespace { + +template <bool> +struct SkCompileAssert { +}; + +} // namespace + +#define SK_COMPILE_ASSERT(expr, msg) \ + typedef SkCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] + /////////////////////////////////////////////////////////////////////// -/** Fast type for signed 8 bits. Use for parameter passing and local variables, not for storage -*/ -typedef int S8CPU; -/** Fast type for unsigned 8 bits. Use for parameter passing and local variables, not for storage -*/ -typedef int S16CPU; -/** Fast type for signed 16 bits. Use for parameter passing and local variables, not for storage -*/ -typedef unsigned U8CPU; -/** Fast type for unsigned 16 bits. Use for parameter passing and local variables, not for storage -*/ -typedef unsigned U16CPU; +/** + * Fast type for signed 8 bits. Use for parameter passing and local variables, + * not for storage. + */ +typedef int S8CPU; -/** Meant to be faster than bool (doesn't promise to be 0 or 1, just 0 or non-zero -*/ -typedef int SkBool; -/** Meant to be a small version of bool, for storage purposes. Will be 0 or 1 -*/ -typedef uint8_t SkBool8; +/** + * Fast type for unsigned 8 bits. Use for parameter passing and local + * variables, not for storage + */ +typedef unsigned U8CPU; + +/** + * Fast type for signed 16 bits. Use for parameter passing and local variables, + * not for storage + */ +typedef int S16CPU; + +/** + * Fast type for unsigned 16 bits. Use for parameter passing and local + * variables, not for storage + */ +typedef unsigned U16CPU; + +/** + * Meant to be faster than bool (doesn't promise to be 0 or 1, + * just 0 or non-zero + */ +typedef int SkBool; + +/** + * Meant to be a small version of bool, for storage purposes. Will be 0 or 1 + */ +typedef uint8_t SkBool8; #ifdef SK_DEBUG int8_t SkToS8(long); @@ -290,6 +316,20 @@ static inline uint32_t SkSetClearMask(uint32_t bits, bool cond, return cond ? bits | mask : bits & ~mask; } +/////////////////////////////////////////////////////////////////////////////// + +/** + * Use to cast a pointer to a different type, and maintaining strict-aliasing + */ +template <typename Dst> Dst SkTCast(const void* ptr) { + union { + const void* src; + Dst dst; + } data; + data.src = ptr; + return data.dst; +} + ////////////////////////////////////////////////////////////////////////////// /** \class SkNoncopyable @@ -300,7 +340,7 @@ be copied. It hides its copy-constructor and its assignment-operator. class SkNoncopyable { public: SkNoncopyable() {} - + private: SkNoncopyable(const SkNoncopyable&); SkNoncopyable& operator=(const SkNoncopyable&); @@ -311,7 +351,7 @@ public: SkAutoFree() : fPtr(NULL) {} explicit SkAutoFree(void* ptr) : fPtr(ptr) {} ~SkAutoFree() { sk_free(fPtr); } - + /** Return the currently allocate buffer, or null */ void* get() const { return fPtr; } @@ -325,7 +365,7 @@ public: fPtr = ptr; return prev; } - + /** Transfer ownership of the current ptr to the caller, setting the internal reference to null. Note the caller is reponsible for calling sk_free on the returned address. diff --git a/include/core/SkUtils.h b/include/core/SkUtils.h index 0700aeb..7cb2066 100644 --- a/include/core/SkUtils.h +++ b/include/core/SkUtils.h @@ -39,7 +39,7 @@ void sk_memset32_portable(uint32_t dst[], uint32_t value, int count); typedef void (*SkMemset32Proc)(uint32_t dst[], uint32_t value, int count); SkMemset32Proc SkMemset32GetPlatformProc(); -#ifdef ANDROID +#if defined(ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) #include "cutils/memory.h" #define sk_memset16(dst, value, count) android_memset16(dst, value, (count) << 1) diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h index d92d346..714468c 100644 --- a/include/core/SkXfermode.h +++ b/include/core/SkXfermode.h @@ -115,6 +115,13 @@ public: kLastMode = kExclusion_Mode }; + /** If the xfermode is one of the modes in the Mode enum, then asMode() + returns true and sets (if not null) mode accordingly. + This is a better version of IsMode(), which is only able to report + about modes that are expressible as coefficients. + */ + virtual bool asMode(Mode* mode); + /** Return an SkXfermode object for the specified mode. */ static SkXfermode* Create(Mode mode); @@ -137,7 +144,7 @@ public: return false and ignore the mode parameter. */ static bool IsMode(SkXfermode*, Mode* mode); - + Mode fMode; protected: @@ -184,6 +191,7 @@ public: // overrides from SkFlattenable virtual Factory getFactory() { return CreateProc; } virtual void flatten(SkFlattenableWriteBuffer&); + virtual bool asMode(SkXfermode::Mode* mode); protected: SkProcXfermode(SkFlattenableReadBuffer&); diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h index 028b2eb..6f96ff6 100644 --- a/include/effects/SkBlurDrawLooper.h +++ b/include/effects/SkBlurDrawLooper.h @@ -29,7 +29,19 @@ class SkMaskFilter; */ class SkBlurDrawLooper : public SkDrawLooper { public: - SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color); + enum BlurFlags { + kNone_BlurFlag = 0x00, + /** + The blur layer's dx/dy/radius aren't affected by the canvas + transform. + */ + kIgnoreTransform_BlurFlag = 0x01, + /** mask for all blur flags */ + kAll_BlurFlag = 0x01 + }; + + SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color, + uint32_t flags = kNone_BlurFlag); virtual ~SkBlurDrawLooper(); // overrides from SkDrawLooper @@ -41,6 +53,7 @@ public: return SkNEW_ARGS(SkBlurDrawLooper, (buffer)); } + protected: SkBlurDrawLooper(SkFlattenableReadBuffer&); // overrides from SkFlattenable @@ -55,6 +68,7 @@ private: SkColor fBlurColor; SkColor fSavedColor; // remember the original int fSaveCount; + uint32_t fBlurFlags; enum State { kBeforeEdge, diff --git a/include/effects/SkBlurMaskFilter.h b/include/effects/SkBlurMaskFilter.h index b90ea5e..0a68f54 100644 --- a/include/effects/SkBlurMaskFilter.h +++ b/include/effects/SkBlurMaskFilter.h @@ -32,12 +32,22 @@ public: kBlurStyleCount }; + enum BlurFlags { + kNone_BlurFlag = 0x00, + /** The blur layer's radius is not affected by transforms */ + kIgnoreTransform_BlurFlag = 0x01, + /** mask for all blur flags */ + kAll_BlurFlag = 0x01 + }; + /** Create a blur maskfilter. @param radius The radius to extend the blur from the original mask. Must be > 0. @param style The BlurStyle to use + @param flags Flags to use - defaults to none @return The new blur maskfilter */ - static SkMaskFilter* Create(SkScalar radius, BlurStyle style); + static SkMaskFilter* Create(SkScalar radius, BlurStyle style, + uint32_t flags = kNone_BlurFlag); /** Create an emboss maskfilter @param direction array of 3 scalars [x, y, z] specifying the direction of the light source diff --git a/include/effects/SkGroupShape.h b/include/effects/SkGroupShape.h new file mode 100644 index 0000000..2c851fa --- /dev/null +++ b/include/effects/SkGroupShape.h @@ -0,0 +1,150 @@ +#ifndef SkGroupShape_DEFINED +#define SkGroupShape_DEFINED + +#include "SkMatrix.h" +#include "SkShape.h" +#include "SkTDArray.h" +#include "SkThread.h" + +template <typename T> class SkTRefCnt : public T { +public: + SkTRefCnt() : fRefCnt(1) {} + ~SkTRefCnt() { SkASSERT(1 == fRefCnt); } + + int32_t getRefCnt() const { return fRefCnt; } + + /** Increment the reference count. Must be balanced by a call to unref(). + */ + void ref() const { + SkASSERT(fRefCnt > 0); + sk_atomic_inc(&fRefCnt); + } + + /** Decrement the reference count. If the reference count is 1 before the + decrement, then call delete on the object. Note that if this is the + case, then the object needs to have been allocated via new, and not on + the stack. + */ + void unref() const { + SkASSERT(fRefCnt > 0); + if (sk_atomic_dec(&fRefCnt) == 1) { + fRefCnt = 1; // so our destructor won't complain + SkDELETE(this); + } + } + + static void SafeRef(const SkTRefCnt* obj) { + if (obj) { + obj->ref(); + } + } + + static void SafeUnref(const SkTRefCnt* obj) { + if (obj) { + obj->unref(); + } + } + +private: + mutable int32_t fRefCnt; +}; + +class SkMatrixRef : public SkTRefCnt<SkMatrix> { +public: + SkMatrixRef() { this->reset(); } + explicit SkMatrixRef(const SkMatrix& matrix) { + SkMatrix& m = *this; + m = matrix; + } + + SkMatrix& operator=(const SkMatrix& matrix) { + SkMatrix& m = *this; + m = matrix; + return m; + } +}; + +class SkGroupShape : public SkShape { +public: + SkGroupShape(); + virtual ~SkGroupShape(); + + /** Return the number of child shapes in this group + */ + int countShapes() const; + + /** Return the shape at the specified index. Note this does not affect the + owner count of the index'd shape. If index is out of range, returns NULL + */ + SkShape* getShape(int index, SkMatrixRef** = NULL) const; + + /** Helper function to return the matrixref of the specified shape. + */ + SkMatrixRef* getShapeMatrixRef(int index) const { + SkMatrixRef* mr = NULL; + (void)this->getShape(index, &mr); + return mr; + } + + /** Ref the specified shape, and insert it into the child list at the + specified index. If index == countShapes(), then the shape will be + appended to the child list, otherwise if index is out of range, the + shape is not added. Either way, the shape parameter is returned. + + Child shapes are drawn in order, after the parent, so the shape at index + 0 will be drawn first, and the shape at index countShapes() - 1 will be + drawn last. + */ + void addShape(int index, SkShape*, SkMatrixRef* = NULL); + + void addShape(int index, SkShape* shape, const SkMatrix& matrix) { + SkMatrixRef* mr = SkNEW_ARGS(SkMatrixRef, (matrix)); + this->addShape(index, shape, mr); + mr->unref(); + } + + /** Helper method to append a shape, passing countShapes() for the index + */ + SkShape* appendShape(SkShape* shape, SkMatrixRef* mr = NULL) { + this->addShape(this->countShapes(), shape, mr); + return shape; + } + + SkShape* appendShape(SkShape* shape, const SkMatrix& matrix) { + this->addShape(this->countShapes(), shape, matrix); + return shape; + } + + /** Unref the specified index, and remove it from the child list. If index + is out of range, does nothing. + */ + void removeShape(int index); + + /** Unrefs and removes all of the child shapes + */ + void removeAllShapes(); + + // overrides + virtual Factory getFactory(); + virtual void flatten(SkFlattenableWriteBuffer&); + + // public for Registrar + static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); + +protected: + // overrides + virtual void onDraw(SkCanvas*); + + SkGroupShape(SkFlattenableReadBuffer&); + +private: + struct Rec { + SkShape* fShape; + SkMatrixRef* fMatrixRef; + }; + SkTDArray<Rec> fList; + + typedef SkShape INHERITED; +}; + +#endif diff --git a/include/effects/SkRectShape.h b/include/effects/SkRectShape.h new file mode 100644 index 0000000..9b8cfc1 --- /dev/null +++ b/include/effects/SkRectShape.h @@ -0,0 +1,56 @@ +#ifndef SkRectShape_DEFINED +#define SkRectShape_DEFINED + +#include "SkShape.h" +#include "SkPaint.h" +#include "SkSize.h" + +class SkPaintShape : public SkShape { +public: + SkPaintShape(); + + SkPaint& paint() { return fPaint; } + const SkPaint& paint() const { return fPaint; } + + // overrides + virtual void flatten(SkFlattenableWriteBuffer&); + +protected: + SkPaintShape(SkFlattenableReadBuffer& buffer); + +private: + SkPaint fPaint; + + typedef SkShape INHERITED; +}; + +class SkRectShape : public SkPaintShape { +public: + SkRectShape(); + + void setRect(const SkRect&); + void setOval(const SkRect&); + void setCircle(SkScalar x, SkScalar y, SkScalar radius); + void setRRect(const SkRect&, SkScalar rx, SkScalar ry); + + // overrides + virtual Factory getFactory(); + virtual void flatten(SkFlattenableWriteBuffer&); + + // public for Registrar + static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); + +protected: + SkRectShape(SkFlattenableReadBuffer&); + + // overrides + virtual void onDraw(SkCanvas*); + +private: + SkRect fBounds; + SkSize fRadii; + + typedef SkPaintShape INHERITED; +}; + +#endif diff --git a/include/images/SkImageRef.h b/include/images/SkImageRef.h index 8672b25..800f12e 100644 --- a/include/images/SkImageRef.h +++ b/include/images/SkImageRef.h @@ -59,7 +59,7 @@ public: /** Return true if the image can be decoded and is opaque. Calling this method will decode and set the pixels in the specified bitmap and - set the opaque flag. + sets the isOpaque flag. */ bool isOpaque(SkBitmap* bm); diff --git a/include/ports/SkHarfBuzzFont.h b/include/ports/SkHarfBuzzFont.h new file mode 100644 index 0000000..b1fce0e --- /dev/null +++ b/include/ports/SkHarfBuzzFont.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SkHarfBuzzFont_DEFINED +#define SkHarfBuzzFont_DEFINED + +extern "C" { +#include "harfbuzz-shaper.h" +//#include "harfbuzz-unicode.h" +} + +#include "SkTypes.h" + +class SkPaint; +class SkTypeface; + +class SkHarfBuzzFont { +public: + /** The subclass returns the typeface for this font, or NULL + */ + virtual SkTypeface* getTypeface() const = 0; + /** The subclass sets the text related attributes of the paint. + e.g. textSize, typeface, textSkewX, etc. + All of the attributes that could effect how the text is measured. + Color information (e.g. color, xfermode, shader, etc.) are not required. + */ + virtual void setupPaint(SkPaint*) const = 0; + + /** Implementation of HB_GetFontTableFunc, using SkHarfBuzzFont* as + the first parameter. + */ + static HB_Error GetFontTableFunc(void* skharfbuzzfont, const HB_Tag tag, + HB_Byte* buffer, HB_UInt* len); + + static const HB_FontClass& GetFontClass(); +}; + +#endif + diff --git a/include/svg/SkSVGParser.h b/include/svg/SkSVGParser.h index 86ae4c2..83b120d 100644 --- a/include/svg/SkSVGParser.h +++ b/include/svg/SkSVGParser.h @@ -32,7 +32,7 @@ class SkSVGElement; class SkSVGParser : public SkXMLParser { public: - SkSVGParser(); + SkSVGParser(SkXMLParserError* err = NULL); virtual ~SkSVGParser(); void _addAttribute(const char* attrName, const char* attrValue) { fXMLWriter.addAttribute(attrName, attrValue); } diff --git a/include/svg/SkSVGTypes.h b/include/svg/SkSVGTypes.h index 38d63ce..99d8ca1 100644 --- a/include/svg/SkSVGTypes.h +++ b/include/svg/SkSVGTypes.h @@ -40,6 +40,7 @@ enum SkSVGTypes { SkSVGType_Symbol, SkSVGType_Text, SkSVGType_Tspan, + SkSVGType_Unknown, SkSVGType_Use }; diff --git a/include/text/SkTextLayout.h b/include/text/SkTextLayout.h new file mode 100644 index 0000000..2152307 --- /dev/null +++ b/include/text/SkTextLayout.h @@ -0,0 +1,50 @@ +#ifndef SkTextLayout_DEFINED +#define SkTextLayout_DEFINED + +#include "SkPaint.h" +#include "SkRefCnt.h" + +class SkTextStyle : public SkRefCnt { +public: + SkTextStyle(); + SkTextStyle(const SkTextStyle&); + explicit SkTextStyle(const SkPaint&); + virtual ~SkTextStyle(); + + const SkPaint& paint() const { return fPaint; } + SkPaint& paint() { return fPaint; } + + // todo: bidi-override, language + +private: + SkPaint fPaint; +}; + +class SkTextLayout { +public: + SkTextLayout(); + ~SkTextLayout(); + + void setText(const char text[], size_t length); + void setBounds(const SkRect& bounds); + + SkTextStyle* getDefaultStyle() const { return fDefaultStyle; } + SkTextStyle* setDefaultStyle(SkTextStyle*); + +// SkTextStyle* setStyle(SkTextStyle*, size_t offset, size_t length); + + void draw(SkCanvas* canvas); + +private: + SkTDArray<char> fText; + SkTextStyle* fDefaultStyle; + SkRect fBounds; + + // cache + struct Line; + struct GlyphRun; + SkTDArray<Line*> fLines; +}; + +#endif + diff --git a/include/utils/SkCubicInterval.h b/include/utils/SkCubicInterval.h new file mode 100644 index 0000000..bd6fc5f --- /dev/null +++ b/include/utils/SkCubicInterval.h @@ -0,0 +1,16 @@ +#ifndef SkCubicInterval_DEFINED +#define SkCubicInterval_DEFINED + +#include "SkPoint.h" + +SkScalar SkEvalCubicInterval(SkScalar x1, SkScalar y1, + SkScalar x2, SkScalar y2, + SkScalar unitX); + +static inline SkScalar SkEvalCubicInterval(const SkPoint pts[2], SkScalar x) { + return SkEvalCubicInterval(pts[0].fX, pts[0].fY, + pts[1].fX, pts[1].fY, x); +} + +#endif + diff --git a/include/utils/SkEGLContext.h b/include/utils/SkEGLContext.h new file mode 100644 index 0000000..4b17be1 --- /dev/null +++ b/include/utils/SkEGLContext.h @@ -0,0 +1,20 @@ +#ifndef SkEGLContext_DEFINED +#define SkEGLContext_DEFINED + +#include "SkTypes.h" + +/** + * Create an offscreen opengl context + */ +class SkEGLContext { +public: + SkEGLContext(); + ~SkEGLContext(); + + bool init(int width, int height); + +private: + void* fContext; +}; + +#endif diff --git a/include/utils/SkLayer.h b/include/utils/SkLayer.h index c42261f..80a2137 100644 --- a/include/utils/SkLayer.h +++ b/include/utils/SkLayer.h @@ -128,6 +128,8 @@ private: uint32_t fFlags; SkTDArray<SkLayer*> m_children; + + typedef SkRefCnt INHERITED; }; #endif diff --git a/include/views/SkOSSound.h b/include/utils/SkParsePath.h index 5d77955..d271f7e 100644 --- a/include/views/SkOSSound.h +++ b/include/utils/SkParsePath.h @@ -14,22 +14,17 @@ * limitations under the License. */ -#ifndef SkOSSound_DEFINED -#define SkOSSound_DEFINED +#ifndef SkParsePath_DEFINED +#define SkParsePath_DEFINED -#include "SkTypes.h" +#include "SkPath.h" -class SkOSSound { -public: - static void Play(const char path[]); - static void Pause(); - static void Resume(); - static bool TogglePause(); // returns true if we are now playing, or false if we're now paused - static void Stop(); +class SkString; - // volume runs from 0 (silent) to 0xFF (max-volume) - static uint8_t GetVolume(); - static void SetVolume(U8CPU volume); +class SkParsePath { +public: + static bool FromSVGString(const char str[], SkPath*); + static void ToSVGString(const SkPath&, SkString*); }; #endif diff --git a/include/utils/SkProxyCanvas.h b/include/utils/SkProxyCanvas.h index 082e0fd..98ef778 100644 --- a/include/utils/SkProxyCanvas.h +++ b/include/utils/SkProxyCanvas.h @@ -22,10 +22,7 @@ public: // overrides from SkCanvas virtual bool getViewport(SkIPoint* size) const; - virtual bool setViewport(int x, int y); - virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap); - virtual int save(SaveFlags flags = kMatrixClip_SaveFlag); virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags = kARGB_ClipLayer_SaveFlag); diff --git a/include/utils/SkTextBox.h b/include/utils/SkTextBox.h index 2c34448..3471f5b 100644 --- a/include/utils/SkTextBox.h +++ b/include/utils/SkTextBox.h @@ -62,10 +62,18 @@ public: void draw(SkCanvas*, const char text[], size_t len, const SkPaint&); + void setText(const char text[], size_t len, const SkPaint&); + void draw(SkCanvas*); + int countLines() const; + SkScalar getTextHeight() const; + private: SkRect fBox; SkScalar fSpacingMul, fSpacingAdd; uint8_t fMode, fSpacingAlign; + const char* fText; + size_t fLen; + const SkPaint* fPaint; }; class SkTextLineBreaker { diff --git a/include/utils/mac/SkCGUtils.h b/include/utils/mac/SkCGUtils.h index 3b74b55..db67edf 100644 --- a/include/utils/mac/SkCGUtils.h +++ b/include/utils/mac/SkCGUtils.h @@ -1,10 +1,37 @@ #ifndef SkCGUtils_DEFINED #define SkCGUtils_DEFINED -#include <Carbon/Carbon.h> +#include "SkTypes.h" + +#ifdef SK_BUILD_FOR_MAC + #include <Carbon/Carbon.h> +#else + #include <CoreGraphics/CoreGraphics.h> +#endif class SkBitmap; -CGImageRef SkCreateCGImageRef(const SkBitmap&); +/** + * Create an imageref from the specified bitmap using the specified colorspace. + * If space is NULL, then CGColorSpaceCreateDeviceRGB() is used. + */ +CGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm, + CGColorSpaceRef space); + +/** + * Create an imageref from the specified bitmap using the colorspace returned + * by CGColorSpaceCreateDeviceRGB() + */ +static inline CGImageRef SkCreateCGImageRef(const SkBitmap& bm) { + return SkCreateCGImageRefWithColorspace(bm, NULL); +} + +/** + * Draw the bitmap into the specified CG context. The bitmap will be converted + * to a CGImage using the generic RGB colorspace. (x,y) specifies the position + * of the top-left corner of the bitmap. The bitmap is converted using the + * colorspace returned by CGColorSpaceCreateDeviceRGB() + */ +void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y); #endif diff --git a/include/views/SkEvent.h b/include/views/SkEvent.h index 2b43f34..f6719d6 100644 --- a/include/views/SkEvent.h +++ b/include/views/SkEvent.h @@ -21,8 +21,6 @@ #include "SkMetaData.h" #include "SkString.h" -//class SkOSWindow; - /** Unique 32bit id used to identify an instance of SkEventSink. When events are posted, they are posted to a specific sinkID. When it is time to dispatch the event, the sinkID is used to find the specific SkEventSink object. If it is found, @@ -100,6 +98,9 @@ public: */ bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); } bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); } + const void* findData(const char name[], size_t* byteCount = NULL) const { + return fMeta.findData(name, byteCount); + } /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */ bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); } @@ -110,6 +111,9 @@ public: /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */ bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); } bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); } + bool hasData(const char name[], const void* data, size_t byteCount) const { + return fMeta.hasData(name, data, byteCount); + } /** Add/replace the named 32bit field to the event. In XML use the subelement <data name=... s32=... /> */ void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); } @@ -124,6 +128,9 @@ public: /** Add/replace the named pointer field to the event. There is no XML equivalent for this call */ void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); } void setBool(const char name[], bool value) { fMeta.setBool(name, value); } + void setData(const char name[], const void* data, size_t byteCount) { + fMeta.setData(name, data, byteCount); + } /** Return the underlying metadata object */ SkMetaData& getMetaData() { return fMeta; } @@ -197,6 +204,12 @@ public: */ static void ServiceQueueTimer(); + /** Return the number of queued events. note that this value may be obsolete + upon return, since another thread may have called ProcessEvent() or + Post() after the count was made. + */ + static int CountEventsOnQueue(); + //////////////////////////////////////////////////// /** Porting layer must implement these functions **/ //////////////////////////////////////////////////// diff --git a/include/views/SkImageView.h b/include/views/SkImageView.h index 157abb1..57215c9 100644 --- a/include/views/SkImageView.h +++ b/include/views/SkImageView.h @@ -22,7 +22,7 @@ class SkAnimator; class SkBitmap; -struct SkMatrix; +class SkMatrix; class SkImageView : public SkView { public: diff --git a/include/views/SkMetaData.h b/include/views/SkMetaData.h index 21739fe..9509710 100644 --- a/include/views/SkMetaData.h +++ b/include/views/SkMetaData.h @@ -35,6 +35,7 @@ public: const char* findString(const char name[]) const; bool findPtr(const char name[], void** value = 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 { @@ -62,6 +63,11 @@ public: 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); @@ -69,12 +75,15 @@ public: void setString(const char name[], const char value[]); void setPtr(const char name[], void* value); 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[]); SkDEBUGCODE(static void UnitTest();) @@ -84,6 +93,7 @@ public: kString_Type, kPtr_Type, kBool_Type, + kData_Type, kTypeCount }; diff --git a/include/views/SkOSWindow_Mac.h b/include/views/SkOSWindow_Mac.h index 98e76b0..3a26d5a 100644 --- a/include/views/SkOSWindow_Mac.h +++ b/include/views/SkOSWindow_Mac.h @@ -33,7 +33,12 @@ public: static OSStatus EventHandler(EventHandlerCallRef inHandler, EventRef inEvent, void* userData); - void doPaint(void* ctx); + void doPaint(void* ctx); + + + bool attachGL(const SkBitmap* offscreen); + void detachGL(); + void presentGL(); protected: // overrides from SkEventSink @@ -43,10 +48,12 @@ protected: // overrides from SkView virtual void onAddMenu(const SkOSMenu*); virtual void onSetTitle(const char[]); + private: void* fHWND; void* fHVIEW; + void* fAGLCtx; typedef SkWindow INHERITED; }; diff --git a/include/views/SkOSWindow_SDL.h b/include/views/SkOSWindow_SDL.h new file mode 100644 index 0000000..0ff24f3 --- /dev/null +++ b/include/views/SkOSWindow_SDL.h @@ -0,0 +1,52 @@ +/* + * 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 SkOSWindow_SDL_DEFINED +#define SkOSWindow_SDL_DEFINED + +#include "SDL.h" +#include "SkWindow.h" + +class SkGLCanvas; + +class SkOSWindow : public SkWindow { +public: + SkOSWindow(void* screen); + virtual ~SkOSWindow(); + + static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay); + + void handleSDLEvent(const SDL_Event& event); + +protected: + // overrides from SkWindow + virtual void onHandleInval(const SkIRect&); + // overrides from SkView + virtual void onAddMenu(const SkOSMenu*); + virtual void onSetTitle(const char[]); + +private: + SDL_Surface* fScreen; + SDL_Surface* fSurface; + SkGLCanvas* fGLCanvas; + + void doDraw(); + + typedef SkWindow INHERITED; +}; + +#endif + diff --git a/include/views/SkOSWindow_Win.h b/include/views/SkOSWindow_Win.h index 0a70f75..09f0c5c 100644 --- a/include/views/SkOSWindow_Win.h +++ b/include/views/SkOSWindow_Win.h @@ -22,12 +22,23 @@ class SkOSWindow : public SkWindow { public: SkOSWindow(void* hwnd); + virtual ~SkOSWindow(); void* getHWND() const { return fHWND; } void setSize(int width, int height); void updateSize(); static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay); + + bool attachGL(const SkBitmap* offscreen); + void detachGL(); + void presentGL(); + + bool attachD3D9(); + void detachD3D9(); + void presentD3D9(); + + void* d3d9Device() { return fD3D9Device; } bool wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); static bool QuitOnDeactivate(HWND hWnd); @@ -45,14 +56,23 @@ protected: // overrides from SkView virtual void onAddMenu(const SkOSMenu*); + virtual void onSetTitle(const char title[]); + private: - void* fHWND; + void* fHWND; + + void doPaint(void* ctx); + + void* fHGLRC; + + bool fGLAttached; - void doPaint(void* ctx); + void* fD3D9Device; + bool fD3D9Attached; - HMENU fMBar; + HMENU fMBar; - typedef SkWindow INHERITED; + typedef SkWindow INHERITED; }; #endif diff --git a/include/views/SkView.h b/include/views/SkView.h index fc36d34..d3633db 100644 --- a/include/views/SkView.h +++ b/include/views/SkView.h @@ -38,6 +38,7 @@ public: kFocusable_Shift, kFlexH_Shift, kFlexV_Shift, + kNoClip_Shift, kFlagShiftCount }; @@ -47,6 +48,7 @@ public: kFocusable_Mask = 1 << kFocusable_Shift, //!< set if the view can receive focus kFlexH_Mask = 1 << kFlexH_Shift, //!< set if the view's width is stretchable kFlexV_Mask = 1 << kFlexV_Shift, //!< set if the view's height is stretchable + kNoClip_Mask = 1 << kNoClip_Shift, //!< set if the view is not clipped to its bounds kAllFlagMasks = (uint32_t)(0 - 1) >> (32 - kFlagShiftCount) }; @@ -66,10 +68,12 @@ public: int isVisible() const { return fFlags & kVisible_Mask; } int isEnabled() const { return fFlags & kEnabled_Mask; } int isFocusable() const { return fFlags & kFocusable_Mask; } + int isClipToBounds() const { return !(fFlags & kNoClip_Mask); } /** Helper to set/clear the view's kVisible_Mask flag */ void setVisibleP(bool); void setEnabledP(bool); void setFocusableP(bool); + void setClipToBounds(bool); /** Return the view's width */ SkScalar width() const { return fWidth; } @@ -302,7 +306,7 @@ protected: Tyically this is only overridden by the by the "window". If your subclass does handle the request, return true so the request will not continue to propogate to the parent. */ - virtual bool handleInval(const SkRect&); + virtual bool handleInval(const SkRect*); //! called once before all of the children are drawn (or clipped/translated) virtual SkCanvas* beforeChildren(SkCanvas* c) { return c; } //! called once after all of the children are drawn (or clipped/translated) diff --git a/include/views/SkWindow.h b/include/views/SkWindow.h index 1c8f9a3..5deefd5 100644 --- a/include/views/SkWindow.h +++ b/include/views/SkWindow.h @@ -19,6 +19,7 @@ #include "SkView.h" #include "SkBitmap.h" +#include "SkMatrix.h" #include "SkRegion.h" #include "SkEvent.h" #include "SkKey.h" @@ -29,6 +30,8 @@ #endif //#define USE_GX_SCREEN +class SkCanvas; + class SkOSMenu; class SkWindow : public SkView { @@ -44,7 +47,13 @@ public: void eraseRGB(U8CPU r, U8CPU g, U8CPU b); bool isDirty() const { return !fDirtyRgn.isEmpty(); } - bool update(SkIRect* updateArea); + bool update(SkIRect* updateArea, SkCanvas* = NULL); + // does not call through to onHandleInval(), but does force the fDirtyRgn + // to be wide open. Call before update() to ensure we redraw everything. + void forceInvalAll(); + // return the bounds of the dirty/inval rgn, or [0,0,0,0] if none + const SkIRect& getDirtyBounds() const { return fDirtyRgn.getBounds(); } + bool handleClick(int x, int y, Click::State); bool handleChar(SkUnichar); bool handleKey(SkKey); @@ -56,6 +65,11 @@ public: const char* getTitle() const { return fTitle.c_str(); } void setTitle(const char title[]); + const SkMatrix& getMatrix() const { return fMatrix; } + void setMatrix(const SkMatrix&); + void preConcat(const SkMatrix&); + void postConcat(const SkMatrix&); + protected: virtual bool onEvent(const SkEvent&); @@ -68,7 +82,7 @@ protected: virtual void onSetTitle(const char title[]) {} // overrides from SkView - virtual bool handleInval(const SkRect&); + virtual bool handleInval(const SkRect*); virtual bool onGetFocusView(SkView** focus) const; virtual bool onSetFocusView(SkView* focus); @@ -84,6 +98,7 @@ private: bool fWaitingOnInval; SkString fTitle; + SkMatrix fMatrix; typedef SkView INHERITED; }; @@ -100,6 +115,8 @@ private: #include "SkOSWindow_Unix.h" #elif defined(SK_BUILD_FOR_SDL) #include "SkOSWindow_SDL.h" +#elif defined(SK_BUILD_FOR_IOS) + #include "SkOSWindow_iOS.h" #endif #endif |