Initial import of Cobalt 2.8885 2016-07-27
diff --git a/src/third_party/skia/include/animator/SkAnimator.h b/src/third_party/skia/include/animator/SkAnimator.h
new file mode 100644
index 0000000..9bb3642
--- /dev/null
+++ b/src/third_party/skia/include/animator/SkAnimator.h
@@ -0,0 +1,500 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkAnimator_DEFINED
+#define SkAnimator_DEFINED
+
+#include "SkScalar.h"
+#include "SkKey.h"
+#include "SkEventSink.h"
+
+class SkAnimateMaker;
+class SkCanvas;
+class SkDisplayable;
+class SkEvent;
+class SkExtras;
+struct SkMemberInfo;
+class SkPaint;
+struct SkRect;
+class SkStream;
+class SkTypedArray;
+class SkXMLParserError;
+class SkDOM;
+struct SkDOMNode;
+
+/** SkElementType is the type of element: a rectangle, a color, an animator, and so on.
+ This enum is incomplete and will be fleshed out in a future release */
+enum SkElementType {
+ kElementDummyType
+};
+/** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on.
+ This enum is incomplete and will be fleshed out in a future release */
+enum SkFieldType {
+ kFieldDummyType
+};
+
+/** \class SkAnimator
+
+ The SkAnimator class decodes an XML stream into a display list. The
+ display list can be drawn statically as a picture, or can drawn
+ different elements at different times to form a moving animation.
+
+ SkAnimator does not read the system time on its own; it relies on the
+ caller to pass the current time. The caller can pause, speed up, or
+ reverse the animation by varying the time passed in.
+
+ The XML describing the display list must conform to the schema
+ described by SkAnimateSchema.xsd.
+
+ The XML must contain an <event> element to draw. Usually, it contains
+ an <event kind="onload" /> block to add some drawing elements to the
+ display list when the document is first decoded.
+
+ Here's an "Hello World" XML sample:
+
+ <screenplay>
+ <event kind="onload" >
+ <text text="Hello World" y="20" />
+ </event>
+ </screenplay>
+
+ To read and draw this sample:
+
+ // choose one of these two
+ SkAnimator animator; // declare an animator instance on the stack
+ // SkAnimator* animator = new SkAnimator() // or one could instantiate the class
+
+ // choose one of these three
+ animator.decodeMemory(buffer, size); // to read from RAM
+ animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file)
+ animator.decodeURI(filename); // to read from a web location, or from a local text file
+
+ // to draw to the current window:
+ SkCanvas canvas(getBitmap()); // create a canvas
+ animator.draw(canvas, &paint, 0); // draw the scene
+*/
+class SkAnimator : public SkEventSink {
+public:
+ SkAnimator();
+ virtual ~SkAnimator();
+
+ /** Add a drawable extension to the graphics engine. Experimental.
+ @param extras A derived class that implements methods that identify and instantiate the class
+ */
+ void addExtras(SkExtras* extras);
+
+ /** Read in XML from a stream, and append it to the current
+ animator. Returns false if an error was encountered.
+ Error diagnostics are stored in fErrorCode and fLineNumber.
+ @param stream The stream to append.
+ @return true if the XML was parsed successfully.
+ */
+ bool appendStream(SkStream* stream);
+
+ /** Read in XML from memory. Returns true if the file can be
+ read without error. Returns false if an error was encountered.
+ Error diagnostics are stored in fErrorCode and fLineNumber.
+ @param buffer The XML text as UTF-8 characters.
+ @param size The XML text length in bytes.
+ @return true if the XML was parsed successfully.
+ */
+ bool decodeMemory(const void* buffer, size_t size);
+
+ /** Read in XML from a stream. Returns true if the file can be
+ read without error. Returns false if an error was encountered.
+ Error diagnostics are stored in fErrorCode and fLineNumber.
+ @param stream The stream containg the XML text as UTF-8 characters.
+ @return true if the XML was parsed successfully.
+ */
+ virtual bool decodeStream(SkStream* stream);
+
+ /** Parse the DOM tree starting at the specified node. Returns true if it can be
+ parsed without error. Returns false if an error was encountered.
+ Error diagnostics are stored in fErrorCode and fLineNumber.
+ @return true if the DOM was parsed successfully.
+ */
+ virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);
+
+ /** Read in XML from a URI. Returns true if the file can be
+ read without error. Returns false if an error was encountered.
+ Error diagnostics are stored in fErrorCode and fLineNumber.
+ @param uri The complete url path to be read (either ftp, http or https).
+ @return true if the XML was parsed successfully.
+ */
+ bool decodeURI(const char uri[]);
+
+ /** Pass a char event, usually a keyboard symbol, to the animator.
+ This triggers events of the form <event kind="keyChar" key="... />
+ @param ch The character to match against <event> element "key"
+ attributes.
+ @return true if the event was dispatched successfully.
+ */
+ bool doCharEvent(SkUnichar ch);
+
+ /** Experimental:
+ Pass a mouse click event along with the mouse coordinates to
+ the animator. This triggers events of the form <event kind="mouseDown" ... />
+ and other mouse events.
+ @param state The mouse state, described by SkView::Click::State : values are
+ down == 0, moved == 1, up == 2
+ @param x The x-position of the mouse
+ @param y The y-position of the mouse
+ @return true if the event was dispatched successfully.
+ */
+ bool doClickEvent(int state, SkScalar x, SkScalar y);
+
+ /** Pass a meta-key event, such as an arrow , to the animator.
+ This triggers events of the form <event kind="keyPress" code="... />
+ @param code The key to match against <event> element "code"
+ attributes.
+ @return true if the event was dispatched successfully.
+ */
+ bool doKeyEvent(SkKey code);
+ bool doKeyUpEvent(SkKey code);
+
+ /** Send an event to the animator. The animator's clock is set
+ relative to the current time.
+ @return true if the event was dispatched successfully.
+ */
+ bool doUserEvent(const SkEvent& evt);
+
+ /** The possible results from the draw function.
+ */
+ enum DifferenceType {
+ kNotDifferent,
+ kDifferent,
+ kPartiallyDifferent
+ };
+ /** Draws one frame of the animation. The first call to draw always
+ draws the initial frame of the animation. Subsequent calls draw
+ the offset into the animation by
+ subtracting the initial time from the current time.
+ @param canvas The canvas to draw into.
+ @param paint The paint to draw with.
+ @param time The offset into the current animation.
+ @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
+ kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
+ redraw area.
+ */
+ DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);
+
+ /** Draws one frame of the animation, using a new Paint each time.
+ The first call to draw always
+ draws the initial frame of the animation. Subsequent calls draw
+ the offset into the animation by
+ subtracting the initial time from the current time.
+ @param canvas The canvas to draw into.
+ @param time The offset into the current animation.
+ @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
+ kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
+ redraw area.
+ */
+ DifferenceType draw(SkCanvas* canvas, SkMSec time);
+
+ /** Experimental:
+ Helper to choose whether to return a SkView::Click handler.
+ @param x ignored
+ @param y ignored
+ @return true if a mouseDown event handler is enabled.
+ */
+ bool findClickEvent(SkScalar x, SkScalar y);
+
+
+ /** Get the nested animator associated with this element, if any.
+ Use this to access a movie's event sink, to send events to movies.
+ @param element the value returned by getElement
+ @return the internal animator.
+ */
+ const SkAnimator* getAnimator(const SkDisplayable* element) const;
+
+ /** Returns the scalar value of the specified element's attribute[index]
+ @param element the value returned by getElement
+ @param field the value returned by getField
+ @param index the array entry
+ @return the integer value to retrieve, or SK_NaN32 if unsuccessful
+ */
+ int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);
+
+ /** Returns the scalar value of the specified element's attribute[index]
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param index the array entry
+ @return the integer value to retrieve, or SK_NaN32 if unsuccessful
+ */
+ int32_t getArrayInt(const char* elementID, const char* fieldName, int index);
+
+ /** Returns the scalar value of the specified element's attribute[index]
+ @param element the value returned by getElement
+ @param field the value returned by getField
+ @param index the array entry
+ @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
+ */
+ SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);
+
+ /** Returns the scalar value of the specified element's attribute[index]
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param index the array entry
+ @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
+ */
+ SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);
+
+ /** Returns the string value of the specified element's attribute[index]
+ @param element is a value returned by getElement
+ @param field is a value returned by getField
+ @param index the array entry
+ @return the string value to retrieve, or null if unsuccessful
+ */
+ const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);
+
+ /** Returns the string value of the specified element's attribute[index]
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param index the array entry
+ @return the string value to retrieve, or null if unsuccessful
+ */
+ const char* getArrayString(const char* elementID, const char* fieldName, int index);
+
+ /** Returns the XML element corresponding to the given ID.
+ @param elementID is the value of the id attribute in the XML of this element
+ @return the element matching the ID, or null if the element can't be found
+ */
+ const SkDisplayable* getElement(const char* elementID);
+
+ /** Returns the element type corresponding to the XML element.
+ The element type matches the element name; for instance, <line> returns kElement_LineType
+ @param element is a value returned by getElement
+ @return element type, or 0 if the element can't be found
+ */
+ SkElementType getElementType(const SkDisplayable* element);
+
+ /** Returns the element type corresponding to the given ID.
+ @param elementID is the value of the id attribute in the XML of this element
+ @return element type, or 0 if the element can't be found
+ */
+ SkElementType getElementType(const char* elementID);
+
+ /** Returns the XML field of the named attribute in the XML element.
+ @param element is a value returned by getElement
+ @param fieldName is the attribute to return
+ @return the attribute matching the fieldName, or null if the element can't be found
+ */
+ const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);
+
+ /** Returns the XML field of the named attribute in the XML element matching the elementID.
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName is the attribute to return
+ @return the attribute matching the fieldName, or null if the element can't be found
+ */
+ const SkMemberInfo* getField(const char* elementID, const char* fieldName);
+
+ /** Returns the value type coresponding to the element's attribute.
+ The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
+ @param field is a value returned by getField
+ @return the attribute type, or 0 if the element can't be found
+ */
+ SkFieldType getFieldType(const SkMemberInfo* field);
+
+ /** Returns the value type coresponding to the element's attribute.
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @return the attribute type, or 0 if the element can't be found
+ */
+ SkFieldType getFieldType(const char* elementID, const char* fieldName);
+
+ /** Returns the recommended animation interval. Returns zero if no
+ interval is specified.
+ */
+ SkMSec getInterval();
+
+ /** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
+ kIsPartiallyDifferent to do a mimimal inval(). */
+ void getInvalBounds(SkRect* inval);
+
+ /** Returns the details of any error encountered while parsing the XML.
+ */
+ const SkXMLParserError* getParserError();
+
+ /** Returns the details of any error encountered while parsing the XML as string.
+ */
+ const char* getParserErrorString();
+
+ /** Returns the scalar value of the specified element's attribute
+ @param element is a value returned by getElement
+ @param field is a value returned by getField
+ @return the integer value to retrieve, or SK_NaN32 if not found
+ */
+ int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);
+
+ /** Returns the scalar value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @return the integer value to retrieve, or SK_NaN32 if not found
+ */
+ int32_t getInt(const char* elementID, const char* fieldName);
+
+ /** Returns the scalar value of the specified element's attribute
+ @param element is a value returned by getElement
+ @param field is a value returned by getField
+ @return the scalar value to retrieve, or SK_ScalarNaN if not found
+ */
+ SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);
+
+ /** Returns the scalar value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @return the scalar value to retrieve, or SK_ScalarNaN if not found
+ */
+ SkScalar getScalar(const char* elementID, const char* fieldName);
+
+ /** Returns the string value of the specified element's attribute
+ @param element is a value returned by getElement
+ @param field is a value returned by getField
+ @return the string value to retrieve, or null if not found
+ */
+ const char* getString(const SkDisplayable* element, const SkMemberInfo* field);
+
+ /** Returns the string value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @return the string value to retrieve, or null if not found
+ */
+ const char* getString(const char* elementID, const char* fieldName);
+
+ /** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
+ const char* getURIBase();
+
+ /** Resets the animator to a newly created state with no animation data. */
+ void initialize();
+
+ /** Experimental. Resets any active animations so that the next time passed is treated as
+ time zero. */
+ void reset();
+
+ /** Sets the scalar value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param array is the c-style array of integers
+ @param count is the length of the array
+ @return true if the value was set successfully
+ */
+ bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);
+
+ /** Sets the scalar value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param array is the c-style array of strings
+ @param count is the length of the array
+ @return true if the value was set successfully
+ */
+ bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);
+
+ /** Sets the scalar value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param data the integer value to set
+ @return true if the value was set successfully
+ */
+ bool setInt(const char* elementID, const char* fieldName, int32_t data);
+
+ /** Sets the scalar value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param data the scalar value to set
+ @return true if the value was set successfully
+ */
+ bool setScalar(const char* elementID, const char* fieldName, SkScalar data);
+
+ /** Sets the string value of the specified element's attribute
+ @param elementID is the value of the id attribute in the XML of this element
+ @param fieldName specifies the name of the attribute
+ @param data the string value to set
+ @return true if the value was set successfully
+ */
+ bool setString(const char* elementID, const char* fieldName, const char* data);
+
+ /** Sets the file default directory of the URL base path
+ @param path the directory path
+ */
+ void setURIBase(const char* path);
+
+ typedef void* Handler;
+ // This guy needs to be exported to java, so don't make it virtual
+ void setHostHandler(Handler handler) {
+ this->onSetHostHandler(handler);
+ }
+
+ /** \class Timeline
+ Returns current time to animator. To return a custom timeline, create a child
+ class and override the getMSecs method.
+ */
+ class Timeline {
+ public:
+ virtual ~Timeline() {}
+
+ /** Returns the current time in milliseconds */
+ virtual SkMSec getMSecs() const = 0;
+ };
+
+ /** Sets a user class to return the current time to the animator.
+ Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead.
+ @param callBack the time function
+ */
+ void setTimeline(const Timeline& );
+
+ static void Init(bool runUnitTests);
+ static void Term();
+
+ /** The event sink events generated by the animation are posted to.
+ Screenplay also posts an inval event to this event sink after processing an
+ event to force a redraw.
+ @param target the event sink id
+ */
+ void setHostEventSinkID(SkEventSinkID hostID);
+ SkEventSinkID getHostEventSinkID() const;
+
+ // helper
+ void setHostEventSink(SkEventSink* sink) {
+ this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
+ }
+
+ virtual void setJavaOwner(Handler owner);
+
+#ifdef SK_DEBUG
+ virtual void eventDone(const SkEvent& evt);
+ virtual bool isTrackingEvents();
+ static bool NoLeaks();
+#endif
+
+protected:
+ virtual void onSetHostHandler(Handler handler);
+ virtual void onEventPost(SkEvent*, SkEventSinkID);
+ virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);
+
+private:
+// helper functions for setters
+ bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
+ bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
+ bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
+ bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
+ bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);
+
+ virtual bool onEvent(const SkEvent&);
+ SkAnimateMaker* fMaker;
+ friend class SkAnimateMaker;
+ friend class SkAnimatorScript;
+ friend class SkAnimatorScript2;
+ friend class SkApply;
+ friend class SkDisplayMovie;
+ friend class SkDisplayType;
+ friend class SkPost;
+ friend class SkXMLAnimatorWriter;
+};
+
+#endif
diff --git a/src/third_party/skia/include/animator/SkAnimatorView.h b/src/third_party/skia/include/animator/SkAnimatorView.h
new file mode 100644
index 0000000..2b2c61b
--- /dev/null
+++ b/src/third_party/skia/include/animator/SkAnimatorView.h
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkAnimatorView_DEFINED
+#define SkAnimatorView_DEFINED
+
+#include "SkView.h"
+#include "SkAnimator.h"
+
+class SkAnimatorView : public SkView {
+public:
+ SkAnimatorView();
+ virtual ~SkAnimatorView();
+
+ SkAnimator* getAnimator() const { return fAnimator; }
+
+ bool decodeFile(const char path[]);
+ bool decodeMemory(const void* buffer, size_t size);
+ bool decodeStream(SkStream* stream);
+
+protected:
+ // overrides
+ virtual bool onEvent(const SkEvent&);
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+
+private:
+ SkAnimator* fAnimator;
+
+ typedef SkView INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/config/SkUserConfig.h b/src/third_party/skia/include/config/SkUserConfig.h
new file mode 100644
index 0000000..5f59b91
--- /dev/null
+++ b/src/third_party/skia/include/config/SkUserConfig.h
@@ -0,0 +1,181 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#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.
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+
+/* 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
+
+/* Skia has certain debug-only code that is extremely intensive even for debug
+ builds. This code is useful for diagnosing specific issues, but is not
+ generally applicable, therefore it must be explicitly enabled to avoid
+ the performance impact. By default these flags are undefined, but can be
+ enabled by uncommenting them below.
+ */
+//#define SK_DEBUG_GLYPH_CACHE
+//#define SK_DEBUG_PATH
+
+/* To assist debugging, Skia provides an instance counting utility in
+ include/core/SkInstCount.h. This flag turns on and off that utility to
+ allow instance count tracking in either debug or release builds. By
+ default it is enabled in debug but disabled in release.
+ */
+//#define SK_ENABLE_INST_COUNT 1
+
+/* 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
+
+/* Most compilers use the same bit endianness for bit flags in a byte as the
+ system byte endianness, and this is the default. If for some reason this
+ needs to be overridden, specify which of the mutually exclusive flags to
+ use. For example, some atom processors in certain configurations have big
+ endian byte order but little endian bit orders.
+*/
+//#define SK_UINT8_BITFIELD_BENDIAN
+//#define SK_UINT8_BITFIELD_LENDIAN
+
+
+/* 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 specify a different default font cache limit, define this. If this is
+ * undefined, skia will use a built-in value.
+ */
+//#define SK_DEFAULT_FONT_CACHE_LIMIT (1024 * 1024)
+
+/*
+ * To specify the default size of the image cache, undefine this and set it to
+ * the desired value (in bytes). SkGraphics.h as a runtime API to set this
+ * value as well. If this is undefined, a built-in value will be used.
+ */
+//#define SK_DEFAULT_IMAGE_CACHE_LIMIT (1024 * 1024)
+
+/* 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. Alternatively, define SK_SYSTEM_ZLIB to use the system zlib
+ library specified as "#include <zlib.h>".
+ */
+//#define SK_ZLIB_INCLUDE <zlib.h>
+//#define SK_SYSTEM_ZLIB
+
+/* Define this to allow PDF scalars above 32k. The PDF/A spec doesn't allow
+ them, but modern PDF interpreters should handle them just fine.
+ */
+//#define SK_ALLOW_LARGE_PDF_SCALARS
+
+/* Define this to provide font subsetter in PDF generation.
+ */
+//#define SK_SFNTLY_SUBSETTER "sfntly/subsetter/font_subsetter.h"
+
+/* Define this to set the upper limit for text to support LCD. Values that
+ are very large increase the cost in the font cache and draw slower, without
+ improving readability. If this is undefined, Skia will use its default
+ value (e.g. 48)
+ */
+//#define SK_MAX_SIZE_FOR_LCDTEXT 48
+
+/* 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
+
+/* Change the ordering to work in X windows.
+ */
+#ifdef SK_SAMPLES_FOR_X
+ #define SK_R32_SHIFT 16
+ #define SK_G32_SHIFT 8
+ #define SK_B32_SHIFT 0
+ #define SK_A32_SHIFT 24
+#endif
+
+
+/* Determines whether to build code that supports the GPU backend. Some classes
+ that are not GPU-specific, such as SkShader subclasses, have optional code
+ that is used allows them to interact with the GPU backend. If you'd like to
+ omit this code set SK_SUPPORT_GPU to 0. This also allows you to omit the gpu
+ directories from your include search path when you're not building the GPU
+ backend. Defaults to 1 (build the GPU code).
+ */
+//#define SK_SUPPORT_GPU 1
+
+
+/* The PDF generation code uses Path Ops to generate inverse fills and complex
+ * clipping paths, but at this time, Path Ops is not release ready yet. So,
+ * the code is hidden behind this #define guard. If you are feeling adventurous
+ * and want the latest and greatest PDF generation code, uncomment the #define.
+ * When Path Ops is release ready, the define guards and this user config
+ * define should be removed entirely.
+ */
+//#define SK_PDF_USE_PATHOPS
+
+/* Skia uses these defines as the target of include preprocessor directives.
+ * The header files pointed to by these defines provide declarations and
+ * possibly inline implementations of threading primitives.
+ *
+ * See SkThread.h for documentation on what these includes must contain.
+ */
+//#define SK_ATOMICS_PLATFORM_H "SkAtomics_xxx.h"
+//#define SK_MUTEX_PLATFORM_H "SkMutex_xxx.h"
+//#define SK_BARRIERS_PLATFORM_H "SkBarriers_xxx.h"
+
+#endif
diff --git a/src/third_party/skia/include/core/SkAdvancedTypefaceMetrics.h b/src/third_party/skia/include/core/SkAdvancedTypefaceMetrics.h
new file mode 100644
index 0000000..1192688
--- /dev/null
+++ b/src/third_party/skia/include/core/SkAdvancedTypefaceMetrics.h
@@ -0,0 +1,162 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkAdvancedTypefaceMetrics_DEFINED
+#define SkAdvancedTypefaceMetrics_DEFINED
+
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+#include "SkTDArray.h"
+#include "SkTemplates.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:
+ SK_DECLARE_INST_COUNT(SkAdvancedTypefaceMetrics)
+
+ SkString fFontName;
+
+ enum FontType {
+ kType1_Font,
+ kType1CID_Font,
+ kCFF_Font,
+ kTrueType_Font,
+ kOther_Font,
+ };
+ // The type of the underlying font program. This field determines which
+ // of the following fields are valid. If it is kOther_Font the per glyph
+ // information will never be populated.
+ FontType fType;
+
+ enum FontFlags {
+ kEmpty_FontFlag = 0x0, //!<No flags set
+ kMultiMaster_FontFlag = 0x1, //!<May be true for Type1 or CFF fonts.
+ kNotEmbeddable_FontFlag = 0x2, //!<May not be embedded.
+ kNotSubsettable_FontFlag = 0x4, //!<May not be subset.
+ };
+ // Global font flags.
+ FontFlags fFlags;
+
+ 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,
+ kScript_Style = 0x00008,
+ 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).
+
+ // The type of advance data wanted.
+ enum PerGlyphInfo {
+ kNo_PerGlyphInfo = 0x0, // Don't populate any per glyph info.
+ kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data.
+ kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data.
+ kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only).
+ kToUnicode_PerGlyphInfo = 0x8 // Populate ToUnicode table, ignored
+ // for Type 1 fonts
+ };
+
+ 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;
+ SkAutoTDelete<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.
+ SkAutoTDelete<WidthRange> fGlyphWidths;
+ // Only used for Vertical CID fonts.
+ SkAutoTDelete<VerticalAdvanceRange> fVerticalMetrics;
+
+ // The names of each glyph, only populated for postscript fonts.
+ SkAutoTDelete<SkAutoTArray<SkString> > fGlyphNames;
+
+ // The mapping from glyph to Unicode, only populated if
+ // kToUnicode_PerGlyphInfo is passed to GetAdvancedTypefaceMetrics.
+ SkTDArray<SkUnichar> fGlyphToUnicode;
+
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+namespace skia_advanced_typeface_metrics_utils {
+
+template <typename Data>
+void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
+ int startId);
+
+template <typename Data>
+SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
+ SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
+ int startId);
+
+template <typename Data>
+void finishRange(
+ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
+ int endId,
+ typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
+ type);
+
+/** Retrieve advance data for glyphs. Used by the PDF backend. It calls
+ underlying platform dependent API getAdvance to acquire the data.
+ @param num_glyphs Total number of glyphs in the given font.
+ @param glyphIDs For per-glyph info, specify subset of the font by
+ giving glyph ids. Each integer represents a glyph
+ id. Passing NULL means all glyphs in the font.
+ @param glyphIDsCount Number of elements in subsetGlyphIds. Ignored if
+ glyphIDs is NULL.
+*/
+template <typename Data, typename FontHandle>
+SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
+ FontHandle fontHandle,
+ int num_glyphs,
+ const uint32_t* glyphIDs,
+ uint32_t glyphIDsCount,
+ bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data));
+
+} // namespace skia_advanced_typeface_metrics_utils
+
+#endif
diff --git a/src/third_party/skia/include/core/SkAnnotation.h b/src/third_party/skia/include/core/SkAnnotation.h
new file mode 100644
index 0000000..d7b9b84
--- /dev/null
+++ b/src/third_party/skia/include/core/SkAnnotation.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkAnnotation_DEFINED
+#define SkAnnotation_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+class SkData;
+class SkReadBuffer;
+class SkWriteBuffer;
+class SkStream;
+class SkWStream;
+struct SkPoint;
+
+/**
+ * Experimental class for annotating draws. Do not use directly yet.
+ * Use helper functions at the bottom of this file for now.
+ */
+class SkAnnotation : public SkRefCnt {
+public:
+ virtual ~SkAnnotation();
+
+ static SkAnnotation* Create(const char key[], SkData* value) {
+ return SkNEW_ARGS(SkAnnotation, (key, value));
+ }
+
+ static SkAnnotation* Create(SkReadBuffer& buffer) {
+ return SkNEW_ARGS(SkAnnotation, (buffer));
+ }
+
+ /**
+ * Return the data for the specified key, or NULL.
+ */
+ SkData* find(const char key[]) const;
+
+ void writeToBuffer(SkWriteBuffer&) const;
+
+private:
+ SkAnnotation(const char key[], SkData* value);
+ SkAnnotation(SkReadBuffer&);
+
+ SkString fKey;
+ SkData* fData;
+
+ typedef SkRefCnt INHERITED;
+};
+
+/**
+ * Experimental collection of predefined Keys into the Annotation dictionary
+ */
+class SkAnnotationKeys {
+public:
+ /**
+ * Returns the canonical key whose payload is a URL
+ */
+ static const char* URL_Key();
+
+ /**
+ * Returns the canonical key whose payload is the name of a destination to
+ * be defined.
+ */
+ static const char* Define_Named_Dest_Key();
+
+ /**
+ * Returns the canonical key whose payload is the name of a destination to
+ * be linked to.
+ */
+ static const char* Link_Named_Dest_Key();
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Experimental helper functions to use Annotations
+//
+
+struct SkRect;
+class SkCanvas;
+
+/**
+ * Experimental!
+ *
+ * Annotate the canvas by associating the specified URL with the
+ * specified rectangle (in local coordinates, just like drawRect). If the
+ * backend of this canvas does not support annotations, this call is
+ * safely ignored.
+ *
+ * The caller is responsible for managing its ownership of the SkData.
+ */
+SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
+
+/**
+ * Experimental!
+ *
+ * Annotate the canvas by associating a name with the specified point.
+ *
+ * If the backend of this canvas does not support annotations, this call is
+ * safely ignored.
+ *
+ * The caller is responsible for managing its ownership of the SkData.
+ */
+SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*);
+
+/**
+ * Experimental!
+ *
+ * Annotate the canvas by making the specified rectangle link to a named
+ * destination.
+ *
+ * If the backend of this canvas does not support annotations, this call is
+ * safely ignored.
+ *
+ * The caller is responsible for managing its ownership of the SkData.
+ */
+SK_API void SkAnnotateLinkToDestination(SkCanvas*, const SkRect&, SkData*);
+
+
+#endif
diff --git a/src/third_party/skia/include/core/SkBBHFactory.h b/src/third_party/skia/include/core/SkBBHFactory.h
new file mode 100644
index 0000000..67c9cd7
--- /dev/null
+++ b/src/third_party/skia/include/core/SkBBHFactory.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBBHFactory_DEFINED
+#define SkBBHFactory_DEFINED
+
+#include "SkSize.h"
+#include "SkPoint.h"
+
+class SkBBoxHierarchy;
+
+class SK_API SkBBHFactory {
+public:
+ /**
+ * Allocate a new SkBBoxHierarchy. Return NULL on failure.
+ */
+ virtual SkBBoxHierarchy* operator()(int width, int height) const = 0;
+ virtual ~SkBBHFactory() {};
+};
+
+class SK_API SkRTreeFactory : public SkBBHFactory {
+public:
+ virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
+private:
+ typedef SkBBHFactory INHERITED;
+};
+
+class SK_API SkTileGridFactory : public SkBBHFactory {
+public:
+ struct TileGridInfo {
+ /** Tile placement interval */
+ SkISize fTileInterval;
+
+ /** Pixel coverage overlap between adjacent tiles */
+ SkISize fMargin;
+
+ /** Offset added to device-space bounding box positions to convert
+ * them to tile-grid space. This can be used to adjust the "phase"
+ * of the tile grid to match probable query rectangles that will be
+ * used to search into the tile grid. As long as the offset is smaller
+ * or equal to the margin, there is no need to extend the domain of
+ * the tile grid to prevent data loss.
+ */
+ SkIPoint fOffset;
+ };
+
+ SkTileGridFactory(const TileGridInfo& info) : fInfo(info) { }
+
+ virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
+
+private:
+ TileGridInfo fInfo;
+
+ typedef SkBBHFactory INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkBitmap.h b/src/third_party/skia/include/core/SkBitmap.h
new file mode 100644
index 0000000..b36a1fd
--- /dev/null
+++ b/src/third_party/skia/include/core/SkBitmap.h
@@ -0,0 +1,883 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBitmap_DEFINED
+#define SkBitmap_DEFINED
+
+#include "SkColor.h"
+#include "SkColorTable.h"
+#include "SkImageInfo.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+
+#ifdef SK_SUPPORT_LEGACY_ALLOCPIXELS_BOOL
+ #define SK_ALLOCPIXELS_RETURN_TYPE bool
+ #define SK_ALLOCPIXELS_RETURN_TRUE return true
+ #define SK_ALLOCPIXELS_RETURN_FAIL return false
+#else
+ #define SK_ALLOCPIXELS_RETURN_TYPE void
+ #define SK_ALLOCPIXELS_RETURN_TRUE return
+ #define SK_ALLOCPIXELS_RETURN_FAIL sk_throw()
+#endif
+
+struct SkMask;
+struct SkIRect;
+struct SkRect;
+class SkPaint;
+class SkPixelRef;
+class SkPixelRefFactory;
+class SkRegion;
+class SkString;
+class GrTexture;
+
+/** \class SkBitmap
+
+ The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
+ and height, and a format (colortype), and a pointer to the actual pixels.
+ Bitmaps can be drawn into a SkCanvas, but they are also used to specify the
+ target of a SkCanvas' drawing operations.
+ A const SkBitmap exposes getAddr(), which lets a caller write its pixels;
+ the constness is considered to apply to the bitmap's configuration, not
+ its contents.
+*/
+class SK_API SkBitmap {
+public:
+ class SK_API Allocator;
+
+ /**
+ * Default construct creates a bitmap with zero width and height, and no pixels.
+ * Its colortype is set to kUnknown_SkColorType.
+ */
+ SkBitmap();
+
+ /**
+ * Copy the settings from the src into this bitmap. If the src has pixels
+ * allocated, they will be shared, not copied, so that the two bitmaps will
+ * reference the same memory for the pixels. If a deep copy is needed,
+ * where the new bitmap has its own separate copy of the pixels, use
+ * deepCopyTo().
+ */
+ SkBitmap(const SkBitmap& src);
+
+ ~SkBitmap();
+
+ /** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
+ with the src bitmap.
+ */
+ SkBitmap& operator=(const SkBitmap& src);
+ /** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
+ */
+ // This method is not exported to java.
+ void swap(SkBitmap& other);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ const SkImageInfo& info() const { return fInfo; }
+
+ int width() const { return fInfo.width(); }
+ int height() const { return fInfo.height(); }
+ SkColorType colorType() const { return fInfo.colorType(); }
+ SkAlphaType alphaType() const { return fInfo.alphaType(); }
+
+ /**
+ * Return the number of bytes per pixel based on the colortype. If the colortype is
+ * kUnknown_SkColorType, then 0 is returned.
+ */
+ int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
+
+ /**
+ * Return the rowbytes expressed as a number of pixels (like width and height).
+ * If the colortype is kUnknown_SkColorType, then 0 is returned.
+ */
+ int rowBytesAsPixels() const {
+ return fRowBytes >> this->shiftPerPixel();
+ }
+
+ /**
+ * Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
+ * colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
+ */
+ int shiftPerPixel() const { return this->bytesPerPixel() >> 1; }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** Return true iff the bitmap has empty dimensions.
+ * Hey! Before you use this, see if you really want to know drawsNothing() instead.
+ */
+ bool empty() const { return fInfo.isEmpty(); }
+
+ /** Return true iff the bitmap has no pixelref. Note: this can return true even if the
+ * dimensions of the bitmap are > 0 (see empty()).
+ * Hey! Before you use this, see if you really want to know drawsNothing() instead.
+ */
+ bool isNull() const { return NULL == fPixelRef; }
+
+ /** Return true iff drawing this bitmap has no effect.
+ */
+ bool drawsNothing() const { return this->empty() || this->isNull(); }
+
+ /** Return the number of bytes between subsequent rows of the bitmap. */
+ size_t rowBytes() const { return fRowBytes; }
+
+ /**
+ * Set the bitmap's alphaType, returning true on success. If false is
+ * returned, then the specified new alphaType is incompatible with the
+ * colortype, and the current alphaType is unchanged.
+ *
+ * Note: this changes the alphatype for the underlying pixels, which means
+ * that all bitmaps that might be sharing (subsets of) the pixels will
+ * be affected.
+ */
+ bool setAlphaType(SkAlphaType);
+
+ /** Return the address of the pixels for this SkBitmap.
+ */
+ void* getPixels() const { return fPixels; }
+
+ /** Return the byte size of the pixels, based on the height and rowBytes.
+ Note this truncates the result to 32bits. Call getSize64() to detect
+ if the real size exceeds 32bits.
+ */
+ size_t getSize() const { return fInfo.height() * 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 extractSubset has been called.
+ */
+ size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
+
+ /**
+ * Return the full size of the bitmap, in bytes.
+ */
+ int64_t computeSize64() const {
+ return sk_64_mul(fInfo.height(), fRowBytes);
+ }
+
+ /**
+ * Return the number of bytes from the pointer returned by getPixels()
+ * to the end of the allocated space in the buffer. This may be smaller
+ * than computeSize64() if there is any rowbytes padding beyond the width.
+ */
+ int64_t computeSafeSize64() const {
+ return fInfo.getSafeSize64(fRowBytes);
+ }
+
+ /** Returns true if this bitmap is marked as immutable, meaning that the
+ contents of its pixels will not change for the lifetime of the bitmap.
+ */
+ bool isImmutable() const;
+
+ /** Marks this bitmap as immutable, meaning that the contents of its
+ pixels will not change for the lifetime of the bitmap and of the
+ underlying pixelref. This state can be set, but it cannot be
+ cleared once it is set. This state propagates to all other bitmaps
+ that share the same pixelref.
+ */
+ void setImmutable();
+
+ /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
+ */
+ bool isOpaque() const {
+ return SkAlphaTypeIsOpaque(this->alphaType());
+ }
+
+ /** Returns true if the bitmap is volatile (i.e. should not be cached by devices.)
+ */
+ bool isVolatile() const;
+
+ /** Specify whether this bitmap is volatile. Bitmaps are not volatile by
+ default. Temporary bitmaps that are discarded after use should be
+ marked as volatile. This provides a hint to the device that the bitmap
+ should not be cached. Providing this hint when appropriate can
+ improve performance by avoiding unnecessary overhead and resource
+ consumption on the device.
+ */
+ void setIsVolatile(bool);
+
+ /** Reset the bitmap to its initial state (see default constructor). If we are a (shared)
+ owner of the pixels, that ownership is decremented.
+ */
+ void reset();
+
+ /**
+ * This will brute-force return true if all of the pixels in the bitmap
+ * are opaque. If it fails to read the pixels, or encounters an error,
+ * it will return false.
+ *
+ * Since this can be an expensive operation, the bitmap stores a flag for
+ * this (isOpaque). Only call this if you need to compute this value from
+ * "unknown" pixels.
+ */
+ static bool ComputeIsOpaque(const SkBitmap&);
+
+ /**
+ * Return the bitmap's bounds [0, 0, width, height] as an SkRect
+ */
+ void getBounds(SkRect* bounds) const;
+ void getBounds(SkIRect* bounds) const;
+
+ bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
+
+ /**
+ * Allocate the bitmap's pixels to match the requested image info. If the Factory
+ * is non-null, call it to allcoate the pixelref. If the ImageInfo requires
+ * a colortable, then ColorTable must be non-null, and will be ref'd.
+ * On failure, the bitmap will be set to empty and return false.
+ */
+ bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
+
+ SK_ALLOCPIXELS_RETURN_TYPE allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory,
+ SkColorTable* ctable) {
+ if (!this->tryAllocPixels(info, factory, ctable)) {
+ SK_ALLOCPIXELS_RETURN_FAIL;
+ }
+ SK_ALLOCPIXELS_RETURN_TRUE;
+ }
+
+ /**
+ * Allocate the bitmap's pixels to match the requested image info and
+ * rowBytes. If the request cannot be met (e.g. the info is invalid or
+ * the requested rowBytes are not compatible with the info
+ * (e.g. rowBytes < info.minRowBytes() or rowBytes is not aligned with
+ * the pixel size specified by info.colorType()) then false is returned
+ * and the bitmap is set to empty.
+ */
+ bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes);
+
+ SK_ALLOCPIXELS_RETURN_TYPE allocPixels(const SkImageInfo& info, size_t rowBytes) {
+ if (!this->tryAllocPixels(info, rowBytes)) {
+ SK_ALLOCPIXELS_RETURN_FAIL;
+ }
+ SK_ALLOCPIXELS_RETURN_TRUE;
+ }
+
+ bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) {
+ return this->tryAllocPixels(info, info.minRowBytes());
+ }
+
+ SK_ALLOCPIXELS_RETURN_TYPE allocPixels(const SkImageInfo& info) {
+ return this->allocPixels(info, info.minRowBytes());
+ }
+
+ bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) {
+ SkImageInfo info = SkImageInfo::MakeN32(width, height,
+ isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+ return this->tryAllocPixels(info);
+ }
+
+ SK_ALLOCPIXELS_RETURN_TYPE allocN32Pixels(int width, int height, bool isOpaque = false) {
+ SkImageInfo info = SkImageInfo::MakeN32(width, height,
+ isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+ return this->allocPixels(info);
+ }
+
+ /**
+ * Install a pixelref that wraps the specified pixels and rowBytes, and
+ * optional ReleaseProc and context. When the pixels are no longer
+ * referenced, if releaseProc is not null, it will be called with the
+ * pixels and context as parameters.
+ * On failure, the bitmap will be set to empty and return false.
+ */
+ bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*,
+ void (*releaseProc)(void* addr, void* context), void* context);
+
+ /**
+ * Call installPixels with no ReleaseProc specified. This means that the
+ * caller must ensure that the specified pixels are valid for the lifetime
+ * of the created bitmap (and its pixelRef).
+ */
+ bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
+ return this->installPixels(info, pixels, rowBytes, NULL, NULL, NULL);
+ }
+
+ /**
+ * Calls installPixels() with the value in the SkMask. The caller must
+ * ensure that the specified mask pixels are valid for the lifetime
+ * of the created bitmap (and its pixelRef).
+ */
+ bool installMaskPixels(const SkMask&);
+
+ /** Use this to assign a new pixel address for an existing bitmap. This
+ will automatically release any pixelref previously installed. Only call
+ this if you are handling ownership/lifetime of the pixel memory.
+
+ If the bitmap retains a reference to the colortable (assuming it is
+ not null) it will take care of incrementing the reference count.
+
+ @param pixels Address for the pixels, managed by the caller.
+ @param ctable ColorTable (or null) that matches the specified pixels
+ */
+ 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 case when the dstRowBytes matches the bitmap's rowBytes, the copy
+ may be made faster by copying over the dst's per-row padding (for all
+ rows but the last). By setting preserveDstPad to true the caller can
+ disable this optimization and ensure that pixels in the padding are not
+ overwritten.
+
+ 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 0, uses
+ bitmap's internal stride.
+ @param preserveDstPad Must we preserve padding in the dst
+ */
+ bool copyPixelsTo(void* const dst, size_t dstSize, size_t dstRowBytes = 0,
+ bool preserveDstPad = false) const;
+
+ /** Use the standard HeapAllocator to create the pixelref that manages the
+ pixel memory. It will be sized based on the current ImageInfo.
+ If this is called multiple times, a new pixelref object will be created
+ each time.
+
+ If the bitmap retains a reference to the colortable (assuming it is
+ not null) it will take care of incrementing the reference count.
+
+ @param ctable ColorTable (or null) to use with the pixels that will
+ be allocated. Only used if colortype == kIndex_8_SkColorType
+ @return true if the allocation succeeds. If not the pixelref field of
+ the bitmap will be unchanged.
+ */
+ bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable* ctable = NULL) {
+ return this->tryAllocPixels(NULL, ctable);
+ }
+
+ SK_ALLOCPIXELS_RETURN_TYPE allocPixels(SkColorTable* ctable = NULL) {
+ return this->allocPixels(NULL, ctable);
+ }
+
+ /** Use the specified Allocator to create the pixelref that manages the
+ pixel memory. It will be sized based on the current ImageInfo.
+ If this is called multiple times, a new pixelref object will be created
+ each time.
+
+ If the bitmap retains a reference to the colortable (assuming it is
+ not null) it will take care of incrementing the reference count.
+
+ @param allocator The Allocator to use to create a pixelref that can
+ manage the pixel memory for the current ImageInfo.
+ If allocator is NULL, the standard HeapAllocator will be used.
+ @param ctable ColorTable (or null) to use with the pixels that will
+ be allocated. Only used if colortype == kIndex_8_SkColorType.
+ If it is non-null and the colortype is not indexed, it will
+ be ignored.
+ @return true if the allocation succeeds. If not the pixelref field of
+ the bitmap will be unchanged.
+ */
+ bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable* ctable);
+
+ SK_ALLOCPIXELS_RETURN_TYPE allocPixels(Allocator* allocator, SkColorTable* ctable) {
+ if (!this->tryAllocPixels(allocator, ctable)) {
+ SK_ALLOCPIXELS_RETURN_FAIL;
+ }
+ SK_ALLOCPIXELS_RETURN_TRUE;
+ }
+
+ /**
+ * Return the current pixelref object or NULL if there is none. This does
+ * not affect the refcount of the pixelref.
+ */
+ SkPixelRef* pixelRef() const { return fPixelRef; }
+
+ /**
+ * A bitmap can reference a subset of a pixelref's pixels. That means the
+ * bitmap's width/height can be <= the dimensions of the pixelref. The
+ * pixelref origin is the x,y location within the pixelref's pixels for
+ * the bitmap's top/left corner. To be valid the following must be true:
+ *
+ * origin_x + bitmap_width <= pixelref_width
+ * origin_y + bitmap_height <= pixelref_height
+ *
+ * pixelRefOrigin() returns this origin, or (0,0) if there is no pixelRef.
+ */
+ SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
+
+ /**
+ * Assign a pixelref and origin to the bitmap. Pixelrefs are reference,
+ * so the existing one (if any) will be unref'd and the new one will be
+ * ref'd. (x,y) specify the offset within the pixelref's pixels for the
+ * top/left corner of the bitmap. For a bitmap that encompases the entire
+ * pixels of the pixelref, these will be (0,0).
+ */
+ SkPixelRef* setPixelRef(SkPixelRef* pr, int dx, int dy);
+
+ SkPixelRef* setPixelRef(SkPixelRef* pr, const SkIPoint& origin) {
+ return this->setPixelRef(pr, origin.fX, origin.fY);
+ }
+
+ SkPixelRef* setPixelRef(SkPixelRef* pr) {
+ return this->setPixelRef(pr, 0, 0);
+ }
+
+ /** Call this to ensure that the bitmap points to the current pixel address
+ in the pixelref. Balance it with a call to unlockPixels(). These calls
+ are harmless if there is no pixelref.
+ */
+ void lockPixels() const;
+ /** When you are finished access the pixel memory, call this to balance a
+ previous call to lockPixels(). This allows pixelrefs that implement
+ cached/deferred image decoding to know when there are active clients of
+ a given image.
+ */
+ void unlockPixels() const;
+
+ /**
+ * Some bitmaps can return a copy of their pixels for lockPixels(), but
+ * that copy, if modified, will not be pushed back. These bitmaps should
+ * not be used as targets for a raster device/canvas (since all pixels
+ * modifications will be lost when unlockPixels() is called.)
+ */
+ bool lockPixelsAreWritable() const;
+
+ /** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
+ it has non-null pixels, and if required by its colortype, it has a
+ non-null colortable. Returns true if all of the above are met.
+ */
+ bool readyToDraw() const {
+ return this->getPixels() != NULL &&
+ (this->colorType() != kIndex_8_SkColorType || fColorTable);
+ }
+
+ /** Returns the pixelRef's texture, or NULL
+ */
+ GrTexture* getTexture() const;
+
+ /** Return the bitmap's colortable, if it uses one (i.e. colorType is
+ Index_8) and the pixels are locked.
+ Otherwise returns NULL. Does not affect the colortable's
+ reference count.
+ */
+ SkColorTable* getColorTable() const { return fColorTable; }
+
+ /** Returns a non-zero, unique value corresponding to the pixels in our
+ pixelref. Each time the pixels are changed (and notifyPixelsChanged
+ is called), a different generation ID will be returned. Finally, if
+ there is no pixelRef then zero is returned.
+ */
+ uint32_t getGenerationID() const;
+
+ /** Call this if you have changed the contents of the pixels. This will in-
+ turn cause a different generation ID value to be returned from
+ getGenerationID().
+ */
+ void notifyPixelsChanged() const;
+
+ /**
+ * Fill the entire bitmap with the specified color.
+ * If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
+ * of the color is ignored (treated as opaque). If the colortype only supports
+ * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
+ */
+ void eraseColor(SkColor c) const {
+ this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
+ SkColorGetB(c));
+ }
+
+ /**
+ * Fill the entire bitmap with the specified color.
+ * If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
+ * of the color is ignored (treated as opaque). If the colortype only supports
+ * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
+ */
+ void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
+
+ SK_ATTR_DEPRECATED("use eraseARGB or eraseColor")
+ void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
+ this->eraseARGB(0xFF, r, g, b);
+ }
+
+ /**
+ * Fill the specified area of this bitmap with the specified color.
+ * If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
+ * of the color is ignored (treated as opaque). If the colortype only supports
+ * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
+ */
+ void eraseArea(const SkIRect& area, SkColor c) const;
+
+ /** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are
+ no pixels allocated (i.e. getPixels() returns null) the method will
+ still update the inval region (if present). If the bitmap is immutable,
+ do nothing and return false.
+
+ @param subset The subset of the bitmap to scroll/move. To scroll the
+ entire contents, specify [0, 0, width, height] or just
+ pass null.
+ @param dx The amount to scroll in X
+ @param dy The amount to scroll in Y
+ @param inval Optional (may be null). Returns the area of the bitmap that
+ was scrolled away. E.g. if dx = dy = 0, then inval would
+ be set to empty. If dx >= width or dy >= height, then
+ inval would be set to the entire bounds of the bitmap.
+ @return true if the scroll was doable. Will return false if the colortype is kUnkown or
+ if the bitmap is immutable.
+ If no pixels are present (i.e. getPixels() returns false)
+ inval will still be updated, and true will be returned.
+ */
+ bool scrollRect(const SkIRect* subset, int dx, int dy,
+ SkRegion* inval = NULL) const;
+
+ /**
+ * Return the SkColor of the specified pixel. In most cases this will
+ * require un-premultiplying the color. Alpha only colortypes (e.g. kAlpha_8_SkColorType)
+ * return black with the appropriate alpha set. The value is undefined
+ * for kUnknown_SkColorType or if x or y are out of bounds, or if the bitmap
+ * does not have any pixels (or has not be locked with lockPixels()).
+ */
+ SkColor getColor(int x, int y) const;
+
+ /** Returns the address of the specified pixel. This performs a runtime
+ check to know the size of the pixels, and will return the same answer
+ as the corresponding size-specific method (e.g. getAddr16). Since the
+ check happens at runtime, it is much slower than using a size-specific
+ version. Unlike the size-specific methods, this routine also checks if
+ getPixels() returns null, and returns that. The size-specific routines
+ perform a debugging assert that getPixels() is not null, but they do
+ not do any runtime checks.
+ */
+ void* getAddr(int x, int y) const;
+
+ /** Returns the address of the pixel specified by x,y for 32bit pixels.
+ * In debug build, this asserts that the pixels are allocated and locked,
+ * and that the colortype is 32-bit, however none of these checks are performed
+ * in the release build.
+ */
+ inline uint32_t* getAddr32(int x, int y) const;
+
+ /** Returns the address of the pixel specified by x,y for 16bit pixels.
+ * In debug build, this asserts that the pixels are allocated and locked,
+ * and that the colortype is 16-bit, however none of these checks are performed
+ * in the release build.
+ */
+ inline uint16_t* getAddr16(int x, int y) const;
+
+ /** Returns the address of the pixel specified by x,y for 8bit pixels.
+ * In debug build, this asserts that the pixels are allocated and locked,
+ * and that the colortype is 8-bit, however none of these checks are performed
+ * in the release build.
+ */
+ inline uint8_t* getAddr8(int x, int y) const;
+
+ /** Returns the color corresponding to the pixel specified by x,y for
+ * colortable based bitmaps.
+ * In debug build, this asserts that the pixels are allocated and locked,
+ * that the colortype is indexed, and that the colortable is allocated,
+ * however none of these checks are performed in the release build.
+ */
+ inline SkPMColor getIndex8Color(int x, int y) const;
+
+ /** Set dst to be a setset of this bitmap. If possible, it will share the
+ pixel memory, and just point into a subset of it. However, if the colortype
+ does not support this, a local copy will be made and associated with
+ the dst bitmap. If the subset rectangle, intersected with the bitmap's
+ dimensions is empty, or if there is an unsupported colortype, false will be
+ returned and dst will be untouched.
+ @param dst The bitmap that will be set to a subset of this bitmap
+ @param subset The rectangle of pixels in this bitmap that dst will
+ reference.
+ @return true if the subset copy was successfully made.
+ */
+ bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
+
+ /** Makes a deep copy of this bitmap, respecting the requested colorType,
+ * and allocating the dst pixels on the cpu.
+ * Returns false if either there is an error (i.e. the src does not have
+ * pixels) or the request cannot be satisfied (e.g. the src has per-pixel
+ * alpha, and the requested colortype does not support alpha).
+ * @param dst The bitmap to be sized and allocated
+ * @param ct The desired colorType for dst
+ * @param allocator Allocator used to allocate the pixelref for the dst
+ * bitmap. If this is null, the standard HeapAllocator
+ * will be used.
+ * @return true if the copy was made.
+ */
+ bool copyTo(SkBitmap* dst, SkColorType ct, Allocator* = NULL) const;
+
+ bool copyTo(SkBitmap* dst, Allocator* allocator = NULL) const {
+ return this->copyTo(dst, this->colorType(), allocator);
+ }
+
+ /**
+ * Copy the bitmap's pixels into the specified buffer (pixels + rowBytes),
+ * converting them into the requested format (SkImageInfo). The src pixels are read
+ * starting at the specified (srcX,srcY) offset, relative to the top-left corner.
+ *
+ * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
+ *
+ * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
+ *
+ * srcR is intersected with the bounds of the bitmap. If this intersection is not empty,
+ * then we have two sets of pixels (of equal size). Replace the dst pixels with the
+ * corresponding src pixels, performing any colortype/alphatype transformations needed
+ * (in the case where the src and dst have different colortypes or alphatypes).
+ *
+ * This call can fail, returning false, for several reasons:
+ * - If srcR does not intersect the bitmap bounds.
+ * - If the requested colortype/alphatype cannot be converted from the src's types.
+ * - If the src pixels are not available.
+ */
+ bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
+ int srcX, int srcY) const;
+
+ /**
+ * Returns true if this bitmap's pixels can be converted into the requested
+ * colorType, such that copyTo() could succeed.
+ */
+ bool canCopyTo(SkColorType colorType) const;
+
+ /** Makes a deep copy of this bitmap, keeping the copied pixels
+ * in the same domain as the source: If the src pixels are allocated for
+ * the cpu, then so will the dst. If the src pixels are allocated on the
+ * gpu (typically as a texture), the it will do the same for the dst.
+ * If the request cannot be fulfilled, returns false and dst is unmodified.
+ */
+ bool deepCopyTo(SkBitmap* dst) const;
+
+#ifdef SK_BUILD_FOR_ANDROID
+ bool hasHardwareMipMap() const {
+ return (fFlags & kHasHardwareMipMap_Flag) != 0;
+ }
+
+ void setHasHardwareMipMap(bool hasHardwareMipMap) {
+ if (hasHardwareMipMap) {
+ fFlags |= kHasHardwareMipMap_Flag;
+ } else {
+ fFlags &= ~kHasHardwareMipMap_Flag;
+ }
+ }
+#endif
+
+ bool extractAlpha(SkBitmap* dst) const {
+ return this->extractAlpha(dst, NULL, NULL, NULL);
+ }
+
+ bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
+ SkIPoint* offset) const {
+ return this->extractAlpha(dst, paint, NULL, offset);
+ }
+
+ /** Set dst to contain alpha layer of this bitmap. If destination bitmap
+ fails to be initialized, e.g. because allocator can't allocate pixels
+ for it, dst will not be modified and false will be returned.
+
+ @param dst The bitmap to be filled with alpha layer
+ @param paint The paint to draw with
+ @param allocator Allocator used to allocate the pixelref for the dst
+ bitmap. If this is null, the standard HeapAllocator
+ will be used.
+ @param offset If not null, it is set to top-left coordinate to position
+ the returned bitmap so that it visually lines up with the
+ original
+ */
+ bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
+ SkIPoint* offset) const;
+
+ SkDEBUGCODE(void validate() const;)
+
+ class Allocator : public SkRefCnt {
+ public:
+ SK_DECLARE_INST_COUNT(Allocator)
+
+ /** Allocate the pixel memory for the bitmap, given its dimensions and
+ colortype. Return true on success, where success means either setPixels
+ or setPixelRef was called. The pixels need not be locked when this
+ returns. If the colortype requires a colortable, it also must be
+ installed via setColorTable. If false is returned, the bitmap and
+ colortable should be left unchanged.
+ */
+ virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
+ private:
+ typedef SkRefCnt INHERITED;
+ };
+
+ /** Subclass of Allocator that returns a pixelref that allocates its pixel
+ memory from the heap. This is the default Allocator invoked by
+ allocPixels().
+ */
+ class HeapAllocator : public Allocator {
+ public:
+ virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE;
+ };
+
+ class RLEPixels {
+ public:
+ RLEPixels(int width, int height);
+ virtual ~RLEPixels();
+
+ uint8_t* packedAtY(int y) const {
+ SkASSERT((unsigned)y < (unsigned)fHeight);
+ return fYPtrs[y];
+ }
+
+ // called by subclasses during creation
+ void setPackedAtY(int y, uint8_t* addr) {
+ SkASSERT((unsigned)y < (unsigned)fHeight);
+ fYPtrs[y] = addr;
+ }
+
+ private:
+ uint8_t** fYPtrs;
+ int fHeight;
+ };
+
+ SK_TO_STRING_NONVIRT()
+
+private:
+ mutable SkPixelRef* fPixelRef;
+ mutable int fPixelLockCount;
+ // These are just caches from the locked pixelref
+ mutable void* fPixels;
+ mutable SkColorTable* fColorTable; // only meaningful for kIndex8
+
+ SkIPoint fPixelRefOrigin;
+
+ enum Flags {
+ kImageIsVolatile_Flag = 0x02,
+#ifdef SK_BUILD_FOR_ANDROID
+ /* A hint for the renderer responsible for drawing this bitmap
+ * indicating that it should attempt to use mipmaps when this bitmap
+ * is drawn scaled down.
+ */
+ kHasHardwareMipMap_Flag = 0x08,
+#endif
+ };
+
+ SkImageInfo fInfo;
+
+ uint32_t fRowBytes;
+
+ uint8_t fFlags;
+
+ void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const;
+
+ /* Unreference any pixelrefs or colortables
+ */
+ void freePixels();
+ void updatePixelsFromRef() const;
+
+ void legacyUnflatten(SkReadBuffer&);
+
+ static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
+ static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
+
+ friend class SkBitmapSource; // unflatten
+ friend class SkReadBuffer; // unflatten, rawpixels
+ friend class SkWriteBuffer; // rawpixels
+ friend struct SkBitmapProcState;
+};
+
+class SkAutoLockPixels : SkNoncopyable {
+public:
+ SkAutoLockPixels(const SkBitmap& bm, bool doLock = true) : fBitmap(bm) {
+ fDidLock = doLock;
+ if (doLock) {
+ bm.lockPixels();
+ }
+ }
+ ~SkAutoLockPixels() {
+ if (fDidLock) {
+ fBitmap.unlockPixels();
+ }
+ }
+
+private:
+ const SkBitmap& fBitmap;
+ bool fDidLock;
+};
+//TODO(mtklein): uncomment when 71713004 lands and Chromium's fixed.
+//#define SkAutoLockPixels(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockPixels)
+
+/** Helper class that performs the lock/unlockColors calls on a colortable.
+ The destructor will call unlockColors(false) if it has a bitmap's colortable
+*/
+class SkAutoLockColors : SkNoncopyable {
+public:
+ /** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's
+ colortable
+ */
+ SkAutoLockColors() : fCTable(NULL), fColors(NULL) {}
+ /** Initialize with bitmap, locking its colortable if present
+ */
+ explicit SkAutoLockColors(const SkBitmap& bm) {
+ fCTable = bm.getColorTable();
+ fColors = fCTable ? fCTable->lockColors() : NULL;
+ }
+ /** Initialize with a colortable (may be null)
+ */
+ explicit SkAutoLockColors(SkColorTable* ctable) {
+ fCTable = ctable;
+ fColors = ctable ? ctable->lockColors() : NULL;
+ }
+ ~SkAutoLockColors() {
+ if (fCTable) {
+ fCTable->unlockColors();
+ }
+ }
+
+ /** Return the currently locked colors, or NULL if no bitmap's colortable
+ is currently locked.
+ */
+ const SkPMColor* colors() const { return fColors; }
+
+ /** Locks the table and returns is colors (assuming ctable is not null) and
+ unlocks the previous table if one was present
+ */
+ const SkPMColor* lockColors(SkColorTable* ctable) {
+ if (fCTable) {
+ fCTable->unlockColors();
+ }
+ fCTable = ctable;
+ fColors = ctable ? ctable->lockColors() : NULL;
+ return fColors;
+ }
+
+ const SkPMColor* lockColors(const SkBitmap& bm) {
+ return this->lockColors(bm.getColorTable());
+ }
+
+private:
+ SkColorTable* fCTable;
+ const SkPMColor* fColors;
+};
+#define SkAutoLockColors(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockColors)
+
+///////////////////////////////////////////////////////////////////////////////
+
+inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(4 == this->bytesPerPixel());
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
+ return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
+}
+
+inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(2 == this->bytesPerPixel());
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
+ return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
+}
+
+inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(1 == this->bytesPerPixel());
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
+ return (uint8_t*)fPixels + y * fRowBytes + x;
+}
+
+inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(kIndex_8_SkColorType == this->colorType());
+ SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
+ SkASSERT(fColorTable);
+ return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
+}
+
+#endif
diff --git a/src/third_party/skia/include/core/SkBitmapDevice.h b/src/third_party/skia/include/core/SkBitmapDevice.h
new file mode 100644
index 0000000..0ab0234
--- /dev/null
+++ b/src/third_party/skia/include/core/SkBitmapDevice.h
@@ -0,0 +1,168 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBitmapDevice_DEFINED
+#define SkBitmapDevice_DEFINED
+
+#include "SkDevice.h"
+
+///////////////////////////////////////////////////////////////////////////////
+class SK_API SkBitmapDevice : public SkBaseDevice {
+public:
+ SK_DECLARE_INST_COUNT(SkBitmapDevice)
+
+ /**
+ * Construct a new device with the specified bitmap as its backend. It is
+ * valid for the bitmap to have no pixels associated with it. In that case,
+ * any drawing to this device will have no effect.
+ */
+ SkBitmapDevice(const SkBitmap& bitmap);
+private:
+ /**
+ * Construct a new device with the specified bitmap as its backend. It is
+ * valid for the bitmap to have no pixels associated with it. In that case,
+ * any drawing to this device will have no effect.
+ */
+ SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties);
+ static SkBitmapDevice* Create(const SkImageInfo&, const SkDeviceProperties*);
+public:
+ static SkBitmapDevice* Create(const SkImageInfo& info) {
+ return Create(info, NULL);
+ }
+
+ virtual SkImageInfo imageInfo() const SK_OVERRIDE;
+
+protected:
+ virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE;
+
+ /** Clears the entire device to the specified color (including alpha).
+ * Ignores the clip.
+ */
+ virtual void clear(SkColor color) SK_OVERRIDE;
+
+ /** These are called inside the per-device-layer loop for each draw call.
+ When these are called, we have already applied any saveLayer operations,
+ and are handling any looping from the paint, and any effects from the
+ DrawFilter.
+ */
+ virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+ const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkDraw&, const SkRect& r,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawOval(const SkDraw&, const SkRect& oval,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkDraw&, const SkRRect& rr,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ /**
+ * If pathIsMutable, then the implementation is allowed to cast path to a
+ * non-const pointer and modify it in place (as an optimization). Canvas
+ * may do this to implement helpers such as drawOval, by placing a temp
+ * path on the stack to hold the representation of the oval.
+ *
+ * If prePathMatrix is not null, it should logically be applied before any
+ * stroking or other effects. If there are no effects on the paint that
+ * affect the geometry/rasterization, then the pre matrix can just be
+ * pre-concated with the current matrix.
+ */
+ virtual void drawPath(const SkDraw&, const SkPath& path,
+ const SkPaint& paint,
+ const SkMatrix* prePathMatrix = NULL,
+ bool pathIsMutable = false) SK_OVERRIDE;
+ virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+ int x, int y, const SkPaint& paint) SK_OVERRIDE;
+
+ /**
+ * The default impl. will create a bitmap-shader from the bitmap,
+ * and call drawRect with it.
+ */
+ virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
+ const SkRect* srcOrNull, const SkRect& dst,
+ const SkPaint& paint,
+ SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE;
+
+ /**
+ * Does not handle text decoration.
+ * Decorations (underline and stike-thru) will be handled by SkCanvas.
+ */
+ virtual void drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+ const SkPoint verts[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) SK_OVERRIDE;
+ /** The SkBaseDevice passed will be an SkBaseDevice which was returned by a call to
+ onCreateDevice on this device with kSaveLayer_Usage.
+ */
+ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+ const SkPaint&) SK_OVERRIDE;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** Update as needed the pixel value in the bitmap, so that the caller can
+ access the pixels directly. Note: only the pixels field should be
+ altered. The config/width/height/rowbytes must remain unchanged.
+ @return the device contents as a bitmap
+ */
+ virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
+
+ SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
+ // just for subclasses, to assign a custom pixelref
+ SkPixelRef* setPixelRef(SkPixelRef* pr) {
+ fBitmap.setPixelRef(pr);
+ return pr;
+ }
+
+ virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) SK_OVERRIDE;
+ virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE;
+ virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes) SK_OVERRIDE;
+
+ /** Called when this device is installed into a Canvas. Balanced by a call
+ to unlockPixels() when the device is removed from a Canvas.
+ */
+ virtual void lockPixels() SK_OVERRIDE;
+ virtual void unlockPixels() SK_OVERRIDE;
+
+private:
+ friend class SkCanvas;
+ friend struct DeviceCM; //for setMatrixClip
+ friend class SkDraw;
+ friend class SkDrawIter;
+ friend class SkDeviceFilteredPaint;
+ friend class SkDeviceImageFilterProxy;
+
+ friend class SkSurface_Raster;
+
+ // used to change the backend's pixels (and possibly config/rowbytes)
+ // but cannot change the width/height, so there should be no change to
+ // any clip information.
+ virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE;
+
+ virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
+
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
+ virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE;
+
+ virtual SkImageFilter::Cache* getImageFilterCache() SK_OVERRIDE;
+
+ SkBitmap fBitmap;
+
+ typedef SkBaseDevice INHERITED;
+};
+
+#endif // SkBitmapDevice_DEFINED
diff --git a/src/third_party/skia/include/core/SkBlitRow.h b/src/third_party/skia/include/core/SkBlitRow.h
new file mode 100644
index 0000000..9393589
--- /dev/null
+++ b/src/third_party/skia/include/core/SkBlitRow.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#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* dst,
+ const SkPMColor* src,
+ int count, U8CPU alpha, int x, int y);
+
+ static Proc Factory(unsigned flags, SkColorType);
+
+ ///////////// 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* dst,
+ const SkPMColor* src,
+ int count, U8CPU alpha);
+
+ static Proc32 Factory32(unsigned flags32);
+
+ /** 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);
+
+ /** 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);
+
+ //! Public entry-point to return a blit function ptr
+ static ColorProc ColorProcFactory();
+
+ /** Function pointer that blends a single color onto a 32-bit rectangle. */
+ typedef void (*ColorRectProc)(SkPMColor* dst, int width, int height,
+ size_t rowBytes, SkPMColor color);
+
+ /** Blend a single color into a rectangle of D32 pixels. */
+ static void ColorRect32(SkPMColor* dst, int width, int height,
+ size_t rowBytes, SkPMColor color);
+
+ //! Public entry-point to return a blit function ptr
+ static ColorRectProc ColorRectProcFactory();
+
+ /** 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 ColorProc PlatformColorProc();
+
+private:
+ enum {
+ kFlags16_Mask = 7,
+ kFlags32_Mask = 3
+ };
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkBlurTypes.h b/src/third_party/skia/include/core/SkBlurTypes.h
new file mode 100644
index 0000000..afbec19
--- /dev/null
+++ b/src/third_party/skia/include/core/SkBlurTypes.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBlurTypes_DEFINED
+#define SkBlurTypes_DEFINED
+
+#include "SkTypes.h"
+
+enum SkBlurStyle {
+ kNormal_SkBlurStyle, //!< fuzzy inside and outside
+ kSolid_SkBlurStyle, //!< solid inside, fuzzy outside
+ kOuter_SkBlurStyle, //!< nothing inside, fuzzy outside
+ kInner_SkBlurStyle, //!< fuzzy inside, nothing outside
+
+ kLastEnum_SkBlurStyle = kInner_SkBlurStyle
+};
+
+enum SkBlurQuality {
+ kLow_SkBlurQuality, //!< e.g. box filter
+ kHigh_SkBlurQuality, //!< e.g. 3-pass similar to gaussian
+
+ kLastEnum_SkBlurQuality
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkCanvas.h b/src/third_party/skia/include/core/SkCanvas.h
new file mode 100644
index 0000000..5828466
--- /dev/null
+++ b/src/third_party/skia/include/core/SkCanvas.h
@@ -0,0 +1,1549 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkCanvas_DEFINED
+#define SkCanvas_DEFINED
+
+#include "SkTypes.h"
+#include "SkBitmap.h"
+#include "SkDeque.h"
+#include "SkClipStack.h"
+#include "SkPaint.h"
+#include "SkRefCnt.h"
+#include "SkPath.h"
+#include "SkRegion.h"
+#include "SkSurfaceProps.h"
+#include "SkXfermode.h"
+
+#ifdef SK_SUPPORT_LEGACY_DRAWTEXT_VIRTUAL
+ #define SK_LEGACY_DRAWTEXT_VIRTUAL virtual
+#else
+ #define SK_LEGACY_DRAWTEXT_VIRTUAL
+#endif
+
+class SkCanvasClipVisitor;
+class SkBaseDevice;
+class SkDraw;
+class SkDrawFilter;
+class SkImage;
+class SkMetaData;
+class SkPicture;
+class SkRRect;
+class SkSurface;
+class SkSurface_Base;
+class SkTextBlob;
+class GrContext;
+class GrRenderTarget;
+
+class SkCanvasState;
+
+namespace SkCanvasStateUtils {
+ SK_API SkCanvasState* CaptureCanvasState(SkCanvas*);
+}
+
+/** \class SkCanvas
+
+ A Canvas encapsulates all of the state about drawing into a device (bitmap).
+ This includes a reference to the device itself, and a stack of matrix/clip
+ values. For any given draw call (e.g. drawRect), the geometry of the object
+ being drawn is transformed by the concatenation of all the matrices in the
+ stack. The transformed geometry is clipped by the intersection of all of
+ the clips in the stack.
+
+ While the Canvas holds the state of the drawing device, the state (style)
+ of the object being drawn is held by the Paint, which is provided as a
+ parameter to each of the draw() methods. The Paint holds attributes such as
+ color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
+ etc.
+*/
+class SK_API SkCanvas : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkCanvas)
+
+ /**
+ * Attempt to allocate an offscreen raster canvas, matching the ImageInfo.
+ * On success, return a new canvas that will draw into that offscreen.
+ *
+ * The caller can access the pixels after drawing into this canvas by
+ * calling readPixels() or peekPixels().
+ *
+ * If the requested ImageInfo is opaque (either the colortype is
+ * intrinsically opaque like RGB_565, or the info's alphatype is kOpaque)
+ * then the pixel memory may be uninitialized. Otherwise, the pixel memory
+ * will be initialized to 0, which is interpreted as transparent.
+ *
+ * On failure, return NULL. This can fail for several reasons:
+ * 1. the memory allocation failed (e.g. request is too large)
+ * 2. invalid ImageInfo (e.g. negative dimensions)
+ * 3. unsupported ImageInfo for a canvas
+ * - kUnknown_SkColorType, kIndex_8_SkColorType
+ * - kIgnore_SkAlphaType
+ * - this list is not complete, so others may also be unsupported
+ *
+ * Note: it is valid to request a supported ImageInfo, but with zero
+ * dimensions.
+ */
+ static SkCanvas* NewRaster(const SkImageInfo&);
+
+ static SkCanvas* NewRasterN32(int width, int height) {
+ return NewRaster(SkImageInfo::MakeN32Premul(width, height));
+ }
+
+ /**
+ * Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
+ * specified pixels. To access the pixels after drawing to them, the caller should call
+ * flush() or call peekPixels(...).
+ *
+ * On failure, return NULL. This can fail for several reasons:
+ * 1. invalid ImageInfo (e.g. negative dimensions)
+ * 2. unsupported ImageInfo for a canvas
+ * - kUnknown_SkColorType, kIndex_8_SkColorType
+ * - kIgnore_SkAlphaType
+ * - this list is not complete, so others may also be unsupported
+ *
+ * Note: it is valid to request a supported ImageInfo, but with zero
+ * dimensions.
+ */
+ static SkCanvas* NewRasterDirect(const SkImageInfo&, void*, size_t);
+
+ static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) {
+ return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
+ }
+
+ /**
+ * Creates an empty canvas with no backing device/pixels, and zero
+ * dimensions.
+ */
+ SkCanvas();
+
+ /**
+ * Creates a canvas of the specified dimensions, but explicitly not backed
+ * by any device/pixels. Typically this use used by subclasses who handle
+ * the draw calls in some other way.
+ */
+ SkCanvas(int width, int height);
+
+ /** Construct a canvas with the specified device to draw into.
+
+ @param device Specifies a device for the canvas to draw into.
+ */
+ explicit SkCanvas(SkBaseDevice* device);
+
+ /** Construct a canvas with the specified bitmap to draw into.
+ @param bitmap Specifies a bitmap for the canvas to draw into. Its
+ structure are copied to the canvas.
+ */
+ explicit SkCanvas(const SkBitmap& bitmap);
+ virtual ~SkCanvas();
+
+ SkMetaData& getMetaData();
+
+ /**
+ * Return ImageInfo for this canvas. If the canvas is not backed by pixels
+ * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
+ */
+ SkImageInfo imageInfo() const;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Trigger the immediate execution of all pending draw operations.
+ */
+ void flush();
+
+ /**
+ * Gets the size of the base or root layer in global canvas coordinates. The
+ * origin of the base layer is always (0,0). The current drawable area may be
+ * smaller (due to clipping or saveLayer).
+ */
+ SkISize getBaseLayerSize() const;
+
+ /**
+ * DEPRECATED: call getBaseLayerSize
+ */
+ SkISize getDeviceSize() const { return this->getBaseLayerSize(); }
+
+ /**
+ * DEPRECATED.
+ * Return the canvas' device object, which may be null. The device holds
+ * the bitmap of the pixels that the canvas draws into. The reference count
+ * of the returned device is not changed by this call.
+ */
+#ifndef SK_SUPPORT_LEGACY_GETDEVICE
+protected: // Can we make this private?
+#endif
+ SkBaseDevice* getDevice() const;
+public:
+
+ /**
+ * saveLayer() can create another device (which is later drawn onto
+ * the previous device). getTopDevice() returns the top-most device current
+ * installed. Note that this can change on other calls like save/restore,
+ * so do not access this device after subsequent canvas calls.
+ * The reference count of the device is not changed.
+ *
+ * @param updateMatrixClip If this is true, then before the device is
+ * returned, we ensure that its has been notified about the current
+ * matrix and clip. Note: this happens automatically when the device
+ * is drawn to, but is optional here, as there is a small perf hit
+ * sometimes.
+ */
+#ifndef SK_SUPPORT_LEGACY_GETTOPDEVICE
+private:
+#endif
+ SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const;
+public:
+
+ /**
+ * Create a new surface matching the specified info, one that attempts to
+ * be maximally compatible when used with this canvas. If there is no matching Surface type,
+ * NULL is returned.
+ *
+ * If surfaceprops is specified, those are passed to the new surface, otherwise the new surface
+ * inherits the properties of the surface that owns this canvas. If this canvas has no parent
+ * surface, then the new surface is created with default properties.
+ */
+ SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL);
+
+ /**
+ * Return the GPU context of the device that is associated with the canvas.
+ * For a canvas with non-GPU device, NULL is returned.
+ */
+ GrContext* getGrContext();
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * If the canvas has writable pixels in its top layer (and is not recording to a picture
+ * or other non-raster target) and has direct access to its pixels (i.e. they are in
+ * local RAM) return the address of those pixels, and if not null,
+ * return the ImageInfo, rowBytes and origin. The returned address is only valid
+ * while the canvas object is in scope and unchanged. Any API calls made on
+ * canvas (or its parent surface if any) will invalidate the
+ * returned address (and associated information).
+ *
+ * On failure, returns NULL and the info, rowBytes, and origin parameters are ignored.
+ */
+ void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL);
+
+ /**
+ * If the canvas has readable pixels in its base layer (and is not recording to a picture
+ * or other non-raster target) and has direct access to its pixels (i.e. they are in
+ * local RAM) return the const-address of those pixels, and if not null,
+ * return the ImageInfo and rowBytes. The returned address is only valid
+ * while the canvas object is in scope and unchanged. Any API calls made on
+ * canvas (or its parent surface if any) will invalidate the
+ * returned address (and associated information).
+ *
+ * On failure, returns NULL and the info and rowBytes parameters are
+ * ignored.
+ */
+ const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
+
+ /**
+ * Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes),
+ * converting them into the requested format (SkImageInfo). The base-layer pixels are read
+ * starting at the specified (srcX,srcY) location in the coordinate system of the base-layer.
+ *
+ * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
+ *
+ * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
+ *
+ * srcR is intersected with the bounds of the base-layer. If this intersection is not empty,
+ * then we have two sets of pixels (of equal size). Replace the dst pixels with the
+ * corresponding src pixels, performing any colortype/alphatype transformations needed
+ * (in the case where the src and dst have different colortypes or alphatypes).
+ *
+ * This call can fail, returning false, for several reasons:
+ * - If srcR does not intersect the base-layer bounds.
+ * - If the requested colortype/alphatype cannot be converted from the base-layer's types.
+ * - If this canvas is not backed by pixels (e.g. picture or PDF)
+ */
+ bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
+ int srcX, int srcY);
+
+ /**
+ * Helper for calling readPixels(info, ...). This call will check if bitmap has been allocated.
+ * If not, it will attempt to call allocPixels(). If this fails, it will return false. If not,
+ * it calls through to readPixels(info, ...) and returns its result.
+ */
+ bool readPixels(SkBitmap* bitmap, int srcX, int srcY);
+
+ /**
+ * Helper for allocating pixels and then calling readPixels(info, ...). The bitmap is resized
+ * to the intersection of srcRect and the base-layer bounds. On success, pixels will be
+ * allocated in bitmap and true returned. On failure, false is returned and bitmap will be
+ * set to empty.
+ */
+ bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
+
+ /**
+ * This method affects the pixels in the base-layer, and operates in pixel coordinates,
+ * ignoring the matrix and clip.
+ *
+ * The specified ImageInfo and (x,y) offset specifies a rectangle: target.
+ *
+ * target.setXYWH(x, y, info.width(), info.height());
+ *
+ * Target is intersected with the bounds of the base-layer. If this intersection is not empty,
+ * then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes
+ * and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src
+ * pixels, performing any colortype/alphatype transformations needed (in the case where the
+ * src and dst have different colortypes or alphatypes).
+ *
+ * This call can fail, returning false, for several reasons:
+ * - If the src colortype/alphatype cannot be converted to the canvas' types
+ * - If this canvas is not backed by pixels (e.g. picture or PDF)
+ */
+ bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
+
+ /**
+ * Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap
+ * is just wrapping a texture, returns false and does nothing.
+ */
+ bool writePixels(const SkBitmap& bitmap, int x, int y);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ enum SaveFlags {
+ /** save the matrix state, restoring it on restore() */
+ // [deprecated] kMatrix_SaveFlag = 0x01,
+ kMatrix_SaveFlag = 0x01,
+ /** save the clip state, restoring it on restore() */
+ // [deprecated] kClip_SaveFlag = 0x02,
+ kClip_SaveFlag = 0x02,
+ /** the layer needs to support per-pixel alpha */
+ kHasAlphaLayer_SaveFlag = 0x04,
+ /** the layer needs to support 8-bits per color component */
+ kFullColorLayer_SaveFlag = 0x08,
+ /**
+ * the layer should clip against the bounds argument
+ *
+ * if SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG is undefined, this is treated as always on.
+ */
+ kClipToLayer_SaveFlag = 0x10,
+
+ // helper masks for common choices
+ // [deprecated] kMatrixClip_SaveFlag = 0x03,
+ kMatrixClip_SaveFlag = 0x03,
+#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
+ kARGB_NoClipLayer_SaveFlag = 0x0F,
+#endif
+ kARGB_ClipLayer_SaveFlag = 0x1F
+ };
+
+ /** This call saves the current matrix, clip, and drawFilter, and pushes a
+ copy onto a private stack. Subsequent calls to translate, scale,
+ rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
+ operate on this copy.
+ When the balancing call to restore() is made, the previous matrix, clip,
+ and drawFilter are restored.
+
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ int save();
+
+ /** This behaves the same as save(), but in addition it allocates an
+ 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) 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
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ int saveLayer(const SkRect* bounds, const SkPaint* paint);
+
+ /** DEPRECATED - use saveLayer(const SkRect*, const SkPaint*) instead.
+
+ This behaves the same as saveLayer(const SkRect*, const SkPaint*),
+ but it allows fine-grained control of which state bits to be saved
+ (and subsequently restored).
+
+ @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
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
+ int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
+
+ /** This behaves the same as save(), but in addition it allocates an
+ 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) 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.
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
+
+ /** DEPRECATED - use saveLayerAlpha(const SkRect*, U8CPU) instead.
+
+ This behaves the same as saveLayerAlpha(const SkRect*, U8CPU),
+ but it allows fine-grained control of which state bits to be saved
+ (and subsequently restored).
+
+ @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()
+ */
+ SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
+ int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, SaveFlags flags);
+
+ /** This call balances a previous call to save(), and is used to remove all
+ modifications to the matrix/clip/drawFilter state since the last save
+ call.
+ It is an error to call restore() more times than save() was called.
+ */
+ void restore();
+
+ /** Returns the number of matrix/clip states on the SkCanvas' private stack.
+ This will equal # save() calls - # restore() calls + 1. The save count on
+ a new canvas is 1.
+ */
+ int getSaveCount() const;
+
+ /** Efficient way to pop any calls to save() that happened after the save
+ count reached saveCount. It is an error for saveCount to be greater than
+ getSaveCount(). To pop all the way back to the initial matrix/clip context
+ pass saveCount == 1.
+ @param saveCount The number of save() levels to restore from
+ */
+ void restoreToCount(int saveCount);
+
+ /** Returns true if drawing is currently going to a layer (from saveLayer)
+ * rather than to the root device.
+ */
+ virtual bool isDrawingToLayer() const;
+
+ /** Preconcat the current matrix with the specified translation
+ @param dx The distance to translate in X
+ @param dy The distance to translate in Y
+ */
+ void translate(SkScalar dx, SkScalar dy);
+
+ /** Preconcat the current matrix with the specified scale.
+ @param sx The amount to scale in X
+ @param sy The amount to scale in Y
+ */
+ void scale(SkScalar sx, SkScalar sy);
+
+ /** Preconcat the current matrix with the specified rotation.
+ @param degrees The amount to rotate, in degrees
+ */
+ void rotate(SkScalar degrees);
+
+ /** Preconcat the current matrix with the specified skew.
+ @param sx The amount to skew in X
+ @param sy The amount to skew in Y
+ */
+ void skew(SkScalar sx, SkScalar sy);
+
+ /** Preconcat the current matrix with the specified matrix.
+ @param matrix The matrix to preconcatenate with the current matrix
+ */
+ void 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.
+ */
+ void setMatrix(const SkMatrix& matrix);
+
+ /** Helper for setMatrix(identity). Sets the current matrix to identity.
+ */
+ void resetMatrix();
+
+ /**
+ * Modify the current clip with the specified rectangle.
+ * @param rect The rect to combine with the current clip
+ * @param op The region op to apply to the current clip
+ * @param doAntiAlias true if the clip should be antialiased
+ */
+ void clipRect(const SkRect& rect,
+ SkRegion::Op op = SkRegion::kIntersect_Op,
+ bool doAntiAlias = false);
+
+ /**
+ * Modify the current clip with the specified SkRRect.
+ * @param rrect The rrect to combine with the current clip
+ * @param op The region op to apply to the current clip
+ * @param doAntiAlias true if the clip should be antialiased
+ */
+ void clipRRect(const SkRRect& rrect,
+ SkRegion::Op op = SkRegion::kIntersect_Op,
+ bool doAntiAlias = false);
+
+ /**
+ * Modify the current clip with the specified path.
+ * @param path The path to combine with the current clip
+ * @param op The region op to apply to the current clip
+ * @param doAntiAlias true if the clip should be antialiased
+ */
+ void clipPath(const SkPath& path,
+ SkRegion::Op op = SkRegion::kIntersect_Op,
+ bool doAntiAlias = false);
+
+ /** EXPERIMENTAL -- only used for testing
+ Set to false to force clips to be hard, even if doAntiAlias=true is
+ passed to clipRect or clipPath.
+ */
+ void setAllowSoftClip(bool allow) {
+ fAllowSoftClip = allow;
+ }
+
+ /** EXPERIMENTAL -- only used for testing
+ Set to simplify clip stack using path ops.
+ */
+ void setAllowSimplifyClip(bool allow) {
+ fAllowSimplifyClip = allow;
+ }
+
+ /** Modify the current clip with the specified region. Note that unlike
+ clipRect() and clipPath() which transform their arguments by the current
+ matrix, clipRegion() assumes its argument is already in device
+ coordinates, and so no transformation is performed.
+ @param deviceRgn The region to apply to the current clip
+ @param op The region op to apply to the current clip
+ */
+ void clipRegion(const SkRegion& deviceRgn,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
+ specified region. This does not intersect or in any other way account
+ for the existing clip region.
+ @param deviceRgn The region to copy into the current clip.
+ */
+ void setClipRegion(const SkRegion& deviceRgn) {
+ this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
+ }
+
+ /** Return true if the specified rectangle, after being transformed by the
+ current matrix, would lie completely outside of the current clip. Call
+ this to check if an area you intend to draw into is clipped out (and
+ therefore you can skip making the draw calls).
+ @param rect the rect to compare with the current clip
+ @return true if the rect (transformed by the canvas' matrix) does not
+ intersect with the canvas' clip
+ */
+ bool quickReject(const SkRect& rect) const;
+
+ /** Return true if the specified path, after being transformed by the
+ current matrix, would lie completely outside of the current clip. Call
+ this to check if an area you intend to draw into is clipped out (and
+ therefore you can skip making the draw calls). Note, for speed it may
+ return false even if the path itself might not intersect the clip
+ (i.e. the bounds of the path intersects, but the path does not).
+ @param path The path to compare with the current clip
+ @return true if the path (transformed by the canvas' matrix) does not
+ intersect with the canvas' clip
+ */
+ bool quickReject(const SkPath& path) const;
+
+ /** Return true if the horizontal band specified by top and bottom is
+ completely clipped out. This is a conservative calculation, meaning
+ that it is possible that if the method returns false, the band may still
+ in fact be clipped out, but the converse is not true. If this method
+ returns true, then the band is guaranteed to be clipped out.
+ @param top The top of the horizontal band to compare with the clip
+ @param bottom The bottom of the horizontal and to compare with the clip
+ @return true if the horizontal band is completely clipped out (i.e. does
+ not intersect the current clip)
+ */
+ bool quickRejectY(SkScalar top, SkScalar bottom) const {
+ SkASSERT(top <= bottom);
+
+#ifndef SK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT
+ // TODO: add a hasPerspective method similar to getLocalClipBounds. This
+ // would cache the SkMatrix::hasPerspective result. Alternatively, have
+ // the MC stack just set a hasPerspective boolean as it is updated.
+ if (this->getTotalMatrix().hasPerspective()) {
+ // TODO: consider implementing some half-plane test between the
+ // two Y planes and the device-bounds (i.e., project the top and
+ // bottom Y planes and then determine if the clip bounds is completely
+ // outside either one).
+ return false;
+ }
+#endif
+
+ const SkRect& clipR = this->getLocalClipBounds();
+ // In the case where the clip is empty and we are provided with a
+ // negative top and positive bottom parameter then this test will return
+ // false even though it will be clipped. We have chosen to exclude that
+ // check as it is rare and would result double the comparisons.
+ return top >= clipR.fBottom || bottom <= clipR.fTop;
+ }
+
+ /** Return the bounds of the current clip (in local coordinates) in the
+ bounds parameter, and return true if it is non-empty. This can be useful
+ in a way similar to quickReject, in that it tells you that drawing
+ outside of these bounds will be clipped out.
+ */
+ virtual bool getClipBounds(SkRect* bounds) const;
+
+ /** Return the bounds of the current clip, in device coordinates; returns
+ true if non-empty. Maybe faster than getting the clip explicitly and
+ then taking its bounds.
+ */
+ virtual bool getClipDeviceBounds(SkIRect* bounds) const;
+
+
+ /** Fill the entire canvas' bitmap (restricted to the current clip) with the
+ specified ARGB color, using the specified mode.
+ @param a the alpha component (0..255) of the color to fill the canvas
+ @param r the red component (0..255) of the color to fill the canvas
+ @param g the green component (0..255) of the color to fill the canvas
+ @param b the blue component (0..255) of the color to fill the canvas
+ @param mode the mode to apply the color in (defaults to SrcOver)
+ */
+ void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
+ SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
+
+ /** Fill the entire canvas' bitmap (restricted to the current clip) with the
+ specified color and mode.
+ @param color the color to draw with
+ @param mode the mode to apply the color in (defaults to SrcOver)
+ */
+ void drawColor(SkColor color,
+ SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
+
+ /**
+ * This erases the entire drawing surface to the specified color,
+ * irrespective of the clip. It does not blend with the previous pixels,
+ * but always overwrites them.
+ *
+ * It is roughly equivalent to the following:
+ * canvas.save();
+ * canvas.clipRect(hugeRect, kReplace_Op);
+ * paint.setColor(color);
+ * paint.setXfermodeMode(kSrc_Mode);
+ * canvas.drawPaint(paint);
+ * canvas.restore();
+ * though it is almost always much more efficient.
+ */
+ virtual void clear(SkColor);
+
+ /**
+ * This makes the contents of the canvas undefined. Subsequent calls that
+ * require reading the canvas contents will produce undefined results. Examples
+ * include blending and readPixels. The actual implementation is backend-
+ * dependent and one legal implementation is to do nothing. Like clear(), this
+ * ignores the clip.
+ *
+ * This function should only be called if the caller intends to subsequently
+ * draw to the canvas. The canvas may do real work at discard() time in order
+ * to optimize performance on subsequent draws. Thus, if you call this and then
+ * never draw to the canvas subsequently you may pay a perfomance penalty.
+ */
+ void discard() { this->onDiscard(); }
+
+ /**
+ * Fill the entire canvas' bitmap (restricted to the current clip) with the
+ * specified paint.
+ * @param paint The paint used to fill the canvas
+ */
+ virtual void drawPaint(const SkPaint& paint);
+
+ enum PointMode {
+ /** drawPoints draws each point separately */
+ kPoints_PointMode,
+ /** drawPoints draws each pair of points as a line segment */
+ kLines_PointMode,
+ /** drawPoints draws the array of points as a polygon */
+ kPolygon_PointMode
+ };
+
+ /** Draw a series of points, interpreted based on the PointMode mode. For
+ all modes, the count parameter is interpreted as the total number of
+ points. For kLine mode, count/2 line segments are drawn.
+ For kPoint mode, each point is drawn centered at its coordinate, and its
+ size is specified by the paint's stroke-width. It draws as a square,
+ unless the paint's cap-type is round, in which the points are drawn as
+ circles.
+ For kLine mode, each pair of points is drawn as a line segment,
+ respecting the paint's settings for cap/join/width.
+ For kPolygon mode, the entire array is drawn as a series of connected
+ line segments.
+ Note that, while similar, kLine and kPolygon modes draw slightly
+ differently than the equivalent path built with a series of moveto,
+ lineto calls, in that the path will draw all of its contours at once,
+ with no interactions if contours intersect each other (think XOR
+ xfermode). drawPoints always draws each element one at a time.
+ @param mode PointMode specifying how to draw the array of points.
+ @param count The number of points in the array
+ @param pts Array of points to draw
+ @param paint The paint used to draw the points
+ */
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint);
+
+ /** Helper method for drawing a single point. See drawPoints() for a more
+ 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
+ @param color The color to draw
+ */
+ void drawPoint(SkScalar x, SkScalar y, SkColor color);
+
+ /** Draw a line segment with the specified start and stop x,y coordinates,
+ using the specified paint. NOTE: since a line is always "framed", the
+ paint's Style is ignored.
+ @param x0 The x-coordinate of the start point of the line
+ @param y0 The y-coordinate of the start point of the line
+ @param x1 The x-coordinate of the end point of the line
+ @param y1 The y-coordinate of the end point of the line
+ @param paint The paint used to draw the line
+ */
+ void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
+ const SkPaint& paint);
+
+ /** Draw the specified rectangle using the specified paint. The rectangle
+ will be filled or stroked based on the Style in the paint.
+ @param rect The rect to be drawn
+ @param paint The paint used to draw the rect
+ */
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint);
+
+ /** Draw the specified rectangle using the specified paint. The rectangle
+ will be filled or framed based on the Style in the paint.
+ @param rect The rect to be drawn
+ @param paint The paint used to draw the rect
+ */
+ void drawIRect(const SkIRect& rect, const SkPaint& paint) {
+ SkRect r;
+ 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
+ @param top The top side of the rectangle to be drawn
+ @param right The right side of the rectangle to be drawn
+ @param bottom The bottom side of the rectangle to be drawn
+ @param paint The paint used to draw the rect
+ */
+ void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
+ SkScalar bottom, const SkPaint& paint);
+
+ /** Draw the specified oval using the specified paint. The oval will be
+ filled or framed based on the Style in the paint.
+ @param oval The rectangle bounds of the oval to be drawn
+ @param paint The paint used to draw the oval
+ */
+ virtual void drawOval(const SkRect& oval, const SkPaint&);
+
+ /**
+ * Draw the specified RRect using the specified paint The rrect will be filled or stroked
+ * based on the Style in the paint.
+ *
+ * @param rrect The round-rect to draw
+ * @param paint The paint used to draw the round-rect
+ */
+ virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint);
+
+ /**
+ * Draw the annulus formed by the outer and inner rrects. The results
+ * are undefined if the outer does not contain the inner.
+ */
+ void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&);
+
+ /** Draw the specified circle using the specified paint. If radius is <= 0,
+ then nothing will be drawn. The circle will be filled
+ or framed based on the Style in the paint.
+ @param cx The x-coordinate of the center of the cirle to be drawn
+ @param cy The y-coordinate of the center of the cirle to be drawn
+ @param radius The radius of the cirle to be drawn
+ @param paint The paint used to draw the circle
+ */
+ void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
+ const SkPaint& paint);
+
+ /** Draw the specified arc, which will be scaled to fit inside the
+ specified oval. If the sweep angle is >= 360, then the oval is drawn
+ completely. Note that this differs slightly from SkPath::arcTo, which
+ treats the sweep angle mod 360.
+ @param oval The bounds of oval used to define the shape of the arc
+ @param startAngle Starting angle (in degrees) where the arc begins
+ @param sweepAngle Sweep angle (in degrees) measured clockwise
+ @param useCenter true means include the center of the oval. For filling
+ this will draw a wedge. False means just use the arc.
+ @param paint The paint used to draw the arc
+ */
+ void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
+ bool useCenter, const SkPaint& paint);
+
+ /** Draw the specified round-rect using the specified paint. The round-rect
+ will be filled or framed based on the Style in the paint.
+ @param rect The rectangular bounds of the roundRect to be drawn
+ @param rx The x-radius of the oval used to round the corners
+ @param ry The y-radius of the oval used to round the corners
+ @param paint The paint used to draw the roundRect
+ */
+ void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
+ const SkPaint& paint);
+
+ /** Draw the specified path using the specified paint. The path will be
+ filled or framed based on the Style in the paint.
+ @param path The path to be drawn
+ @param paint The paint used to draw the path
+ */
+ virtual void drawPath(const SkPath& path, const SkPaint& paint);
+
+ virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
+ const SkPaint* paint = NULL);
+
+ virtual void drawImageRect(const SkImage* image, const SkRect* src,
+ const SkRect& dst,
+ const SkPaint* paint = NULL);
+
+ /** Draw the specified bitmap, with its top/left corner at (x,y), using the
+ specified paint, transformed by the current matrix. Note: if the paint
+ contains a maskfilter that generates a mask which extends beyond the
+ bitmap's original width/height, then the bitmap will be drawn as if it
+ were in a Shader with CLAMP mode. Thus the color outside of the original
+ width/height will be the edge color replicated.
+
+ If a shader is present on the paint it will be ignored, except in the
+ case where the bitmap is kAlpha_8_SkColorType. In that case, the color is
+ generated by the shader.
+
+ @param bitmap The bitmap to be drawn
+ @param left The position of the left side of the bitmap being drawn
+ @param top The position of the top side of the bitmap being drawn
+ @param paint The paint used to draw the bitmap, or NULL
+ */
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint = NULL);
+
+ enum DrawBitmapRectFlags {
+ kNone_DrawBitmapRectFlag = 0x0,
+ /**
+ * When filtering is enabled, allow the color samples outside of
+ * the src rect (but still in the src bitmap) to bleed into the
+ * drawn portion
+ */
+ kBleed_DrawBitmapRectFlag = 0x1,
+ };
+
+ /** Draw the specified bitmap, with the specified matrix applied (before the
+ canvas' matrix is applied).
+ @param bitmap The bitmap to be drawn
+ @param src Optional: specify the subset of the bitmap to be drawn
+ @param dst The destination rectangle where the scaled/translated
+ image will be drawn
+ @param paint The paint used to draw the bitmap, or NULL
+ */
+ virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
+ const SkRect& dst,
+ const SkPaint* paint = NULL,
+ DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag);
+
+ void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
+ const SkPaint* paint = NULL) {
+ this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag);
+ }
+
+ void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* isrc,
+ const SkRect& dst, const SkPaint* paint = NULL,
+ DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag) {
+ SkRect realSrcStorage;
+ SkRect* realSrcPtr = NULL;
+ if (isrc) {
+ realSrcStorage.set(*isrc);
+ realSrcPtr = &realSrcStorage;
+ }
+ this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint, flags);
+ }
+
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint = NULL);
+
+ /**
+ * Draw the bitmap stretched differentially to fit into dst.
+ * center is a rect within the bitmap, and logically divides the bitmap
+ * into 9 sections (3x3). For example, if the middle pixel of a [5x5]
+ * bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
+ *
+ * If the dst is >= the bitmap size, then...
+ * - The 4 corners are not stretched at all.
+ * - The sides are stretched in only one axis.
+ * - The center is stretched in both axes.
+ * Else, for each axis where dst < bitmap,
+ * - The corners shrink proportionally
+ * - The sides (along the shrink axis) and center are not drawn
+ */
+ virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, 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
+ bitmap's original width/height, then the bitmap will be drawn as if it
+ were in a Shader with CLAMP mode. Thus the color outside of the original
+ width/height will be the edge color replicated.
+ @param bitmap The bitmap to be drawn
+ @param left The position of the left side of the bitmap being drawn
+ @param top The position of the top side of the bitmap being drawn
+ @param paint The paint used to draw the bitmap, or NULL
+ */
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint = NULL);
+
+ /** Draw the text, with origin at (x,y), using the specified paint.
+ The origin is interpreted based on 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 x The x-coordinate of the origin of the text being drawn
+ @param y The y-coordinate of the origin of the text being drawn
+ @param paint The paint used for the text (e.g. color, size, style)
+ */
+ SK_LEGACY_DRAWTEXT_VIRTUAL void drawText(const void* text, size_t byteLength, SkScalar x,
+ 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.
+ @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
+ @param paint The paint used for the text (e.g. color, size, style)
+ */
+ SK_LEGACY_DRAWTEXT_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.
+ @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
+ @param constY The shared Y coordinate for all of the positions
+ @param paint The paint used for the text (e.g. color, size, style)
+ */
+ SK_LEGACY_DRAWTEXT_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.
+ @param text The text to be drawn
+ @param byteLength The number of bytes to read from the text parameter
+ @param path The path the text should follow for its baseline
+ @param hOffset The distance along the path to add to the text's
+ starting position
+ @param vOffset The distance above(-) or below(+) the path to
+ position the text
+ @param paint The paint used for the text
+ */
+ void drawTextOnPathHV(const void* text, size_t byteLength,
+ const SkPath& path, SkScalar hOffset,
+ SkScalar vOffset, 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.
+ @param text The text to be drawn
+ @param byteLength The number of bytes to read from the text parameter
+ @param path The path the text should follow for its baseline
+ @param matrix (may be null) Applied to the text before it is
+ mapped onto the path
+ @param paint The paint used for the text
+ */
+ SK_LEGACY_DRAWTEXT_VIRTUAL void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint);
+
+ /** Draw the text blob, offset by (x,y), using the specified paint.
+ @param blob The text blob to be drawn
+ @param x The x-offset of the text being drawn
+ @param y The y-offset of the text being drawn
+ @param paint The paint used for the text (e.g. color, size, style)
+ */
+ void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
+
+ /** PRIVATE / EXPERIMENTAL -- do not call
+ Perform back-end analysis/optimization of a picture. This may attach
+ optimization data to the picture which can be used by a later
+ drawPicture call.
+ @param picture The recorded drawing commands to analyze/optimize
+ */
+ void EXPERIMENTAL_optimize(const SkPicture* picture);
+
+ /** Draw the picture into this canvas. This method effective brackets the
+ playback of the picture's draw calls with save/restore, so the state
+ of this canvas will be unchanged after this call.
+ @param picture The recorded drawing commands to playback into this
+ canvas.
+ */
+ void drawPicture(const SkPicture* picture);
+
+ /**
+ * Draw the picture into this canvas.
+ *
+ * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
+ * logically equivalent to
+ * save/concat/drawPicture/restore
+ *
+ * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
+ * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
+ * This is logically equivalent to
+ * saveLayer(paint)/drawPicture/restore
+ */
+ void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint);
+
+ enum VertexMode {
+ kTriangles_VertexMode,
+ kTriangleStrip_VertexMode,
+ kTriangleFan_VertexMode
+ };
+
+ /** Draw the array of vertices, interpreted as triangles (based on mode).
+
+ If both textures and vertex-colors are NULL, it strokes hairlines with
+ the paint's color. This behavior is a useful debugging mode to visualize
+ the mesh.
+
+ @param vmode How to interpret the array of vertices
+ @param vertexCount The number of points in the vertices array (and
+ corresponding texs and colors arrays if non-null)
+ @param vertices Array of vertices for the mesh
+ @param texs May be null. If not null, specifies the coordinate
+ in _texture_ space (not uv space) for each vertex.
+ @param colors May be null. If not null, specifies a color for each
+ vertex, to be interpolated across the triangle.
+ @param xmode Used if both texs and colors are present. In this
+ case the colors are combined with the texture using mode,
+ before being drawn using the paint. If mode is null, then
+ kModulate_Mode is used.
+ @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.
+ */
+ virtual void drawVertices(VertexMode vmode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint);
+
+ /**
+ Draw a cubic coons patch
+
+ @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
+ starting at the top left corner.
+ @param colors specifies the colors for the corners which will be bilerp across the patch,
+ their order is clockwise starting at the top left corner.
+ @param texCoords specifies the texture coordinates that will be bilerp across the patch,
+ their order is the same as the colors.
+ @param xmode specifies how are the colors and the textures combined if both of them are
+ present.
+ @param paint Specifies the shader/texture if present.
+ */
+ void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
+
+ /** Send a blob of data to the canvas.
+ For canvases that draw, this call is effectively a no-op, as the data
+ is not parsed, but just ignored. However, this call exists for
+ subclasses like SkPicture's recording canvas, that can store the data
+ and then play it back later (via another call to drawData).
+ */
+ virtual void drawData(const void* data, size_t length) {
+ // do nothing. Subclasses may do something with the data
+ }
+
+ /** Add comments. beginCommentGroup/endCommentGroup open/close a new group.
+ Each comment added via addComment is notionally attached to its
+ enclosing group. Top-level comments simply belong to no group.
+ */
+ virtual void beginCommentGroup(const char* description) {
+ // do nothing. Subclasses may do something
+ }
+ virtual void addComment(const char* kywd, const char* value) {
+ // do nothing. Subclasses may do something
+ }
+ virtual void endCommentGroup() {
+ // do nothing. Subclasses may do something
+ }
+
+ /**
+ * With this call the client asserts that subsequent draw operations (up to the
+ * matching popCull()) are fully contained within the given bounding box. The assertion
+ * is not enforced, but the information might be used to quick-reject command blocks,
+ * so an incorrect bounding box may result in incomplete rendering.
+ */
+ void pushCull(const SkRect& cullRect);
+
+ /**
+ * Terminates the current culling block, and restores the previous one (if any).
+ */
+ void popCull();
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /** 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
+ refcnt is incremented. The filter is saved/restored, just like the
+ matrix and clip.
+ @param filter the new filter (or NULL)
+ @return the new filter
+ */
+ virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Return true if the current clip is empty (i.e. nothing will draw).
+ * Note: this is not always a free call, so it should not be used
+ * more often than necessary. However, once the canvas has computed this
+ * result, subsequent calls will be cheap (until the clip state changes,
+ * which can happen on any clip..() or restore() call.
+ */
+ virtual bool isClipEmpty() const;
+
+ /**
+ * Returns true if the current clip is just a (non-empty) rectangle.
+ * Returns false if the clip is empty, or if it is complex.
+ */
+ virtual bool isClipRect() const;
+
+ /** Return the current matrix on the canvas.
+ This does not account for the translate in any of the devices.
+ @return The current matrix on the canvas.
+ */
+ const SkMatrix& getTotalMatrix() const;
+
+ /** Return the clip stack. The clip stack stores all the individual
+ * clips organized by the save/restore frame in which they were
+ * added.
+ * @return the current clip stack ("list" of individual clip elements)
+ */
+ const SkClipStack* getClipStack() const {
+ return &fClipStack;
+ }
+
+ typedef SkCanvasClipVisitor ClipVisitor;
+ /**
+ * Replays the clip operations, back to front, that have been applied to
+ * the canvas, calling the appropriate method on the visitor for each
+ * clip. All clips have already been transformed into device space.
+ */
+ void replayClips(ClipVisitor*) const;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** After calling saveLayer(), there can be any number of devices that make
+ up the top-most drawing area. LayerIter can be used to iterate through
+ those devices. Note that the iterator is only valid until the next API
+ call made on the canvas. Ownership of all pointers in the iterator stays
+ with the canvas, so none of them should be modified or deleted.
+ */
+ class SK_API LayerIter /*: SkNoncopyable*/ {
+ 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
+
+ SkBaseDevice* device() const;
+ const SkMatrix& matrix() const;
+ const SkRegion& clip() const;
+ 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[32];
+ class SkDrawIter* fImpl; // this points at fStorage
+ SkPaint fDefaultPaint;
+ bool fDone;
+ };
+
+ // don't call
+ GrRenderTarget* internal_private_accessTopLayerRenderTarget();
+
+protected:
+ // default impl defers to getDevice()->newSurface(info)
+ virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&);
+
+ // default impl defers to its device
+ virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes);
+ virtual void* onAccessTopLayerPixels(SkImageInfo*, size_t* rowBytes);
+
+ // Subclass save/restore notifiers.
+ // Overriders should call the corresponding INHERITED method up the inheritance chain.
+ // willSaveLayer()'s return value may suppress full layer allocation.
+ enum SaveLayerStrategy {
+ kFullLayer_SaveLayerStrategy,
+ kNoLayer_SaveLayerStrategy
+ };
+
+ virtual void willSave() {}
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) {
+ return kFullLayer_SaveLayerStrategy;
+ }
+ virtual void willRestore() {}
+ virtual void didRestore() {}
+ virtual void didConcat(const SkMatrix&) {}
+ virtual void didSetMatrix(const SkMatrix&) {}
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
+
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint);
+
+ virtual void onDrawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint);
+
+ virtual void onDrawPosTextH(const void* text, size_t byteLength,
+ const SkScalar xpos[], SkScalar constY,
+ const SkPaint& paint);
+
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint);
+
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint);
+
+ virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
+
+ enum ClipEdgeStyle {
+ kHard_ClipEdgeStyle,
+ kSoft_ClipEdgeStyle
+ };
+
+ virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
+ virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
+ virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle);
+ virtual void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op);
+
+ virtual void onDiscard();
+
+ virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
+
+ // Returns the canvas to be used by DrawIter. Default implementation
+ // returns this. Subclasses that encapsulate an indirect canvas may
+ // need to overload this method. The impl must keep track of this, as it
+ // is not released or deleted by the caller.
+ virtual SkCanvas* canvasForDrawIter();
+
+ // Clip rectangle bounds. Called internally by saveLayer.
+ // returns false if the entire rectangle is entirely clipped out
+ // If non-NULL, The imageFilter parameter will be used to expand the clip
+ // and offscreen bounds for any margin required by the filter DAG.
+ bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
+ SkIRect* intersection,
+ const SkImageFilter* imageFilter = NULL);
+
+ // notify our surface (if we have one) that we are about to draw, so it
+ // can perform copy-on-write or invalidate any cached images
+ void predrawNotify();
+
+ virtual void onPushCull(const SkRect& cullRect);
+ virtual void onPopCull();
+
+private:
+ class MCRec;
+
+ SkClipStack fClipStack;
+ SkDeque fMCStack;
+ // points to top of stack
+ MCRec* fMCRec;
+ // the first N recs that can fit here mean we won't call malloc
+ uint32_t fMCRecStorage[32];
+
+ const SkSurfaceProps fProps;
+
+ int fSaveLayerCount; // number of successful saveLayer calls
+ int fCullCount; // number of active culls
+
+ SkMetaData* fMetaData;
+
+ SkSurface_Base* fSurfaceBase;
+ SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
+ void setSurfaceBase(SkSurface_Base* sb) {
+ fSurfaceBase = sb;
+ }
+ friend class SkSurface_Base;
+ friend class SkSurface_Gpu;
+
+ bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
+ void updateDeviceCMCache();
+
+ friend class SkDrawIter; // needs setupDrawForLayerDevice()
+ friend class AutoDrawLooper;
+ friend class SkLua; // needs top layer size and offset
+ friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
+ friend class SkDeferredDevice; // needs getTopDevice()
+ friend class SkSurface_Raster; // needs getDevice()
+ friend class SkRecorder; // InitFlags
+ friend class SkNoSaveLayerCanvas; // InitFlags
+
+ enum InitFlags {
+ kDefault_InitFlags = 0,
+ kConservativeRasterClip_InitFlag = 1 << 0,
+ };
+ SkCanvas(int width, int height, InitFlags);
+ SkCanvas(SkBaseDevice*, const SkSurfaceProps*, InitFlags);
+ SkCanvas(const SkBitmap&, const SkSurfaceProps&);
+
+ // needs gettotalclip()
+ friend SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas*);
+
+ SkBaseDevice* createLayerDevice(const SkImageInfo&);
+
+ // call this each time we attach ourselves to a device
+ // - constructor
+ // - internalSaveLayer
+ void setupDevice(SkBaseDevice*);
+
+ SkBaseDevice* init(SkBaseDevice*, InitFlags);
+
+ /**
+ * DEPRECATED
+ *
+ * Specify a device for this canvas to draw into. If it is not null, its
+ * reference count is incremented. If the canvas was already holding a
+ * device, its reference count is decremented. The new device is returned.
+ */
+ SkBaseDevice* setRootDevice(SkBaseDevice* device);
+
+ /**
+ * Gets the size/origin of the top level layer in global canvas coordinates. We don't want this
+ * to be public because it exposes decisions about layer sizes that are internal to the canvas.
+ */
+ SkISize getTopLayerSize() const;
+ SkIPoint getTopLayerOrigin() const;
+
+ // internal methods are not virtual, so they can safely be called by other
+ // canvas apis, without confusing subclasses (like SkPictureRecording)
+ void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint);
+ void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
+ const SkRect& dst, const SkPaint* paint,
+ DrawBitmapRectFlags flags);
+ void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint* paint);
+ void internalDrawPaint(const SkPaint& paint);
+ int internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
+ SaveFlags, bool justForImageFilter, SaveLayerStrategy strategy);
+ void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
+
+ // shared by save() and saveLayer()
+ int internalSave();
+ void internalRestore();
+ static void DrawRect(const SkDraw& draw, const SkPaint& paint,
+ const SkRect& r, SkScalar textSize);
+ static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y);
+
+ // only for canvasutils
+ const SkRegion& internal_private_getTotalClip() const;
+
+ /* These maintain a cache of the clip bounds in local coordinates,
+ (converted to 2s-compliment if floats are slow).
+ */
+ mutable SkRect fCachedLocalClipBounds;
+ mutable bool fCachedLocalClipBoundsDirty;
+ bool fAllowSoftClip;
+ bool fAllowSimplifyClip;
+ bool fConservativeRasterClip;
+
+ const SkRect& getLocalClipBounds() const {
+ if (fCachedLocalClipBoundsDirty) {
+ if (!this->getClipBounds(&fCachedLocalClipBounds)) {
+ fCachedLocalClipBounds.setEmpty();
+ }
+ fCachedLocalClipBoundsDirty = false;
+ }
+ return fCachedLocalClipBounds;
+ }
+
+ class AutoValidateClip : ::SkNoncopyable {
+ public:
+ explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
+ fCanvas->validateClip();
+ }
+ ~AutoValidateClip() { fCanvas->validateClip(); }
+
+ private:
+ const SkCanvas* fCanvas;
+ };
+
+#ifdef SK_DEBUG
+ // The cull stack rects are in device-space
+ SkTDArray<SkIRect> fCullStack;
+ void validateCull(const SkIRect&);
+ void validateClip() const;
+#else
+ void validateClip() const {}
+#endif
+
+ typedef SkRefCnt INHERITED;
+};
+
+/** Stack helper class to automatically call restoreToCount() on the canvas
+ when this object goes out of scope. Use this to guarantee that the canvas
+ is restored to a known state.
+*/
+class SkAutoCanvasRestore : SkNoncopyable {
+public:
+ SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
+ if (fCanvas) {
+ fSaveCount = canvas->getSaveCount();
+ if (doSave) {
+ canvas->save();
+ }
+ }
+ }
+ ~SkAutoCanvasRestore() {
+ if (fCanvas) {
+ fCanvas->restoreToCount(fSaveCount);
+ }
+ }
+
+ /**
+ * Perform the restore now, instead of waiting for the destructor. Will
+ * only do this once.
+ */
+ void restore() {
+ if (fCanvas) {
+ fCanvas->restoreToCount(fSaveCount);
+ fCanvas = NULL;
+ }
+ }
+
+private:
+ SkCanvas* fCanvas;
+ int fSaveCount;
+};
+#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
+
+/** Stack helper class to automatically open and close a comment block
+ */
+class SkAutoCommentBlock : SkNoncopyable {
+public:
+ SkAutoCommentBlock(SkCanvas* canvas, const char* description) {
+ fCanvas = canvas;
+ if (fCanvas) {
+ fCanvas->beginCommentGroup(description);
+ }
+ }
+
+ ~SkAutoCommentBlock() {
+ if (fCanvas) {
+ fCanvas->endCommentGroup();
+ }
+ }
+
+private:
+ SkCanvas* fCanvas;
+};
+#define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock)
+
+/**
+ * If the caller wants read-only access to the pixels in a canvas, it can just
+ * call canvas->peekPixels(), since that is the fastest way to "peek" at the
+ * pixels on a raster-backed canvas.
+ *
+ * If the canvas has pixels, but they are not readily available to the CPU
+ * (e.g. gpu-backed), then peekPixels() will fail, but readPixels() will
+ * succeed (though be slower, since it will return a copy of the pixels).
+ *
+ * SkAutoROCanvasPixels encapsulates these two techniques, trying first to call
+ * peekPixels() (for performance), but if that fails, calling readPixels() and
+ * storing the copy locally.
+ *
+ * The caller must respect the restrictions associated with peekPixels(), since
+ * that may have been called: The returned information is invalidated if...
+ * - any API is called on the canvas (or its parent surface if present)
+ * - the canvas goes out of scope
+ */
+class SkAutoROCanvasPixels : SkNoncopyable {
+public:
+ SkAutoROCanvasPixels(SkCanvas* canvas);
+
+ // returns NULL on failure
+ const void* addr() const { return fAddr; }
+
+ // undefined if addr() == NULL
+ size_t rowBytes() const { return fRowBytes; }
+
+ // undefined if addr() == NULL
+ const SkImageInfo& info() const { return fInfo; }
+
+ // helper that, if returns true, installs the pixels into the bitmap. Note
+ // that the bitmap may reference the address returned by peekPixels(), so
+ // the caller must respect the restrictions associated with peekPixels().
+ bool asROBitmap(SkBitmap*) const;
+
+private:
+ SkBitmap fBitmap; // used if peekPixels() fails
+ const void* fAddr; // NULL on failure
+ SkImageInfo fInfo;
+ size_t fRowBytes;
+};
+
+static inline SkCanvas::SaveFlags operator|(const SkCanvas::SaveFlags lhs,
+ const SkCanvas::SaveFlags rhs) {
+ return static_cast<SkCanvas::SaveFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
+}
+
+static inline SkCanvas::SaveFlags& operator|=(SkCanvas::SaveFlags& lhs,
+ const SkCanvas::SaveFlags rhs) {
+ lhs = lhs | rhs;
+ return lhs;
+}
+
+class SkCanvasClipVisitor {
+public:
+ virtual ~SkCanvasClipVisitor();
+ virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
+ virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
+ virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkChunkAlloc.h b/src/third_party/skia/include/core/SkChunkAlloc.h
new file mode 100644
index 0000000..e13e2b9
--- /dev/null
+++ b/src/third_party/skia/include/core/SkChunkAlloc.h
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkChunkAlloc_DEFINED
+#define SkChunkAlloc_DEFINED
+
+#include "SkTypes.h"
+
+class SkChunkAlloc : SkNoncopyable {
+public:
+ SkChunkAlloc(size_t minSize);
+ ~SkChunkAlloc();
+
+ /**
+ * Free up all allocated blocks. This invalidates all returned
+ * pointers.
+ */
+ void reset();
+
+ enum AllocFailType {
+ kReturnNil_AllocFailType,
+ kThrow_AllocFailType
+ };
+
+ void* alloc(size_t bytes, AllocFailType);
+ void* allocThrow(size_t bytes) {
+ return this->alloc(bytes, kThrow_AllocFailType);
+ }
+
+ /** Call this to unalloc the most-recently allocated ptr by alloc(). On
+ success, the number of bytes freed is returned, or 0 if the block could
+ not be unallocated. This is a hint to the underlying allocator that
+ the previous allocation may be reused, but the implementation is free
+ to ignore this call (and return 0).
+ */
+ size_t unalloc(void* ptr);
+
+ size_t totalCapacity() const { return fTotalCapacity; }
+ size_t totalUsed() const { return fTotalUsed; }
+ int blockCount() const { return fBlockCount; }
+
+ /**
+ * 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;
+ size_t fMinSize;
+ size_t fChunkSize;
+ size_t fTotalCapacity;
+ size_t fTotalUsed; // will be <= fTotalCapacity
+ int fBlockCount;
+
+ Block* newBlock(size_t bytes, AllocFailType ftype);
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkClipStack.h b/src/third_party/skia/include/core/SkClipStack.h
new file mode 100644
index 0000000..95e41e6
--- /dev/null
+++ b/src/third_party/skia/include/core/SkClipStack.h
@@ -0,0 +1,479 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkClipStack_DEFINED
+#define SkClipStack_DEFINED
+
+#include "SkDeque.h"
+#include "SkPath.h"
+#include "SkRect.h"
+#include "SkRRect.h"
+#include "SkRegion.h"
+#include "SkTDArray.h"
+#include "SkTLazy.h"
+
+class SkCanvasClipVisitor;
+
+// Because a single save/restore state can have multiple clips, this class
+// stores the stack depth (fSaveCount) and clips (fDeque) separately.
+// Each clip in fDeque stores the stack state to which it belongs
+// (i.e., the fSaveCount in force when it was added). Restores are thus
+// implemented by removing clips from fDeque that have an fSaveCount larger
+// then the freshly decremented count.
+class SK_API SkClipStack {
+public:
+ enum BoundsType {
+ // The bounding box contains all the pixels that can be written to
+ kNormal_BoundsType,
+ // The bounding box contains all the pixels that cannot be written to.
+ // The real bound extends out to infinity and all the pixels outside
+ // of the bound can be written to. Note that some of the pixels inside
+ // the bound may also be writeable but all pixels that cannot be
+ // written to are guaranteed to be inside.
+ kInsideOut_BoundsType
+ };
+
+ class Element {
+ public:
+ enum Type {
+ //!< This element makes the clip empty (regardless of previous elements).
+ kEmpty_Type,
+ //!< This element combines a rect with the current clip using a set operation
+ kRect_Type,
+ //!< This element combines a round-rect with the current clip using a set operation
+ kRRect_Type,
+ //!< This element combines a path with the current clip using a set operation
+ kPath_Type,
+
+ kLastType = kPath_Type
+ };
+ static const int kTypeCnt = kLastType + 1;
+
+ Element() {
+ this->initCommon(0, SkRegion::kReplace_Op, false);
+ this->setEmpty();
+ }
+
+ Element(const Element&);
+
+ Element(const SkRect& rect, SkRegion::Op op, bool doAA) {
+ this->initRect(0, rect, op, doAA);
+ }
+
+ Element(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ this->initRRect(0, rrect, op, doAA);
+ }
+
+ Element(const SkPath& path, SkRegion::Op op, bool doAA) {
+ this->initPath(0, path, op, doAA);
+ }
+
+ bool operator== (const Element& element) const;
+ bool operator!= (const Element& element) const { return !(*this == element); }
+
+ //!< Call to get the type of the clip element.
+ Type getType() const { return fType; }
+
+ //!< Call to get the save count associated with this clip element.
+ int getSaveCount() const { return fSaveCount; }
+
+ //!< Call if getType() is kPath to get the path.
+ const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return *fPath.get(); }
+
+ //!< Call if getType() is kRRect to get the round-rect.
+ const SkRRect& getRRect() const { SkASSERT(kRRect_Type == fType); return fRRect; }
+
+ //!< Call if getType() is kRect to get the rect.
+ const SkRect& getRect() const {
+ SkASSERT(kRect_Type == fType && (fRRect.isRect() || fRRect.isEmpty()));
+ return fRRect.getBounds();
+ }
+
+ //!< Call if getType() is not kEmpty to get the set operation used to combine this element.
+ SkRegion::Op getOp() const { return fOp; }
+
+ //!< Call to get the element as a path, regardless of its type.
+ void asPath(SkPath* path) const;
+
+ /** If getType() is not kEmpty this indicates whether the clip shape should be anti-aliased
+ when it is rasterized. */
+ bool isAA() const { return fDoAA; }
+
+ //!< Inverts the fill of the clip shape. Note that a kEmpty element remains kEmpty.
+ void invertShapeFillType();
+
+ //!< Sets the set operation represented by the element.
+ void setOp(SkRegion::Op op) { fOp = op; }
+
+ /** The GenID can be used by clip stack clients to cache representations of the clip. The
+ ID corresponds to the set of clip elements up to and including this element within the
+ stack not to the element itself. That is the same clip path in different stacks will
+ have a different ID since the elements produce different clip result in the context of
+ their stacks. */
+ int32_t getGenID() const { SkASSERT(kInvalidGenID != fGenID); return fGenID; }
+
+ /**
+ * Gets the bounds of the clip element, either the rect or path bounds. (Whether the shape
+ * is inverse filled is not considered.)
+ */
+ const SkRect& getBounds() const {
+ static const SkRect kEmpty = { 0, 0, 0, 0 };
+ switch (fType) {
+ case kRect_Type: // fallthrough
+ case kRRect_Type:
+ return fRRect.getBounds();
+ case kPath_Type:
+ return fPath.get()->getBounds();
+ case kEmpty_Type:
+ return kEmpty;
+ default:
+ SkDEBUGFAIL("Unexpected type.");
+ return kEmpty;
+ }
+ }
+
+ /**
+ * Conservatively checks whether the clip shape contains the rect param. (Whether the shape
+ * is inverse filled is not considered.)
+ */
+ bool contains(const SkRect& rect) const {
+ switch (fType) {
+ case kRect_Type:
+ return this->getRect().contains(rect);
+ case kRRect_Type:
+ return fRRect.contains(rect);
+ case kPath_Type:
+ return fPath.get()->conservativelyContainsRect(rect);
+ case kEmpty_Type:
+ return false;
+ default:
+ SkDEBUGFAIL("Unexpected type.");
+ return false;
+ }
+ }
+
+ /**
+ * Is the clip shape inverse filled.
+ */
+ bool isInverseFilled() const {
+ return kPath_Type == fType && fPath.get()->isInverseFillType();
+ }
+
+ /**
+ * Replay this clip into the visitor.
+ */
+ void replay(SkCanvasClipVisitor*) const;
+
+#ifdef SK_DEVELOPER
+ /**
+ * Dumps the element to SkDebugf. This is intended for Skia development debugging
+ * Don't rely on the existence of this function or the formatting of its output.
+ */
+ void dump() const;
+#endif
+
+ private:
+ friend class SkClipStack;
+
+ SkTLazy<SkPath> fPath;
+ SkRRect fRRect;
+ int fSaveCount; // save count of stack when this element was added.
+ SkRegion::Op fOp;
+ Type fType;
+ bool fDoAA;
+
+ /* fFiniteBoundType and fFiniteBound are used to incrementally update the clip stack's
+ bound. When fFiniteBoundType is kNormal_BoundsType, fFiniteBound represents the
+ conservative bounding box of the pixels that aren't clipped (i.e., any pixels that can be
+ drawn to are inside the bound). When fFiniteBoundType is kInsideOut_BoundsType (which
+ occurs when a clip is inverse filled), fFiniteBound represents the conservative bounding
+ box of the pixels that _are_ clipped (i.e., any pixels that cannot be drawn to are inside
+ the bound). When fFiniteBoundType is kInsideOut_BoundsType the actual bound is the
+ infinite plane. This behavior of fFiniteBoundType and fFiniteBound is required so that we
+ can capture the cancelling out of the extensions to infinity when two inverse filled
+ clips are Booleaned together. */
+ SkClipStack::BoundsType fFiniteBoundType;
+ SkRect fFiniteBound;
+
+ // When element is applied to the previous elements in the stack is the result known to be
+ // equivalent to a single rect intersection? IIOW, is the clip effectively a rectangle.
+ bool fIsIntersectionOfRects;
+
+ int fGenID;
+
+ Element(int saveCount) {
+ this->initCommon(saveCount, SkRegion::kReplace_Op, false);
+ this->setEmpty();
+ }
+
+ Element(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ this->initRRect(saveCount, rrect, op, doAA);
+ }
+
+ Element(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) {
+ this->initRect(saveCount, rect, op, doAA);
+ }
+
+ Element(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) {
+ this->initPath(saveCount, path, op, doAA);
+ }
+
+ void initCommon(int saveCount, SkRegion::Op op, bool doAA) {
+ fSaveCount = saveCount;
+ fOp = op;
+ fDoAA = doAA;
+ // A default of inside-out and empty bounds means the bounds are effectively void as it
+ // indicates that nothing is known to be outside the clip.
+ fFiniteBoundType = kInsideOut_BoundsType;
+ fFiniteBound.setEmpty();
+ fIsIntersectionOfRects = false;
+ fGenID = kInvalidGenID;
+ }
+
+ void initRect(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) {
+ fRRect.setRect(rect);
+ fType = kRect_Type;
+ this->initCommon(saveCount, op, doAA);
+ }
+
+ void initRRect(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ SkRRect::Type type = rrect.getType();
+ fRRect = rrect;
+ if (SkRRect::kRect_Type == type || SkRRect::kEmpty_Type == type) {
+ fType = kRect_Type;
+ } else {
+ fType = kRRect_Type;
+ }
+ this->initCommon(saveCount, op, doAA);
+ }
+
+ void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA);
+
+ void setEmpty();
+
+ // All Element methods below are only used within SkClipStack.cpp
+ inline void checkEmpty() const;
+ inline bool canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const;
+ /* This method checks to see if two rect clips can be safely merged into one. The issue here
+ is that to be strictly correct all the edges of the resulting rect must have the same
+ anti-aliasing. */
+ bool rectRectIntersectAllowed(const SkRect& newR, bool newAA) const;
+ /** Determines possible finite bounds for the Element given the previous element of the
+ stack */
+ void updateBoundAndGenID(const Element* prior);
+ // The different combination of fill & inverse fill when combining bounding boxes
+ enum FillCombo {
+ kPrev_Cur_FillCombo,
+ kPrev_InvCur_FillCombo,
+ kInvPrev_Cur_FillCombo,
+ kInvPrev_InvCur_FillCombo
+ };
+ // per-set operation functions used by updateBoundAndGenID().
+ inline void combineBoundsDiff(FillCombo combination, const SkRect& prevFinite);
+ inline void combineBoundsXOR(int combination, const SkRect& prevFinite);
+ inline void combineBoundsUnion(int combination, const SkRect& prevFinite);
+ inline void combineBoundsIntersection(int combination, const SkRect& prevFinite);
+ inline void combineBoundsRevDiff(int combination, const SkRect& prevFinite);
+ };
+
+ SkClipStack();
+ SkClipStack(const SkClipStack& b);
+ explicit SkClipStack(const SkRect& r);
+ explicit SkClipStack(const SkIRect& r);
+ ~SkClipStack();
+
+ SkClipStack& operator=(const SkClipStack& b);
+ bool operator==(const SkClipStack& b) const;
+ bool operator!=(const SkClipStack& b) const { return !(*this == b); }
+
+ void reset();
+
+ int getSaveCount() const { return fSaveCount; }
+ void save();
+ void restore();
+
+ /**
+ * getBounds places the current finite bound in its first parameter. In its
+ * second, it indicates which kind of bound is being returned. If
+ * 'canvFiniteBound' is a normal bounding box then it encloses all writeable
+ * pixels. If 'canvFiniteBound' is an inside out bounding box then it
+ * encloses all the un-writeable pixels and the true/normal bound is the
+ * infinite plane. isIntersectionOfRects is an optional parameter
+ * that is true if 'canvFiniteBound' resulted from an intersection of rects.
+ */
+ void getBounds(SkRect* canvFiniteBound,
+ BoundsType* boundType,
+ bool* isIntersectionOfRects = NULL) const;
+
+ /**
+ * Takes an input rect in device space and conservatively clips it to the
+ * clip-stack. If false is returned then the rect does not intersect the
+ * clip and is unmodified.
+ */
+ bool intersectRectWithClip(SkRect* devRect) const;
+
+ /**
+ * Returns true if the input rect in device space is entirely contained
+ * by the clip. A return value of false does not guarantee that the rect
+ * is not contained by the clip.
+ */
+ bool quickContains(const SkRect& devRect) const;
+
+ void clipDevRect(const SkIRect& ir, SkRegion::Op op) {
+ SkRect r;
+ r.set(ir);
+ this->clipDevRect(r, op, false);
+ }
+ void clipDevRect(const SkRect&, SkRegion::Op, bool doAA);
+ void clipDevRRect(const SkRRect&, SkRegion::Op, bool doAA);
+ void clipDevPath(const SkPath&, SkRegion::Op, bool doAA);
+ // An optimized version of clipDevRect(emptyRect, kIntersect, ...)
+ void clipEmpty();
+
+ /**
+ * isWideOpen returns true if the clip state corresponds to the infinite
+ * plane (i.e., draws are not limited at all)
+ */
+ bool isWideOpen() const;
+
+ /**
+ * The generation ID has three reserved values to indicate special
+ * (potentially ignorable) cases
+ */
+ static const int32_t kInvalidGenID = 0; //!< Invalid id that is never returned by
+ //!< SkClipStack. Useful when caching clips
+ //!< based on GenID.
+ static const int32_t kEmptyGenID = 1; // no pixels writeable
+ static const int32_t kWideOpenGenID = 2; // all pixels writeable
+
+ int32_t getTopmostGenID() const;
+
+#ifdef SK_DEVELOPER
+ /**
+ * Dumps the contents of the clip stack to SkDebugf. This is intended for Skia development
+ * debugging. Don't rely on the existence of this function or the formatting of its output.
+ */
+ void dump() const;
+#endif
+
+public:
+ class Iter {
+ public:
+ enum IterStart {
+ kBottom_IterStart = SkDeque::Iter::kFront_IterStart,
+ kTop_IterStart = SkDeque::Iter::kBack_IterStart
+ };
+
+ /**
+ * Creates an uninitialized iterator. Must be reset()
+ */
+ Iter();
+
+ Iter(const SkClipStack& stack, IterStart startLoc);
+
+ /**
+ * Return the clip element for this iterator. If next()/prev() returns NULL, then the
+ * iterator is done.
+ */
+ const Element* next();
+ const Element* prev();
+
+ /**
+ * Moves the iterator to the topmost element with the specified RegionOp and returns that
+ * element. If no clip element with that op is found, the first element is returned.
+ */
+ const Element* skipToTopmost(SkRegion::Op op);
+
+ /**
+ * Restarts the iterator on a clip stack.
+ */
+ void reset(const SkClipStack& stack, IterStart startLoc);
+
+ private:
+ const SkClipStack* fStack;
+ SkDeque::Iter fIter;
+ };
+
+ /**
+ * The B2TIter iterates from the bottom of the stack to the top.
+ * It inherits privately from Iter to prevent access to reverse iteration.
+ */
+ class B2TIter : private Iter {
+ public:
+ B2TIter() {}
+
+ /**
+ * Wrap Iter's 2 parameter ctor to force initialization to the
+ * beginning of the deque/bottom of the stack
+ */
+ B2TIter(const SkClipStack& stack)
+ : INHERITED(stack, kBottom_IterStart) {
+ }
+
+ using Iter::next;
+
+ /**
+ * Wrap Iter::reset to force initialization to the
+ * beginning of the deque/bottom of the stack
+ */
+ void reset(const SkClipStack& stack) {
+ this->INHERITED::reset(stack, kBottom_IterStart);
+ }
+
+ private:
+
+ typedef Iter INHERITED;
+ };
+
+ /**
+ * GetConservativeBounds returns a conservative bound of the current clip.
+ * Since this could be the infinite plane (if inverse fills were involved) the
+ * maxWidth and maxHeight parameters can be used to limit the returned bound
+ * to the expected drawing area. Similarly, the offsetX and offsetY parameters
+ * allow the caller to offset the returned bound to account for translated
+ * drawing areas (i.e., those resulting from a saveLayer). For finite bounds,
+ * the translation (+offsetX, +offsetY) is applied before the clamp to the
+ * maximum rectangle: [0,maxWidth) x [0,maxHeight).
+ * isIntersectionOfRects is an optional parameter that is true when
+ * 'devBounds' is the result of an intersection of rects. In this case
+ * 'devBounds' is the exact answer/clip.
+ */
+ void getConservativeBounds(int offsetX,
+ int offsetY,
+ int maxWidth,
+ int maxHeight,
+ SkRect* devBounds,
+ bool* isIntersectionOfRects = NULL) const;
+
+private:
+ friend class Iter;
+
+ SkDeque fDeque;
+ int fSaveCount;
+
+ // Generation ID for the clip stack. This is incremented for each
+ // clipDevRect and clipDevPath call. 0 is reserved to indicate an
+ // invalid ID.
+ static int32_t gGenID;
+
+ /**
+ * Helper for clipDevPath, etc.
+ */
+ void pushElement(const Element& element);
+
+ /**
+ * Restore the stack back to the specified save count.
+ */
+ void restoreTo(int saveCount);
+
+ /**
+ * Return the next unique generation ID.
+ */
+ static int32_t GetNextGenID();
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkColor.h b/src/third_party/skia/include/core/SkColor.h
new file mode 100644
index 0000000..7faeca7
--- /dev/null
+++ b/src/third_party/skia/include/core/SkColor.h
@@ -0,0 +1,169 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkColor_DEFINED
+#define SkColor_DEFINED
+
+#include "SkScalar.h"
+
+/** \file SkColor.h
+
+ Types and macros for colors
+*/
+
+/** 8-bit type for an alpha value. 0xFF is 100% opaque, 0x00 is 100% transparent.
+*/
+typedef uint8_t SkAlpha;
+/** 32 bit ARGB color value, not premultiplied. The color components are always in
+ a known order. This is different from SkPMColor, which has its bytes in a configuration
+ dependent order, to match the format of kARGB32 bitmaps. SkColor is the type used to
+ specify colors in SkPaint and in gradients.
+*/
+typedef uint32_t SkColor;
+
+/** Return a SkColor value from 8 bit component values
+*/
+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)
+*/
+#define SkColorSetRGB(r, g, b) SkColorSetARGB(0xFF, r, g, b)
+
+/** return the alpha byte from a SkColor value */
+#define SkColorGetA(color) (((color) >> 24) & 0xFF)
+/** return the red byte from a SkColor value */
+#define SkColorGetR(color) (((color) >> 16) & 0xFF)
+/** return the green byte from a SkColor value */
+#define SkColorGetG(color) (((color) >> 8) & 0xFF)
+/** return the blue byte from a SkColor value */
+#define SkColorGetB(color) (((color) >> 0) & 0xFF)
+
+static inline SkColor SkColorSetA(SkColor c, U8CPU a) {
+ return (c & 0x00FFFFFF) | (a << 24);
+}
+
+// common colors
+
+#define SK_AlphaTRANSPARENT 0x00 //!< transparent SkAlpha value
+#define SK_AlphaOPAQUE 0xFF //!< opaque SkAlpha value
+
+#define SK_ColorTRANSPARENT 0x00000000 //!< transparent SkColor value
+
+#define SK_ColorBLACK 0xFF000000 //!< black SkColor value
+#define SK_ColorDKGRAY 0xFF444444 //!< dark gray SkColor value
+#define SK_ColorGRAY 0xFF888888 //!< gray SkColor value
+#define SK_ColorLTGRAY 0xFFCCCCCC //!< light gray SkColor value
+#define SK_ColorWHITE 0xFFFFFFFF //!< white SkColor value
+
+#define SK_ColorRED 0xFFFF0000 //!< red SkColor value
+#define SK_ColorGREEN 0xFF00FF00 //!< green SkColor value
+#define SK_ColorBLUE 0xFF0000FF //!< blue SkColor value
+#define SK_ColorYELLOW 0xFFFFFF00 //!< yellow SkColor value
+#define SK_ColorCYAN 0xFF00FFFF //!< cyan SkColor value
+#define SK_ColorMAGENTA 0xFFFF00FF //!< magenta SkColor value
+
+////////////////////////////////////////////////////////////////////////
+
+/** Convert RGB components to HSV.
+ hsv[0] is Hue [0 .. 360)
+ hsv[1] is Saturation [0...1]
+ hsv[2] is Value [0...1]
+ @param red red component value [0..255]
+ @param green green component value [0..255]
+ @param blue blue component value [0..255]
+ @param hsv 3 element array which holds the resulting HSV components.
+*/
+SK_API void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]);
+
+/** Convert the argb color to its HSV components.
+ hsv[0] is Hue [0 .. 360)
+ hsv[1] is Saturation [0...1]
+ hsv[2] is Value [0...1]
+ @param color the argb color to convert. Note: the alpha component is ignored.
+ @param hsv 3 element array which holds the resulting HSV components.
+*/
+static inline void SkColorToHSV(SkColor color, SkScalar hsv[3])
+{
+ SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv);
+}
+
+/** Convert HSV components to an ARGB color. The alpha component is passed through unchanged.
+ hsv[0] is Hue [0 .. 360)
+ hsv[1] is Saturation [0...1]
+ hsv[2] is Value [0...1]
+ If hsv values are out of range, they are pinned.
+ @param alpha the alpha component of the returned argb color.
+ @param hsv 3 element array which holds the input HSV components.
+ @return the resulting argb color
+*/
+SK_API SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]);
+
+/** Convert HSV components to an ARGB color. The alpha component set to 0xFF.
+ hsv[0] is Hue [0 .. 360)
+ hsv[1] is Saturation [0...1]
+ hsv[2] is Value [0...1]
+ If hsv values are out of range, they are pinned.
+ @param hsv 3 element array which holds the input HSV components.
+ @return the resulting argb color
+*/
+static inline SkColor SkHSVToColor(const SkScalar hsv[3])
+{
+ return SkHSVToColor(0xFF, hsv);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+/** 32 bit ARGB color value, premultiplied. The byte order for this value is
+ configuration dependent, matching the format of kARGB32 bitmaps. This is different
+ from SkColor, which is nonpremultiplied, and is always in the same byte order.
+*/
+typedef uint32_t SkPMColor;
+
+/** Return a SkPMColor value from unpremultiplied 8 bit component values
+*/
+SK_API SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
+/** Return a SkPMColor value from a SkColor value. This is done by multiplying the color
+ components by the color's alpha, and by arranging the bytes in a configuration
+ dependent order, to match the format of kARGB32 bitmaps.
+*/
+SK_API SkPMColor SkPreMultiplyColor(SkColor c);
+
+/** Define a function pointer type for combining two premultiplied colors
+*/
+typedef SkPMColor (*SkXfermodeProc)(SkPMColor src, SkPMColor dst);
+
+/** Define a function pointer type for combining a premultiplied src color
+ and a 16bit device color.
+*/
+typedef uint16_t (*SkXfermodeProc16)(SkPMColor src, uint16_t dst);
+
+#endif
diff --git a/src/third_party/skia/include/core/SkColorFilter.h b/src/third_party/skia/include/core/SkColorFilter.h
new file mode 100644
index 0000000..31d4a01
--- /dev/null
+++ b/src/third_party/skia/include/core/SkColorFilter.h
@@ -0,0 +1,146 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkColorFilter_DEFINED
+#define SkColorFilter_DEFINED
+
+#include "SkColor.h"
+#include "SkFlattenable.h"
+#include "SkXfermode.h"
+
+class SkBitmap;
+class GrProcessor;
+class GrContext;
+
+/**
+ * ColorFilters are optional objects in the drawing pipeline. When present in
+ * a paint, they are called with the "src" colors, and return new colors, which
+ * are then passed onto the next stage (either ImageFilter or Xfermode).
+ *
+ * All subclasses are required to be reentrant-safe : it must be legal to share
+ * the same instance between several threads.
+ */
+class SK_API SkColorFilter : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkColorFilter)
+
+ /**
+ * If the filter can be represented by a source color plus Mode, this
+ * returns true, and sets (if not NULL) the color and mode appropriately.
+ * If not, this returns false and ignores the parameters.
+ */
+ virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const;
+
+ /**
+ * If the filter can be represented by a 5x4 matrix, this
+ * returns true, and sets the matrix appropriately.
+ * If not, this returns false and ignores the parameter.
+ */
+ virtual bool asColorMatrix(SkScalar matrix[20]) const;
+
+ /**
+ * If the filter can be represented by per-component table, return true,
+ * and if table is not null, copy the bitmap containing the table into it.
+ *
+ * The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
+ * to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
+ * etc. To transform a color, you (logically) perform the following:
+ *
+ * a' = *table.getAddr8(a, 0);
+ * r' = *table.getAddr8(r, 1);
+ * g' = *table.getAddr8(g, 2);
+ * b' = *table.getAddr8(b, 3);
+ *
+ * The original component value is the horizontal index for a given row,
+ * and the stored value at that index is the new value for that component.
+ */
+ virtual bool asComponentTable(SkBitmap* table) const;
+
+ /** Called with a scanline of colors, as if there was a shader installed.
+ The implementation writes out its filtered version into result[].
+ Note: shader and result may be the same buffer.
+ @param src array of colors, possibly generated by a shader
+ @param count the number of entries in the src[] and result[] arrays
+ @param result written by the filter
+ */
+ virtual void filterSpan(const SkPMColor src[], int count,
+ SkPMColor result[]) const = 0;
+ /** Called with a scanline of colors, as if there was a shader installed.
+ The implementation writes out its filtered version into result[].
+ Note: shader and result may be the same buffer.
+ @param src array of colors, possibly generated by a shader
+ @param count the number of entries in the src[] and result[] arrays
+ @param result written by the filter
+ */
+ virtual void filterSpan16(const uint16_t shader[], int count,
+ uint16_t result[]) const;
+
+ enum Flags {
+ /** If set the filter methods will not change the alpha channel of the
+ colors.
+ */
+ kAlphaUnchanged_Flag = 0x01,
+ /** If set, this subclass implements filterSpan16(). If this flag is
+ set, then kAlphaUnchanged_Flag must also be set.
+ */
+ kHasFilter16_Flag = 0x02
+ };
+
+ /** Returns the flags for this filter. Override in subclasses to return
+ custom flags.
+ */
+ virtual uint32_t getFlags() const { return 0; }
+
+ /**
+ * Apply this colorfilter to the specified SkColor. This routine handles
+ * converting to SkPMColor, calling the filter, and then converting back
+ * to SkColor. This method is not virtual, but will call filterSpan()
+ * which is virtual.
+ */
+ SkColor filterColor(SkColor) const;
+
+ /** Create a colorfilter that uses the specified color and mode.
+ If the Mode is DST, this function will return NULL (since that
+ mode will have no effect on the result).
+ @param c The source color used with the specified mode
+ @param mode The xfermode mode that is applied to each color in
+ the colorfilter's filterSpan[16,32] methods
+ @return colorfilter object that applies the src color and mode,
+ or NULL if the mode will have no effect.
+ */
+ static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode);
+
+ /** Create a colorfilter that multiplies the RGB channels by one color, and
+ then adds a second color, pinning the result for each component to
+ [0..255]. The alpha components of the mul and add arguments
+ are ignored.
+ */
+ static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
+
+ /** A subclass may implement this factory function to work with the GPU backend. If the return
+ is non-NULL then the caller owns a ref on the returned object.
+ */
+ virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const;
+
+ SK_TO_STRING_PUREVIRT()
+
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+ SK_DEFINE_FLATTENABLE_TYPE(SkColorFilter)
+
+protected:
+ SkColorFilter() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkColorFilter(SkReadBuffer& rb) : INHERITED(rb) {}
+#endif
+
+private:
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkColorPriv.h b/src/third_party/skia/include/core/SkColorPriv.h
new file mode 100644
index 0000000..9db7687
--- /dev/null
+++ b/src/third_party/skia/include/core/SkColorPriv.h
@@ -0,0 +1,1030 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkColorPriv_DEFINED
+#define SkColorPriv_DEFINED
+
+// turn this own for extra debug checking when blending onto 565
+#ifdef SK_DEBUG
+ #define CHECK_FOR_565_OVERFLOW
+#endif
+
+#include "SkColor.h"
+#include "SkMath.h"
+
+//////////////////////////////////////////////////////////////////////////////
+
+#define SkASSERT_IS_BYTE(x) SkASSERT(0 == ((x) & ~0xFF))
+
+/*
+ * Skia's 32bit backend only supports 1 sizzle order at a time (compile-time).
+ * This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B.
+ *
+ * For easier compatibility with Skia's GPU backend, we further restrict these
+ * to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does
+ * not directly correspond to the same shift-order, since we have to take endianess
+ * into account.
+ *
+ * Here we enforce this constraint.
+ */
+
+#ifdef SK_CPU_BENDIAN
+ #define SK_RGBA_R32_SHIFT 24
+ #define SK_RGBA_G32_SHIFT 16
+ #define SK_RGBA_B32_SHIFT 8
+ #define SK_RGBA_A32_SHIFT 0
+
+ #define SK_BGRA_B32_SHIFT 24
+ #define SK_BGRA_G32_SHIFT 16
+ #define SK_BGRA_R32_SHIFT 8
+ #define SK_BGRA_A32_SHIFT 0
+#else
+ #define SK_RGBA_R32_SHIFT 0
+ #define SK_RGBA_G32_SHIFT 8
+ #define SK_RGBA_B32_SHIFT 16
+ #define SK_RGBA_A32_SHIFT 24
+
+ #define SK_BGRA_B32_SHIFT 0
+ #define SK_BGRA_G32_SHIFT 8
+ #define SK_BGRA_R32_SHIFT 16
+ #define SK_BGRA_A32_SHIFT 24
+#endif
+
+#if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA)
+ #error "can't define PMCOLOR to be RGBA and BGRA"
+#endif
+
+#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \
+ (SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \
+ SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \
+ SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \
+ SK_B32_SHIFT == SK_RGBA_B32_SHIFT)
+
+#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA \
+ (SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \
+ SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \
+ SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \
+ SK_B32_SHIFT == SK_BGRA_B32_SHIFT)
+
+
+#if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
+ #error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values"
+#endif
+
+#if defined(SK_PMCOLOR_IS_BGRA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
+ #error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values"
+#endif
+
+#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
+ // deduce which to define from the _SHIFT defines
+
+ #if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
+ #define SK_PMCOLOR_IS_RGBA
+ #elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
+ #define SK_PMCOLOR_IS_BGRA
+ #else
+ #error "need 32bit packing to be either RGBA or BGRA"
+ #endif
+#endif
+
+// hide these now that we're done
+#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
+#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Reverse the bytes coorsponding to RED and BLUE in a packed pixels. Note the
+// pair of them are in the same 2 slots in both RGBA and BGRA, thus there is
+// no need to pass in the colortype to this function.
+static inline uint32_t SkSwizzle_RB(uint32_t c) {
+ static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT);
+
+ unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF;
+ unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF;
+ return (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT);
+}
+
+static inline uint32_t SkPackARGB_as_RGBA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
+ SkASSERT_IS_BYTE(a);
+ SkASSERT_IS_BYTE(r);
+ SkASSERT_IS_BYTE(g);
+ SkASSERT_IS_BYTE(b);
+ return (a << SK_RGBA_A32_SHIFT) | (r << SK_RGBA_R32_SHIFT) |
+ (g << SK_RGBA_G32_SHIFT) | (b << SK_RGBA_B32_SHIFT);
+}
+
+static inline uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
+ SkASSERT_IS_BYTE(a);
+ SkASSERT_IS_BYTE(r);
+ SkASSERT_IS_BYTE(g);
+ SkASSERT_IS_BYTE(b);
+ return (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) |
+ (g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT);
+}
+
+static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) {
+#ifdef SK_PMCOLOR_IS_RGBA
+ return c;
+#else
+ return SkSwizzle_RB(c);
+#endif
+}
+
+static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) {
+#ifdef SK_PMCOLOR_IS_BGRA
+ return c;
+#else
+ return SkSwizzle_RB(c);
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+///@{
+/** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/
+#define SK_ITU_BT709_LUM_COEFF_R (0.2126f)
+#define SK_ITU_BT709_LUM_COEFF_G (0.7152f)
+#define SK_ITU_BT709_LUM_COEFF_B (0.0722f)
+///@}
+
+///@{
+/** A float value which specifies this channel's contribution to luminance. */
+#define SK_LUM_COEFF_R SK_ITU_BT709_LUM_COEFF_R
+#define SK_LUM_COEFF_G SK_ITU_BT709_LUM_COEFF_G
+#define SK_LUM_COEFF_B SK_ITU_BT709_LUM_COEFF_B
+///@}
+
+/** Computes the luminance from the given r, g, and b in accordance with
+ SK_LUM_COEFF_X. For correct results, r, g, and b should be in linear space.
+*/
+static inline U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b) {
+ //The following is
+ //r * SK_LUM_COEFF_R + g * SK_LUM_COEFF_G + b * SK_LUM_COEFF_B
+ //with SK_LUM_COEFF_X in 1.8 fixed point (rounding adjusted to sum to 256).
+ return (r * 54 + g * 183 + b * 19) >> 8;
+}
+
+/** 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) {
+ SkASSERT(SkToU8(alpha) == alpha);
+ // this one assues that blending on top of an opaque dst keeps it that way
+ // even though it is less accurate than a+(a>>7) for non-opaque dsts
+ return alpha + 1;
+}
+
+/**
+ * Turn a 0..255 value into a 0..256 value, rounding up if the value is >= 0x80.
+ * This is slightly more accurate than SkAlpha255To256.
+ */
+static inline unsigned Sk255To256(U8CPU value) {
+ SkASSERT(SkToU8(value) == value);
+ return value + (value >> 7);
+}
+
+/** Multiplify value by 0..256, and shift the result down 8
+ (i.e. return (value * alpha256) >> 8)
+ */
+#define SkAlphaMul(value, alpha256) (SkMulS16(value, alpha256) >> 8)
+
+// The caller may want negative values, so keep all params signed (int)
+// so we don't accidentally slip into unsigned math and lose the sign
+// extension when we shift (in SkAlphaMul)
+static inline int SkAlphaBlend(int src, int dst, int scale256) {
+ SkASSERT((unsigned)scale256 <= 256);
+ return dst + SkAlphaMul(src - dst, scale256);
+}
+
+/**
+ * Returns (src * alpha + dst * (255 - alpha)) / 255
+ *
+ * This is more accurate than SkAlphaBlend, but slightly slower
+ */
+static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) {
+ SkASSERT((int16_t)src == src);
+ SkASSERT((int16_t)dst == dst);
+ SkASSERT((uint8_t)alpha == alpha);
+
+ int prod = SkMulS16(src - dst, alpha) + 128;
+ prod = (prod + (prod >> 8)) >> 8;
+ return dst + prod;
+}
+
+#define SK_R16_BITS 5
+#define SK_G16_BITS 6
+#define SK_B16_BITS 5
+
+#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
+#define SK_G16_SHIFT (SK_B16_BITS)
+#define SK_B16_SHIFT 0
+
+#define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
+#define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
+#define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
+
+#define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
+#define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
+#define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
+
+#define SkR16Assert(r) SkASSERT((unsigned)(r) <= SK_R16_MASK)
+#define SkG16Assert(g) SkASSERT((unsigned)(g) <= SK_G16_MASK)
+#define SkB16Assert(b) SkASSERT((unsigned)(b) <= SK_B16_MASK)
+
+static inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) {
+ SkASSERT(r <= SK_R16_MASK);
+ SkASSERT(g <= SK_G16_MASK);
+ SkASSERT(b <= SK_B16_MASK);
+
+ return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT));
+}
+
+#define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT)
+#define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT)
+#define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT)
+
+/** Expand the 16bit color into a 32bit value that can be scaled all at once
+ by a value up to 32. Used in conjunction with SkCompact_rgb_16.
+*/
+static inline uint32_t SkExpand_rgb_16(U16CPU c) {
+ SkASSERT(c == (uint16_t)c);
+
+ return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
+}
+
+/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit
+ color value. The computation yields only 16bits of valid data, but we claim
+ to return 32bits, so that the compiler won't generate extra instructions to
+ "clean" the top 16bits. However, the top 16 can contain garbage, so it is
+ up to the caller to safely ignore them.
+*/
+static inline U16CPU SkCompact_rgb_16(uint32_t c) {
+ return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
+}
+
+/** Scale the 16bit color value by the 0..256 scale parameter.
+ The computation yields only 16bits of valid data, but we claim
+ to return 32bits, so that the compiler won't generate extra instructions to
+ "clean" the top 16bits.
+*/
+static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) {
+ return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5);
+}
+
+// this helper explicitly returns a clean 16bit value (but slower)
+#define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s)
+
+/** Blend src and dst 16bit colors by the 0..256 scale parameter.
+ The computation yields only 16bits of valid data, but we claim
+ to return 32bits, so that the compiler won't generate extra instructions to
+ "clean" the top 16bits.
+*/
+static inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) {
+ SkASSERT((unsigned)srcScale <= 256);
+
+ srcScale >>= 3;
+
+ uint32_t src32 = SkExpand_rgb_16(src);
+ uint32_t dst32 = SkExpand_rgb_16(dst);
+ return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
+}
+
+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 {
+ uint32_t src32 = SkExpand_rgb_16(*src++);
+ uint32_t dst32 = SkExpand_rgb_16(*dst);
+ *dst++ = static_cast<uint16_t>(
+ SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)));
+ } while (--count > 0);
+}
+
+#ifdef SK_DEBUG
+ static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) {
+ 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
+ #define SkRGB16Add(a, b) ((a) + (b))
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define SK_A32_BITS 8
+#define SK_R32_BITS 8
+#define SK_G32_BITS 8
+#define SK_B32_BITS 8
+
+#define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
+#define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
+#define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
+#define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
+
+#define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
+#define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
+#define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
+#define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
+
+#define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK)
+#define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK)
+#define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK)
+#define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK)
+
+#ifdef SK_DEBUG
+ #define SkPMColorAssert(color_value) \
+ do { \
+ SkPMColor pm_color_value = (color_value); \
+ uint32_t alpha_color_value = SkGetPackedA32(pm_color_value); \
+ SkA32Assert(alpha_color_value); \
+ SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value); \
+ SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value); \
+ SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value); \
+ } while (false)
+#else
+ #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);
+ SkASSERT(g <= a);
+ SkASSERT(b <= a);
+
+ return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
+ (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
+}
+
+static inline uint32_t SkPackPMColor_as_RGBA(SkPMColor c) {
+ return SkPackARGB_as_RGBA(SkGetPackedA32(c), SkGetPackedR32(c),
+ SkGetPackedG32(c), SkGetPackedB32(c));
+}
+
+static inline uint32_t SkPackPMColor_as_BGRA(SkPMColor c) {
+ return SkPackARGB_as_BGRA(SkGetPackedA32(c), SkGetPackedR32(c),
+ SkGetPackedG32(c), SkGetPackedB32(c));
+}
+
+/**
+ * Abstract 4-byte interpolation, implemented on top of SkPMColor
+ * utility functions. Third parameter controls blending of the first two:
+ * (src, dst, 0) returns dst
+ * (src, dst, 0xFF) returns src
+ * srcWeight is [0..256], unlike SkFourByteInterp which takes [0..255]
+ */
+static inline SkPMColor SkFourByteInterp256(SkPMColor src, SkPMColor dst,
+ unsigned scale) {
+ unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale);
+ unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
+ unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
+ unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
+
+ return SkPackARGB32(a, r, g, b);
+}
+
+/**
+ * Abstract 4-byte interpolation, implemented on top of SkPMColor
+ * utility functions. Third parameter controls blending of the first two:
+ * (src, dst, 0) returns dst
+ * (src, dst, 0xFF) returns src
+ */
+static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst,
+ U8CPU srcWeight) {
+ unsigned scale = SkAlpha255To256(srcWeight);
+ return SkFourByteInterp256(src, dst, scale);
+}
+
+/**
+ * 0xAARRGGBB -> 0x00AA00GG, 0x00RR00BB
+ */
+static inline void SkSplay(uint32_t color, uint32_t* ag, uint32_t* rb) {
+ const uint32_t mask = 0x00FF00FF;
+ *ag = (color >> 8) & mask;
+ *rb = color & mask;
+}
+
+/**
+ * 0xAARRGGBB -> 0x00AA00GG00RR00BB
+ * (note, ARGB -> AGRB)
+ */
+static inline uint64_t SkSplay(uint32_t color) {
+ const uint32_t mask = 0x00FF00FF;
+ uint64_t agrb = (color >> 8) & mask; // 0x0000000000AA00GG
+ agrb <<= 32; // 0x00AA00GG00000000
+ agrb |= color & mask; // 0x00AA00GG00RR00BB
+ return agrb;
+}
+
+/**
+ * 0xAAxxGGxx, 0xRRxxBBxx-> 0xAARRGGBB
+ */
+static inline uint32_t SkUnsplay(uint32_t ag, uint32_t rb) {
+ const uint32_t mask = 0xFF00FF00;
+ return (ag & mask) | ((rb & mask) >> 8);
+}
+
+/**
+ * 0xAAxxGGxxRRxxBBxx -> 0xAARRGGBB
+ * (note, AGRB -> ARGB)
+ */
+static inline uint32_t SkUnsplay(uint64_t agrb) {
+ const uint32_t mask = 0xFF00FF00;
+ return SkPMColor(
+ ((agrb & mask) >> 8) | // 0x00RR00BB
+ ((agrb >> 32) & mask)); // 0xAARRGGBB
+}
+
+static inline SkPMColor SkFastFourByteInterp256_32(SkPMColor src, SkPMColor dst, unsigned scale) {
+ SkASSERT(scale <= 256);
+
+ // Two 8-bit blends per two 32-bit registers, with space to make sure the math doesn't collide.
+ uint32_t src_ag, src_rb, dst_ag, dst_rb;
+ SkSplay(src, &src_ag, &src_rb);
+ SkSplay(dst, &dst_ag, &dst_rb);
+
+ const uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
+ const uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
+
+ return SkUnsplay(ret_ag, ret_rb);
+}
+
+static inline SkPMColor SkFastFourByteInterp256_64(SkPMColor src, SkPMColor dst, unsigned scale) {
+ SkASSERT(scale <= 256);
+ // Four 8-bit blends in one 64-bit register, with space to make sure the math doesn't collide.
+ return SkUnsplay(SkSplay(src) * scale + (256-scale) * SkSplay(dst));
+}
+
+// TODO(mtklein): Replace slow versions with fast versions, using scale + (scale>>7) everywhere.
+
+/**
+ * Same as SkFourByteInterp256, but faster.
+ */
+static inline SkPMColor SkFastFourByteInterp256(SkPMColor src, SkPMColor dst, unsigned scale) {
+ // On a 64-bit machine, _64 is about 10% faster than _32, but ~40% slower on a 32-bit machine.
+ if (sizeof(void*) == 4) {
+ return SkFastFourByteInterp256_32(src, dst, scale);
+ } else {
+ return SkFastFourByteInterp256_64(src, dst, scale);
+ }
+}
+
+/**
+ * Nearly the same as SkFourByteInterp, but faster and a touch more accurate, due to better
+ * srcWeight scaling to [0, 256].
+ */
+static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
+ SkPMColor dst,
+ U8CPU srcWeight) {
+ SkASSERT(srcWeight <= 255);
+ // scale = srcWeight + (srcWeight >> 7) is more accurate than
+ // scale = srcWeight + 1, but 7% slower
+ return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7));
+}
+
+/**
+ * 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);
+}
+
+static inline
+SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
+ SkA32Assert(a);
+ SkR32Assert(r);
+ SkG32Assert(g);
+ SkB32Assert(b);
+
+ if (a != 255) {
+ r = SkMulDiv255Round(r, a);
+ g = SkMulDiv255Round(g, a);
+ b = SkMulDiv255Round(b, a);
+ }
+ return SkPackARGB32(a, r, g, b);
+}
+
+// When Android is compiled optimizing for size, SkAlphaMulQ doesn't get
+// inlined; forcing inlining significantly improves performance.
+static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
+ uint32_t mask = 0xFF00FF;
+
+ uint32_t rb = ((c & mask) * scale) >> 8;
+ uint32_t ag = ((c >> 8) & mask) * scale;
+ return (rb & mask) | (ag & ~mask);
+}
+
+static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
+ return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
+}
+
+static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
+ SkASSERT((unsigned)aa <= 255);
+
+ unsigned src_scale = SkAlpha255To256(aa);
+ unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale));
+
+ return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Convert a 32bit pixel to a 16bit pixel (no dither)
+
+#define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
+#define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
+#define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
+
+#ifdef SK_DEBUG
+ static inline unsigned SkR32ToR16(unsigned r) {
+ SkR32Assert(r);
+ return SkR32ToR16_MACRO(r);
+ }
+ static inline unsigned SkG32ToG16(unsigned g) {
+ SkG32Assert(g);
+ return SkG32ToG16_MACRO(g);
+ }
+ static inline unsigned SkB32ToB16(unsigned b) {
+ SkB32Assert(b);
+ return SkB32ToB16_MACRO(b);
+ }
+#else
+ #define SkR32ToR16(r) SkR32ToR16_MACRO(r)
+ #define SkG32ToG16(g) SkG32ToG16_MACRO(g)
+ #define SkB32ToB16(b) SkB32ToB16_MACRO(b)
+#endif
+
+#define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK)
+#define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK)
+#define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK)
+
+static inline U16CPU SkPixel32ToPixel16(SkPMColor c) {
+ unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT;
+ unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT;
+ unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT;
+ return r | g | b;
+}
+
+static inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) {
+ return (SkR32ToR16(r) << SK_R16_SHIFT) |
+ (SkG32ToG16(g) << SK_G16_SHIFT) |
+ (SkB32ToB16(b) << SK_B16_SHIFT);
+}
+
+#define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src))
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Fast dither from 32->16
+
+#define SkShouldDitherXY(x, y) (((x) ^ (y)) & 1)
+
+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);
+}
+
+static inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c) {
+ return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c));
+}
+
+/* Return c in expanded_rgb_16 format, but also scaled up by 32 (5 bits)
+ It is now suitable for combining with a scaled expanded_rgb_16 color
+ as in SkSrcOver32To16().
+ We must do this 565 high-bit replication, in order for the subsequent add
+ to saturate properly (and not overflow). If we take the 8 bits as is, it is
+ possible to overflow.
+*/
+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;
+ return (sr << 11) | (sg << 21) | (sb << 0);
+}
+
+/* SrcOver the 32bit src color with the 16bit dst, returning a 16bit value
+ (with dirt in the high 16bits, so caller beware).
+*/
+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);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Convert a 16bit pixel to a 32bit pixel
+
+static inline unsigned SkR16ToR32(unsigned r) {
+ return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
+}
+
+static inline unsigned SkG16ToG32(unsigned g) {
+ return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
+}
+
+static inline unsigned SkB16ToB32(unsigned b) {
+ return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
+}
+
+#define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c))
+#define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c))
+#define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c))
+
+static inline SkPMColor SkPixel16ToPixel32(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 SkPackARGB32(0xFF, r, g, b);
+}
+
+// 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);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef uint16_t SkPMColor16;
+
+// Put in OpenGL order (r g b a)
+#define SK_A4444_SHIFT 0
+#define SK_R4444_SHIFT 12
+#define SK_G4444_SHIFT 8
+#define SK_B4444_SHIFT 4
+
+#define SkA32To4444(a) ((unsigned)(a) >> 4)
+#define SkR32To4444(r) ((unsigned)(r) >> 4)
+#define SkG32To4444(g) ((unsigned)(g) >> 4)
+#define SkB32To4444(b) ((unsigned)(b) >> 4)
+
+static inline U8CPU SkReplicateNibble(unsigned nib) {
+ SkASSERT(nib <= 0xF);
+ return (nib << 4) | nib;
+}
+
+#define SkA4444ToA32(a) SkReplicateNibble(a)
+#define SkR4444ToR32(r) SkReplicateNibble(r)
+#define SkG4444ToG32(g) SkReplicateNibble(g)
+#define SkB4444ToB32(b) SkReplicateNibble(b)
+
+#define SkGetPackedA4444(c) (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF)
+#define SkGetPackedR4444(c) (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF)
+#define SkGetPackedG4444(c) (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF)
+#define SkGetPackedB4444(c) (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF)
+
+#define SkPacked4444ToA32(c) SkReplicateNibble(SkGetPackedA4444(c))
+#define SkPacked4444ToR32(c) SkReplicateNibble(SkGetPackedR4444(c))
+#define SkPacked4444ToG32(c) SkReplicateNibble(SkGetPackedG4444(c))
+#define SkPacked4444ToB32(c) SkReplicateNibble(SkGetPackedB4444(c))
+
+#ifdef SK_DEBUG
+static inline void SkPMColor16Assert(U16CPU c) {
+ unsigned a = SkGetPackedA4444(c);
+ unsigned r = SkGetPackedR4444(c);
+ unsigned g = SkGetPackedG4444(c);
+ unsigned b = SkGetPackedB4444(c);
+
+ SkASSERT(a <= 0xF);
+ SkASSERT(r <= a);
+ SkASSERT(g <= a);
+ SkASSERT(b <= a);
+}
+#else
+#define SkPMColor16Assert(c)
+#endif
+
+static inline unsigned SkAlpha15To16(unsigned a) {
+ SkASSERT(a <= 0xF);
+ return a + (a >> 3);
+}
+
+#ifdef SK_DEBUG
+ static inline int SkAlphaMul4(int value, int scale) {
+ SkASSERT((unsigned)scale <= 0x10);
+ return value * scale >> 4;
+ }
+#else
+ #define SkAlphaMul4(value, scale) ((value) * (scale) >> 4)
+#endif
+
+static inline unsigned SkR4444ToR565(unsigned r) {
+ SkASSERT(r <= 0xF);
+ return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS));
+}
+
+static inline unsigned SkG4444ToG565(unsigned g) {
+ SkASSERT(g <= 0xF);
+ return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS));
+}
+
+static inline unsigned SkB4444ToB565(unsigned b) {
+ SkASSERT(b <= 0xF);
+ return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS));
+}
+
+static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r,
+ unsigned g, unsigned b) {
+ SkASSERT(a <= 0xF);
+ 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));
+}
+
+static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) {
+ SkASSERT(scale <= 16);
+
+ const unsigned mask = 0xF0F; //gMask_0F0F;
+
+#if 0
+ unsigned rb = ((c & mask) * scale) >> 4;
+ unsigned ag = ((c >> 4) & mask) * scale;
+ return (rb & mask) | (ag & ~mask);
+#else
+ unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12);
+ unsigned scaled_c = (expanded_c * scale) >> 4;
+ return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4));
+#endif
+}
+
+/** Expand the SkPMColor16 color into a 32bit value that can be scaled all at
+ once by a value up to 16.
+*/
+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);
+}
+
+static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) {
+ unsigned sa = SkGetPackedA4444(s);
+ unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
+ unsigned sg = SkG4444ToG565(SkGetPackedG4444(s));
+ unsigned sb = SkB4444ToB565(SkGetPackedB4444(s));
+
+ // To avoid overflow, we have to clear the low bit of the synthetic sg
+ // if the src alpha is <= 7.
+ // to see why, try blending 0x4444 on top of 565-white and watch green
+ // overflow (sum == 64)
+ sg &= ~(~(sa >> 3) & 1);
+
+ unsigned scale = SkAlpha15To16(15 - sa);
+ 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);
+ }
+#endif
+ return SkPackRGB16(sr + dr, sg + dg, sb + db);
+}
+
+static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16) {
+ SkASSERT((unsigned)scale16 <= 16);
+
+ return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
+}
+
+static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) {
+ uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
+ (SkGetPackedR4444(c) << SK_R32_SHIFT) |
+ (SkGetPackedG4444(c) << SK_G32_SHIFT) |
+ (SkGetPackedB4444(c) << SK_B32_SHIFT);
+ return d | (d << 4);
+}
+
+static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) {
+ return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) |
+ (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) |
+ (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) |
+ (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT);
+}
+
+// cheap 2x2 dither
+static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r,
+ U8CPU g, U8CPU b) {
+ // to ensure that we stay a legal premultiplied color, we take the max()
+ // of the truncated and dithered alpha values. If we didn't, cases like
+ // SkDitherARGB32To4444(0x31, 0x2E, ...) would generate SkPackARGB4444(2, 3, ...)
+ // which is not legal premultiplied, since a < color
+ unsigned dithered_a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4;
+ a = SkMax32(a >> 4, dithered_a);
+ // these we just dither in place
+ 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);
+}
+
+static inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c) {
+ return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c),
+ SkGetPackedG32(c), SkGetPackedB32(c));
+}
+
+/* Assumes 16bit is in standard RGBA order.
+ Transforms a normal ARGB_8888 into the same byte order as
+ expanded ARGB_4444, but keeps each component 8bits
+*/
+static inline uint32_t SkExpand_8888(SkPMColor c) {
+ return (((c >> SK_R32_SHIFT) & 0xFF) << 24) |
+ (((c >> SK_G32_SHIFT) & 0xFF) << 8) |
+ (((c >> SK_B32_SHIFT) & 0xFF) << 16) |
+ (((c >> SK_A32_SHIFT) & 0xFF) << 0);
+}
+
+/* Undo the operation of SkExpand_8888, turning the argument back into
+ a SkPMColor.
+*/
+static inline SkPMColor SkCompact_8888(uint32_t c) {
+ return (((c >> 24) & 0xFF) << SK_R32_SHIFT) |
+ (((c >> 8) & 0xFF) << SK_G32_SHIFT) |
+ (((c >> 16) & 0xFF) << SK_B32_SHIFT) |
+ (((c >> 0) & 0xFF) << SK_A32_SHIFT);
+}
+
+/* Like SkExpand_8888, this transforms a pmcolor into the expanded 4444 format,
+ but this routine just keeps the high 4bits of each component in the low
+ 4bits of the result (just like a newly expanded PMColor16).
+*/
+static inline uint32_t SkExpand32_4444(SkPMColor c) {
+ return (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) |
+ (((c >> (SK_G32_SHIFT + 4)) & 0xF) << 8) |
+ (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) |
+ (((c >> (SK_A32_SHIFT + 4)) & 0xF) << 0);
+}
+
+// takes two values and alternamtes them as part of a memset16
+// used for cheap 2x2 dithering when the colors are opaque
+void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n);
+
+///////////////////////////////////////////////////////////////////////////////
+
+static inline int SkUpscale31To32(int value) {
+ SkASSERT((unsigned)value <= 31);
+ return value + (value >> 4);
+}
+
+static inline int SkBlend32(int src, int dst, int scale) {
+ SkASSERT((unsigned)src <= 0xFF);
+ SkASSERT((unsigned)dst <= 0xFF);
+ SkASSERT((unsigned)scale <= 32);
+ return dst + ((src - dst) * scale >> 5);
+}
+
+static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB,
+ SkPMColor dst, uint16_t mask) {
+ if (mask == 0) {
+ return dst;
+ }
+
+ /* We want all of these in 5bits, hence the shifts in case one of them
+ * (green) is 6bits.
+ */
+ int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
+ int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
+ int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
+
+ // Now upscale them to 0..32, so we can use blend32
+ maskR = SkUpscale31To32(maskR);
+ maskG = SkUpscale31To32(maskG);
+ maskB = SkUpscale31To32(maskB);
+
+ // srcA has been upscaled to 256 before passed into this function
+ maskR = maskR * srcA >> 8;
+ maskG = maskG * srcA >> 8;
+ maskB = maskB * srcA >> 8;
+
+ int dstR = SkGetPackedR32(dst);
+ int dstG = SkGetPackedG32(dst);
+ int dstB = SkGetPackedB32(dst);
+
+ // LCD blitting is only supported if the dst is known/required
+ // to be opaque
+ return SkPackARGB32(0xFF,
+ SkBlend32(srcR, dstR, maskR),
+ SkBlend32(srcG, dstG, maskG),
+ SkBlend32(srcB, dstB, maskB));
+}
+
+static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB,
+ SkPMColor dst, uint16_t mask,
+ SkPMColor opaqueDst) {
+ if (mask == 0) {
+ return dst;
+ }
+
+ if (0xFFFF == mask) {
+ return opaqueDst;
+ }
+
+ /* We want all of these in 5bits, hence the shifts in case one of them
+ * (green) is 6bits.
+ */
+ int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
+ int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
+ int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
+
+ // Now upscale them to 0..32, so we can use blend32
+ maskR = SkUpscale31To32(maskR);
+ maskG = SkUpscale31To32(maskG);
+ maskB = SkUpscale31To32(maskB);
+
+ int dstR = SkGetPackedR32(dst);
+ int dstG = SkGetPackedG32(dst);
+ int dstB = SkGetPackedB32(dst);
+
+ // LCD blitting is only supported if the dst is known/required
+ // to be opaque
+ return SkPackARGB32(0xFF,
+ SkBlend32(srcR, dstR, maskR),
+ SkBlend32(srcG, dstG, maskG),
+ SkBlend32(srcB, dstB, maskB));
+}
+
+static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t mask[],
+ SkColor src, int width, SkPMColor) {
+ int srcA = SkColorGetA(src);
+ int srcR = SkColorGetR(src);
+ int srcG = SkColorGetG(src);
+ int srcB = SkColorGetB(src);
+
+ srcA = SkAlpha255To256(srcA);
+
+ for (int i = 0; i < width; i++) {
+ dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], mask[i]);
+ }
+}
+
+static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t mask[],
+ SkColor src, int width,
+ SkPMColor opaqueDst) {
+ int srcR = SkColorGetR(src);
+ int srcG = SkColorGetG(src);
+ int srcB = SkColorGetB(src);
+
+ for (int i = 0; i < width; i++) {
+ dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i],
+ opaqueDst);
+ }
+}
+
+#endif
diff --git a/src/third_party/skia/include/core/SkColorShader.h b/src/third_party/skia/include/core/SkColorShader.h
new file mode 100644
index 0000000..dc45f2d
--- /dev/null
+++ b/src/third_party/skia/include/core/SkColorShader.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkColorShader_DEFINED
+#define SkColorShader_DEFINED
+
+#include "SkShader.h"
+
+/** \class SkColorShader
+ A Shader that represents a single color. In general, this effect can be
+ accomplished by just using the color field on the paint, but if an
+ actual shader object is needed, this provides that feature.
+*/
+class SK_API SkColorShader : public SkShader {
+public:
+ /** 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.
+ */
+ explicit SkColorShader(SkColor c);
+
+ virtual bool isOpaque() const SK_OVERRIDE;
+
+ virtual size_t contextSize() const SK_OVERRIDE {
+ return sizeof(ColorShaderContext);
+ }
+
+ class ColorShaderContext : public SkShader::Context {
+ public:
+ ColorShaderContext(const SkColorShader& shader, const ContextRec&);
+
+ virtual uint32_t getFlags() const SK_OVERRIDE;
+ virtual uint8_t getSpan16Alpha() const SK_OVERRIDE;
+ virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE;
+ virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
+ virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE;
+
+ private:
+ SkPMColor fPMColor;
+ uint32_t fFlags;
+ uint16_t fColor16;
+
+ typedef SkShader::Context INHERITED;
+ };
+
+ // we return false for this, use asAGradient
+ virtual BitmapType asABitmap(SkBitmap* outTexture,
+ SkMatrix* outMatrix,
+ TileMode xy[2]) const SK_OVERRIDE;
+
+ virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
+
+ virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+ GrFragmentProcessor**) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
+
+protected:
+ SkColorShader(SkReadBuffer&);
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+ virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
+ virtual bool onAsLuminanceColor(SkColor* lum) const SK_OVERRIDE {
+ *lum = fColor;
+ return true;
+ }
+
+private:
+ SkColor fColor;
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkColorTable.h b/src/third_party/skia/include/core/SkColorTable.h
new file mode 100644
index 0000000..c73b431
--- /dev/null
+++ b/src/third_party/skia/include/core/SkColorTable.h
@@ -0,0 +1,94 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkColorTable_DEFINED
+#define SkColorTable_DEFINED
+
+#include "SkColor.h"
+#include "SkFlattenable.h"
+#include "SkImageInfo.h"
+
+/** \class SkColorTable
+
+ SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
+ 8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
+*/
+class SK_API SkColorTable : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkColorTable)
+
+ /** Makes a deep copy of colors.
+ */
+ SkColorTable(const SkColorTable& src);
+ SkColorTable(const SkPMColor colors[], int count,
+ SkAlphaType alphaType = kPremul_SkAlphaType);
+ virtual ~SkColorTable();
+
+ SkAlphaType alphaType() const { return (SkAlphaType)fAlphaType; }
+
+ bool isOpaque() const {
+ return SkAlphaTypeIsOpaque(this->alphaType());
+ }
+
+ /** Returns the number of colors in the table.
+ */
+ int count() const { return fCount; }
+
+ /** Returns the specified color from the table. In the debug build, this asserts that
+ the index is in range (0 <= index < count).
+ */
+ SkPMColor operator[](int index) const {
+ SkASSERT(fColors != NULL && (unsigned)index < fCount);
+ return fColors[index];
+ }
+
+ /**
+ * Return the array of colors for reading. This must be balanced by a call
+ * to unlockColors().
+ */
+ const SkPMColor* lockColors() {
+ SkDEBUGCODE(sk_atomic_inc(&fColorLockCount);)
+ return fColors;
+ }
+
+ /**
+ * Balancing call to lockColors().
+ */
+ void unlockColors();
+
+ /** Similar to lockColors(), lock16BitCache() returns the array of
+ RGB16 colors that mirror the 32bit colors. However, this function
+ will return null if kColorsAreOpaque_Flag is not set.
+ Also, unlike lockColors(), the returned array here cannot be modified.
+ */
+ const uint16_t* lock16BitCache();
+ /** Balancing call to lock16BitCache().
+ */
+ void unlock16BitCache() {
+ SkASSERT(f16BitCacheLockCount > 0);
+ SkDEBUGCODE(f16BitCacheLockCount -= 1);
+ }
+
+ explicit SkColorTable(SkReadBuffer&);
+ void writeToBuffer(SkWriteBuffer&) const;
+
+private:
+ SkPMColor* fColors;
+ uint16_t* f16BitCache;
+ uint16_t fCount;
+ uint8_t fAlphaType;
+ SkDEBUGCODE(int fColorLockCount;)
+ SkDEBUGCODE(int f16BitCacheLockCount;)
+
+ void inval16BitCache();
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkComposeShader.h b/src/third_party/skia/include/core/SkComposeShader.h
new file mode 100644
index 0000000..3a28e1e
--- /dev/null
+++ b/src/third_party/skia/include/core/SkComposeShader.h
@@ -0,0 +1,83 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkComposeShader_DEFINED
+#define SkComposeShader_DEFINED
+
+#include "SkShader.h"
+
+class SkXfermode;
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+/** \class SkComposeShader
+ This subclass of shader returns the composition of two other shaders, combined by
+ a xfermode.
+*/
+class SK_API SkComposeShader : public SkShader {
+public:
+ /** Create a new compose shader, given shaders A, B, and a combining xfermode mode.
+ When the xfermode is called, it will be given the result from shader A as its
+ "dst", and the result from shader B as its "src".
+ mode->xfer32(sA_result, sB_result, ...)
+ @param shaderA The colors from this shader are seen as the "dst" by the xfermode
+ @param shaderB The colors from this shader are seen as the "src" by the xfermode
+ @param mode The xfermode that combines the colors from the two shaders. If mode
+ is null, then SRC_OVER is assumed.
+ */
+ SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL);
+ virtual ~SkComposeShader();
+
+ virtual size_t contextSize() const SK_OVERRIDE;
+
+ class ComposeShaderContext : public SkShader::Context {
+ public:
+ // When this object gets destroyed, it will call contextA and contextB's destructor
+ // but it will NOT free the memory.
+ ComposeShaderContext(const SkComposeShader&, const ContextRec&,
+ SkShader::Context* contextA, SkShader::Context* contextB);
+
+ SkShader::Context* getShaderContextA() const { return fShaderContextA; }
+ SkShader::Context* getShaderContextB() const { return fShaderContextB; }
+
+ virtual ~ComposeShaderContext();
+
+ virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
+
+ private:
+ SkShader::Context* fShaderContextA;
+ SkShader::Context* fShaderContextB;
+
+ typedef SkShader::Context INHERITED;
+ };
+
+#ifdef SK_DEBUG
+ SkShader* getShaderA() { return fShaderA; }
+ SkShader* getShaderB() { return fShaderB; }
+#endif
+
+ virtual bool asACompose(ComposeRec* rec) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader)
+
+protected:
+ SkComposeShader(SkReadBuffer& );
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+ virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE;
+
+private:
+ SkShader* fShaderA;
+ SkShader* fShaderB;
+ SkXfermode* fMode;
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkData.h b/src/third_party/skia/include/core/SkData.h
new file mode 100644
index 0000000..e25ef50
--- /dev/null
+++ b/src/third_party/skia/include/core/SkData.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkData_DEFINED
+#define SkData_DEFINED
+
+#include "SkRefCnt.h"
+
+struct SkFILE;
+class SkStream;
+
+/**
+ * SkData holds an immutable data buffer. Not only is the data immutable,
+ * but the actual ptr that is returned (by data() or bytes()) is guaranteed
+ * to always be the same for the life of this instance.
+ */
+class SK_API SkData : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkData)
+
+ /**
+ * Returns the number of bytes stored.
+ */
+ size_t size() const { return fSize; }
+
+ bool isEmpty() const { return 0 == fSize; }
+
+ /**
+ * Returns the ptr to the data.
+ */
+ const void* data() const { return fPtr; }
+
+ /**
+ * Like data(), returns a read-only ptr into the data, but in this case
+ * it is cast to uint8_t*, to make it easy to add an offset to it.
+ */
+ const uint8_t* bytes() const {
+ return reinterpret_cast<const uint8_t*>(fPtr);
+ }
+
+ /**
+ * USE WITH CAUTION.
+ * This call will assert that the refcnt is 1, as a precaution against modifying the
+ * contents when another client/thread has access to the data.
+ */
+ void* writable_data() {
+ if (fSize) {
+ // only assert we're unique if we're not empty
+ SkASSERT(this->unique());
+ }
+ return fPtr;
+ }
+
+ /**
+ * Helper to copy a range of the data into a caller-provided buffer.
+ * Returns the actual number of bytes copied, after clamping offset and
+ * length to the size of the data. If buffer is NULL, it is ignored, and
+ * only the computed number of bytes is returned.
+ */
+ size_t copyRange(size_t offset, size_t length, void* buffer) const;
+
+ /**
+ * Returns true if these two objects have the same length and contents,
+ * effectively returning 0 == memcmp(...)
+ */
+ bool equals(const SkData* other) const;
+
+ /**
+ * Function that, if provided, will be called when the SkData goes out
+ * of scope, allowing for custom allocation/freeing of the data.
+ */
+ typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context);
+
+ /**
+ * Create a new dataref by copying the specified data
+ */
+ static SkData* NewWithCopy(const void* data, size_t length);
+
+ /**
+ * Create a new data with uninitialized contents. The caller should call writable_data()
+ * to write into the buffer, but this must be done before another ref() is made.
+ */
+ static SkData* NewUninitialized(size_t length);
+
+ /**
+ * Create a new dataref by copying the specified c-string
+ * (a null-terminated array of bytes). The returned SkData will have size()
+ * equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
+ * as "".
+ */
+ static SkData* NewWithCString(const char cstr[]);
+
+ /**
+ * Create a new dataref, taking the data ptr as is, and using the
+ * releaseproc to free it. The proc may be NULL.
+ */
+ static SkData* NewWithProc(const void* data, size_t length, ReleaseProc proc, void* context);
+
+ /**
+ * Call this when the data parameter is already const and will outlive the lifetime of the
+ * SkData. Suitable for with const globals.
+ */
+ static SkData* NewWithoutCopy(const void* data, size_t length) {
+ return NewWithProc(data, length, NULL, NULL);
+ }
+
+ /**
+ * Create a new dataref from a pointer allocated by malloc. The Data object
+ * takes ownership of that allocation, and will handling calling sk_free.
+ */
+ static SkData* NewFromMalloc(const void* data, size_t length);
+
+ /**
+ * Create a new dataref the file with the specified path.
+ * If the file cannot be opened, this returns NULL.
+ */
+ static SkData* NewFromFileName(const char path[]);
+
+ /**
+ * Create a new dataref from a SkFILE.
+ * This does not take ownership of the SkFILE, nor close it.
+ * The caller is free to close the SkFILE at its convenience.
+ * The SkFILE must be open for reading only.
+ * Returns NULL on failure.
+ */
+ static SkData* NewFromFILE(SkFILE* f);
+
+ /**
+ * Create a new dataref from a file descriptor.
+ * This does not take ownership of the file descriptor, nor close it.
+ * The caller is free to close the file descriptor at its convenience.
+ * The file descriptor must be open for reading only.
+ * Returns NULL on failure.
+ */
+ static SkData* NewFromFD(int fd);
+
+ /**
+ * Attempt to read size bytes into a SkData. If the read succeeds, return the data,
+ * else return NULL. Either way the stream's cursor may have been changed as a result
+ * of calling read().
+ */
+ static SkData* NewFromStream(SkStream*, size_t size);
+
+ /**
+ * Create a new dataref using a subset of the data in the specified
+ * src dataref.
+ */
+ static SkData* NewSubset(const SkData* src, size_t offset, size_t length);
+
+ /**
+ * Returns a new empty dataref (or a reference to a shared empty dataref).
+ * New or shared, the caller must see that unref() is eventually called.
+ */
+ static SkData* NewEmpty();
+
+private:
+ ReleaseProc fReleaseProc;
+ void* fReleaseProcContext;
+
+ void* fPtr;
+ size_t fSize;
+
+ SkData(const void* ptr, size_t size, ReleaseProc, void* context);
+ SkData(size_t size); // inplace new/delete
+ virtual ~SkData();
+
+ virtual void internal_dispose() const SK_OVERRIDE;
+
+ // Called the first time someone calls NewEmpty to initialize the singleton.
+ static SkData* NewEmptyImpl();
+ static void DeleteEmpty(SkData*);
+
+ // shared internal factory
+ static SkData* PrivateNewWithCopy(const void* srcOrNull, size_t length);
+
+ typedef SkRefCnt INHERITED;
+};
+
+/** Typedef of SkAutoTUnref<SkData> for automatically unref-ing a SkData. */
+typedef SkAutoTUnref<SkData> SkAutoDataUnref;
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDataTable.h b/src/third_party/skia/include/core/SkDataTable.h
new file mode 100644
index 0000000..9440000
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDataTable.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDataTable_DEFINED
+#define SkDataTable_DEFINED
+
+#include "SkChunkAlloc.h"
+#include "SkData.h"
+#include "SkString.h"
+#include "SkTDArray.h"
+
+/**
+ * Like SkData, SkDataTable holds an immutable data buffer. The data buffer is
+ * organized into a table of entries, each with a length, so the entries are
+ * not required to all be the same size.
+ */
+class SK_API SkDataTable : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkDataTable)
+
+ /**
+ * Returns true if the table is empty (i.e. has no entries).
+ */
+ bool isEmpty() const { return 0 == fCount; }
+
+ /**
+ * Return the number of entries in the table. 0 for an empty table
+ */
+ int count() const { return fCount; }
+
+ /**
+ * Return the size of the index'th entry in the table. The caller must
+ * ensure that index is valid for this table.
+ */
+ size_t atSize(int index) const;
+
+ /**
+ * Return a pointer to the data of the index'th entry in the table.
+ * The caller must ensure that index is valid for this table.
+ *
+ * @param size If non-null, this returns the byte size of this entry. This
+ * will be the same value that atSize(index) would return.
+ */
+ const void* at(int index, size_t* size = NULL) const;
+
+ template <typename T>
+ const T* atT(int index, size_t* size = NULL) const {
+ return reinterpret_cast<const T*>(this->at(index, size));
+ }
+
+ /**
+ * Returns the index'th entry as a c-string, and assumes that the trailing
+ * null byte had been copied into the table as well.
+ */
+ const char* atStr(int index) const {
+ size_t size;
+ const char* str = this->atT<const char>(index, &size);
+ SkASSERT(strlen(str) + 1 == size);
+ return str;
+ }
+
+ typedef void (*FreeProc)(void* context);
+
+ static SkDataTable* NewEmpty();
+
+ /**
+ * Return a new DataTable that contains a copy of the data stored in each
+ * "array".
+ *
+ * @param ptrs array of points to each element to be copied into the table.
+ * @param sizes array of byte-lengths for each entry in the corresponding
+ * ptrs[] array.
+ * @param count the number of array elements in ptrs[] and sizes[] to copy.
+ */
+ static SkDataTable* NewCopyArrays(const void * const * ptrs,
+ const size_t sizes[], int count);
+
+ /**
+ * Return a new table that contains a copy of the data in array.
+ *
+ * @param array contiguous array of data for all elements to be copied.
+ * @param elemSize byte-length for a given element.
+ * @param count the number of entries to be copied out of array. The number
+ * of bytes that will be copied is count * elemSize.
+ */
+ static SkDataTable* NewCopyArray(const void* array, size_t elemSize,
+ int count);
+
+ static SkDataTable* NewArrayProc(const void* array, size_t elemSize,
+ int count, FreeProc proc, void* context);
+
+private:
+ struct Dir {
+ const void* fPtr;
+ uintptr_t fSize;
+ };
+
+ int fCount;
+ size_t fElemSize;
+ union {
+ const Dir* fDir;
+ const char* fElems;
+ } fU;
+
+ FreeProc fFreeProc;
+ void* fFreeProcContext;
+
+ SkDataTable();
+ SkDataTable(const void* array, size_t elemSize, int count,
+ FreeProc, void* context);
+ SkDataTable(const Dir*, int count, FreeProc, void* context);
+ virtual ~SkDataTable();
+
+ friend class SkDataTableBuilder; // access to Dir
+
+ typedef SkRefCnt INHERITED;
+};
+
+/**
+ * Helper class that allows for incrementally building up the data needed to
+ * create a SkDataTable.
+ */
+class SK_API SkDataTableBuilder : SkNoncopyable {
+public:
+ SkDataTableBuilder(size_t minChunkSize);
+ ~SkDataTableBuilder();
+
+ int count() const { return fDir.count(); }
+ size_t minChunkSize() const { return fMinChunkSize; }
+
+ /**
+ * Forget any previously appended entries, setting count() back to 0.
+ */
+ void reset(size_t minChunkSize);
+ void reset() {
+ this->reset(fMinChunkSize);
+ }
+
+ /**
+ * Copy size-bytes from data, and append it to the growing SkDataTable.
+ */
+ void append(const void* data, size_t size);
+
+ /**
+ * Helper version of append() passes strlen() + 1 for the size,
+ * so the trailing-zero will be copied as well.
+ */
+ void appendStr(const char str[]) {
+ this->append(str, strlen(str) + 1);
+ }
+
+ /**
+ * Helper version of append() passes string.size() + 1 for the size,
+ * so the trailing-zero will be copied as well.
+ */
+ void appendString(const SkString& string) {
+ this->append(string.c_str(), string.size() + 1);
+ }
+
+ /**
+ * Return an SkDataTable from the accumulated entries that were added by
+ * calls to append(). This call also clears any accumluated entries from
+ * this builder, so its count() will be 0 after this call.
+ */
+ SkDataTable* detachDataTable();
+
+private:
+ SkTDArray<SkDataTable::Dir> fDir;
+ SkChunkAlloc* fHeap;
+ size_t fMinChunkSize;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDeque.h b/src/third_party/skia/include/core/SkDeque.h
new file mode 100644
index 0000000..0b3e37f
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDeque.h
@@ -0,0 +1,138 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkDeque_DEFINED
+#define SkDeque_DEFINED
+
+#include "SkTypes.h"
+
+/*
+ * The deque class works by blindly creating memory space of a specified element
+ * size. It manages the memory as a doubly linked list of blocks each of which
+ * can contain multiple elements. Pushes and pops add/remove blocks from the
+ * beginning/end of the list as necessary while each block tracks the used
+ * portion of its memory.
+ * One behavior to be aware of is that the pops do not immediately remove an
+ * empty block from the beginning/end of the list (Presumably so push/pop pairs
+ * on the block boundaries don't cause thrashing). This can result in the first/
+ * last element not residing in the first/last block.
+ */
+class SK_API SkDeque : SkNoncopyable {
+public:
+ /**
+ * elemSize specifies the size of each individual element in the deque
+ * allocCount specifies how many elements are to be allocated as a block
+ */
+ explicit SkDeque(size_t elemSize, int allocCount = 1);
+ SkDeque(size_t elemSize, void* storage, size_t storageSize, int allocCount = 1);
+ ~SkDeque();
+
+ bool empty() const { return 0 == fCount; }
+ int count() const { return fCount; }
+ size_t elemSize() const { return fElemSize; }
+
+ const void* front() const { return fFront; }
+ const void* back() const { return fBack; }
+
+ void* front() {
+ return (void*)((const SkDeque*)this)->front();
+ }
+
+ void* back() {
+ return (void*)((const SkDeque*)this)->back();
+ }
+
+ /**
+ * push_front and push_back return a pointer to the memory space
+ * for the new element
+ */
+ void* push_front();
+ void* push_back();
+
+ void pop_front();
+ void pop_back();
+
+private:
+ struct Block;
+
+public:
+ class Iter {
+ public:
+ enum IterStart {
+ kFront_IterStart,
+ kBack_IterStart
+ };
+
+ /**
+ * Creates an uninitialized iterator. Must be reset()
+ */
+ Iter();
+
+ Iter(const SkDeque& d, IterStart startLoc);
+ void* next();
+ void* prev();
+
+ void reset(const SkDeque& d, IterStart startLoc);
+
+ private:
+ SkDeque::Block* fCurBlock;
+ char* fPos;
+ size_t fElemSize;
+ };
+
+ // Inherit privately from Iter to prevent access to reverse iteration
+ class F2BIter : private Iter {
+ public:
+ F2BIter() {}
+
+ /**
+ * Wrap Iter's 2 parameter ctor to force initialization to the
+ * beginning of the deque
+ */
+ F2BIter(const SkDeque& d) : INHERITED(d, kFront_IterStart) {}
+
+ using Iter::next;
+
+ /**
+ * Wrap Iter::reset to force initialization to the beginning of the
+ * deque
+ */
+ void reset(const SkDeque& d) {
+ this->INHERITED::reset(d, kFront_IterStart);
+ }
+
+ private:
+ typedef Iter INHERITED;
+ };
+
+private:
+ // allow unit test to call numBlocksAllocated
+ friend class DequeUnitTestHelper;
+
+ void* fFront;
+ void* fBack;
+
+ Block* fFrontBlock;
+ Block* fBackBlock;
+ size_t fElemSize;
+ void* fInitialStorage;
+ int fCount; // number of elements in the deque
+ int fAllocCount; // number of elements to allocate per block
+
+ Block* allocateBlock(int allocCount);
+ void freeBlock(Block* block);
+
+ /**
+ * This returns the number of chunk blocks allocated by the deque. It
+ * can be used to gauge the effectiveness of the selected allocCount.
+ */
+ int numBlocksAllocated() const;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDevice.h b/src/third_party/skia/include/core/SkDevice.h
new file mode 100644
index 0000000..b19177a
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDevice.h
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2010 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDevice_DEFINED
+#define SkDevice_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkColor.h"
+#include "SkImageFilter.h"
+
+class SkClipStack;
+class SkDraw;
+struct SkIRect;
+class SkMatrix;
+class SkMetaData;
+class SkRegion;
+struct SkDeviceProperties;
+class GrRenderTarget;
+
+class SK_API SkBaseDevice : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkBaseDevice)
+
+ /**
+ * Construct a new device.
+ */
+ SkBaseDevice();
+ virtual ~SkBaseDevice();
+
+ SkBaseDevice* createCompatibleDevice(const SkImageInfo&);
+
+ SkMetaData& getMetaData();
+
+ /**
+ * Return ImageInfo for this device. If the canvas is not backed by pixels
+ * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
+ */
+ virtual SkImageInfo imageInfo() const;
+
+ /**
+ * Return the bounds of the device in the coordinate space of the root
+ * canvas. The root device will have its top-left at 0,0, but other devices
+ * such as those associated with saveLayer may have a non-zero origin.
+ */
+ void getGlobalBounds(SkIRect* bounds) const {
+ SkASSERT(bounds);
+ const SkIPoint& origin = this->getOrigin();
+ bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
+ }
+
+ int width() const {
+ return this->imageInfo().width();
+ }
+
+ int height() const {
+ return this->imageInfo().height();
+ }
+
+ bool isOpaque() const {
+ return this->imageInfo().isOpaque();
+ }
+
+ /** Return the bitmap associated with this device. Call this each time you need
+ to access the bitmap, as it notifies the subclass to perform any flushing
+ etc. before you examine the pixels.
+ @param changePixels set to true if the caller plans to change the pixels
+ @return the device's bitmap
+ */
+ const SkBitmap& accessBitmap(bool changePixels);
+
+ bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
+
+ void* accessPixels(SkImageInfo* info, size_t* rowBytes);
+
+ /**
+ * Return the device's associated gpu render target, or NULL.
+ */
+ virtual GrRenderTarget* accessRenderTarget() { return NULL; }
+
+
+ /**
+ * Return the device's origin: its offset in device coordinates from
+ * the default origin in its canvas' matrix/clip
+ */
+ const SkIPoint& getOrigin() const { return fOrigin; }
+
+ /**
+ * onAttachToCanvas is invoked whenever a device is installed in a canvas
+ * (i.e., setDevice, saveLayer (for the new device created by the save),
+ * and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the
+ * devices to prepare for drawing (e.g., locking their pixels, etc.)
+ */
+ virtual void onAttachToCanvas(SkCanvas*) {
+ SkASSERT(!fAttachedToCanvas);
+ this->lockPixels();
+#ifdef SK_DEBUG
+ fAttachedToCanvas = true;
+#endif
+ };
+
+ /**
+ * onDetachFromCanvas notifies a device that it will no longer be drawn to.
+ * It gives the device a chance to clean up (e.g., unlock its pixels). It
+ * is invoked from setDevice (for the displaced device), restore and
+ * possibly from SkCanvas' dtor.
+ */
+ virtual void onDetachFromCanvas() {
+ SkASSERT(fAttachedToCanvas);
+ this->unlockPixels();
+#ifdef SK_DEBUG
+ fAttachedToCanvas = false;
+#endif
+ };
+
+protected:
+ enum Usage {
+ kGeneral_Usage,
+ kSaveLayer_Usage, // <! internal use only
+ kImageFilter_Usage // <! internal use only
+ };
+
+ struct TextFlags {
+ uint32_t fFlags; // SkPaint::getFlags()
+ };
+
+ /**
+ * Device may filter the text flags for drawing text here. If it wants to
+ * make a change to the specified values, it should write them into the
+ * textflags parameter (output) and return true. If the paint is fine as
+ * is, then ignore the textflags parameter and return false.
+ */
+ virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) { return false; }
+
+ /**
+ *
+ * DEPRECATED: This will be removed in a future change. Device subclasses
+ * should use the matrix and clip from the SkDraw passed to draw functions.
+ *
+ * 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.
+ *
+ * The clipstack is another view of the clip. It records the actual
+ * geometry that went into building the region. It is present for devices
+ * that want to parse it, but is not required: the region is a complete
+ * picture of the current clip. (i.e. if you regionize all of the geometry
+ * in the clipstack, you will arrive at an equivalent region to the one
+ * passed in).
+ */
+ virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
+ const SkClipStack&) {};
+
+ /** Clears the entire device to the specified color (including alpha).
+ * Ignores the clip.
+ */
+ virtual void clear(SkColor color) = 0;
+
+ SK_ATTR_DEPRECATED("use clear() instead")
+ void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
+
+ /** These are called inside the per-device-layer loop for each draw call.
+ When these are called, we have already applied any saveLayer operations,
+ and are handling any looping from the paint, and any effects from the
+ DrawFilter.
+ */
+ virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
+ virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+ const SkPoint[], const SkPaint& paint) = 0;
+ virtual void drawRect(const SkDraw&, const SkRect& r,
+ const SkPaint& paint) = 0;
+ virtual void drawOval(const SkDraw&, const SkRect& oval,
+ const SkPaint& paint) = 0;
+ virtual void drawRRect(const SkDraw&, const SkRRect& rr,
+ const SkPaint& paint) = 0;
+
+ // Default impl calls drawPath()
+ virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
+ const SkRRect& inner, const SkPaint&);
+
+ /**
+ * If pathIsMutable, then the implementation is allowed to cast path to a
+ * non-const pointer and modify it in place (as an optimization). Canvas
+ * may do this to implement helpers such as drawOval, by placing a temp
+ * path on the stack to hold the representation of the oval.
+ *
+ * If prePathMatrix is not null, it should logically be applied before any
+ * stroking or other effects. If there are no effects on the paint that
+ * affect the geometry/rasterization, then the pre matrix can just be
+ * pre-concated with the current matrix.
+ */
+ virtual void drawPath(const SkDraw&, const SkPath& path,
+ const SkPaint& paint,
+ const SkMatrix* prePathMatrix = NULL,
+ bool pathIsMutable = false) = 0;
+ virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint& paint) = 0;
+ virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+ int x, int y, const SkPaint& paint) = 0;
+
+ /**
+ * The default impl. will create a bitmap-shader from the bitmap,
+ * and call drawRect with it.
+ */
+ virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
+ const SkRect* srcOrNull, const SkRect& dst,
+ const SkPaint& paint,
+ SkCanvas::DrawBitmapRectFlags flags) = 0;
+
+ /**
+ * Does not handle text decoration.
+ * Decorations (underline and stike-thru) will be handled by SkCanvas.
+ */
+ virtual void drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint) = 0;
+ virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint& paint) = 0;
+ virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) = 0;
+ virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+ const SkPoint verts[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) = 0;
+ // default implementation unrolls the blob runs.
+ virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
+ const SkPaint& paint);
+ // default implementation calls drawVertices
+ virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
+ /** The SkDevice passed will be an SkDevice which was returned by a call to
+ onCreateDevice on this device with kSaveLayer_Usage.
+ */
+ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+ const SkPaint&) = 0;
+
+ bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** Update as needed the pixel value in the bitmap, so that the caller can
+ access the pixels directly.
+ @return The device contents as a bitmap
+ */
+ virtual const SkBitmap& onAccessBitmap() = 0;
+
+ /** Called when this device is installed into a Canvas. Balanced by a call
+ to unlockPixels() when the device is removed from a Canvas.
+ */
+ virtual void lockPixels() {}
+ virtual void unlockPixels() {}
+
+ /**
+ * Returns true if the device allows processing of this imagefilter. If
+ * false is returned, then the filter is ignored. This may happen for
+ * some subclasses that do not support pixel manipulations after drawing
+ * has occurred (e.g. printing). The default implementation returns true.
+ */
+ virtual bool allowImageFilter(const SkImageFilter*) { return true; }
+
+ /**
+ * Override and return true for filters that the device can handle
+ * intrinsically. Doing so means that SkCanvas will pass-through this
+ * filter to drawSprite and drawDevice (and potentially filterImage).
+ * Returning false means the SkCanvas will have apply the filter itself,
+ * and just pass the resulting image to the device.
+ */
+ virtual bool canHandleImageFilter(const SkImageFilter*) { return false; }
+
+ /**
+ * Related (but not required) to canHandleImageFilter, this method returns
+ * true if the device could apply the filter to the src bitmap and return
+ * the result (and updates offset as needed).
+ * If the device does not recognize or support this filter,
+ * it just returns false and leaves result and offset unchanged.
+ */
+ virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
+ const SkImageFilter::Context& ctx,
+ SkBitmap* result, SkIPoint* offset) {
+ return false;
+ }
+
+protected:
+ // default impl returns NULL
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&);
+
+ // default impl returns NULL
+ virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
+
+ /**
+ * The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
+ * image at the specified x,y offset will fit within the device's bounds.
+ *
+ * This is explicitly asserted in readPixels(), the public way to call this.
+ */
+ virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y);
+
+ /**
+ * The caller is responsible for "pre-clipping" the src. The impl can assume that the src
+ * image at the specified x,y offset will fit within the device's bounds.
+ *
+ * This is explicitly asserted in writePixelsDirect(), the public way to call this.
+ */
+ virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y);
+
+ /**
+ * Default impl returns NULL.
+ */
+ virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes);
+
+ /**
+ * Leaky properties are those which the device should be applying but it isn't.
+ * These properties will be applied by the draw, when and as it can.
+ * If the device does handle a property, that property should be set to the identity value
+ * for that property, effectively making it non-leaky.
+ */
+ const SkDeviceProperties& getLeakyProperties() const {
+ return *fLeakyProperties;
+ }
+
+ /**
+ * PRIVATE / EXPERIMENTAL -- do not call
+ * Construct an acceleration object and attach it to 'picture'
+ */
+ virtual void EXPERIMENTAL_optimize(const SkPicture* picture);
+
+ /**
+ * PRIVATE / EXPERIMENTAL -- do not call
+ * This entry point gives the backend an opportunity to take over the rendering
+ * of 'picture'. If optimization data is available (due to an earlier
+ * 'optimize' call) this entry point should make use of it and return true
+ * if all rendering has been done. If false is returned, SkCanvas will
+ * perform its own rendering pass. It is acceptable for the backend
+ * to perform some device-specific warm up tasks and then let SkCanvas
+ * perform the main rendering loop (by return false from here).
+ */
+ virtual bool EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
+ const SkPaint*);
+
+ void setPixelGeometry(SkPixelGeometry geo);
+
+private:
+ friend class SkCanvas;
+ friend struct DeviceCM; //for setMatrixClip
+ friend class SkDraw;
+ friend class SkDrawIter;
+ friend class SkDeviceFilteredPaint;
+ friend class SkDeviceImageFilterProxy;
+ friend class SkDeferredDevice; // for newSurface
+
+ friend class SkSurface_Raster;
+
+ // used to change the backend's pixels (and possibly config/rowbytes)
+ // but cannot change the width/height, so there should be no change to
+ // any clip information.
+ // TODO: move to SkBitmapDevice
+ virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {}
+
+ virtual bool forceConservativeRasterClip() const { return false; }
+
+ // just called by SkCanvas when built as a layer
+ void setOrigin(int x, int y) { fOrigin.set(x, y); }
+ // just called by SkCanvas for saveLayer
+ SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
+ // just called by SkCanvas for imagefilter
+ SkBaseDevice* createCompatibleDeviceForImageFilter(const SkImageInfo&);
+
+ virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
+ return NULL;
+ }
+
+ /** Causes any deferred drawing to the device to be completed.
+ */
+ virtual void flush() {}
+
+ virtual SkImageFilter::Cache* getImageFilterCache() { return NULL; }
+
+ SkIPoint fOrigin;
+ SkMetaData* fMetaData;
+ SkDeviceProperties* fLeakyProperties; // will always exist.
+
+#ifdef SK_DEBUG
+ bool fAttachedToCanvas;
+#endif
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDither.h b/src/third_party/skia/include/core/SkDither.h
new file mode 100644
index 0000000..d82b4167
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDither.h
@@ -0,0 +1,198 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkDither_DEFINED
+#define SkDither_DEFINED
+
+#include "SkColorPriv.h"
+
+#define SK_DitherValueMax4444 15
+#define SK_DitherValueMax565 7
+
+/* need to use macros for bit-counts for each component, and then
+ move these into SkColorPriv.h
+*/
+
+#define SkDITHER_R32_FOR_565_MACRO(r, d) (r + d - (r >> 5))
+#define SkDITHER_G32_FOR_565_MACRO(g, d) (g + (d >> 1) - (g >> 6))
+#define SkDITHER_B32_FOR_565_MACRO(b, d) (b + d - (b >> 5))
+
+#define SkDITHER_A32_FOR_4444_MACRO(a, d) (a + 15 - (a >> 4))
+#define SkDITHER_R32_FOR_4444_MACRO(r, d) (r + d - (r >> 4))
+#define SkDITHER_G32_FOR_4444_MACRO(g, d) (g + d - (g >> 4))
+#define SkDITHER_B32_FOR_4444_MACRO(b, d) (b + d - (b >> 4))
+
+#ifdef SK_DEBUG
+ inline unsigned SkDITHER_R32_FOR_565(unsigned r, unsigned d)
+ {
+ SkASSERT(d <= SK_DitherValueMax565);
+ SkA32Assert(r);
+ r = SkDITHER_R32_FOR_565_MACRO(r, d);
+ SkA32Assert(r);
+ return r;
+ }
+ inline unsigned SkDITHER_G32_FOR_565(unsigned g, unsigned d)
+ {
+ SkASSERT(d <= SK_DitherValueMax565);
+ SkG32Assert(g);
+ g = SkDITHER_G32_FOR_565_MACRO(g, d);
+ SkG32Assert(g);
+ return g;
+ }
+ inline unsigned SkDITHER_B32_FOR_565(unsigned b, unsigned d)
+ {
+ SkASSERT(d <= SK_DitherValueMax565);
+ SkB32Assert(b);
+ b = SkDITHER_B32_FOR_565_MACRO(b, d);
+ SkB32Assert(b);
+ return b;
+ }
+#else
+ #define SkDITHER_R32_FOR_565(r, d) SkDITHER_R32_FOR_565_MACRO(r, d)
+ #define SkDITHER_G32_FOR_565(g, d) SkDITHER_G32_FOR_565_MACRO(g, d)
+ #define SkDITHER_B32_FOR_565(b, d) SkDITHER_B32_FOR_565_MACRO(b, d)
+#endif
+
+#define SkDITHER_R32To565(r, d) SkR32ToR16(SkDITHER_R32_FOR_565(r, d))
+#define SkDITHER_G32To565(g, d) SkG32ToG16(SkDITHER_G32_FOR_565(g, d))
+#define SkDITHER_B32To565(b, d) SkB32ToB16(SkDITHER_B32_FOR_565(b, d))
+
+#define SkDITHER_A32To4444(a, d) SkA32To4444(SkDITHER_A32_FOR_4444_MACRO(a, d))
+#define SkDITHER_R32To4444(r, d) SkR32To4444(SkDITHER_R32_FOR_4444_MACRO(r, d))
+#define SkDITHER_G32To4444(g, d) SkG32To4444(SkDITHER_G32_FOR_4444_MACRO(g, d))
+#define SkDITHER_B32To4444(b, d) SkB32To4444(SkDITHER_B32_FOR_4444_MACRO(b, d))
+
+static inline SkPMColor SkDitherARGB32For565(SkPMColor c, unsigned dither)
+{
+ SkASSERT(dither <= SK_DitherValueMax565);
+
+ unsigned sa = SkGetPackedA32(c);
+ dither = SkAlphaMul(dither, SkAlpha255To256(sa));
+
+ unsigned sr = SkGetPackedR32(c);
+ unsigned sg = SkGetPackedG32(c);
+ unsigned sb = SkGetPackedB32(c);
+ sr = SkDITHER_R32_FOR_565(sr, dither);
+ sg = SkDITHER_G32_FOR_565(sg, dither);
+ sb = SkDITHER_B32_FOR_565(sb, dither);
+
+ return SkPackARGB32(sa, sr, sg, sb);
+}
+
+static inline SkPMColor SkDitherRGB32For565(SkPMColor c, unsigned dither)
+{
+ SkASSERT(dither <= SK_DitherValueMax565);
+
+ unsigned sr = SkGetPackedR32(c);
+ unsigned sg = SkGetPackedG32(c);
+ unsigned sb = SkGetPackedB32(c);
+ sr = SkDITHER_R32_FOR_565(sr, dither);
+ sg = SkDITHER_G32_FOR_565(sg, dither);
+ sb = SkDITHER_B32_FOR_565(sb, dither);
+
+ return SkPackARGB32(0xFF, sr, sg, sb);
+}
+
+static inline uint16_t SkDitherRGBTo565(U8CPU r, U8CPU g, U8CPU b,
+ unsigned dither)
+{
+ SkASSERT(dither <= SK_DitherValueMax565);
+ r = SkDITHER_R32To565(r, dither);
+ g = SkDITHER_G32To565(g, dither);
+ b = SkDITHER_B32To565(b, dither);
+ return SkPackRGB16(r, g, b);
+}
+
+static inline uint16_t SkDitherRGB32To565(SkPMColor c, unsigned dither)
+{
+ SkASSERT(dither <= SK_DitherValueMax565);
+
+ unsigned sr = SkGetPackedR32(c);
+ unsigned sg = SkGetPackedG32(c);
+ unsigned sb = SkGetPackedB32(c);
+ sr = SkDITHER_R32To565(sr, dither);
+ sg = SkDITHER_G32To565(sg, dither);
+ sb = SkDITHER_B32To565(sb, dither);
+
+ return SkPackRGB16(sr, sg, sb);
+}
+
+static inline uint16_t SkDitherARGB32To565(U8CPU sa, SkPMColor c, unsigned dither)
+{
+ SkASSERT(dither <= SK_DitherValueMax565);
+ dither = SkAlphaMul(dither, SkAlpha255To256(sa));
+
+ unsigned sr = SkGetPackedR32(c);
+ unsigned sg = SkGetPackedG32(c);
+ unsigned sb = SkGetPackedB32(c);
+ sr = SkDITHER_R32To565(sr, dither);
+ sg = SkDITHER_G32To565(sg, dither);
+ sb = SkDITHER_B32To565(sb, dither);
+
+ return SkPackRGB16(sr, sg, sb);
+}
+
+///////////////////////// 4444
+
+static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, U8CPU g,
+ U8CPU b, unsigned dither)
+{
+ dither = SkAlphaMul(dither, SkAlpha255To256(a));
+
+ a = SkDITHER_A32To4444(a, dither);
+ r = SkDITHER_R32To4444(r, dither);
+ g = SkDITHER_G32To4444(g, dither);
+ b = SkDITHER_B32To4444(b, dither);
+
+ return SkPackARGB4444(a, r, g, b);
+}
+
+static inline SkPMColor16 SkDitherARGB32To4444(SkPMColor c, unsigned dither)
+{
+ unsigned a = SkGetPackedA32(c);
+ unsigned r = SkGetPackedR32(c);
+ unsigned g = SkGetPackedG32(c);
+ unsigned b = SkGetPackedB32(c);
+
+ dither = SkAlphaMul(dither, SkAlpha255To256(a));
+
+ a = SkDITHER_A32To4444(a, dither);
+ r = SkDITHER_R32To4444(r, dither);
+ g = SkDITHER_G32To4444(g, dither);
+ b = SkDITHER_B32To4444(b, dither);
+
+ return SkPackARGB4444(a, r, g, b);
+}
+
+// TODO: need dither routines for 565 -> 4444
+
+// this toggles between a 4x4 and a 1x4 array
+//#define ENABLE_DITHER_MATRIX_4X4
+
+#ifdef ENABLE_DITHER_MATRIX_4X4
+ extern const uint8_t gDitherMatrix_4Bit_4X4[4][4];
+ extern const uint8_t gDitherMatrix_3Bit_4X4[4][4];
+
+ #define DITHER_4444_SCAN(y) const uint8_t* dither_scan = gDitherMatrix_4Bit_4X4[(y) & 3]
+ #define DITHER_565_SCAN(y) const uint8_t* dither_scan = gDitherMatrix_3Bit_4X4[(y) & 3]
+
+ #define DITHER_VALUE(x) dither_scan[(x) & 3]
+#else
+ extern const uint16_t gDitherMatrix_4Bit_16[4];
+ extern const uint16_t gDitherMatrix_3Bit_16[4];
+
+ #define DITHER_4444_SCAN(y) const uint16_t dither_scan = gDitherMatrix_4Bit_16[(y) & 3]
+ #define DITHER_565_SCAN(y) const uint16_t dither_scan = gDitherMatrix_3Bit_16[(y) & 3]
+
+ #define DITHER_VALUE(x) ((dither_scan >> (((x) & 3) << 2)) & 0xF)
+#endif
+
+#define DITHER_INC_X(x) ++(x)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDocument.h b/src/third_party/skia/include/core/SkDocument.h
new file mode 100644
index 0000000..dbf4bc5
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDocument.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDocument_DEFINED
+#define SkDocument_DEFINED
+
+#include "SkBitmap.h"
+#include "SkPicture.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+
+class SkCanvas;
+class SkWStream;
+
+/** SK_ScalarDefaultDPI is 72 DPI.
+*/
+#define SK_ScalarDefaultRasterDPI 72.0f
+
+/**
+ * High-level API for creating a document-based canvas. To use..
+ *
+ * 1. Create a document, specifying a stream to store the output.
+ * 2. For each "page" of content:
+ * a. canvas = doc->beginPage(...)
+ * b. draw_my_content(canvas);
+ * c. doc->endPage();
+ * 3. Close the document with doc->close().
+ */
+class SkDocument : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkDocument)
+
+ /**
+ * Create a PDF-backed document, writing the results into a file.
+ * If there is an error trying to create the doc, returns NULL.
+ * encoder sets the DCTEncoder for images, to encode a bitmap
+ * as JPEG (DCT).
+ * rasterDpi - the DPI at which features without native PDF support
+ * will be rasterized (e.g. draw image with perspective,
+ * draw text with perspective, ...)
+ * A larger DPI would create a PDF that reflects the original
+ * intent with better fidelity, but it can make for larger
+ * PDF files too, which would use more memory while rendering,
+ * and it would be slower to be processed or sent online or
+ * to printer.
+ */
+ static SkDocument* CreatePDF(
+ const char filename[],
+ SkPicture::EncodeBitmap encoder = NULL,
+ SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);
+
+ /**
+ * Create a PDF-backed document, writing the results into a stream.
+ * If there is an error trying to create the doc, returns NULL.
+ *
+ * The document may write to the stream at anytime during its lifetime,
+ * until either close() is called or the document is deleted. Once close()
+ * has been called, and all of the data has been written to the stream,
+ * if there is a Done proc provided, it will be called with the stream.
+ * The proc can delete the stream, or whatever it needs to do.
+ * encoder sets the DCTEncoder for images, to encode a bitmap
+ * as JPEG (DCT).
+ * Done - clean up method intended to allow deletion of the stream.
+ * Its aborted parameter is true if the cleanup is due to an abort
+ * call. It is false otherwise.
+ * rasterDpi - the DPI at which features without native PDF support
+ * will be rasterized (e.g. draw image with perspective,
+ * draw text with perspective, ...)
+ * A larger DPI would create a PDF that reflects the original
+ * intent with better fidelity, but it can make for larger
+ * PDF files too, which would use more memory while rendering,
+ * and it would be slower to be processed or sent online or
+ * to printer. */
+ static SkDocument* CreatePDF(
+ SkWStream*, void (*Done)(SkWStream*,bool aborted) = NULL,
+ SkPicture::EncodeBitmap encoder = NULL,
+ SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);
+
+ /**
+ * Begin a new page for the document, returning the canvas that will draw
+ * into the page. The document owns this canvas, and it will go out of
+ * scope when endPage() or close() is called, or the document is deleted.
+ */
+ SkCanvas* beginPage(SkScalar width, SkScalar height,
+ const SkRect* content = NULL);
+
+ /**
+ * Call endPage() when the content for the current page has been drawn
+ * (into the canvas returned by beginPage()). After this call the canvas
+ * returned by beginPage() will be out-of-scope.
+ */
+ void endPage();
+
+ /**
+ * Call close() when all pages have been drawn. This will close the file
+ * or stream holding the document's contents. After close() the document
+ * can no longer add new pages. Deleting the document will automatically
+ * call close() if need be.
+ * Returns true on success or false on failure.
+ */
+ bool close();
+
+ /**
+ * Call abort() to stop producing the document immediately.
+ * The stream output must be ignored, and should not be trusted.
+ */
+ void abort();
+
+protected:
+ SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted));
+ // note: subclasses must call close() in their destructor, as the base class
+ // cannot do this for them.
+ virtual ~SkDocument();
+
+ virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height,
+ const SkRect& content) = 0;
+ virtual void onEndPage() = 0;
+ virtual bool onClose(SkWStream*) = 0;
+ virtual void onAbort() = 0;
+
+ enum State {
+ kBetweenPages_State,
+ kInPage_State,
+ kClosed_State
+ };
+ State getState() const { return fState; }
+
+private:
+ SkWStream* fStream;
+ void (*fDoneProc)(SkWStream*, bool aborted);
+ State fState;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDraw.h b/src/third_party/skia/include/core/SkDraw.h
new file mode 100644
index 0000000..21d4210
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDraw.h
@@ -0,0 +1,155 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkDraw_DEFINED
+#define SkDraw_DEFINED
+
+#include "SkCanvas.h"
+#include "SkMask.h"
+#include "SkPaint.h"
+
+class SkBitmap;
+class SkClipStack;
+class SkBaseDevice;
+class SkBlitter;
+class SkMatrix;
+class SkPath;
+class SkRegion;
+class SkRasterClip;
+struct SkDrawProcs;
+struct SkRect;
+class SkRRect;
+
+class SkDraw {
+public:
+ SkDraw();
+ SkDraw(const SkDraw& src);
+
+ void drawPaint(const SkPaint&) const;
+ void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[],
+ const SkPaint&, bool forceUseDevice = false) const;
+ void drawRect(const SkRect&, const SkPaint&) const;
+ void drawRRect(const SkRRect&, 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.
+ *
+ * If prePathMatrix is not null, it should logically be applied before any
+ * stroking or other effects. If there are no effects on the paint that
+ * affect the geometry/rasterization, then the pre matrix can just be
+ * pre-concated with the current matrix.
+ */
+ void drawPath(const SkPath& path, const SkPaint& paint,
+ const SkMatrix* prePathMatrix, bool pathIsMutable) const {
+ this->drawPath(path, paint, prePathMatrix, pathIsMutable, false);
+ }
+
+ void drawPath(const SkPath& path, const SkPaint& paint,
+ SkBlitter* customBlitter = NULL) const {
+ this->drawPath(path, paint, NULL, false, false, customBlitter);
+ }
+
+ void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const;
+ void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
+ void drawText(const char text[], size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint) const;
+ void drawPosText(const char text[], size_t byteLength,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPosition, const SkPaint& paint) const;
+ void drawTextOnPath(const char text[], size_t byteLength,
+ const SkPath&, const SkMatrix*, const SkPaint&) const;
+ void drawVertices(SkCanvas::VertexMode mode, int count,
+ const SkPoint vertices[], const SkPoint textures[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int ptCount,
+ const SkPaint& paint) const;
+
+ /**
+ * Overwrite the target with the path's coverage (i.e. its mask).
+ * Will overwrite the entire device, so it need not be zero'd first.
+ *
+ * Only device A8 is supported right now.
+ */
+ void drawPathCoverage(const SkPath& src, const SkPaint& paint,
+ SkBlitter* customBlitter = NULL) const {
+ this->drawPath(src, paint, NULL, false, true, customBlitter);
+ }
+
+ /** Helper function that creates a mask from a path and an optional maskfilter.
+ Note however, that the resulting mask will not have been actually filtered,
+ that must be done afterwards (by calling filterMask). The maskfilter is provided
+ solely to assist in computing the mask's bounds (if the mode requests that).
+ */
+ static bool DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
+ const SkMaskFilter*, const SkMatrix* filterMatrix,
+ SkMask* mask, SkMask::CreateMode mode,
+ SkPaint::Style style);
+
+ enum RectType {
+ kHair_RectType,
+ kFill_RectType,
+ kStroke_RectType,
+ kPath_RectType
+ };
+
+ /**
+ * Based on the paint's style, strokeWidth, and the matrix, classify how
+ * to draw the rect. If no special-case is available, returns
+ * kPath_RectType.
+ *
+ * Iff RectType == kStroke_RectType, then strokeSize is set to the device
+ * width and height of the stroke.
+ */
+ static RectType ComputeRectType(const SkPaint&, const SkMatrix&,
+ SkPoint* strokeSize);
+
+ static bool ShouldDrawTextAsPaths(const SkPaint&, const SkMatrix&);
+ void drawText_asPaths(const char text[], size_t byteLength,
+ SkScalar x, SkScalar y, const SkPaint&) const;
+ void drawPosText_asPaths(const char text[], size_t byteLength,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPosition, const SkPaint&) const;
+
+private:
+ void drawDevMask(const SkMask& mask, const SkPaint&) const;
+ void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
+
+ void drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix,
+ bool pathIsMutable, bool drawCoverage,
+ SkBlitter* customBlitter = NULL) const;
+
+ /**
+ * Return the current clip bounds, in local coordinates, with slop to account
+ * for antialiasing or hairlines (i.e. device-bounds outset by 1, and then
+ * run through the inverse of the matrix).
+ *
+ * If the matrix cannot be inverted, or the current clip is empty, return
+ * false and ignore bounds parameter.
+ */
+ bool SK_WARN_UNUSED_RESULT
+ computeConservativeLocalClipBounds(SkRect* bounds) const;
+
+public:
+ const SkBitmap* fBitmap; // required
+ const SkMatrix* fMatrix; // required
+ const SkRegion* fClip; // DEPRECATED
+ const SkRasterClip* fRC; // required
+
+ const SkClipStack* fClipStack; // optional
+ SkBaseDevice* fDevice; // optional
+ SkDrawProcs* fProcs; // optional
+
+#ifdef SK_DEBUG
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDrawFilter.h b/src/third_party/skia/include/core/SkDrawFilter.h
new file mode 100644
index 0000000..52cbba9
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDrawFilter.h
@@ -0,0 +1,55 @@
+
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkDrawFilter_DEFINED
+#define SkDrawFilter_DEFINED
+
+#include "SkRefCnt.h"
+
+class SkCanvas;
+class SkPaint;
+
+/**
+ * Right before something is being draw, filter() is called with the
+ * paint. The filter may modify the paint as it wishes, which will then be
+ * used for the actual drawing. Note: this modification only lasts for the
+ * current draw, as a temporary copy of the paint is used.
+ */
+class SK_API SkDrawFilter : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkDrawFilter)
+
+ enum Type {
+ kPaint_Type,
+ kPoint_Type,
+ kLine_Type,
+ kBitmap_Type,
+ kRect_Type,
+ kRRect_Type,
+ kOval_Type,
+ kPath_Type,
+ kText_Type,
+ };
+
+ enum {
+ kTypeCount = kText_Type + 1
+ };
+
+ /**
+ * Called with the paint that will be used to draw the specified type.
+ * The implementation may modify the paint as they wish. If filter()
+ * returns false, the draw will be skipped.
+ */
+ virtual bool filter(SkPaint*, Type) = 0;
+
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDrawLooper.h b/src/third_party/skia/include/core/SkDrawLooper.h
new file mode 100644
index 0000000..f771d01
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDrawLooper.h
@@ -0,0 +1,125 @@
+
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkDrawLooper_DEFINED
+#define SkDrawLooper_DEFINED
+
+#include "SkBlurTypes.h"
+#include "SkFlattenable.h"
+#include "SkPoint.h"
+#include "SkColor.h"
+
+class SkCanvas;
+class SkPaint;
+struct SkRect;
+class SkString;
+
+/** \class SkDrawLooper
+ Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
+ and something is drawn to a canvas with that paint, the looper subclass will
+ be called, allowing it to modify the canvas and/or paint for that draw call.
+ More than that, via the next() method, the looper can modify the draw to be
+ invoked multiple times (hence the name loop-er), allow it to perform effects
+ like shadows or frame/fills, that require more than one pass.
+*/
+class SK_API SkDrawLooper : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkDrawLooper)
+
+ /**
+ * Holds state during a draw. Users call next() until it returns false.
+ *
+ * Subclasses of SkDrawLooper should create a subclass of this object to
+ * hold state specific to their subclass.
+ */
+ class SK_API Context : ::SkNoncopyable {
+ public:
+ Context() {}
+ virtual ~Context() {}
+
+ /**
+ * Called in a loop on objects returned by SkDrawLooper::createContext().
+ * Each time true is returned, the object is drawn (possibly with a modified
+ * canvas and/or paint). When false is finally returned, drawing for the object
+ * stops.
+ *
+ * On each call, the paint will be in its original state, but the
+ * canvas will be as it was following the previous call to next() or
+ * createContext().
+ *
+ * The implementation must ensure that, when next() finally returns
+ * false, the canvas has been restored to the state it was
+ * initially, before createContext() was first called.
+ */
+ virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0;
+ };
+
+ /**
+ * Called right before something is being drawn. Returns a Context
+ * whose next() method should be called until it returns false.
+ * The caller has to ensure that the storage pointer provides enough
+ * memory for the Context. The required size can be queried by calling
+ * contextSize(). It is also the caller's responsibility to destroy the
+ * object after use.
+ */
+ virtual Context* createContext(SkCanvas*, void* storage) const = 0;
+
+ /**
+ * Returns the number of bytes needed to store subclasses of Context (belonging to the
+ * corresponding SkDrawLooper subclass).
+ */
+ virtual size_t contextSize() const = 0;
+
+
+ /**
+ * The fast bounds functions are used to enable the paint to be culled early
+ * in the drawing pipeline. If a subclass can support this feature it must
+ * return true for the canComputeFastBounds() function. If that function
+ * returns false then computeFastBounds behavior is undefined otherwise it
+ * is expected to have the following behavior. Given the parent paint and
+ * the parent's bounding rect the subclass must fill in and return the
+ * storage rect, where the storage rect is with the union of the src rect
+ * and the looper's bounding rect.
+ */
+ virtual bool canComputeFastBounds(const SkPaint& paint) const;
+ virtual void computeFastBounds(const SkPaint& paint,
+ const SkRect& src, SkRect* dst) const;
+
+ struct BlurShadowRec {
+ SkScalar fSigma;
+ SkVector fOffset;
+ SkColor fColor;
+ SkBlurStyle fStyle;
+ SkBlurQuality fQuality;
+ };
+ /**
+ * If this looper can be interpreted as having two layers, such that
+ * 1. The first layer (bottom most) just has a blur and translate
+ * 2. The second layer has no modifications to either paint or canvas
+ * 3. No other layers.
+ * then return true, and if not null, fill out the BlurShadowRec).
+ *
+ * If any of the above are not met, return false and ignore the BlurShadowRec parameter.
+ */
+ virtual bool asABlurShadow(BlurShadowRec*) const;
+
+ SK_TO_STRING_PUREVIRT()
+ SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)
+
+protected:
+ SkDrawLooper() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+private:
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkDrawPictureCallback.h b/src/third_party/skia/include/core/SkDrawPictureCallback.h
new file mode 100644
index 0000000..d5a360e
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDrawPictureCallback.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDrawPictureCallback_DEFINED
+#define SkDrawPictureCallback_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ * Subclasses of this can be passed to canvas.drawPicture(). During the drawing
+ * of the picture, this callback will periodically be invoked. If its
+ * abortDrawing() returns true, then picture playback will be interrupted.
+ *
+ * The resulting drawing is undefined, as there is no guarantee how often the
+ * callback will be invoked. If the abort happens inside some level of nested
+ * calls to save(), restore will automatically be called to return the state
+ * to the same level it was before the drawPicture call was made.
+ */
+class SK_API SkDrawPictureCallback {
+public:
+ SkDrawPictureCallback() {}
+ virtual ~SkDrawPictureCallback() {}
+
+ virtual bool abortDrawing() = 0;
+};
+
+#endif//SkDrawPictureCallback_DEFINED
diff --git a/src/third_party/skia/include/core/SkDynamicAnnotations.h b/src/third_party/skia/include/core/SkDynamicAnnotations.h
new file mode 100644
index 0000000..422d98d
--- /dev/null
+++ b/src/third_party/skia/include/core/SkDynamicAnnotations.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDynamicAnnotations_DEFINED
+#define SkDynamicAnnotations_DEFINED
+
+// This file contains macros used to send out-of-band signals to dynamic instrumentation systems,
+// namely thread sanitizer. This is a cut-down version of the full dynamic_annotations library with
+// only the features used by Skia.
+
+#if SK_DYNAMIC_ANNOTATIONS_ENABLED
+
+extern "C" {
+// TSAN provides these hooks.
+void AnnotateIgnoreReadsBegin(const char* file, int line);
+void AnnotateIgnoreReadsEnd(const char* file, int line);
+void AnnotateIgnoreWritesBegin(const char* file, int line);
+void AnnotateIgnoreWritesEnd(const char* file, int line);
+void AnnotateBenignRaceSized(const char* file, int line,
+ const volatile void* addr, long size, const char* desc);
+} // extern "C"
+
+// SK_ANNOTATE_UNPROTECTED_READ can wrap any variable read to tell TSAN to ignore that it appears to
+// be a racy read. This should be used only when we can make an external guarantee that though this
+// particular read is racy, it is being used as part of a mechanism which is thread safe. Examples:
+// - the first check in double-checked locking;
+// - checking if a ref count is equal to 1.
+// Note that in both these cases, we must still add terrifyingly subtle memory barriers to provide
+// that overall thread safety guarantee. Using this macro to shut TSAN up without providing such an
+// external guarantee is pretty much never correct.
+template <typename T>
+inline T SK_ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
+ AnnotateIgnoreReadsBegin(__FILE__, __LINE__);
+ T read = x;
+ AnnotateIgnoreReadsEnd(__FILE__, __LINE__);
+ return read;
+}
+
+// Like SK_ANNOTATE_UNPROTECTED_READ, but for writes.
+template <typename T>
+inline void SK_ANNOTATE_UNPROTECTED_WRITE(T* ptr, const volatile T& val) {
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
+ *ptr = val;
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+}
+
+// Ignore racy reads and racy writes to this pointer, indefinitely.
+// If at all possible, use the more precise SK_ANNOTATE_UNPROTECTED_READ.
+template <typename T>
+void SK_ANNOTATE_BENIGN_RACE(T* ptr) {
+ AnnotateBenignRaceSized(__FILE__, __LINE__, ptr, sizeof(*ptr), "SK_ANNOTATE_BENIGN_RACE");
+}
+
+#else // !SK_DYNAMIC_ANNOTATIONS_ENABLED
+
+#define SK_ANNOTATE_UNPROTECTED_READ(x) (x)
+#define SK_ANNOTATE_UNPROTECTED_WRITE(ptr, val) *(ptr) = (val)
+#define SK_ANNOTATE_BENIGN_RACE(ptr)
+
+#endif
+
+// Can be used to wrap values that are intentionally racy, usually small mutable cached values, e.g.
+// - SkMatrix type mask
+// - SkPixelRef genIDs
+template <typename T>
+class SkTRacy {
+public:
+ operator const T() const {
+ return SK_ANNOTATE_UNPROTECTED_READ(fVal);
+ }
+
+ SkTRacy& operator=(const T& val) {
+ SK_ANNOTATE_UNPROTECTED_WRITE(&fVal, val);
+ return *this;
+ }
+
+private:
+ T fVal;
+};
+
+// This is like SkTRacy, but allows you to return the value by reference.
+// TSAN is better at suppressing SkTRacy than SkTRacyReffable, so use SkTRacy when possible.
+//
+// We use this for SkPathRef bounds, which is an SkRect we pass around by reference publically.
+template <typename T>
+class SkTRacyReffable {
+public:
+ SkTRacyReffable() { SK_ANNOTATE_BENIGN_RACE(&fVal); }
+
+ operator const T&() const {
+ return fVal;
+ }
+
+ SkTRacyReffable& operator=(const T& val) {
+ fVal = val;
+ return *this;
+ }
+
+ const T* get() const { return &fVal; }
+ T* get() { return &fVal; }
+
+ const T* operator->() const { return &fVal; }
+ T* operator->() { return &fVal; }
+
+private:
+ T fVal;
+};
+
+#endif//SkDynamicAnnotations_DEFINED
diff --git a/src/third_party/skia/include/core/SkEndian.h b/src/third_party/skia/include/core/SkEndian.h
new file mode 100644
index 0000000..0955fcc
--- /dev/null
+++ b/src/third_party/skia/include/core/SkEndian.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkEndian_DEFINED
+#define SkEndian_DEFINED
+
+#include "SkTypes.h"
+
+/** \file SkEndian.h
+
+ Macros and helper functions for handling 16 and 32 bit values in
+ big and little endian formats.
+*/
+
+#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
+ #error "can't have both LENDIAN and BENDIAN defined"
+#endif
+
+#if !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
+ #error "need either LENDIAN or BENDIAN defined"
+#endif
+
+/** Swap the two bytes in the low 16bits of the parameters.
+ e.g. 0x1234 -> 0x3412
+*/
+static inline uint16_t SkEndianSwap16(uint16_t value) {
+ return static_cast<uint16_t>((value >> 8) | (value << 8));
+}
+
+template<uint16_t N> struct SkTEndianSwap16 {
+ static const uint16_t value = static_cast<uint16_t>((N >> 8) | ((N & 0xFF) << 8));
+};
+
+/** Vector version of SkEndianSwap16(), which swaps the
+ low two bytes of each value in the array.
+*/
+static inline void SkEndianSwap16s(uint16_t array[], int count) {
+ SkASSERT(count == 0 || array != NULL);
+
+ while (--count >= 0) {
+ *array = SkEndianSwap16(*array);
+ array += 1;
+ }
+}
+
+/** Reverse all 4 bytes in a 32bit value.
+ e.g. 0x12345678 -> 0x78563412
+*/
+static inline uint32_t SkEndianSwap32(uint32_t value) {
+ return ((value & 0xFF) << 24) |
+ ((value & 0xFF00) << 8) |
+ ((value & 0xFF0000) >> 8) |
+ (value >> 24);
+}
+
+template<uint32_t N> struct SkTEndianSwap32 {
+ static const uint32_t value = ((N & 0xFF) << 24) |
+ ((N & 0xFF00) << 8) |
+ ((N & 0xFF0000) >> 8) |
+ (N >> 24);
+};
+
+/** Vector version of SkEndianSwap32(), which swaps the
+ bytes of each value in the array.
+*/
+static inline void SkEndianSwap32s(uint32_t array[], int count) {
+ SkASSERT(count == 0 || array != NULL);
+
+ while (--count >= 0) {
+ *array = SkEndianSwap32(*array);
+ array += 1;
+ }
+}
+
+/** Reverse all 8 bytes in a 64bit value.
+ e.g. 0x1122334455667788 -> 0x8877665544332211
+*/
+static inline uint64_t SkEndianSwap64(uint64_t value) {
+ return (((value & 0x00000000000000FFULL) << (8*7)) |
+ ((value & 0x000000000000FF00ULL) << (8*5)) |
+ ((value & 0x0000000000FF0000ULL) << (8*3)) |
+ ((value & 0x00000000FF000000ULL) << (8*1)) |
+ ((value & 0x000000FF00000000ULL) >> (8*1)) |
+ ((value & 0x0000FF0000000000ULL) >> (8*3)) |
+ ((value & 0x00FF000000000000ULL) >> (8*5)) |
+ ((value) >> (8*7)));
+}
+template<uint64_t N> struct SkTEndianSwap64 {
+ static const uint64_t value = (((N & 0x00000000000000FFULL) << (8*7)) |
+ ((N & 0x000000000000FF00ULL) << (8*5)) |
+ ((N & 0x0000000000FF0000ULL) << (8*3)) |
+ ((N & 0x00000000FF000000ULL) << (8*1)) |
+ ((N & 0x000000FF00000000ULL) >> (8*1)) |
+ ((N & 0x0000FF0000000000ULL) >> (8*3)) |
+ ((N & 0x00FF000000000000ULL) >> (8*5)) |
+ ((N) >> (8*7)));
+};
+
+/** Vector version of SkEndianSwap64(), which swaps the
+ bytes of each value in the array.
+*/
+static inline void SkEndianSwap64s(uint64_t array[], int count) {
+ SkASSERT(count == 0 || array != NULL);
+
+ while (--count >= 0) {
+ *array = SkEndianSwap64(*array);
+ array += 1;
+ }
+}
+
+#ifdef SK_CPU_LENDIAN
+ #define SkEndian_SwapBE16(n) SkEndianSwap16(n)
+ #define SkEndian_SwapBE32(n) SkEndianSwap32(n)
+ #define SkEndian_SwapBE64(n) SkEndianSwap64(n)
+ #define SkEndian_SwapLE16(n) (n)
+ #define SkEndian_SwapLE32(n) (n)
+ #define SkEndian_SwapLE64(n) (n)
+
+ #define SkTEndian_SwapBE16(n) SkTEndianSwap16<n>::value
+ #define SkTEndian_SwapBE32(n) SkTEndianSwap32<n>::value
+ #define SkTEndian_SwapBE64(n) SkTEndianSwap64<n>::value
+ #define SkTEndian_SwapLE16(n) (n)
+ #define SkTEndian_SwapLE32(n) (n)
+ #define SkTEndian_SwapLE64(n) (n)
+#else // SK_CPU_BENDIAN
+ #define SkEndian_SwapBE16(n) (n)
+ #define SkEndian_SwapBE32(n) (n)
+ #define SkEndian_SwapBE64(n) (n)
+ #define SkEndian_SwapLE16(n) SkEndianSwap16(n)
+ #define SkEndian_SwapLE32(n) SkEndianSwap32(n)
+ #define SkEndian_SwapLE64(n) SkEndianSwap64(n)
+
+ #define SkTEndian_SwapBE16(n) (n)
+ #define SkTEndian_SwapBE32(n) (n)
+ #define SkTEndian_SwapBE64(n) (n)
+ #define SkTEndian_SwapLE16(n) SkTEndianSwap16<n>::value
+ #define SkTEndian_SwapLE32(n) SkTEndianSwap32<n>::value
+ #define SkTEndian_SwapLE64(n) SkTEndianSwap64<n>::value
+#endif
+
+// When a bytestream is embedded in a 32-bit word, how far we need to
+// shift the word to extract each byte from the low 8 bits by anding with 0xff.
+#ifdef SK_CPU_LENDIAN
+ #define SkEndian_Byte0Shift 0
+ #define SkEndian_Byte1Shift 8
+ #define SkEndian_Byte2Shift 16
+ #define SkEndian_Byte3Shift 24
+#else // SK_CPU_BENDIAN
+ #define SkEndian_Byte0Shift 24
+ #define SkEndian_Byte1Shift 16
+ #define SkEndian_Byte2Shift 8
+ #define SkEndian_Byte3Shift 0
+#endif
+
+
+#if defined(SK_UINT8_BITFIELD_LENDIAN) && defined(SK_UINT8_BITFIELD_BENDIAN)
+ #error "can't have both bitfield LENDIAN and BENDIAN defined"
+#endif
+
+#if !defined(SK_UINT8_BITFIELD_LENDIAN) && !defined(SK_UINT8_BITFIELD_BENDIAN)
+ #ifdef SK_CPU_LENDIAN
+ #define SK_UINT8_BITFIELD_LENDIAN
+ #else
+ #define SK_UINT8_BITFIELD_BENDIAN
+ #endif
+#endif
+
+#ifdef SK_UINT8_BITFIELD_LENDIAN
+ #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \
+ SK_OT_BYTE f0 : 1; \
+ SK_OT_BYTE f1 : 1; \
+ SK_OT_BYTE f2 : 1; \
+ SK_OT_BYTE f3 : 1; \
+ SK_OT_BYTE f4 : 1; \
+ SK_OT_BYTE f5 : 1; \
+ SK_OT_BYTE f6 : 1; \
+ SK_OT_BYTE f7 : 1;
+#else
+ #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \
+ SK_OT_BYTE f7 : 1; \
+ SK_OT_BYTE f6 : 1; \
+ SK_OT_BYTE f5 : 1; \
+ SK_OT_BYTE f4 : 1; \
+ SK_OT_BYTE f3 : 1; \
+ SK_OT_BYTE f2 : 1; \
+ SK_OT_BYTE f1 : 1; \
+ SK_OT_BYTE f0 : 1;
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/core/SkError.h b/src/third_party/skia/include/core/SkError.h
new file mode 100644
index 0000000..678c910
--- /dev/null
+++ b/src/third_party/skia/include/core/SkError.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkError_DEFINED
+#define SkError_DEFINED
+
+
+/** \file SkError.h
+*/
+
+enum SkError {
+ /** All is well
+ */
+ kNoError_SkError=0,
+
+ /** User argument passed to Skia function was invalid: NULL when that’s
+ * not allowed, out of numeric range, bad enum, or violating some
+ * other general precondition.
+ */
+ kInvalidArgument_SkError,
+
+ /** User tried to perform some operation in a state when the operation
+ * was not legal, or the operands make no sense (e.g., asking for
+ * pixels from an SkPictureCanvas). Other examples might be
+ * inset()’ing a rectangle to make it degenerate (negative width/height).
+ */
+ kInvalidOperation_SkError,
+
+ /** Probably not needed right now, but in the future we could have opaque
+ * handles for SkPictures floating around, and it would be a good idea
+ * to anticipate this kind of issue.
+ */
+ kInvalidHandle_SkError,
+
+ /** This is probably not possible because paint surely has defaults for
+ * everything, but perhaps a paint can get into a bad state somehow.
+ */
+ kInvalidPaint_SkError,
+
+ /** Skia was unable to allocate memory to perform some task.
+ */
+ kOutOfMemory_SkError,
+
+ /** Skia failed while trying to consume some external resource.
+ */
+ kParseError_SkError,
+
+ /** Something went wrong internally; could be resource exhaustion but
+ * will often be a bug.
+ */
+ kInternalError_SkError
+};
+
+/** Return the current per-thread error code. Error codes are "sticky"; they
+ * are not not reset by subsequent successful operations.
+ */
+SkError SkGetLastError();
+
+/** Clear the current per-thread error code back to kNoError_SkError.
+ */
+void SkClearLastError();
+
+/** Type for callback functions to be invoked whenever an error is registered.
+ * Callback functions take the error code being set, as well as a context
+ * argument that is provided when the callback is registered.
+ */
+typedef void (*SkErrorCallbackFunction)(SkError, void *);
+
+/** Set the current per-thread error callback.
+ *
+ * @param cb The callback function to be invoked. Passing NULL
+ * for cb will revert to the default error callback which
+ * does nothing on release builds, but on debug builds will
+ * print an informative error message to the screen.
+ * @param context An arbitrary pointer that will be passed to
+ * the provided callback function.
+ */
+void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context);
+
+/** Get a human-readable description of the last (per-thread) error that
+ * occurred. The returned error message will include not only a human
+ * readable version of the error code, but also information about the
+ * conditions that led to the error itself.
+ */
+const char *SkGetLastErrorString();
+
+#endif /* SkError_DEFINED */
diff --git a/src/third_party/skia/include/core/SkFixed.h b/src/third_party/skia/include/core/SkFixed.h
new file mode 100644
index 0000000..6f168c8
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFixed.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFixed_DEFINED
+#define SkFixed_DEFINED
+
+#include "SkTypes.h"
+
+/** \file SkFixed.h
+
+ Types and macros for 16.16 fixed point
+*/
+
+/** 32 bit signed integer used to represent fractions values with 16 bits to the right of the decimal point
+*/
+typedef int32_t SkFixed;
+#define SK_Fixed1 (1 << 16)
+#define SK_FixedHalf (1 << 15)
+#define SK_FixedMax (0x7FFFFFFF)
+#define SK_FixedMin (-SK_FixedMax)
+#define SK_FixedNaN ((int) 0x80000000)
+#define SK_FixedPI (0x3243F)
+#define SK_FixedSqrt2 (92682)
+#define SK_FixedTanPIOver8 (0x6A0A)
+#define SK_FixedRoot2Over2 (0xB505)
+
+#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
+
+#ifdef SK_DEBUG
+ static inline SkFixed SkFloatToFixed_Check(float x) {
+ int64_t n64 = (int64_t)(x * SK_Fixed1);
+ SkFixed n32 = (SkFixed)n64;
+ SkASSERT(n64 == n32);
+ return n32;
+ }
+#else
+ #define SkFloatToFixed_Check(x) SkFloatToFixed(x)
+#endif
+
+#define SkFixedToDouble(x) ((x) * 1.5258789e-5)
+#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
+
+/** Converts an integer to a SkFixed, asserting that the result does not overflow
+ a 32 bit signed integer
+*/
+#ifdef SK_DEBUG
+ inline SkFixed SkIntToFixed(int n)
+ {
+ SkASSERT(n >= -32768 && n <= 32767);
+ return n << 16;
+ }
+#else
+ // force the cast to SkFixed to ensure that the answer is signed (like the debug version)
+ #define SkIntToFixed(n) (SkFixed)((n) << 16)
+#endif
+
+#define SkFixedRoundToInt(x) (((x) + SK_FixedHalf) >> 16)
+#define SkFixedCeilToInt(x) (((x) + SK_Fixed1 - 1) >> 16)
+#define SkFixedFloorToInt(x) ((x) >> 16)
+
+#define SkFixedRoundToFixed(x) (((x) + SK_FixedHalf) & 0xFFFF0000)
+#define SkFixedCeilToFixed(x) (((x) + SK_Fixed1 - 1) & 0xFFFF0000)
+#define SkFixedFloorToFixed(x) ((x) & 0xFFFF0000)
+
+#define SkFixedAbs(x) SkAbs32(x)
+#define SkFixedAve(a, b) (((a) + (b)) >> 1)
+
+SkFixed SkFixedMul_portable(SkFixed, SkFixed);
+
+#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
+
+///////////////////////////////////////////////////////////////////////////////
+// TODO: move fixed sin/cos into SkCosineMapper, as that is the only caller
+// or rewrite SkCosineMapper to not use it at all
+
+SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull);
+#define SkFixedSin(radians) SkFixedSinCos(radians, NULL)
+static inline SkFixed SkFixedCos(SkFixed radians) {
+ SkFixed cosValue;
+ (void)SkFixedSinCos(radians, &cosValue);
+ return cosValue;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+// Now look for ASM overrides for our portable versions (should consider putting this in its own file)
+
+#ifdef SkLONGLONG
+ inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b)
+ {
+ return (SkFixed)((int64_t)a * b >> 16);
+ }
+ #define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
+#endif
+
+#if defined(SK_CPU_ARM32)
+ /* This guy does not handle NaN or other obscurities, but is faster than
+ than (int)(x*65536). When built on Android with -Os, needs forcing
+ to inline or we lose the speed benefit.
+ */
+ SK_ALWAYS_INLINE SkFixed SkFloatToFixed_arm(float x)
+ {
+ int32_t y, z;
+ asm("movs %1, %3, lsl #1 \n"
+ "mov %2, #0x8E \n"
+ "sub %1, %2, %1, lsr #24 \n"
+ "mov %2, %3, lsl #8 \n"
+ "orr %2, %2, #0x80000000 \n"
+ "mov %1, %2, lsr %1 \n"
+ "it cs \n"
+ "rsbcs %1, %1, #0 \n"
+ : "=r"(x), "=&r"(y), "=&r"(z)
+ : "r"(x)
+ : "cc"
+ );
+ return y;
+ }
+ inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y)
+ {
+ int32_t t;
+ asm("smull %0, %2, %1, %3 \n"
+ "mov %0, %0, lsr #16 \n"
+ "orr %0, %0, %2, lsl #16 \n"
+ : "=r"(x), "=&r"(y), "=r"(t)
+ : "r"(x), "1"(y)
+ :
+ );
+ return x;
+ }
+ #undef SkFixedMul
+ #define SkFixedMul(x, y) SkFixedMul_arm(x, y)
+
+ #undef SkFloatToFixed
+ #define SkFloatToFixed(x) SkFloatToFixed_arm(x)
+#endif
+
+#ifndef SkFixedMul
+ #define SkFixedMul(x, y) SkFixedMul_portable(x, y)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef int64_t SkFixed48;
+
+#define SkIntToFixed48(x) ((SkFixed48)(x) << 48)
+#define SkFixed48ToInt(x) ((int)((x) >> 48))
+#define SkFixedToFixed48(x) ((SkFixed48)(x) << 32)
+#define SkFixed48ToFixed(x) ((SkFixed)((x) >> 32))
+#define SkFloatToFixed48(x) ((SkFixed48)((x) * (65536.0f * 65536.0f * 65536.0f)))
+
+#define SkScalarToFixed48(x) SkFloatToFixed48(x)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkFlattenable.h b/src/third_party/skia/include/core/SkFlattenable.h
new file mode 100644
index 0000000..679f640
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFlattenable.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFlattenable_DEFINED
+#define SkFlattenable_DEFINED
+
+#include "SkRefCnt.h"
+
+class SkReadBuffer;
+class SkWriteBuffer;
+
+#define SK_SUPPORT_LEGACY_DEEPFLATTENING
+
+/*
+ * Flattening is straight-forward:
+ * 1. call getFactory() so we have a function-ptr to recreate the subclass
+ * 2. call flatten(buffer) to write out enough data for the factory to read
+ *
+ * Unflattening is easy for the caller: new_instance = factory(buffer)
+ *
+ * The complexity of supporting this is as follows.
+ *
+ * If your subclass wants to control unflattening, use this macro in your declaration:
+ * SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
+ * This will provide a getFactory(), and require that the subclass implements CreateProc.
+ *
+ * For older buffers (before the DEEPFLATTENING change, the macros below declare
+ * a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
+ * then it calls through to a (usually protected) constructor, passing the buffer.
+ * If the buffer is newer, then it directly calls the "real" factory: CreateProc.
+ */
+
+#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
+
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
+ void flattenable::InitializeFlattenables() {
+
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
+ }
+
+#define SK_DECLARE_UNFLATTENABLE_OBJECT() \
+ virtual Factory getFactory() const SK_OVERRIDE { return NULL; }
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+ SkFlattenable::Registrar(#flattenable, flattenable::DeepCreateProc, \
+ flattenable::GetFlattenableType());
+
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
+ private: \
+ static SkFlattenable* CreateProc(SkReadBuffer&); \
+ static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) { \
+ if (NeedsDeepUnflatten(buffer)) { \
+ return SkNEW_ARGS(flattenable, (buffer)); \
+ } \
+ return CreateProc(buffer); \
+ } \
+ friend class SkPrivateEffectInitializer; \
+ public: \
+ virtual Factory getFactory() const SK_OVERRIDE {return DeepCreateProc;}
+#else
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+ SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \
+ flattenable::GetFlattenableType());
+
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
+ private: \
+ static SkFlattenable* CreateProc(SkReadBuffer&); \
+ friend class SkPrivateEffectInitializer; \
+ public: \
+ virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; }
+#endif
+
+// If your subclass will *never* need to be unflattened, declare this.
+#define SK_DECLARE_NOT_FLATTENABLE_PROCS(flattenable) \
+ virtual Factory getFactory() const SK_OVERRIDE { return ReturnNullCreateProc; }
+
+/** For SkFlattenable derived objects with a valid type
+ This macro should only be used in base class objects in core
+ */
+#define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
+ static Type GetFlattenableType() { \
+ return k##flattenable##_Type; \
+ }
+
+/** \class SkFlattenable
+
+ SkFlattenable is the base class for objects that need to be flattened
+ into a data stream for either transport or as part of the key to the
+ font cache.
+ */
+class SK_API SkFlattenable : public SkRefCnt {
+public:
+ enum Type {
+ kSkColorFilter_Type,
+ kSkDrawLooper_Type,
+ kSkImageFilter_Type,
+ kSkMaskFilter_Type,
+ kSkPathEffect_Type,
+ kSkPixelRef_Type,
+ kSkRasterizer_Type,
+ kSkShader_Type,
+ kSkUnused_Type, // used to be SkUnitMapper
+ kSkXfermode_Type,
+ };
+
+ SK_DECLARE_INST_COUNT(SkFlattenable)
+
+ typedef SkFlattenable* (*Factory)(SkReadBuffer&);
+
+ SkFlattenable() {}
+
+ /** Implement this to return a factory function pointer that can be called
+ to recreate your class given a buffer (previously written to by your
+ override of flatten().
+ */
+ virtual Factory getFactory() const = 0;
+
+ /** Returns the name of the object's class
+ */
+ const char* getTypeName() const { return FactoryToName(getFactory()); }
+
+ static Factory NameToFactory(const char name[]);
+ static const char* FactoryToName(Factory);
+ static bool NameToType(const char name[], Type* type);
+
+ static void Register(const char name[], Factory, Type);
+
+ class Registrar {
+ public:
+ Registrar(const char name[], Factory factory, Type type) {
+ SkFlattenable::Register(name, factory, type);
+ }
+ };
+
+ /**
+ * Override this if your subclass needs to record data that it will need to recreate itself
+ * from its CreateProc (returned by getFactory()).
+ */
+ virtual void flatten(SkWriteBuffer&) const {}
+
+protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ static bool NeedsDeepUnflatten(const SkReadBuffer&);
+ SkFlattenable(SkReadBuffer&) {}
+#endif
+
+ static SkFlattenable* ReturnNullCreateProc(SkReadBuffer&) {
+ return NULL;
+ }
+
+private:
+ static void InitializeFlattenablesIfNeeded();
+
+ friend class SkGraphics;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkFlattenableBuffers.h b/src/third_party/skia/include/core/SkFlattenableBuffers.h
new file mode 100644
index 0000000..6c7c2ad
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFlattenableBuffers.h
@@ -0,0 +1,2 @@
+// Temporary shim to keep a couple dependencies working in Chromium.
+// TODO(halcanary): delete this file.
diff --git a/src/third_party/skia/include/core/SkFlattenableSerialization.h b/src/third_party/skia/include/core/SkFlattenableSerialization.h
new file mode 100644
index 0000000..ffb1b5a
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFlattenableSerialization.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFlattenableSerialization_DEFINED
+#define SkFlattenableSerialization_DEFINED
+
+#include "SkFlattenable.h"
+
+class SkData;
+
+SK_API SkData* SkValidatingSerializeFlattenable(SkFlattenable*);
+SK_API SkFlattenable* SkValidatingDeserializeFlattenable(const void* data, size_t size,
+ SkFlattenable::Type type);
+
+#endif
diff --git a/src/third_party/skia/include/core/SkFloatBits.h b/src/third_party/skia/include/core/SkFloatBits.h
new file mode 100644
index 0000000..3ddb9ef
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFloatBits.h
@@ -0,0 +1,132 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkFloatBits_DEFINED
+#define SkFloatBits_DEFINED
+
+#include "SkTypes.h"
+
+/** Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement
+ int. This also converts -0 (0x80000000) to 0. Doing this to a float allows
+ it to be compared using normal C operators (<, <=, etc.)
+*/
+static inline int32_t SkSignBitTo2sCompliment(int32_t x) {
+ if (x < 0) {
+ x &= 0x7FFFFFFF;
+ x = -x;
+ }
+ return x;
+}
+
+/** Convert a 2s compliment int to a sign-bit (i.e. int interpreted as float).
+ This undoes the result of SkSignBitTo2sCompliment().
+ */
+static inline int32_t Sk2sComplimentToSignBit(int32_t x) {
+ int sign = x >> 31;
+ // make x positive
+ x = (x ^ sign) - sign;
+ // set the sign bit as needed
+ x |= sign << 31;
+ return x;
+}
+
+/** Given the bit representation of a float, return its value cast to an int.
+ If the value is out of range, or NaN, return return +/- SK_MaxS32
+*/
+int32_t SkFloatBits_toIntCast(int32_t floatBits);
+
+/** Given the bit representation of a float, return its floor as an int.
+ If the value is out of range, or NaN, return return +/- SK_MaxS32
+ */
+SK_API int32_t SkFloatBits_toIntFloor(int32_t floatBits);
+
+/** Given the bit representation of a float, return it rounded to an int.
+ If the value is out of range, or NaN, return return +/- SK_MaxS32
+ */
+SK_API int32_t SkFloatBits_toIntRound(int32_t floatBits);
+
+/** Given the bit representation of a float, return its ceiling as an int.
+ If the value is out of range, or NaN, return return +/- SK_MaxS32
+ */
+SK_API int32_t SkFloatBits_toIntCeil(int32_t floatBits);
+
+
+union SkFloatIntUnion {
+ float fFloat;
+ int32_t fSignBitInt;
+};
+
+// Helper to see a float as its bit pattern (w/o aliasing warnings)
+static inline int32_t SkFloat2Bits(float x) {
+ SkFloatIntUnion data;
+ data.fFloat = x;
+ return data.fSignBitInt;
+}
+
+// Helper to see a bit pattern as a float (w/o aliasing warnings)
+static inline float SkBits2Float(int32_t floatAsBits) {
+ SkFloatIntUnion data;
+ data.fSignBitInt = floatAsBits;
+ return data.fFloat;
+}
+
+/** Return the float as a 2s compliment int. Just to be used to compare floats
+ to each other or against positive float-bit-constants (like 0). This does
+ not return the int equivalent of the float, just something cheaper for
+ compares-only.
+ */
+static inline int32_t SkFloatAs2sCompliment(float x) {
+ return SkSignBitTo2sCompliment(SkFloat2Bits(x));
+}
+
+/** Return the 2s compliment int as a float. This undos the result of
+ SkFloatAs2sCompliment
+ */
+static inline float Sk2sComplimentAsFloat(int32_t x) {
+ return SkBits2Float(Sk2sComplimentToSignBit(x));
+}
+
+/** Return x cast to a float (i.e. (float)x)
+*/
+float SkIntToFloatCast(int x);
+
+/** Return the float cast to an int.
+ If the value is out of range, or NaN, return +/- SK_MaxS32
+*/
+static inline int32_t SkFloatToIntCast(float x) {
+ return SkFloatBits_toIntCast(SkFloat2Bits(x));
+}
+
+/** Return the floor of the float as an int.
+ If the value is out of range, or NaN, return +/- SK_MaxS32
+*/
+static inline int32_t SkFloatToIntFloor(float x) {
+ return SkFloatBits_toIntFloor(SkFloat2Bits(x));
+}
+
+/** Return the float rounded to an int.
+ If the value is out of range, or NaN, return +/- SK_MaxS32
+*/
+static inline int32_t SkFloatToIntRound(float x) {
+ return SkFloatBits_toIntRound(SkFloat2Bits(x));
+}
+
+/** Return the ceiling of the float as an int.
+ If the value is out of range, or NaN, return +/- SK_MaxS32
+*/
+static inline int32_t SkFloatToIntCeil(float x) {
+ return SkFloatBits_toIntCeil(SkFloat2Bits(x));
+}
+
+// Scalar wrappers for float-bit routines
+
+#define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x)
+#define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkFloatingPoint.h b/src/third_party/skia/include/core/SkFloatingPoint.h
new file mode 100644
index 0000000..f7eb059
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFloatingPoint.h
@@ -0,0 +1,197 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkFloatingPoint_DEFINED
+#define SkFloatingPoint_DEFINED
+
+#include "SkTypes.h"
+
+#include <math.h>
+#include <float.h>
+#if defined(COBALT)
+#include <string.h>
+#endif
+
+// For _POSIX_VERSION
+#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \
+ !defined(STARBOARD)
+#include <unistd.h>
+#endif
+
+#if defined(STARBOARD)
+#include "starboard/double.h"
+#endif
+
+#include "SkFloatBits.h"
+
+// C++98 cmath std::pow seems to be the earliest portable way to get float pow.
+// However, on Linux including cmath undefines isfinite.
+// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14608
+static inline float sk_float_pow(float base, float exp) {
+ return powf(base, exp);
+}
+
+static inline float sk_float_copysign(float x, float y) {
+// c++11 contains a 'float copysign(float, float)' function in <cmath>.
+// clang-cl reports __cplusplus for clang, not the __cplusplus vc++ version _MSC_VER would report.
+#if (defined(_MSC_VER) && defined(__clang__))
+#define SK_BUILD_WITH_CLANG_CL 1
+#else
+#define SK_BUILD_WITH_CLANG_CL 0
+#endif
+#if (!SK_BUILD_WITH_CLANG_CL && __cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
+ return copysign(x, y);
+
+// Posix has demanded 'float copysignf(float, float)' (from C99) since Issue 6.
+#elif defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+ return copysignf(x, y);
+
+// Visual studio prior to 13 only has 'double _copysign(double, double)'.
+#elif defined(_MSC_VER)
+ return (float)_copysign(x, y);
+
+// Otherwise convert to bits and extract sign.
+#else
+ int32_t xbits = SkFloat2Bits(x);
+ int32_t ybits = SkFloat2Bits(y);
+ return SkBits2Float((xbits & 0x7FFFFFFF) | (ybits & 0x80000000));
+#endif
+}
+
+#ifdef SK_BUILD_FOR_WINCE
+ #define sk_float_sqrt(x) (float)::sqrt(x)
+ #define sk_float_sin(x) (float)::sin(x)
+ #define sk_float_cos(x) (float)::cos(x)
+ #define sk_float_tan(x) (float)::tan(x)
+ #define sk_float_acos(x) (float)::acos(x)
+ #define sk_float_asin(x) (float)::asin(x)
+ #define sk_float_atan2(y,x) (float)::atan2(y,x)
+ #define sk_float_abs(x) (float)::fabs(x)
+ #define sk_float_mod(x,y) (float)::fmod(x,y)
+ #define sk_float_exp(x) (float)::exp(x)
+ #define sk_float_log(x) (float)::log(x)
+ #define sk_float_floor(x) (float)::floor(x)
+ #define sk_float_ceil(x) (float)::ceil(x)
+#else
+ #define sk_float_sqrt(x) sqrtf(x)
+ #define sk_float_sin(x) sinf(x)
+ #define sk_float_cos(x) cosf(x)
+ #define sk_float_tan(x) tanf(x)
+ #define sk_float_floor(x) floorf(x)
+ #define sk_float_ceil(x) ceilf(x)
+#ifdef SK_BUILD_FOR_MAC
+ #define sk_float_acos(x) static_cast<float>(acos(x))
+ #define sk_float_asin(x) static_cast<float>(asin(x))
+#else
+ #define sk_float_acos(x) acosf(x)
+ #define sk_float_asin(x) asinf(x)
+#endif
+ #define sk_float_atan2(y,x) atan2f(y,x)
+#if defined(SK_BUILD_FOR_STARBOARD)
+ #define sk_float_abs(x) static_cast<float>(SbDoubleAbsolute(x))
+#else
+ #define sk_float_abs(x) fabsf(x)
+#endif
+ #define sk_float_mod(x,y) fmodf(x,y)
+ #define sk_float_exp(x) expf(x)
+ #define sk_float_log(x) logf(x)
+#endif
+
+#ifdef SK_BUILD_FOR_WIN
+ #define sk_float_isfinite(x) _finite(x)
+ #define sk_float_isnan(x) _isnan(x)
+ static inline int sk_float_isinf(float x) {
+ int32_t bits = SkFloat2Bits(x);
+ return (bits << 1) == (0xFF << 24);
+ }
+#elif defined(SK_BUILD_FOR_STARBOARD)
+ #define sk_float_isfinite(x) SbDoubleIsFinite(x)
+ #define sk_float_isnan(x) SbDoubleIsNaN(x)
+ #define sk_float_isinf(x) !(SbDoubleIsFinite(x) || SbDoubleIsNaN(x))
+#else
+ #define sk_float_isfinite(x) isfinite(x)
+ #define sk_float_isnan(x) isnan(x)
+ #define sk_float_isinf(x) isinf(x)
+#endif
+
+#define sk_double_isnan(a) sk_float_isnan(a)
+
+#ifdef SK_USE_FLOATBITS
+ #define sk_float_floor2int(x) SkFloatToIntFloor(x)
+ #define sk_float_round2int(x) SkFloatToIntRound(x)
+ #define sk_float_ceil2int(x) SkFloatToIntCeil(x)
+#else
+ #define sk_float_floor2int(x) (int)sk_float_floor(x)
+ #define sk_float_round2int(x) (int)sk_float_floor((x) + 0.5f)
+ #define sk_float_ceil2int(x) (int)sk_float_ceil(x)
+#endif
+
+extern const uint32_t gIEEENotANumber;
+extern const uint32_t gIEEEInfinity;
+extern const uint32_t gIEEENegativeInfinity;
+
+#define SK_FloatNaN (*SkTCast<const float*>(&gIEEENotANumber))
+#define SK_FloatInfinity (*SkTCast<const float*>(&gIEEEInfinity))
+#define SK_FloatNegativeInfinity (*SkTCast<const float*>(&gIEEENegativeInfinity))
+
+#if defined(__SSE__)
+#include <xmmintrin.h>
+#elif defined(SK_ARM_HAS_NEON)
+#include <arm_neon.h>
+#endif
+
+// Fast, approximate inverse square root.
+// Compare to name-brand "1.0f / sk_float_sqrt(x)". Should be around 10x faster on SSE, 2x on NEON.
+static inline float sk_float_rsqrt(const float x) {
+// We want all this inlined, so we'll inline SIMD and just take the hit when we don't know we've got
+// it at compile time. This is going to be too fast to productively hide behind a function pointer.
+//
+// We do one step of Newton's method to refine the estimates in the NEON and null paths. No
+// refinement is faster, but very innacurate. Two steps is more accurate, but slower than 1/sqrt.
+#if defined(__SSE__)
+ float result;
+ _mm_store_ss(&result, _mm_rsqrt_ss(_mm_set_ss(x)));
+ return result;
+#elif defined(SK_ARM_HAS_NEON)
+ // Get initial estimate.
+ const float32x2_t xx = vdup_n_f32(x); // Clever readers will note we're doing everything 2x.
+ float32x2_t estimate = vrsqrte_f32(xx);
+
+ // One step of Newton's method to refine.
+ const float32x2_t estimate_sq = vmul_f32(estimate, estimate);
+ estimate = vmul_f32(estimate, vrsqrts_f32(xx, estimate_sq));
+ return vget_lane_f32(estimate, 0); // 1 will work fine too; the answer's in both places.
+#elif defined(COBALT)
+ // Certain platforms really doen't like going through SkTCast(), giving
+ // the wrong values. So we use memcpy() instead.
+
+ // Get initial estimate.
+ int32_t i;
+ memcpy(&i, &x, sizeof(i));
+ i = 0x5f3759df - (i>>1);
+ float estimate;
+ memcpy(&estimate, &i, sizeof(estimate));
+ // One step of Newton's method to refine.
+ const float estimate_sq = estimate*estimate;
+ estimate *= (1.5f-0.5f*x*estimate_sq);
+ return estimate;
+#else
+ // Get initial estimate.
+ int i = *SkTCast<int*>(&x);
+ i = 0x5f3759df - (i>>1);
+ float estimate = *SkTCast<float*>(&i);
+
+ // One step of Newton's method to refine.
+ const float estimate_sq = estimate*estimate;
+ estimate *= (1.5f-0.5f*x*estimate_sq);
+ return estimate;
+#endif
+}
+
+#endif
diff --git a/src/third_party/skia/include/core/SkFont.h b/src/third_party/skia/include/core/SkFont.h
new file mode 100644
index 0000000..e4ebebb
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFont.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFont_DEFINED
+#define SkFont_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+
+class SkPaint;
+class SkTypeface;
+
+enum SkTextEncoding {
+ kUTF8_SkTextEncoding,
+ kUTF16_SkTextEncoding,
+ kUTF32_SkTextEncoding,
+ kGlyphID_SkTextEncoding,
+};
+
+/*
+ 1. The Hinting enum in SkPaint is gone entirely, absorbed into SkFont's flags.
+
+ 2. SkPaint Flags look like this today
+
+ enum Flags {
+ kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
+ kDither_Flag = 0x04, //!< mask to enable dithering
+ kUnderlineText_Flag = 0x08, //!< mask to enable underline text
+ kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
+ kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
+ kLinearText_Flag = 0x40, //!< mask to enable linear-text
+ kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
+ 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
+ kVerticalText_Flag = 0x1000,
+ kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it
+ };
+
+ SkFont would absorb these:
+
+ kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
+ kLinearText_Flag = 0x40, //!< mask to enable linear-text
+ kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
+ 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
+ kVerticalText_Flag = 0x1000,
+ kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it
+
+ leaving these still in paint
+
+ kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
+ kDither_Flag = 0x04, //!< mask to enable dithering
+ kUnderlineText_Flag = 0x08, //!< mask to enable underline text
+ kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
+
+ 3. Antialiasing
+
+ SkFont has a mask-type: BW, AA, LCD
+ SkPaint has antialias boolean
+
+ What to do if the font's mask-type disagrees with the paint?
+
+ */
+
+class SkFont : public SkRefCnt {
+public:
+ enum Flags {
+ /**
+ * Use the system's automatic hinting mechanism to hint the typeface.
+ * This is a last resort hinting method applied only if other hinting methods do not apply.
+ * TODO: where to put auto-normal vs auto-light?
+ */
+ kEnableAutoHints_Flag = 1 << 0,
+
+ /**
+ * If the typeface contains explicit bytecodes for hinting, use them.
+ * If both bytecode and auto hints are specified, attempt to use the bytecodes first;
+ * if that fails (e.g. there are no codes), then attempt to autohint.
+ */
+ kEnableByteCodeHints_Flag = 1 << 1,
+
+ /**
+ * If the typeface contains explicit bitmaps for hinting, use them.
+ * If both bytecode and auto hints are also specified, attempt to use the bitmaps first;
+ * if that fails (e.g. there are no bitmaps), then attempt to bytecode or autohint.
+ */
+ kEmbeddedBitmaps_Flag = 1 << 2,
+
+ /**
+ * Use rounded metric values (e.g. advance).
+ * If either auto or bytecode hinting was used, apply those results to the metrics of the
+ * glyphs as well. If no hinting was applied, the metrics will just be rounded to the
+ * nearest integer.
+ *
+ * This applies to calls that return metrics (e.g. measureText) and to drawing the glyphs
+ * (see SkCanvas drawText and drawPosText).
+ */
+ kUseNonlinearMetrics_Flag = 1 << 3,
+
+ kVertical_Flag = 1 << 4,
+ kGenA8FromLCD_Flag = 1 << 5,
+ kEmbolden_Flag = 1 << 6,
+ kDevKern_Flag = 1 << 7, // ifdef ANDROID ?
+ };
+
+ enum MaskType {
+ kBW_MaskType,
+ kA8_MaskType,
+ kLCD_MaskType,
+ };
+
+ static SkFont* Create(SkTypeface*, SkScalar size, MaskType, uint32_t flags);
+ static SkFont* Create(SkTypeface*, SkScalar size, SkScalar scaleX, SkScalar skewX,
+ MaskType, uint32_t flags);
+
+ /**
+ * Return a font with the same attributes of this font, but with the specified size.
+ * If size is not supported (e.g. <= 0 or non-finite) NULL will be returned.
+ */
+ SkFont* cloneWithSize(SkScalar size) const;
+
+ SkTypeface* getTypeface() const { return fTypeface; }
+ SkScalar getSize() const { return fSize; }
+ SkScalar getScaleX() const { return fScaleX; }
+ SkScalar getSkewX() const { return fSkewX; }
+ uint32_t getFlags() const { return fFlags; }
+ MaskType getMaskType() const { return (MaskType)fMaskType; }
+
+ bool isVertical() const { return SkToBool(fFlags & kVertical_Flag); }
+ bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_Flag); }
+ bool isEnableAutoHints() const { return SkToBool(fFlags & kEnableAutoHints_Flag); }
+ bool isEnableByteCodeHints() const { return SkToBool(fFlags & kEnableByteCodeHints_Flag); }
+ bool isUseNonLinearMetrics() const { return SkToBool(fFlags & kUseNonlinearMetrics_Flag); }
+
+ int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding,
+ uint16_t glyphs[], int maxGlyphCount) const;
+
+ SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding) const;
+
+ static SkFont* Testing_CreateFromPaint(const SkPaint&);
+
+private:
+ enum {
+ kAllFlags = 0xFF,
+ };
+
+ SkFont(SkTypeface*, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType, uint32_t flags);
+ virtual ~SkFont();
+
+ SkTypeface* fTypeface;
+ SkScalar fSize;
+ SkScalar fScaleX;
+ SkScalar fSkewX;
+ uint16_t fFlags;
+ uint8_t fMaskType;
+// uint8_t fPad;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkFontHost.h b/src/third_party/skia/include/core/SkFontHost.h
new file mode 100644
index 0000000..a2cc04b
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFontHost.h
@@ -0,0 +1,95 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkFontHost_DEFINED
+#define SkFontHost_DEFINED
+
+#include "SkTypeface.h"
+
+class SkDescriptor;
+class SkScalerContext;
+struct SkScalerContextRec;
+class SkStream;
+class SkWStream;
+
+/** \class SkFontHost
+
+ This class is ported to each environment. It is responsible for bridging
+ the gap between the (sort of) abstract class SkTypeface and the
+ platform-specific implementation that provides access to font files.
+
+ One basic task is for each create (subclass of) SkTypeface, the FontHost is
+ responsible for assigning a uniqueID. The ID should be unique for the
+ underlying font file/data, not unique per typeface instance. Thus it is
+ possible/common to request a typeface for the same font more than once
+ (e.g. asking for the same font by name several times). The FontHost may
+ return seperate typeface instances in that case, or it may choose to use a
+ cache and return the same instance (but calling typeface->ref(), since the
+ caller is always responsible for calling unref() on each instance that is
+ returned). Either way, the fontID for those instance(s) will be the same.
+ In addition, the fontID should never be set to 0. That value is used as a
+ sentinel to indicate no-font-id.
+
+ The major aspects are:
+ 1) Given either a name/style, return a subclass of SkTypeface that
+ references the closest matching font available on the host system.
+ 2) Given the data for a font (either in a stream or a file name), return
+ a typeface that allows access to that data.
+ 3) Each typeface instance carries a 32bit ID for its corresponding font.
+ SkFontHost turns that ID into a stream to access the font's data.
+ 4) Given a font ID, return a subclass of SkScalerContext, which connects a
+ font scaler (e.g. freetype or other) to the font's data.
+ 5) Utilites to manage the font cache (budgeting) and gamma correction
+*/
+class SK_API SkFontHost {
+public:
+ /** LCDs either have their color elements arranged horizontally or
+ vertically. When rendering subpixel glyphs we need to know which way
+ round they are.
+
+ Note, if you change this after startup, you'll need to flush the glyph
+ cache because it'll have the wrong type of masks cached.
+
+ @deprecated use SkPixelGeometry instead.
+ */
+ enum LCDOrientation {
+ kHorizontal_LCDOrientation = 0, //!< this is the default
+ kVertical_LCDOrientation = 1
+ };
+
+ /** @deprecated set on Device creation. */
+ static void SetSubpixelOrientation(LCDOrientation orientation);
+ /** @deprecated get from Device. */
+ static LCDOrientation GetSubpixelOrientation();
+
+ /** LCD color elements can vary in order. For subpixel text we need to know
+ the order which the LCDs uses so that the color fringes are in the
+ correct place.
+
+ Note, if you change this after startup, you'll need to flush the glyph
+ cache because it'll have the wrong type of masks cached.
+
+ kNONE_LCDOrder means that the subpixel elements are not spatially
+ separated in any usable fashion.
+
+ @deprecated use SkPixelGeometry instead.
+ */
+ enum LCDOrder {
+ kRGB_LCDOrder = 0, //!< this is the default
+ kBGR_LCDOrder = 1,
+ kNONE_LCDOrder = 2
+ };
+
+ /** @deprecated set on Device creation. */
+ static void SetSubpixelOrder(LCDOrder order);
+ /** @deprecated get from Device. */
+ static LCDOrder GetSubpixelOrder();
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkFontLCDConfig.h b/src/third_party/skia/include/core/SkFontLCDConfig.h
new file mode 100644
index 0000000..03ee09f
--- /dev/null
+++ b/src/third_party/skia/include/core/SkFontLCDConfig.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontLCDConfig_DEFINED
+#define SkFontLCDConfig_DEFINED
+
+#include "SkTypes.h"
+
+class SkFontLCDConfig {
+public:
+ /** LCDs either have their color elements arranged horizontally or
+ vertically. When rendering subpixel glyphs we need to know which way
+ round they are.
+
+ Note, if you change this after startup, you'll need to flush the glyph
+ cache because it'll have the wrong type of masks cached.
+
+ @deprecated use SkPixelGeometry instead.
+ */
+ enum LCDOrientation {
+ kHorizontal_LCDOrientation = 0, //!< this is the default
+ kVertical_LCDOrientation = 1
+ };
+
+ /** @deprecated set on Device creation. */
+ static void SetSubpixelOrientation(LCDOrientation orientation);
+ /** @deprecated get from Device. */
+ static LCDOrientation GetSubpixelOrientation();
+
+ /** LCD color elements can vary in order. For subpixel text we need to know
+ the order which the LCDs uses so that the color fringes are in the
+ correct place.
+
+ Note, if you change this after startup, you'll need to flush the glyph
+ cache because it'll have the wrong type of masks cached.
+
+ kNONE_LCDOrder means that the subpixel elements are not spatially
+ separated in any usable fashion.
+
+ @deprecated use SkPixelGeometry instead.
+ */
+ enum LCDOrder {
+ kRGB_LCDOrder = 0, //!< this is the default
+ kBGR_LCDOrder = 1,
+ kNONE_LCDOrder = 2
+ };
+
+ /** @deprecated set on Device creation. */
+ static void SetSubpixelOrder(LCDOrder order);
+ /** @deprecated get from Device. */
+ static LCDOrder GetSubpixelOrder();
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkGraphics.h b/src/third_party/skia/include/core/SkGraphics.h
new file mode 100644
index 0000000..c154df1
--- /dev/null
+++ b/src/third_party/skia/include/core/SkGraphics.h
@@ -0,0 +1,191 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkGraphics_DEFINED
+#define SkGraphics_DEFINED
+
+#include "SkTypes.h"
+
+class SK_API SkGraphics {
+public:
+ /**
+ * Call this at process initialization time if your environment does not
+ * permit static global initializers that execute code. Note that
+ * Init() is not thread-safe.
+ */
+ static void Init();
+
+ /**
+ * Call this to release any memory held privately, such as the font cache.
+ */
+ static void Term();
+
+ /**
+ * Return the version numbers for the library. If the parameter is not
+ * null, it is set to the version number.
+ */
+ static void GetVersion(int32_t* major, int32_t* minor, int32_t* patch);
+
+ /**
+ * Return the max number of bytes that should be used by the font cache.
+ * If the cache needs to allocate more, it will purge previous entries.
+ * This max can be changed by calling SetFontCacheLimit().
+ */
+ static size_t GetFontCacheLimit();
+
+ /**
+ * Specify the max number of bytes that should be used by the font cache.
+ * If the cache needs to allocate more, it will purge previous entries.
+ *
+ * This function returns the previous setting, as if GetFontCacheLimit()
+ * had be called before the new limit was set.
+ */
+ static size_t SetFontCacheLimit(size_t bytes);
+
+ /**
+ * Return the number of bytes currently used by the font cache.
+ */
+ static size_t GetFontCacheUsed();
+
+ /**
+ * Return the number of entries in the font cache.
+ * A cache "entry" is associated with each typeface + pointSize + matrix.
+ */
+ static int GetFontCacheCountUsed();
+
+ /**
+ * Return the current limit to the number of entries in the font cache.
+ * A cache "entry" is associated with each typeface + pointSize + matrix.
+ */
+ static int GetFontCacheCountLimit();
+
+ /**
+ * Set the limit to the number of entries in the font cache, and return
+ * the previous value. If this new value is lower than the previous,
+ * it will automatically try to purge entries to meet the new limit.
+ */
+ static int SetFontCacheCountLimit(int count);
+
+ /**
+ * For debugging purposes, this will attempt to purge the font cache. It
+ * does not change the limit, but will cause subsequent font measures and
+ * draws to be recreated, since they will no longer be in the cache.
+ */
+ static void PurgeFontCache();
+
+ /**
+ * Scaling bitmaps with the SkPaint::kHigh_FilterLevel setting is
+ * expensive, so the result is saved in the global Scaled Image
+ * Cache.
+ *
+ * This function returns the memory usage of the Scaled Image Cache.
+ */
+ static size_t GetResourceCacheTotalBytesUsed();
+
+ /**
+ * These functions get/set the memory usage limit for the resource cache, used for temporary
+ * bitmaps and other resources. Entries are purged from the cache when the memory useage
+ * exceeds this limit.
+ */
+ static size_t GetResourceCacheTotalByteLimit();
+ static size_t SetResourceCacheTotalByteLimit(size_t newLimit);
+
+ /**
+ * For debugging purposes, this will attempt to purge the resource cache. It
+ * does not change the limit.
+ */
+ static void PurgeResourceCache();
+
+ /**
+ * When the cachable entry is very lage (e.g. a large scaled bitmap), adding it to the cache
+ * can cause most/all of the existing entries to be purged. To avoid the, the client can set
+ * a limit for a single allocation. If a cacheable entry would have been cached, but its size
+ * exceeds this limit, then we do not attempt to cache it at all.
+ *
+ * Zero is the default value, meaning we always attempt to cache entries.
+ */
+ static size_t GetResourceCacheSingleAllocationByteLimit();
+ static size_t SetResourceCacheSingleAllocationByteLimit(size_t newLimit);
+
+#ifdef SK_SUPPORT_LEGACY_IMAGECACHE_NAME
+ static size_t GetImageCacheBytesUsed() {
+ return GetImageCacheTotalBytesUsed();
+ }
+ static size_t GetImageCacheByteLimit() {
+ return GetImageCacheTotalByteLimit();
+ }
+ static size_t SetImageCacheByteLimit(size_t newLimit) {
+ return SetImageCacheTotalByteLimit(newLimit);
+ }
+ static size_t GetImageCacheTotalBytesUsed() {
+ return GetResourceCacheTotalBytesUsed();
+ }
+ static size_t GetImageCacheTotalByteLimit() {
+ return GetResourceCacheTotalByteLimit();
+ }
+ static size_t SetImageCacheTotalByteLimit(size_t newLimit) {
+ return SetResourceCacheTotalByteLimit(newLimit);
+ }
+ static size_t GetImageCacheSingleAllocationByteLimit() {
+ return GetResourceCacheSingleAllocationByteLimit();
+ }
+ static size_t SetImageCacheSingleAllocationByteLimit(size_t newLimit) {
+ return SetResourceCacheSingleAllocationByteLimit(newLimit);
+ }
+#endif
+
+ /**
+ * Applications with command line options may pass optional state, such
+ * as cache sizes, here, for instance:
+ * font-cache-limit=12345678
+ *
+ * The flags format is name=value[;name=value...] with no spaces.
+ * This format is subject to change.
+ */
+ static void SetFlags(const char* flags);
+
+ /**
+ * Return the max number of bytes that should be used by the thread-local
+ * font cache.
+ * If the cache needs to allocate more, it will purge previous entries.
+ * This max can be changed by calling SetFontCacheLimit().
+ *
+ * If this thread has never called SetTLSFontCacheLimit, or has called it
+ * with 0, then this thread is using the shared font cache. In that case,
+ * this function will always return 0, and the caller may want to call
+ * GetFontCacheLimit.
+ */
+ static size_t GetTLSFontCacheLimit();
+
+ /**
+ * Specify the max number of bytes that should be used by the thread-local
+ * font cache. If this value is 0, then this thread will use the shared
+ * global font cache.
+ */
+ static void SetTLSFontCacheLimit(size_t bytes);
+
+private:
+ /** This is automatically called by SkGraphics::Init(), and must be
+ implemented by the host OS. This allows the host OS to register a callback
+ with the C++ runtime to call SkGraphics::FreeCaches()
+ */
+ static void InstallNewHandler();
+};
+
+class SkAutoGraphics {
+public:
+ SkAutoGraphics() {
+ SkGraphics::Init();
+ }
+ ~SkAutoGraphics() {
+ SkGraphics::Term();
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkImage.h b/src/third_party/skia/include/core/SkImage.h
new file mode 100644
index 0000000..5a6c966
--- /dev/null
+++ b/src/third_party/skia/include/core/SkImage.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImage_DEFINED
+#define SkImage_DEFINED
+
+#include "SkImageInfo.h"
+#include "SkImageEncoder.h"
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+#include "SkShader.h"
+
+class SkData;
+class SkCanvas;
+class SkImageGenerator;
+class SkPaint;
+class GrContext;
+class GrTexture;
+
+/**
+ * SkImage is an abstraction for drawing a rectagle of pixels, though the
+ * particular type of image could be actually storing its data on the GPU, or
+ * as drawing commands (picture or PDF or otherwise), ready to be played back
+ * into another canvas.
+ *
+ * The content of SkImage is always immutable, though the actual storage may
+ * change, if for example that image can be re-created via encoded data or
+ * other means.
+ */
+class SK_API SkImage : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkImage)
+
+ typedef SkImageInfo Info;
+
+ static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes);
+ static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
+
+ /**
+ * GrTexture is a more logical parameter for this factory, but its
+ * interactions with scratch cache still has issues, so for now we take
+ * SkBitmap instead. This will be changed in the future. skbug.com/1449
+ */
+ static SkImage* NewTexture(const SkBitmap&);
+
+ virtual bool isOpaque() const { return false; }
+
+ /**
+ * Construct a new SkImage based on the given ImageGenerator.
+ * This function will always take ownership of the passed
+ * ImageGenerator. Returns NULL on error.
+ */
+ static SkImage* NewFromGenerator(SkImageGenerator*);
+
+ int width() const { return fWidth; }
+ int height() const { return fHeight; }
+ uint32_t uniqueID() const { return fUniqueID; }
+
+ /**
+ * Return the GrTexture that stores the image pixels. Calling getTexture
+ * does not affect the reference count of the GrTexture object.
+ * Will return NULL if the image does not use a texture.
+ */
+ GrTexture* getTexture();
+
+ virtual SkShader* newShader(SkShader::TileMode,
+ SkShader::TileMode,
+ const SkMatrix* localMatrix = NULL) const;
+
+ /**
+ * If the image has direct access to its pixels (i.e. they are in local
+ * RAM) return the (const) address of those pixels, and if not null, return
+ * the ImageInfo and rowBytes. The returned address is only valid while
+ * the image object is in scope.
+ *
+ * On failure, returns NULL and the info and rowBytes parameters are
+ * ignored.
+ */
+ const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const;
+
+ /**
+ * Encode the image's pixels and return the result as a new SkData, which
+ * the caller must manage (i.e. call unref() when they are done).
+ *
+ * If the image type cannot be encoded, or the requested encoder type is
+ * not supported, this will return NULL.
+ */
+ SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type,
+ int quality = 80) const;
+
+ void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
+
+ /**
+ * Draw the image, cropped to the src rect, to the dst rect of a canvas.
+ * If src is larger than the bounds of the image, the rest of the image is
+ * filled with transparent black pixels.
+ *
+ * See SkCanvas::drawBitmapRectToRect for similar behavior.
+ */
+ void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) const;
+
+protected:
+ SkImage(int width, int height) :
+ fWidth(width),
+ fHeight(height),
+ fUniqueID(NextUniqueID()) {
+
+ SkASSERT(width >= 0);
+ SkASSERT(height >= 0);
+ }
+
+private:
+ const int fWidth;
+ const int fHeight;
+ const uint32_t fUniqueID;
+
+ static uint32_t NextUniqueID();
+
+ typedef SkRefCnt INHERITED;
+
+ /**
+ * Return a copy of the image's pixels, limiting them to the subset
+ * rectangle's intersection wit the image bounds. If subset is NULL, then
+ * the entire image will be considered.
+ *
+ * If the bitmap's pixels have already been allocated, then readPixels()
+ * will succeed only if it can support converting the image's pixels into
+ * the bitmap's ColorType/AlphaType. Any pixels in the bitmap that do not
+ * intersect with the image's bounds and the subset (if not null) will be
+ * left untouched.
+ *
+ * If the bitmap is initially empty/unallocated, then it will be allocated
+ * using the default allocator, and the ColorType/AlphaType will be chosen
+ * to most closely fit the image's configuration.
+ *
+ * On failure, false will be returned, and bitmap will unmodified.
+ */
+ // On ice for now:
+ // - should it respect the particular colortype/alphatype of the src
+ // - should it have separate entrypoints for preallocated and not bitmaps?
+ // - isn't it enough to allow the caller to draw() the image into a canvas?
+ bool readPixels(SkBitmap* bitmap, const SkIRect* subset = NULL) const;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkImageDecoder.h b/src/third_party/skia/include/core/SkImageDecoder.h
new file mode 100644
index 0000000..5910d33
--- /dev/null
+++ b/src/third_party/skia/include/core/SkImageDecoder.h
@@ -0,0 +1,486 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImageDecoder_DEFINED
+#define SkImageDecoder_DEFINED
+
+#include "SkBitmap.h"
+#include "SkImage.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkTRegistry.h"
+#include "SkTypes.h"
+
+class SkStream;
+class SkStreamRewindable;
+
+/** \class SkImageDecoder
+
+ Base class for decoding compressed images into a SkBitmap
+*/
+class SkImageDecoder : SkNoncopyable {
+public:
+ virtual ~SkImageDecoder();
+
+ enum Format {
+ kUnknown_Format,
+ kBMP_Format,
+ kGIF_Format,
+ kICO_Format,
+ kJPEG_Format,
+ kPNG_Format,
+ kWBMP_Format,
+ kWEBP_Format,
+ kPKM_Format,
+ kKTX_Format,
+ kASTC_Format,
+
+ kLastKnownFormat = kKTX_Format,
+ };
+
+ /** Return the format of image this decoder can decode. If this decoder can decode multiple
+ formats, kUnknown_Format will be returned.
+ */
+ virtual Format getFormat() const;
+
+ /** Return the format of the SkStreamRewindable or kUnknown_Format if it cannot be determined.
+ Rewinds the stream before returning.
+ */
+ static Format GetStreamFormat(SkStreamRewindable*);
+
+ /** Return a readable string of the Format provided.
+ */
+ static const char* GetFormatName(Format);
+
+ /** Return a readable string of the value returned by getFormat().
+ */
+ const char* getFormatName() const;
+
+ /** Whether the decoder should skip writing zeroes to output if possible.
+ */
+ bool getSkipWritingZeroes() const { return fSkipWritingZeroes; }
+
+ /** Set to true if the decoder should skip writing any zeroes when
+ creating the output image.
+ This is a hint that may not be respected by the decoder.
+ It should only be used if it is known that the memory to write
+ to has already been set to 0; otherwise the resulting image will
+ have garbage.
+ This is ideal for images that contain a lot of completely transparent
+ pixels, but may be a performance hit for an image that has only a
+ few transparent pixels.
+ The default is false.
+ */
+ void setSkipWritingZeroes(bool skip) { fSkipWritingZeroes = skip; }
+
+ /** Returns true if the decoder should try to dither the resulting image.
+ The default setting is true.
+ */
+ bool getDitherImage() const { return fDitherImage; }
+
+ /** Set to true if the the decoder should try to dither the resulting image.
+ The default setting is true.
+ */
+ void setDitherImage(bool dither) { fDitherImage = dither; }
+
+ /** Returns true if the decoder should try to decode the
+ resulting image to a higher quality even at the expense of
+ the decoding speed.
+ */
+ bool getPreferQualityOverSpeed() const { return fPreferQualityOverSpeed; }
+
+ /** Set to true if the the decoder should try to decode the
+ resulting image to a higher quality even at the expense of
+ the decoding speed.
+ */
+ void setPreferQualityOverSpeed(bool qualityOverSpeed) {
+ fPreferQualityOverSpeed = qualityOverSpeed;
+ }
+
+ /** Set to true to require the decoder to return a bitmap with unpremultiplied
+ colors. The default is false, meaning the resulting bitmap will have its
+ colors premultiplied.
+ NOTE: Passing true to this function may result in a bitmap which cannot
+ be properly used by Skia.
+ */
+ void setRequireUnpremultipliedColors(bool request) {
+ fRequireUnpremultipliedColors = request;
+ }
+
+ /** Returns true if the decoder will only return bitmaps with unpremultiplied
+ colors.
+ */
+ bool getRequireUnpremultipliedColors() const { return fRequireUnpremultipliedColors; }
+
+ /** \class Peeker
+
+ Base class for optional callbacks to retrieve meta/chunk data out of
+ an image as it is being decoded.
+ */
+ class Peeker : public SkRefCnt {
+ public:
+ SK_DECLARE_INST_COUNT(Peeker)
+
+ /** Return true to continue decoding, or false to indicate an error, which
+ will cause the decoder to not return the image.
+ */
+ virtual bool peek(const char tag[], const void* data, size_t length) = 0;
+ private:
+ typedef SkRefCnt INHERITED;
+ };
+
+ Peeker* getPeeker() const { return fPeeker; }
+ Peeker* setPeeker(Peeker*);
+
+#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
+ /** \class Chooser
+
+ Base class for optional callbacks to choose an image from a format that
+ contains multiple images.
+ */
+ class Chooser : public SkRefCnt {
+ public:
+ SK_DECLARE_INST_COUNT(Chooser)
+
+ virtual void begin(int count) {}
+ virtual void inspect(int index, SkBitmap::Config config, int width, int height) {}
+ /** Return the index of the subimage you want, or -1 to choose none of them.
+ */
+ virtual int choose() = 0;
+
+ private:
+ typedef SkRefCnt INHERITED;
+ };
+
+ Chooser* getChooser() const { return fChooser; }
+ Chooser* setChooser(Chooser*);
+#endif
+
+ /**
+ * By default, the codec will try to comply with the "pref" colortype
+ * that is passed to decode() or decodeSubset(). However, this can be called
+ * to override that, causing the codec to try to match the src depth instead
+ * (as shown below).
+ *
+ * src_8Index -> kIndex_8_SkColorType
+ * src_8Gray -> kN32_SkColorType
+ * src_8bpc -> kN32_SkColorType
+ */
+ void setPreserveSrcDepth(bool preserve) {
+ fPreserveSrcDepth = preserve;
+ }
+
+ SkBitmap::Allocator* getAllocator() const { return fAllocator; }
+ SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
+
+ // sample-size, if set to > 1, tells the decoder to return a smaller than
+ // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample
+ // size is set to 3, then the returned bitmap will be 1/3 as wide and high,
+ // and will contain 1/9 as many pixels as the original.
+ // Note: this is a hint, and the codec may choose to ignore this, or only
+ // approximate the sample size.
+ int getSampleSize() const { return fSampleSize; }
+ void setSampleSize(int size);
+
+ /** Reset the sampleSize to its default of 1
+ */
+ void resetSampleSize() { this->setSampleSize(1); }
+
+ /** Decoding is synchronous, but for long decodes, a different thread can
+ call this method safely. This sets a state that the decoders will
+ periodically check, and if they see it changed to cancel, they will
+ cancel. This will result in decode() returning false. However, there is
+ no guarantee that the decoder will see the state change in time, so
+ it is possible that cancelDecode() will be called, but will be ignored
+ and decode() will return true (assuming no other problems were
+ encountered).
+
+ This state is automatically reset at the beginning of decode().
+ */
+ void cancelDecode() {
+ // now the subclass must query shouldCancelDecode() to be informed
+ // of the request
+ fShouldCancelDecode = true;
+ }
+
+ /** Passed to the decode method. If kDecodeBounds_Mode is passed, then
+ only the bitmap's info need be set. If kDecodePixels_Mode
+ is passed, then the bitmap must have pixels or a pixelRef.
+ */
+ enum Mode {
+ kDecodeBounds_Mode, //!< only return info in bitmap
+ kDecodePixels_Mode //!< return entire bitmap (including pixels)
+ };
+
+ /** Given a stream, decode it into the specified bitmap.
+ If the decoder can decompress the image, it calls bitmap.setInfo(),
+ and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
+ which will allocated a pixelRef. To access the pixel memory, the codec
+ needs to call lockPixels/unlockPixels on the
+ bitmap. It can then set the pixels with the decompressed image.
+ * If the image cannot be decompressed, return false. After the
+ * decoding, the function converts the decoded colortype in bitmap
+ * to pref if possible. Whether a conversion is feasible is
+ * tested by Bitmap::canCopyTo(pref).
+
+ If an SkBitmap::Allocator is installed via setAllocator, it will be
+ used to allocate the pixel memory. A clever allocator can be used
+ to allocate the memory from a cache, volatile memory, or even from
+ an existing bitmap's memory.
+
+ If a Peeker is installed via setPeeker, it may be used to peek into
+ meta data during the decode.
+ */
+ bool decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode);
+ bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
+ return this->decode(stream, bitmap, kUnknown_SkColorType, mode);
+ }
+
+ /**
+ * Given a stream, build an index for doing tile-based decode.
+ * The built index will be saved in the decoder, and the image size will
+ * be returned in width and height.
+ *
+ * Return true for success or false on failure.
+ */
+ bool buildTileIndex(SkStreamRewindable*, int *width, int *height);
+
+ /**
+ * Decode a rectangle subset in the image.
+ * The method can only be called after buildTileIndex().
+ *
+ * Return true for success.
+ * Return false if the index is never built or failing in decoding.
+ */
+ bool decodeSubset(SkBitmap* bm, const SkIRect& subset, SkColorType pref);
+
+ /** Given a stream, this will try to find an appropriate decoder object.
+ If none is found, the method returns NULL.
+ */
+ static SkImageDecoder* Factory(SkStreamRewindable*);
+
+ /** Decode the image stored in the specified file, and store the result
+ in bitmap. Return true for success or false on failure.
+
+ @param pref If the PrefConfigTable is not set, prefer this colortype.
+ See NOTE ABOUT PREFERRED CONFIGS.
+
+ @param format On success, if format is non-null, it is set to the format
+ of the decoded file. On failure it is ignored.
+ */
+ static bool DecodeFile(const char file[], SkBitmap* bitmap, SkColorType pref, Mode,
+ Format* format = NULL);
+ static bool DecodeFile(const char file[], SkBitmap* bitmap) {
+ return DecodeFile(file, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
+ }
+
+ /** Decode the image stored in the specified memory buffer, and store the
+ result in bitmap. Return true for success or false on failure.
+
+ @param pref If the PrefConfigTable is not set, prefer this colortype.
+ See NOTE ABOUT PREFERRED CONFIGS.
+
+ @param format On success, if format is non-null, it is set to the format
+ of the decoded buffer. On failure it is ignored.
+ */
+ static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, SkColorType pref,
+ Mode, Format* format = NULL);
+ static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){
+ return DecodeMemory(buffer, size, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
+ }
+
+ /**
+ * Struct containing information about a pixel destination.
+ */
+ struct Target {
+ /**
+ * Pre-allocated memory.
+ */
+ void* fAddr;
+
+ /**
+ * Rowbytes of the allocated memory.
+ */
+ size_t fRowBytes;
+ };
+
+ /** Decode the image stored in the specified SkStreamRewindable, and store the result
+ in bitmap. Return true for success or false on failure.
+
+ @param pref If the PrefConfigTable is not set, prefer this colortype.
+ See NOTE ABOUT PREFERRED CONFIGS.
+
+ @param format On success, if format is non-null, it is set to the format
+ of the decoded stream. On failure it is ignored.
+ */
+ static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap, SkColorType pref, Mode,
+ Format* format = NULL);
+ static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap) {
+ return DecodeStream(stream, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
+ }
+
+protected:
+ // must be overridden in subclasses. This guy is called by decode(...)
+ virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
+
+ // If the decoder wants to support tiled based decoding,
+ // this method must be overridden. This guy is called by buildTileIndex(...)
+ virtual bool onBuildTileIndex(SkStreamRewindable*, int *width, int *height) {
+ return false;
+ }
+
+ // If the decoder wants to support tiled based decoding,
+ // this method must be overridden. This guy is called by decodeRegion(...)
+ virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) {
+ return false;
+ }
+
+ /*
+ * Crop a rectangle from the src Bitmap to the dest Bitmap. src and dst are
+ * both sampled by sampleSize from an original Bitmap.
+ *
+ * @param dst the destination bitmap.
+ * @param src the source bitmap that is sampled by sampleSize from the
+ * original bitmap.
+ * @param sampleSize the sample size that src is sampled from the original bitmap.
+ * @param (dstX, dstY) the upper-left point of the dest bitmap in terms of
+ * the coordinate in the original bitmap.
+ * @param (width, height) the width and height of the unsampled dst.
+ * @param (srcX, srcY) the upper-left point of the src bitmap in terms of
+ * the coordinate in the original bitmap.
+ * @return bool Whether or not it succeeded.
+ */
+ bool cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize,
+ int dstX, int dstY, int width, int height,
+ int srcX, int srcY);
+
+ /**
+ * Copy all fields on this decoder to the other decoder. Used by subclasses
+ * to decode a subimage using a different decoder, but with the same settings.
+ */
+ void copyFieldsToOther(SkImageDecoder* other);
+
+ /** Can be queried from within onDecode, to see if the user (possibly in
+ a different thread) has requested the decode to cancel. If this returns
+ true, your onDecode() should stop and return false.
+ Each subclass needs to decide how often it can query this, to balance
+ responsiveness with performance.
+
+ Calling this outside of onDecode() may return undefined values.
+ */
+
+public:
+ bool shouldCancelDecode() const { return fShouldCancelDecode; }
+
+protected:
+ SkImageDecoder();
+
+ /**
+ * Return the default preference being used by the current or latest call to decode.
+ */
+ SkColorType getDefaultPref() { return fDefaultPref; }
+
+#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
+ // helper function for decoders to handle the (common) case where there is only
+ // once choice available in the image file.
+ bool chooseFromOneChoice(SkColorType, int width, int height) const;
+#endif
+
+ /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's info.
+ Returns true on success. This method handles checking for an optional Allocator.
+ */
+ bool allocPixelRef(SkBitmap*, SkColorTable*) const;
+
+ /**
+ * The raw data of the src image.
+ */
+ enum SrcDepth {
+ // Color-indexed.
+ kIndex_SrcDepth,
+ // Grayscale in 8 bits.
+ k8BitGray_SrcDepth,
+ // 8 bits per component. Used for 24 bit if there is no alpha.
+ k32Bit_SrcDepth,
+ };
+ /** The subclass, inside onDecode(), calls this to determine the colorType of
+ the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the
+ src image. This routine returns the caller's preference given
+ srcDepth and hasAlpha, or kUnknown_SkColorType if there is no preference.
+ */
+ SkColorType getPrefColorType(SrcDepth, bool hasAlpha) const;
+
+private:
+ Peeker* fPeeker;
+#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
+ Chooser* fChooser;
+#endif
+ SkBitmap::Allocator* fAllocator;
+ int fSampleSize;
+ SkColorType fDefaultPref; // use if fUsePrefTable is false
+ bool fPreserveSrcDepth;
+ bool fDitherImage;
+ bool fSkipWritingZeroes;
+ mutable bool fShouldCancelDecode;
+ bool fPreferQualityOverSpeed;
+ bool fRequireUnpremultipliedColors;
+};
+
+/** Calling newDecoder with a stream returns a new matching imagedecoder
+ instance, or NULL if none can be found. The caller must manage its ownership
+ of the stream as usual, calling unref() when it is done, as the returned
+ decoder may have called ref() (and if so, the decoder is responsible for
+ balancing its ownership when it is destroyed).
+ */
+class SkImageDecoderFactory : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkImageDecoderFactory)
+
+ virtual SkImageDecoder* newDecoder(SkStreamRewindable*) = 0;
+
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+class SkDefaultImageDecoderFactory : SkImageDecoderFactory {
+public:
+ // calls SkImageDecoder::Factory(stream)
+ virtual SkImageDecoder* newDecoder(SkStreamRewindable* stream) {
+ return SkImageDecoder::Factory(stream);
+ }
+};
+
+// This macro declares a global (i.e., non-class owned) creation entry point
+// for each decoder (e.g., CreateJPEGImageDecoder)
+#define DECLARE_DECODER_CREATOR(codec) \
+ SkImageDecoder *Create ## codec ();
+
+// This macro defines the global creation entry point for each decoder. Each
+// decoder implementation that registers with the decoder factory must call it.
+#define DEFINE_DECODER_CREATOR(codec) \
+ SkImageDecoder *Create ## codec () { \
+ return SkNEW( Sk ## codec ); \
+ }
+
+// All the decoders known by Skia. Note that, depending on the compiler settings,
+// not all of these will be available
+DECLARE_DECODER_CREATOR(BMPImageDecoder);
+DECLARE_DECODER_CREATOR(GIFImageDecoder);
+DECLARE_DECODER_CREATOR(ICOImageDecoder);
+DECLARE_DECODER_CREATOR(JPEGImageDecoder);
+DECLARE_DECODER_CREATOR(PNGImageDecoder);
+DECLARE_DECODER_CREATOR(WBMPImageDecoder);
+DECLARE_DECODER_CREATOR(WEBPImageDecoder);
+DECLARE_DECODER_CREATOR(PKMImageDecoder);
+DECLARE_DECODER_CREATOR(KTXImageDecoder);
+DECLARE_DECODER_CREATOR(ASTCImageDecoder);
+
+// Typedefs to make registering decoder and formatter callbacks easier.
+// These have to be defined outside SkImageDecoder. :(
+typedef SkTRegistry<SkImageDecoder*(*)(SkStreamRewindable*)> SkImageDecoder_DecodeReg;
+typedef SkTRegistry<SkImageDecoder::Format(*)(SkStreamRewindable*)> SkImageDecoder_FormatReg;
+
+#endif
diff --git a/src/third_party/skia/include/core/SkImageEncoder.h b/src/third_party/skia/include/core/SkImageEncoder.h
new file mode 100644
index 0000000..4d4d2a8
--- /dev/null
+++ b/src/third_party/skia/include/core/SkImageEncoder.h
@@ -0,0 +1,110 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkImageEncoder_DEFINED
+#define SkImageEncoder_DEFINED
+
+#include "SkTypes.h"
+#include "SkTRegistry.h"
+
+class SkBitmap;
+class SkData;
+class SkWStream;
+
+class SkImageEncoder {
+public:
+ enum Type {
+ kUnknown_Type,
+ kBMP_Type,
+ kGIF_Type,
+ kICO_Type,
+ kJPEG_Type,
+ kPNG_Type,
+ kWBMP_Type,
+ kWEBP_Type,
+ kKTX_Type,
+ };
+ static SkImageEncoder* Create(Type);
+
+ virtual ~SkImageEncoder();
+
+ /* Quality ranges from 0..100 */
+ enum {
+ kDefaultQuality = 80
+ };
+
+ /**
+ * Encode bitmap 'bm', returning the results in an SkData, at quality level
+ * 'quality' (which can be in range 0-100). If the bitmap cannot be
+ * encoded, return null. On success, the caller is responsible for
+ * calling unref() on the data when they are finished.
+ */
+ SkData* encodeData(const SkBitmap&, int quality);
+
+ /**
+ * Encode bitmap 'bm' in the desired format, writing results to
+ * file 'file', at quality level 'quality' (which can be in range
+ * 0-100). Returns false on failure.
+ */
+ bool encodeFile(const char file[], const SkBitmap& bm, int quality);
+
+ /**
+ * Encode bitmap 'bm' in the desired format, writing results to
+ * stream 'stream', at quality level 'quality' (which can be in
+ * range 0-100). Returns false on failure.
+ */
+ bool encodeStream(SkWStream* stream, const SkBitmap& bm, int quality);
+
+ static SkData* EncodeData(const SkBitmap&, Type, int quality);
+ static bool EncodeFile(const char file[], const SkBitmap&, Type,
+ int quality);
+ static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
+ int quality);
+
+protected:
+ /**
+ * Encode bitmap 'bm' in the desired format, writing results to
+ * stream 'stream', at quality level 'quality' (which can be in
+ * range 0-100).
+ *
+ * This must be overridden by each SkImageEncoder implementation.
+ */
+ virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) = 0;
+};
+
+// This macro declares a global (i.e., non-class owned) creation entry point
+// for each encoder (e.g., CreateJPEGImageEncoder)
+#define DECLARE_ENCODER_CREATOR(codec) \
+ SkImageEncoder *Create ## codec ();
+
+// This macro defines the global creation entry point for each encoder. Each
+// encoder implementation that registers with the encoder factory must call it.
+#define DEFINE_ENCODER_CREATOR(codec) \
+ SkImageEncoder *Create ## codec () { \
+ return SkNEW( Sk ## codec ); \
+ }
+
+// All the encoders known by Skia. Note that, depending on the compiler settings,
+// not all of these will be available
+/** An ARGBImageEncoder will always write out
+ * bitmap.width() * bitmap.height() * 4
+ * bytes.
+ */
+DECLARE_ENCODER_CREATOR(ARGBImageEncoder);
+DECLARE_ENCODER_CREATOR(JPEGImageEncoder);
+DECLARE_ENCODER_CREATOR(PNGImageEncoder);
+DECLARE_ENCODER_CREATOR(KTXImageEncoder);
+DECLARE_ENCODER_CREATOR(WEBPImageEncoder);
+
+#ifdef SK_BUILD_FOR_IOS
+DECLARE_ENCODER_CREATOR(PNGImageEncoder_IOS);
+#endif
+
+// Typedef to make registering encoder callback easier
+// This has to be defined outside SkImageEncoder. :(
+typedef SkTRegistry<SkImageEncoder*(*)(SkImageEncoder::Type)> SkImageEncoder_EncodeReg;
+#endif
diff --git a/src/third_party/skia/include/core/SkImageFilter.h b/src/third_party/skia/include/core/SkImageFilter.h
new file mode 100644
index 0000000..9f17f81
--- /dev/null
+++ b/src/third_party/skia/include/core/SkImageFilter.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImageFilter_DEFINED
+#define SkImageFilter_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkMatrix.h"
+#include "SkRect.h"
+#include "SkTemplates.h"
+
+class SkBitmap;
+class SkColorFilter;
+class SkBaseDevice;
+struct SkIPoint;
+class GrFragmentProcessor;
+class GrTexture;
+
+/**
+ * Base class for image filters. If one is installed in the paint, then
+ * all drawing occurs as usual, but it is as if the drawing happened into an
+ * offscreen (before the xfermode is applied). This offscreen bitmap will
+ * then be handed to the imagefilter, who in turn creates a new bitmap which
+ * is what will finally be drawn to the device (using the original xfermode).
+ */
+class SK_API SkImageFilter : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkImageFilter)
+
+ class CropRect {
+ public:
+ enum CropEdge {
+ kHasLeft_CropEdge = 0x01,
+ kHasTop_CropEdge = 0x02,
+ kHasRight_CropEdge = 0x04,
+ kHasBottom_CropEdge = 0x08,
+ kHasAll_CropEdge = 0x0F,
+ };
+ CropRect() {}
+ explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) : fRect(rect), fFlags(flags) {}
+ uint32_t flags() const { return fFlags; }
+ const SkRect& rect() const { return fRect; }
+ private:
+ SkRect fRect;
+ uint32_t fFlags;
+ };
+
+ // This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to
+ // (result, offset).
+ class Cache : public SkRefCnt {
+ public:
+ struct Key;
+ virtual ~Cache() {}
+ static Cache* Create(size_t maxBytes);
+ static Cache* Get();
+ virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const = 0;
+ virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) = 0;
+ };
+
+ class Context {
+ public:
+ Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache) :
+ fCTM(ctm), fClipBounds(clipBounds), fCache(cache) {
+ }
+ const SkMatrix& ctm() const { return fCTM; }
+ const SkIRect& clipBounds() const { return fClipBounds; }
+ Cache* cache() const { return fCache; }
+ private:
+ SkMatrix fCTM;
+ SkIRect fClipBounds;
+ Cache* fCache;
+ };
+
+ class Proxy {
+ public:
+ virtual ~Proxy() {};
+
+ virtual SkBaseDevice* createDevice(int width, int height) = 0;
+ // returns true if the proxy can handle this filter natively
+ virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
+ // returns true if the proxy handled the filter itself. if this returns
+ // false then the filter's code will be called.
+ virtual bool filterImage(const SkImageFilter*, const SkBitmap& src,
+ const Context&,
+ SkBitmap* result, SkIPoint* offset) = 0;
+ };
+
+ /**
+ * Request a new (result) image to be created from the src image.
+ * If the src has no pixels (isNull()) then the request just wants to
+ * receive the config and width/height of the result.
+ *
+ * The matrix is the current matrix on the canvas.
+ *
+ * Offset is the amount to translate the resulting image relative to the
+ * src when it is drawn. This is an out-param.
+ *
+ * If the result image cannot be created, return false, in which case both
+ * the result and offset parameters will be ignored by the caller.
+ */
+ bool filterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const;
+
+ /**
+ * Given the src bounds of an image, this returns the bounds of the result
+ * image after the filter has been applied.
+ */
+ bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const;
+
+ /**
+ * Returns true if the filter can be processed on the GPU. This is most
+ * often used for multi-pass effects, where intermediate results must be
+ * rendered to textures. For single-pass effects, use asFragmentProcessor().
+ * The default implementation returns asFragmentProcessor(NULL, NULL, SkMatrix::I(),
+ * SkIRect()).
+ */
+ virtual bool canFilterImageGPU() const;
+
+ /**
+ * Process this image filter on the GPU. This is most often used for
+ * multi-pass effects, where intermediate results must be rendered to
+ * textures. For single-pass effects, use asFragmentProcessor(). src is the
+ * source image for processing, as a texture-backed bitmap. result is
+ * the destination bitmap, which should contain a texture-backed pixelref
+ * on success. offset is the amount to translate the resulting image
+ * relative to the src when it is drawn. The default implementation does
+ * single-pass processing using asFragmentProcessor().
+ */
+ virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const;
+
+ /**
+ * Returns whether this image filter is a color filter and puts the color filter into the
+ * "filterPtr" parameter if it can. Does nothing otherwise.
+ * If this returns false, then the filterPtr is unchanged.
+ * If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler
+ * (i.e. it may not be set to NULL).
+ */
+ virtual bool asColorFilter(SkColorFilter** filterPtr) const;
+
+ /**
+ * Returns the number of inputs this filter will accept (some inputs can
+ * be NULL).
+ */
+ int countInputs() const { return fInputCount; }
+
+ /**
+ * Returns the input filter at a given index, or NULL if no input is
+ * connected. The indices used are filter-specific.
+ */
+ SkImageFilter* getInput(int i) const {
+ SkASSERT(i < fInputCount);
+ return fInputs[i];
+ }
+
+ /**
+ * Returns whether any edges of the crop rect have been set. The crop
+ * rect is set at construction time, and determines which pixels from the
+ * input image will be processed. The size of the crop rect should be
+ * used as the size of the destination image. The origin of this rect
+ * should be used to offset access to the input images, and should also
+ * be added to the "offset" parameter in onFilterImage and
+ * filterImageGPU(). (The latter ensures that the resulting buffer is
+ * drawn in the correct location.)
+ */
+ bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
+
+ // Default impl returns union of all input bounds.
+ virtual void computeFastBounds(const SkRect&, SkRect*) const;
+
+#if SK_SUPPORT_GPU
+ /**
+ * Wrap the given texture in a texture-backed SkBitmap.
+ */
+ static void WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result);
+
+ /**
+ * Recursively evaluate this filter on the GPU. If the filter has no GPU
+ * implementation, it will be processed in software and uploaded to the GPU.
+ */
+ bool getInputResultGPU(SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const;
+#endif
+
+ SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
+
+protected:
+ class Common {
+ public:
+ Common() {}
+ ~Common();
+
+ /**
+ * Attempt to unflatten the cropRect and the expected number of input filters.
+ * If any number of input filters is valid, pass -1.
+ * If this fails (i.e. corrupt buffer or contents) then return false and common will
+ * be left uninitialized.
+ * If this returns true, then inputCount() is the number of found input filters, each
+ * of which may be NULL or a valid imagefilter.
+ */
+ bool unflatten(SkReadBuffer&, int expectedInputs);
+
+ const CropRect& cropRect() const { return fCropRect; }
+ int inputCount() const { return fInputs.count(); }
+ SkImageFilter** inputs() const { return fInputs.get(); }
+ uint32_t uniqueID() const { return fUniqueID; }
+
+ SkImageFilter* getInput(int index) const { return fInputs[index]; }
+
+ // If the caller wants a copy of the inputs, call this and it will transfer ownership
+ // of the unflattened input filters to the caller. This is just a short-cut for copying
+ // the inputs, calling ref() on each, and then waiting for Common's destructor to call
+ // unref() on each.
+ void detachInputs(SkImageFilter** inputs);
+
+ private:
+ CropRect fCropRect;
+ // most filters accept at most 2 input-filters
+ SkAutoSTArray<2, SkImageFilter*> fInputs;
+ uint32_t fUniqueID;
+
+ void allocInputs(int count);
+ };
+
+ SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL, uint32_t uniqueID = 0);
+
+ virtual ~SkImageFilter();
+
+ /**
+ * Constructs a new SkImageFilter read from an SkReadBuffer object.
+ *
+ * @param inputCount The exact number of inputs expected for this SkImageFilter object.
+ * -1 can be used if the filter accepts any number of inputs.
+ * @param rb SkReadBuffer object from which the SkImageFilter is read.
+ */
+ explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
+
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ /**
+ * This is the virtual which should be overridden by the derived class
+ * to perform image filtering.
+ *
+ * src is the original primitive bitmap. If the filter has a connected
+ * input, it should recurse on that input and use that in place of src.
+ *
+ * The matrix is the current matrix on the canvas.
+ *
+ * Offset is the amount to translate the resulting image relative to the
+ * src when it is drawn. This is an out-param.
+ *
+ * If the result image cannot be created, this should false, in which
+ * case both the result and offset parameters will be ignored by the
+ * caller.
+ */
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const;
+ // Given the bounds of the destination rect to be filled in device
+ // coordinates (first parameter), and the CTM, compute (conservatively)
+ // which rect of the source image would be required (third parameter).
+ // Used for clipping and temp-buffer allocations, so the result need not
+ // be exact, but should never be smaller than the real answer. The default
+ // implementation recursively unions all input bounds, or returns false if
+ // no inputs.
+ virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const;
+
+ /** Computes source bounds as the src bitmap bounds offset by srcOffset.
+ * Apply the transformed crop rect to the bounds if any of the
+ * corresponding edge flags are set. Intersects the result against the
+ * context's clipBounds, and returns the result in "bounds". If there is
+ * no intersection, returns false and leaves "bounds" unchanged.
+ */
+ bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset,
+ SkIRect* bounds) const;
+
+ /** Same as the above call, except that if the resulting crop rect is not
+ * entirely contained by the source bitmap's bounds, it creates a new
+ * bitmap in "result" and pads the edges with transparent black. In that
+ * case, the srcOffset is modified to be the same as the bounds, since no
+ * further adjustment is needed by the caller. This version should only
+ * be used by filters which are not capable of processing a smaller
+ * source bitmap into a larger destination.
+ */
+ bool applyCropRect(const Context&, Proxy* proxy, const SkBitmap& src, SkIPoint* srcOffset,
+ SkIRect* bounds, SkBitmap* result) const;
+
+ /**
+ * Returns true if the filter can be expressed a single-pass
+ * GrProcessor, used to process this filter on the GPU, or false if
+ * not.
+ *
+ * If effect is non-NULL, a new GrProcessor instance is stored
+ * in it. The caller assumes ownership of the stage, and it is up to the
+ * caller to unref it.
+ *
+ * The effect can assume its vertexCoords space maps 1-to-1 with texels
+ * in the texture. "matrix" is a transformation to apply to filter
+ * parameters before they are used in the effect. Note that this function
+ * will be called with (NULL, NULL, SkMatrix::I()) to query for support,
+ * so returning "true" indicates support for all possible matrices.
+ */
+ virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+ const SkIRect& bounds) const;
+
+private:
+ bool usesSrcInput() const { return fUsesSrcInput; }
+
+ typedef SkFlattenable INHERITED;
+ int fInputCount;
+ SkImageFilter** fInputs;
+ bool fUsesSrcInput;
+ CropRect fCropRect;
+ uint32_t fUniqueID; // Globally unique
+};
+
+/**
+ * Helper to unflatten the common data, and return NULL if we fail.
+ */
+#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount) \
+ Common localVar; \
+ do { \
+ if (!localVar.unflatten(buffer, expectedCount)) { \
+ return NULL; \
+ } \
+ } while (0)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkImageGenerator.h b/src/third_party/skia/include/core/SkImageGenerator.h
new file mode 100644
index 0000000..fc6b1b4
--- /dev/null
+++ b/src/third_party/skia/include/core/SkImageGenerator.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImageGenerator_DEFINED
+#define SkImageGenerator_DEFINED
+
+#include "SkColor.h"
+#include "SkImageInfo.h"
+
+class SkBitmap;
+class SkData;
+class SkImageGenerator;
+
+/**
+ * Takes ownership of SkImageGenerator. If this method fails for
+ * whatever reason, it will return false and immediatetely delete
+ * the generator. If it succeeds, it will modify destination
+ * bitmap.
+ *
+ * If generator is NULL, will safely return false.
+ *
+ * If this fails or when the SkDiscardablePixelRef that is
+ * installed into destination is destroyed, it will call
+ * SkDELETE() on the generator. Therefore, generator should be
+ * allocated with SkNEW() or SkNEW_ARGS().
+ *
+ * @param destination Upon success, this bitmap will be
+ * configured and have a pixelref installed.
+ *
+ * @return true iff successful.
+ */
+SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination);
+
+
+/**
+ * An interface that allows a purgeable PixelRef (such as a
+ * SkDiscardablePixelRef) to decode and re-decode an image as needed.
+ */
+class SK_API SkImageGenerator {
+public:
+ /**
+ * The PixelRef which takes ownership of this SkImageGenerator
+ * will call the image generator's destructor.
+ */
+ virtual ~SkImageGenerator() { }
+
+#ifdef SK_SUPPORT_LEGACY_IMAGEGENERATORAPI
+ virtual SkData* refEncodedData() { return this->onRefEncodedData(); }
+ virtual bool getInfo(SkImageInfo* info) { return this->onGetInfo(info); }
+ virtual bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
+ return this->onGetPixels(info, pixels, rowBytes, NULL, NULL);
+ }
+#else
+ /**
+ * Return a ref to the encoded (i.e. compressed) representation,
+ * of this data.
+ *
+ * If non-NULL is returned, the caller is responsible for calling
+ * unref() on the data when it is finished.
+ */
+ SkData* refEncodedData() { return this->onRefEncodedData(); }
+
+ /**
+ * Return some information about the image, allowing the owner of
+ * this object to allocate pixels.
+ *
+ * Repeated calls to this function should give the same results,
+ * allowing the PixelRef to be immutable.
+ *
+ * @return false if anything goes wrong.
+ */
+ bool getInfo(SkImageInfo* info);
+
+ /**
+ * Decode into the given pixels, a block of memory of size at
+ * least (info.fHeight - 1) * rowBytes + (info.fWidth *
+ * bytesPerPixel)
+ *
+ * Repeated calls to this function should give the same results,
+ * allowing the PixelRef to be immutable.
+ *
+ * @param info A description of the format (config, size)
+ * expected by the caller. This can simply be identical
+ * to the info returned by getInfo().
+ *
+ * This contract also allows the caller to specify
+ * different output-configs, which the implementation can
+ * decide to support or not.
+ *
+ * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
+ * SkPMColor values in ctable. On success the generator must copy N colors into that storage,
+ * (where N is the logical number of table entries) and set ctableCount to N.
+ *
+ * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
+ * is not null, it will be set to 0.
+ *
+ * @return false if anything goes wrong or if the image info is
+ * unsupported.
+ */
+ bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount);
+
+ /**
+ * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType.
+ */
+ bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
+#endif
+
+ /**
+ * If planes or rowBytes is NULL or if any entry in planes is NULL or if any entry in rowBytes
+ * is 0, this imagegenerator should output the sizes and return true if it can efficiently
+ * return YUV planar data. If it cannot, it should return false. Note that either planes and
+ * rowBytes are both fully defined and non NULL/non 0 or they are both NULL or have NULL or 0
+ * entries only. Having only partial planes/rowBytes information is not supported.
+ *
+ * If all planes and rowBytes entries are non NULL or non 0, then it should copy the
+ * associated YUV data into those planes of memory supplied by the caller. It should validate
+ * that the sizes match what it expected. If the sizes do not match, it should return false.
+ */
+ bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace);
+
+protected:
+ virtual SkData* onRefEncodedData();
+ virtual bool onGetInfo(SkImageInfo* info);
+ virtual bool onGetPixels(const SkImageInfo& info,
+ void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount);
+ virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
+ virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace);
+};
+
+#endif // SkImageGenerator_DEFINED
diff --git a/src/third_party/skia/include/core/SkImageInfo.h b/src/third_party/skia/include/core/SkImageInfo.h
new file mode 100644
index 0000000..7934c81
--- /dev/null
+++ b/src/third_party/skia/include/core/SkImageInfo.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImageInfo_DEFINED
+#define SkImageInfo_DEFINED
+
+#include "SkMath.h"
+#include "SkSize.h"
+
+class SkWriteBuffer;
+class SkReadBuffer;
+
+/**
+ * Describes how to interpret the alpha compoent of a pixel.
+ */
+enum SkAlphaType {
+ /**
+ * All pixels should be treated as opaque, regardless of the value stored
+ * in their alpha field. Used for legacy images that wrote 0 or garbarge
+ * in their alpha field, but intended the RGB to be treated as opaque.
+ */
+ kIgnore_SkAlphaType,
+
+ /**
+ * All pixels are stored as opaque. This differs slightly from kIgnore in
+ * that kOpaque has correct "opaque" values stored in the pixels, while
+ * kIgnore may not, but in both cases the caller should treat the pixels
+ * as opaque.
+ */
+ kOpaque_SkAlphaType,
+
+ /**
+ * All pixels have their alpha premultiplied in their color components.
+ * This is the natural format for the rendering target pixels.
+ */
+ kPremul_SkAlphaType,
+
+ /**
+ * All pixels have their color components stored without any regard to the
+ * alpha. e.g. this is the default configuration for PNG images.
+ *
+ * This alpha-type is ONLY supported for input images. Rendering cannot
+ * generate this on output.
+ */
+ kUnpremul_SkAlphaType,
+
+ kLastEnum_SkAlphaType = kUnpremul_SkAlphaType
+};
+
+static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
+ SK_COMPILE_ASSERT(kIgnore_SkAlphaType < kOpaque_SkAlphaType, bad_alphatype_order);
+ SK_COMPILE_ASSERT(kPremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order);
+ SK_COMPILE_ASSERT(kUnpremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order);
+
+ return (unsigned)at <= kOpaque_SkAlphaType;
+}
+
+static inline bool SkAlphaTypeIsValid(unsigned value) {
+ return value <= kLastEnum_SkAlphaType;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Describes how to interpret the components of a pixel.
+ *
+ * kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native"
+ * form for skia's blitters. Use this if you don't have a swizzle preference
+ * for 32bit pixels.
+ */
+enum SkColorType {
+ kUnknown_SkColorType,
+ kAlpha_8_SkColorType,
+ kRGB_565_SkColorType,
+ kARGB_4444_SkColorType,
+ kRGBA_8888_SkColorType,
+ kBGRA_8888_SkColorType,
+ kIndex_8_SkColorType,
+
+ kLastEnum_SkColorType = kIndex_8_SkColorType,
+
+#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
+ kN32_SkColorType = kBGRA_8888_SkColorType,
+#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
+ kN32_SkColorType = kRGBA_8888_SkColorType,
+#else
+#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
+#endif
+
+#ifdef SK_SUPPORT_LEGACY_N32_NAME
+ kPMColor_SkColorType = kN32_SkColorType
+#endif
+};
+
+static int SkColorTypeBytesPerPixel(SkColorType ct) {
+ static const uint8_t gSize[] = {
+ 0, // Unknown
+ 1, // Alpha_8
+ 2, // RGB_565
+ 2, // ARGB_4444
+ 4, // RGBA_8888
+ 4, // BGRA_8888
+ 1, // kIndex_8
+ };
+ SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1),
+ size_mismatch_with_SkColorType_enum);
+
+ SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize));
+ return gSize[ct];
+}
+
+static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
+ return width * SkColorTypeBytesPerPixel(ct);
+}
+
+static inline bool SkColorTypeIsValid(unsigned value) {
+ return value <= kLastEnum_SkColorType;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Return true if alphaType is supported by colorType. If there is a canonical
+ * alphaType for this colorType, return it in canonical.
+ */
+bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
+ SkAlphaType* canonical = NULL);
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Describes the color space a YUV pixel.
+ */
+enum SkYUVColorSpace {
+ /** Standard JPEG color space. */
+ kJPEG_SkYUVColorSpace,
+ /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color
+ range. See http://en.wikipedia.org/wiki/Rec._601 for details. */
+ kRec601_SkYUVColorSpace,
+
+ /** HDTV standard Rec. 709 color space.
+ See http://en.wikipedia.org/wiki/Rec._709 for details. */
+ kRec709_SkYUVColorSpace,
+
+ kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Describe an image's dimensions and pixel type.
+ */
+struct SkImageInfo {
+public:
+ SkImageInfo()
+ : fWidth(0)
+ , fHeight(0)
+ , fColorType(kUnknown_SkColorType)
+ , fAlphaType(kIgnore_SkAlphaType)
+ {}
+
+ static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) {
+ return SkImageInfo(width, height, ct, at);
+ }
+
+ /**
+ * Sets colortype to the native ARGB32 type.
+ */
+ static SkImageInfo MakeN32(int width, int height, SkAlphaType at) {
+ return SkImageInfo(width, height, kN32_SkColorType, at);
+ }
+
+ /**
+ * Sets colortype to the native ARGB32 type, and the alphatype to premul.
+ */
+ static SkImageInfo MakeN32Premul(int width, int height) {
+ return SkImageInfo(width, height, kN32_SkColorType, kPremul_SkAlphaType);
+ }
+
+ /**
+ * Sets colortype to the native ARGB32 type, and the alphatype to premul.
+ */
+ static SkImageInfo MakeN32Premul(const SkISize& size) {
+ return MakeN32Premul(size.width(), size.height());
+ }
+
+ static SkImageInfo MakeA8(int width, int height) {
+ return SkImageInfo(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType);
+ }
+
+ static SkImageInfo MakeUnknown(int width, int height) {
+ return SkImageInfo(width, height, kUnknown_SkColorType, kIgnore_SkAlphaType);
+ }
+
+ static SkImageInfo MakeUnknown() {
+ return SkImageInfo();
+ }
+
+ int width() const { return fWidth; }
+ int height() const { return fHeight; }
+ SkColorType colorType() const { return fColorType; }
+ SkAlphaType alphaType() const { return fAlphaType; }
+
+ bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
+
+ bool isOpaque() const {
+ return SkAlphaTypeIsOpaque(fAlphaType);
+ }
+
+ SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
+
+ /**
+ * Return a new ImageInfo with the same colortype and alphatype as this info,
+ * but with the specified width and height.
+ */
+ SkImageInfo makeWH(int newWidth, int newHeight) const {
+ return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType);
+ }
+
+ SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
+ return SkImageInfo::Make(fWidth, fHeight, fColorType, newAlphaType);
+ }
+
+ SkImageInfo makeColorType(SkColorType newColorType) const {
+ return SkImageInfo::Make(fWidth, fHeight, newColorType, fAlphaType);
+ }
+
+ int bytesPerPixel() const {
+ return SkColorTypeBytesPerPixel(fColorType);
+ }
+
+ uint64_t minRowBytes64() const {
+ return sk_64_mul(fWidth, this->bytesPerPixel());
+ }
+
+ size_t minRowBytes() const {
+ return (size_t)this->minRowBytes64();
+ }
+
+ bool operator==(const SkImageInfo& other) const {
+ return 0 == memcmp(this, &other, sizeof(other));
+ }
+ bool operator!=(const SkImageInfo& other) const {
+ return 0 != memcmp(this, &other, sizeof(other));
+ }
+
+ void unflatten(SkReadBuffer&);
+ void flatten(SkWriteBuffer&) const;
+
+ int64_t getSafeSize64(size_t rowBytes) const {
+ if (0 == fHeight) {
+ return 0;
+ }
+ return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
+ }
+
+ size_t getSafeSize(size_t rowBytes) const {
+ return (size_t)this->getSafeSize64(rowBytes);
+ }
+
+ bool validRowBytes(size_t rowBytes) const {
+ uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel());
+ return rowBytes >= rb;
+ }
+
+ SkDEBUGCODE(void validate() const;)
+
+#ifdef SK_SUPPORT_LEGACY_PUBLIC_IMAGEINFO_FIELDS
+public:
+#else
+private:
+#endif
+ int fWidth;
+ int fHeight;
+ SkColorType fColorType;
+ SkAlphaType fAlphaType;
+
+private:
+ SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at)
+ : fWidth(width)
+ , fHeight(height)
+ , fColorType(ct)
+ , fAlphaType(at)
+ {}
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkInstCnt.h b/src/third_party/skia/include/core/SkInstCnt.h
new file mode 100644
index 0000000..e4b43d1
--- /dev/null
+++ b/src/third_party/skia/include/core/SkInstCnt.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkInstCnt_DEFINED
+#define SkInstCnt_DEFINED
+
+/*
+ * The instance counting system consists of three macros that create the
+ * instance counting machinery. A class is added to the system by adding:
+ * SK_DECLARE_INST_COUNT at the top of its declaration for derived classes
+ * SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class
+ * At the end of an application a call to all the "root" objects'
+ * CheckInstanceCount methods should be made
+ */
+#include "SkTypes.h"
+
+#if SK_ENABLE_INST_COUNT
+// Static variables inside member functions below may be defined multiple times
+// if Skia is being used as a dynamic library. Instance counting should be on
+// only for static builds. See bug skia:2058.
+#if defined(SKIA_DLL)
+#error Instance counting works only when Skia is built as a static library.
+#endif
+
+#include "SkOnce.h"
+#include "SkTArray.h"
+#include "SkThread.h"
+extern bool gPrintInstCount;
+
+// The non-root classes just register themselves with their parent
+#define SK_DECLARE_INST_COUNT(className) \
+ SK_DECLARE_INST_COUNT_INTERNAL(className, \
+ INHERITED::AddInstChild(CheckInstanceCount);)
+
+// The root classes registers a function to print out the memory stats when
+// the app ends
+#define SK_DECLARE_INST_COUNT_ROOT(className) \
+ SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);)
+
+#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \
+ class SkInstanceCountHelper { \
+ public: \
+ SkInstanceCountHelper() { \
+ SK_DECLARE_STATIC_ONCE(once); \
+ SkOnce(&once, init); \
+ sk_atomic_inc(GetInstanceCountPtr()); \
+ } \
+ \
+ static void init() { \
+ initStep \
+ } \
+ \
+ SkInstanceCountHelper(const SkInstanceCountHelper&) { \
+ sk_atomic_inc(GetInstanceCountPtr()); \
+ } \
+ \
+ ~SkInstanceCountHelper() { \
+ sk_atomic_dec(GetInstanceCountPtr()); \
+ } \
+ \
+ static int32_t* GetInstanceCountPtr() { \
+ static int32_t gInstanceCount; \
+ return &gInstanceCount; \
+ } \
+ \
+ static SkTArray<int (*)(int, bool)>*& GetChildren() { \
+ static SkTArray<int (*)(int, bool)>* gChildren; \
+ return gChildren; \
+ } \
+ \
+ static void create_mutex(SkMutex** mutex) { \
+ *mutex = SkNEW(SkMutex); \
+ } \
+ static SkBaseMutex& GetChildrenMutex() { \
+ static SkMutex* childrenMutex; \
+ SK_DECLARE_STATIC_ONCE(once); \
+ SkOnce(&once, className::SkInstanceCountHelper::create_mutex, &childrenMutex);\
+ return *childrenMutex; \
+ } \
+ \
+ } fInstanceCountHelper; \
+ \
+ static int32_t GetInstanceCount() { \
+ return *SkInstanceCountHelper::GetInstanceCountPtr(); \
+ } \
+ \
+ static void exitPrint() { \
+ CheckInstanceCount(0, true); \
+ } \
+ \
+ static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \
+ if (gPrintInstCount && 0 != GetInstanceCount()) { \
+ SkDebugf("%*c Leaked %s: %d\n", \
+ 4*level, ' ', #className, \
+ GetInstanceCount()); \
+ } \
+ if (NULL == SkInstanceCountHelper::GetChildren()) { \
+ return GetInstanceCount(); \
+ } \
+ SkTArray<int (*)(int, bool)>* children = \
+ SkInstanceCountHelper::GetChildren(); \
+ int childCount = children->count(); \
+ int count = GetInstanceCount(); \
+ for (int i = 0; i < childCount; ++i) { \
+ count -= (*(*children)[i])(level+1, cleanUp); \
+ } \
+ SkASSERT(count >= 0); \
+ if (gPrintInstCount && childCount > 0 && count > 0) { \
+ SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \
+ } \
+ if (cleanUp) { \
+ delete children; \
+ SkInstanceCountHelper::GetChildren() = NULL; \
+ } \
+ return GetInstanceCount(); \
+ } \
+ \
+ static void AddInstChild(int (*childCheckInstCnt)(int, bool)) { \
+ if (CheckInstanceCount != childCheckInstCnt) { \
+ SkAutoMutexAcquire ama(SkInstanceCountHelper::GetChildrenMutex()); \
+ if (NULL == SkInstanceCountHelper::GetChildren()) { \
+ SkInstanceCountHelper::GetChildren() = \
+ new SkTArray<int (*)(int, bool)>; \
+ } \
+ SkInstanceCountHelper::GetChildren()->push_back(childCheckInstCnt); \
+ } \
+ }
+
+#else
+// Typically SK_ENABLE_INST_COUNT=0. Make sure the class declares public typedef INHERITED by
+// causing a compile-time error if the typedef is missing. This way SK_ENABLE_INST_COUNT=1 stays
+// compiling.
+#define SK_DECLARE_INST_COUNT(className) static void AddInstChild() { INHERITED::AddInstChild(); }
+#define SK_DECLARE_INST_COUNT_ROOT(className) static void AddInstChild() { }
+#endif
+
+// Following are deprecated. They are defined only for backwards API compatibility.
+#define SK_DECLARE_INST_COUNT_TEMPLATE(className) SK_DECLARE_INST_COUNT(className)
+#define SK_DEFINE_INST_COUNT(className)
+#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className)
+
+#endif // SkInstCnt_DEFINED
diff --git a/src/third_party/skia/include/core/SkMallocPixelRef.h b/src/third_party/skia/include/core/SkMallocPixelRef.h
new file mode 100644
index 0000000..63ed19a
--- /dev/null
+++ b/src/third_party/skia/include/core/SkMallocPixelRef.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMallocPixelRef_DEFINED
+#define SkMallocPixelRef_DEFINED
+
+#include "SkPixelRef.h"
+
+/** We explicitly use the same allocator for our pixels that SkMask does,
+ so that we can freely assign memory allocated by one class to the other.
+*/
+class SK_API SkMallocPixelRef : public SkPixelRef {
+public:
+ SK_DECLARE_INST_COUNT(SkMallocPixelRef)
+ /**
+ * Return a new SkMallocPixelRef with the provided pixel storage, rowBytes,
+ * and optional colortable. The caller is responsible for managing the
+ * lifetime of the pixel storage buffer, as this pixelref will not try
+ * to delete it.
+ *
+ * The pixelref will ref() the colortable (if not NULL).
+ *
+ * Returns NULL on failure.
+ */
+ static SkMallocPixelRef* NewDirect(const SkImageInfo&, void* addr,
+ size_t rowBytes, SkColorTable*);
+
+ /**
+ * Return a new SkMallocPixelRef, automatically allocating storage for the
+ * pixels. If rowBytes are 0, an optimal value will be chosen automatically.
+ * If rowBytes is > 0, then it will be respected, or NULL will be returned
+ * if rowBytes is invalid for the specified info.
+ *
+ * This pixelref will ref() the specified colortable (if not NULL).
+ *
+ * Returns NULL on failure.
+ */
+ static SkMallocPixelRef* NewAllocate(const SkImageInfo& info,
+ size_t rowBytes, SkColorTable*);
+
+ /**
+ * Return a new SkMallocPixelRef with the provided pixel storage,
+ * rowBytes, and optional colortable. On destruction, ReleaseProc
+ * will be called.
+ *
+ * This pixelref will ref() the specified colortable (if not NULL).
+ *
+ * Returns NULL on failure.
+ */
+ typedef void (*ReleaseProc)(void* addr, void* context);
+ static SkMallocPixelRef* NewWithProc(const SkImageInfo& info,
+ size_t rowBytes, SkColorTable*,
+ void* addr, ReleaseProc proc,
+ void* context);
+
+ /**
+ * Return a new SkMallocPixelRef that will use the provided
+ * SkData, rowBytes, and optional colortable as pixel storage.
+ * The SkData will be ref()ed and on destruction of the PielRef,
+ * the SkData will be unref()ed.
+ *
+ * This pixelref will ref() the specified colortable (if not NULL).
+ *
+ * Returns NULL on failure.
+ */
+ static SkMallocPixelRef* NewWithData(const SkImageInfo& info,
+ size_t rowBytes,
+ SkColorTable* ctable,
+ SkData* data);
+
+ void* getAddr() const { return fStorage; }
+
+ class PRFactory : public SkPixelRefFactory {
+ public:
+ virtual SkPixelRef* create(const SkImageInfo&,
+ size_t rowBytes,
+ SkColorTable*) SK_OVERRIDE;
+ };
+
+protected:
+ // The ownPixels version of this constructor is deprecated.
+ SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
+ bool ownPixels);
+ virtual ~SkMallocPixelRef();
+
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+ virtual void onUnlockPixels() SK_OVERRIDE;
+ virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
+
+private:
+ void* fStorage;
+ SkColorTable* fCTable;
+ size_t fRB;
+ ReleaseProc fReleaseProc;
+ void* fReleaseProcContext;
+
+ SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
+ ReleaseProc proc, void* context);
+
+ typedef SkPixelRef INHERITED;
+};
+
+
+#endif
diff --git a/src/third_party/skia/include/core/SkMask.h b/src/third_party/skia/include/core/SkMask.h
new file mode 100644
index 0000000..5cfef97
--- /dev/null
+++ b/src/third_party/skia/include/core/SkMask.h
@@ -0,0 +1,162 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMask_DEFINED
+#define SkMask_DEFINED
+
+#include "SkRect.h"
+
+/** \class SkMask
+ SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
+ the 3-channel 3D format. These are passed to SkMaskFilter objects.
+*/
+struct SkMask {
+ enum Format {
+ kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
+ kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
+ k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
+ kARGB32_Format, //!< SkPMColor
+ kLCD16_Format, //!< 565 alpha for r/g/b
+ kLCD32_Format //!< 888 alpha for r/g/b
+ };
+
+ enum {
+ kCountMaskFormats = kLCD32_Format + 1
+ };
+
+ uint8_t* fImage;
+ SkIRect fBounds;
+ uint32_t fRowBytes;
+ Format fFormat;
+
+ /** Returns true if the mask is empty: i.e. it has an empty bounds.
+ */
+ bool isEmpty() const { return fBounds.isEmpty(); }
+
+ /** Return the byte size of the mask, assuming only 1 plane.
+ Does not account for k3D_Format. For that, use computeTotalImageSize().
+ If there is an overflow of 32bits, then returns 0.
+ */
+ size_t computeImageSize() const;
+
+ /** Return the byte size of the mask, taking into account
+ any extra planes (e.g. k3D_Format).
+ If there is an overflow of 32bits, then returns 0.
+ */
+ size_t computeTotalImageSize() const;
+
+ /** Returns the address of the byte that holds the specified bit.
+ Asserts that the mask is kBW_Format, and that x,y are in range.
+ x,y are in the same coordiate space as fBounds.
+ */
+ uint8_t* getAddr1(int x, int y) const {
+ SkASSERT(kBW_Format == fFormat);
+ SkASSERT(fBounds.contains(x, y));
+ SkASSERT(fImage != NULL);
+ return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
+ }
+
+ /** Returns the address of the specified byte.
+ Asserts that the mask is kA8_Format, and that x,y are in range.
+ x,y are in the same coordiate space as fBounds.
+ */
+ uint8_t* getAddr8(int x, int y) const {
+ SkASSERT(kA8_Format == fFormat);
+ SkASSERT(fBounds.contains(x, y));
+ SkASSERT(fImage != NULL);
+ return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
+ }
+
+ /**
+ * Return the address of the specified 16bit mask. In the debug build,
+ * this asserts that the mask's format is kLCD16_Format, and that (x,y)
+ * are contained in the mask's fBounds.
+ */
+ uint16_t* getAddrLCD16(int x, int y) const {
+ SkASSERT(kLCD16_Format == fFormat);
+ SkASSERT(fBounds.contains(x, y));
+ SkASSERT(fImage != NULL);
+ uint16_t* row = (uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
+ return row + (x - fBounds.fLeft);
+ }
+
+ /**
+ * Return the address of the specified 32bit mask. In the debug build,
+ * this asserts that the mask's format is kLCD32_Format, and that (x,y)
+ * are contained in the mask's fBounds.
+ */
+ uint32_t* getAddrLCD32(int x, int y) const {
+ SkASSERT(kLCD32_Format == fFormat);
+ SkASSERT(fBounds.contains(x, y));
+ SkASSERT(fImage != NULL);
+ uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
+ return row + (x - fBounds.fLeft);
+ }
+
+ /**
+ * Return the address of the specified 32bit mask. In the debug build,
+ * this asserts that the mask's format is 32bits, and that (x,y)
+ * are contained in the mask's fBounds.
+ */
+ uint32_t* getAddr32(int x, int y) const {
+ SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat);
+ SkASSERT(fBounds.contains(x, y));
+ SkASSERT(fImage != NULL);
+ uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
+ return row + (x - fBounds.fLeft);
+ }
+
+ /**
+ * Returns the address of the specified pixel, computing the pixel-size
+ * at runtime based on the mask format. This will be slightly slower than
+ * using one of the routines where the format is implied by the name
+ * e.g. getAddr8 or getAddrLCD32.
+ *
+ * x,y must be contained by the mask's bounds (this is asserted in the
+ * debug build, but not checked in the release build.)
+ *
+ * This should not be called with kBW_Format, as it will give unspecified
+ * results (and assert in the debug build).
+ */
+ void* getAddr(int x, int y) const;
+
+ static uint8_t* AllocImage(size_t bytes);
+ static void FreeImage(void* image);
+
+ enum CreateMode {
+ kJustComputeBounds_CreateMode, //!< compute bounds and return
+ kJustRenderImage_CreateMode, //!< render into preallocate mask
+ kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * \class SkAutoMaskImage
+ *
+ * Stack class used to manage the fImage buffer in a SkMask.
+ * When this object loses scope, the buffer is freed with SkMask::FreeImage().
+ */
+class SkAutoMaskFreeImage {
+public:
+ SkAutoMaskFreeImage(uint8_t* maskImage) {
+ fImage = maskImage;
+ }
+
+ ~SkAutoMaskFreeImage() {
+ SkMask::FreeImage(fImage);
+ }
+
+private:
+ uint8_t* fImage;
+};
+#define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkMaskFilter.h b/src/third_party/skia/include/core/SkMaskFilter.h
new file mode 100644
index 0000000..026ef40
--- /dev/null
+++ b/src/third_party/skia/include/core/SkMaskFilter.h
@@ -0,0 +1,220 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMaskFilter_DEFINED
+#define SkMaskFilter_DEFINED
+
+#include "SkBlurTypes.h"
+#include "SkFlattenable.h"
+#include "SkMask.h"
+#include "SkPaint.h"
+
+class GrContext;
+class GrPaint;
+class SkBitmap;
+class SkBlitter;
+class SkMatrix;
+class SkPath;
+class SkRasterClip;
+class SkRRect;
+class SkStrokeRec;
+
+/** \class SkMaskFilter
+
+ SkMaskFilter is the base class for object that perform transformations on
+ an alpha-channel mask before drawing it. A subclass of SkMaskFilter may be
+ installed into a SkPaint. Once there, each time a primitive is drawn, it
+ is first scan converted into a SkMask::kA8_Format mask, and handed to the
+ filter, calling its filterMask() method. If this returns true, then the
+ new mask is used to render into the device.
+
+ Blur and emboss are implemented as subclasses of SkMaskFilter.
+*/
+class SK_API SkMaskFilter : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkMaskFilter)
+
+ /** Returns the format of the resulting mask that this subclass will return
+ when its filterMask() method is called.
+ */
+ virtual SkMask::Format getFormat() const = 0;
+
+ /** Create a new mask by filter the src mask.
+ If src.fImage == null, then do not allocate or create the dst image
+ but do fill out the other fields in dstMask.
+ If you do allocate a dst image, use SkMask::AllocImage()
+ If this returns false, dst mask is ignored.
+ @param dst the result of the filter. If src.fImage == null, dst should not allocate its image
+ @param src the original image to be filtered.
+ @param matrix the CTM
+ @param margin if not null, return the buffer dx/dy need when calculating the effect. Used when
+ drawing a clipped object to know how much larger to allocate the src before
+ applying the filter. If returning false, ignore this parameter.
+ @return true if the dst mask was correctly created.
+ */
+ virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
+ SkIPoint* margin) const;
+
+#if SK_SUPPORT_GPU
+ /**
+ * Returns true if the filter can be expressed a single-pass GrProcessor without requiring an
+ * explicit input mask. Per-pixel, the effect receives the incoming mask's coverage as
+ * the input color and outputs the filtered covereage value. This means that each pixel's
+ * filtered coverage must only depend on the unfiltered mask value for that pixel and not on
+ * surrounding values.
+ *
+ * If effect is non-NULL, a new GrProcessor instance is stored in it. The caller assumes
+ * ownership of the effect and must unref it.
+ */
+ virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix& ctm) const;
+
+ /**
+ * If asFragmentProcessor() fails the filter may be implemented on the GPU by a subclass
+ * overriding filterMaskGPU (declared below). That code path requires constructing a src mask
+ * as input. Since that is a potentially expensive operation, the subclass must also override
+ * this function to indicate whether filterTextureMaskGPU would succeeed if the mask were to be
+ * created.
+ *
+ * 'maskRect' returns the device space portion of the mask that the filter needs. The mask
+ * passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be translated
+ * to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop) appears at
+ * (0, 0) in the mask).
+ */
+ virtual bool canFilterMaskGPU(const SkRect& devBounds,
+ const SkIRect& clipBounds,
+ const SkMatrix& ctm,
+ SkRect* maskRect) const;
+
+ /**
+ * Try to directly render the mask filter into the target. Returns
+ * true if drawing was successful.
+ */
+ virtual bool directFilterMaskGPU(GrContext* context,
+ GrPaint* grp,
+ const SkStrokeRec& strokeRec,
+ const SkPath& path) const;
+ /**
+ * Try to directly render a rounded rect mask filter into the target. Returns
+ * true if drawing was successful.
+ */
+ virtual bool directFilterRRectMaskGPU(GrContext* context,
+ GrPaint* grp,
+ const SkStrokeRec& strokeRec,
+ const SkRRect& rrect) const;
+
+ /**
+ * This function is used to implement filters that require an explicit src mask. It should only
+ * be called if canFilterMaskGPU returned true and the maskRect param should be the output from
+ * that call. canOverwriteSrc indicates whether the implementation may treat src as a scratch
+ * texture and overwrite its contents. When true it is also legal to return src as the result.
+ * Implementations are free to get the GrContext from the src texture in order to create
+ * additional textures and perform multiple passes.
+ */
+ virtual bool filterMaskGPU(GrTexture* src,
+ const SkMatrix& ctm,
+ const SkRect& maskRect,
+ GrTexture** result,
+ bool canOverwriteSrc) const;
+#endif
+
+ /**
+ * The fast bounds function is used to enable the paint to be culled early
+ * in the drawing pipeline. This function accepts the current bounds of the
+ * paint as its src param and the filter adjust those bounds using its
+ * current mask and returns the result using the dest param. Callers are
+ * allowed to provide the same struct for both src and dest so each
+ * implementation must accomodate that behavior.
+ *
+ * The default impl calls filterMask with the src mask having no image,
+ * but subclasses may override this if they can compute the rect faster.
+ */
+ virtual void computeFastBounds(const SkRect& src, SkRect* dest) const;
+
+ struct BlurRec {
+ SkScalar fSigma;
+ SkBlurStyle fStyle;
+ SkBlurQuality fQuality;
+ };
+ /**
+ * If this filter can be represented by a BlurRec, return true and (if not null) fill in the
+ * provided BlurRec parameter. If this effect cannot be represented as a BlurRec, return false
+ * and ignore the BlurRec parameter.
+ */
+ virtual bool asABlur(BlurRec*) const;
+
+ SK_TO_STRING_PUREVIRT()
+ SK_DEFINE_FLATTENABLE_TYPE(SkMaskFilter)
+
+protected:
+ SkMaskFilter() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ // empty for now, but lets get our subclass to remember to init us for the future
+ SkMaskFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+ enum FilterReturn {
+ kFalse_FilterReturn,
+ kTrue_FilterReturn,
+ kUnimplemented_FilterReturn
+ };
+
+ struct NinePatch {
+ SkMask fMask; // fBounds must have [0,0] in its top-left
+ SkIRect fOuterRect; // width/height must be >= fMask.fBounds'
+ SkIPoint fCenter; // identifies center row/col for stretching
+ };
+
+ /**
+ * Override if your subclass can filter a rect, and return the answer as
+ * a ninepatch mask to be stretched over the returned outerRect. On success
+ * return kTrue_FilterReturn. On failure (e.g. out of memory) return
+ * kFalse_FilterReturn. If the normal filterMask() entry-point should be
+ * called (the default) return kUnimplemented_FilterReturn.
+ *
+ * By convention, the caller will take the center rol/col from the returned
+ * mask as the slice it can replicate horizontally and vertically as we
+ * stretch the mask to fit inside outerRect. It is an error for outerRect
+ * to be smaller than the mask's bounds. This would imply that the width
+ * and height of the mask should be odd. This is not required, just that
+ * the caller will call mask.fBounds.centerX() and centerY() to find the
+ * strips that will be replicated.
+ */
+ virtual FilterReturn filterRectsToNine(const SkRect[], int count,
+ const SkMatrix&,
+ const SkIRect& clipBounds,
+ NinePatch*) const;
+ /**
+ * Similar to filterRectsToNine, except it performs the work on a round rect.
+ */
+ virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&,
+ const SkIRect& clipBounds,
+ NinePatch*) const;
+
+private:
+ friend class SkDraw;
+
+ /** Helper method that, given a path in device space, will rasterize it into a kA8_Format mask
+ and then call filterMask(). If this returns true, the specified blitter will be called
+ to render that mask. Returns false if filterMask() returned false.
+ This method is not exported to java.
+ */
+ bool filterPath(const SkPath& devPath, const SkMatrix& ctm, const SkRasterClip&, SkBlitter*,
+ SkPaint::Style) const;
+
+ /** Helper method that, given a roundRect in device space, will rasterize it into a kA8_Format
+ mask and then call filterMask(). If this returns true, the specified blitter will be called
+ to render that mask. Returns false if filterMask() returned false.
+ */
+ bool filterRRect(const SkRRect& devRRect, const SkMatrix& ctm, const SkRasterClip&,
+ SkBlitter*, SkPaint::Style style) const;
+
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkMath.h b/src/third_party/skia/include/core/SkMath.h
new file mode 100644
index 0000000..014f014
--- /dev/null
+++ b/src/third_party/skia/include/core/SkMath.h
@@ -0,0 +1,229 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMath_DEFINED
+#define SkMath_DEFINED
+
+#include "SkTypes.h"
+
+// 64bit -> 32bit utilities
+
+/**
+ * Return true iff the 64bit value can exactly be represented in signed 32bits
+ */
+static inline bool sk_64_isS32(int64_t value) {
+ return (int32_t)value == value;
+}
+
+/**
+ * Return the 64bit argument as signed 32bits, asserting in debug that the arg
+ * exactly fits in signed 32bits. In the release build, no checks are preformed
+ * and the return value if the arg does not fit is undefined.
+ */
+static inline int32_t sk_64_asS32(int64_t value) {
+ SkASSERT(sk_64_isS32(value));
+ return (int32_t)value;
+}
+
+// Handy util that can be passed two ints, and will automatically promote to
+// 64bits before the multiply, so the caller doesn't have to remember to cast
+// e.g. (int64_t)a * b;
+static inline int64_t sk_64_mul(int64_t a, int64_t b) {
+ return a * b;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Computes numer1 * numer2 / denom in full 64 intermediate precision.
+ * It is an error for denom to be 0. There is no special handling if
+ * the result overflows 32bits.
+ */
+static inline int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) {
+ SkASSERT(denom);
+
+ int64_t tmp = sk_64_mul(numer1, numer2) / denom;
+ return sk_64_asS32(tmp);
+}
+
+/**
+ * Computes (numer1 << shift) / denom in full 64 intermediate precision.
+ * It is an error for denom to be 0. There is no special handling if
+ * the result overflows 32bits.
+ */
+int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
+
+/**
+ * Return the integer square root of value, with a bias of bitBias
+ */
+int32_t SkSqrtBits(int32_t value, int bitBias);
+
+/** Return the integer square root of n, treated as a SkFixed (16.16)
+ */
+#define SkSqrt32(n) SkSqrtBits(n, 15)
+
+//! Returns the number of leading zero bits (0...32)
+int SkCLZ_portable(uint32_t);
+
+#ifndef SkCLZ
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
+ #include <intrin.h>
+
+ static inline int SkCLZ(uint32_t mask) {
+ if (mask) {
+ DWORD index;
+ _BitScanReverse(&index, mask);
+ return index ^ 0x1F;
+ } else {
+ return 32;
+ }
+ }
+ #elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__)
+ static inline int SkCLZ(uint32_t mask) {
+ // __builtin_clz(0) is undefined, so we have to detect that case.
+ return mask ? __builtin_clz(mask) : 32;
+ }
+ #else
+ #define SkCLZ(x) SkCLZ_portable(x)
+ #endif
+#endif
+
+/**
+ * Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
+ */
+static inline int SkClampPos(int value) {
+ return value & ~(value >> 31);
+}
+
+/** Given an integer and a positive (max) integer, return the value
+ * pinned against 0 and max, inclusive.
+ * @param value The value we want returned pinned between [0...max]
+ * @param max The positive max value
+ * @return 0 if value < 0, max if value > max, else value
+ */
+static inline int SkClampMax(int value, int max) {
+ // ensure that max is positive
+ SkASSERT(max >= 0);
+ if (value < 0) {
+ value = 0;
+ }
+ if (value > max) {
+ value = max;
+ }
+ return value;
+}
+
+/**
+ * Returns the smallest power-of-2 that is >= the specified value. If value
+ * is already a power of 2, then it is returned unchanged. It is undefined
+ * if value is <= 0.
+ */
+static inline int SkNextPow2(int value) {
+ SkASSERT(value > 0);
+ return 1 << (32 - SkCLZ(value - 1));
+}
+
+/**
+ * Returns the log2 of the specified value, were that value to be rounded up
+ * to the next power of 2. It is undefined to pass 0. Examples:
+ * SkNextLog2(1) -> 0
+ * SkNextLog2(2) -> 1
+ * SkNextLog2(3) -> 2
+ * SkNextLog2(4) -> 2
+ * SkNextLog2(5) -> 3
+ */
+static inline int SkNextLog2(uint32_t value) {
+ SkASSERT(value != 0);
+ return 32 - SkCLZ(value - 1);
+}
+
+/**
+ * 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.
+ * With this requirement, we can generate faster instructions on some
+ * architectures.
+ */
+#ifdef SK_ARM_HAS_EDSP
+ static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
+ SkASSERT((int16_t)x == x);
+ SkASSERT((int16_t)y == y);
+ int32_t product;
+ asm("smulbb %0, %1, %2 \n"
+ : "=r"(product)
+ : "r"(x), "r"(y)
+ );
+ return product;
+ }
+#else
+ #ifdef SK_DEBUG
+ static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
+ SkASSERT((int16_t)x == x);
+ SkASSERT((int16_t)y == y);
+ return x * y;
+ }
+ #else
+ #define SkMulS16(x, y) ((x) * (y))
+ #endif
+#endif
+
+/**
+ * Return a*b/((1 << shift) - 1), rounding any fractional bits.
+ * Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
+ */
+static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) {
+ SkASSERT(a <= 32767);
+ SkASSERT(b <= 32767);
+ SkASSERT(shift > 0 && shift <= 8);
+ unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
+ return (prod + (prod >> shift)) >> shift;
+}
+
+/**
+ * Return a*b/255, rounding any fractional bits.
+ * Only valid if a and b are unsigned and <= 32767.
+ */
+static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
+ SkASSERT(a <= 32767);
+ SkASSERT(b <= 32767);
+ unsigned prod = SkMulS16(a, b) + 128;
+ return (prod + (prod >> 8)) >> 8;
+}
+
+/**
+ * Stores numer/denom and numer%denom into div and mod respectively.
+ */
+template <typename In, typename Out>
+inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) {
+#ifdef SK_CPU_ARM32
+ // If we wrote this as in the else branch, GCC won't fuse the two into one
+ // divmod call, but rather a div call followed by a divmod. Silly! This
+ // version is just as fast as calling __aeabi_[u]idivmod manually, but with
+ // prettier code.
+ //
+ // This benches as around 2x faster than the code in the else branch.
+ const In d = numer/denom;
+ *div = static_cast<Out>(d);
+ *mod = static_cast<Out>(numer-d*denom);
+#else
+ // On x86 this will just be a single idiv.
+ *div = static_cast<Out>(numer/denom);
+ *mod = static_cast<Out>(numer%denom);
+#endif
+}
+
+#endif
diff --git a/src/third_party/skia/include/core/SkMatrix.h b/src/third_party/skia/include/core/SkMatrix.h
new file mode 100644
index 0000000..a65cd19
--- /dev/null
+++ b/src/third_party/skia/include/core/SkMatrix.h
@@ -0,0 +1,724 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMatrix_DEFINED
+#define SkMatrix_DEFINED
+
+#include "SkDynamicAnnotations.h"
+#include "SkRect.h"
+
+class SkString;
+
+// TODO: can we remove these 3 (need to check chrome/android)
+typedef SkScalar SkPersp;
+#define SkScalarToPersp(x) (x)
+#define SkPerspToScalar(x) (x)
+
+/** \class SkMatrix
+
+ The SkMatrix class holds a 3x3 matrix for transforming coordinates.
+ SkMatrix does not have a constructor, so it must be explicitly initialized
+ using either reset() - to construct an identity matrix, or one of the set
+ functions (e.g. setTranslate, setRotate, etc.).
+*/
+class SK_API SkMatrix {
+public:
+ /** Enum of bit fields for the mask return by getType().
+ Use this to identify the complexity of the matrix.
+ */
+ enum TypeMask {
+ kIdentity_Mask = 0,
+ kTranslate_Mask = 0x01, //!< set if the matrix has translation
+ kScale_Mask = 0x02, //!< set if the matrix has X or Y scale
+ kAffine_Mask = 0x04, //!< set if the matrix skews or rotates
+ kPerspective_Mask = 0x08 //!< set if the matrix is in perspective
+ };
+
+ /** Returns a bitfield describing the transformations the matrix may
+ perform. The bitfield is computed conservatively, so it may include
+ false positives. For example, when kPerspective_Mask is true, all
+ other bits may be set to true even in the case of a pure perspective
+ transform.
+ */
+ TypeMask getType() const {
+ if (fTypeMask & kUnknown_Mask) {
+ fTypeMask = this->computeTypeMask();
+ }
+ // only return the public masks
+ return (TypeMask)(fTypeMask & 0xF);
+ }
+
+ /** Returns true if the matrix is identity.
+ */
+ bool isIdentity() const {
+ return this->getType() == 0;
+ }
+
+ bool isScaleTranslate() const {
+ return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
+ }
+
+ /** Returns true if will map a rectangle to another rectangle. This can be
+ true if the matrix is identity, scale-only, or rotates a multiple of
+ 90 degrees.
+ */
+ bool rectStaysRect() const {
+ if (fTypeMask & kUnknown_Mask) {
+ fTypeMask = this->computeTypeMask();
+ }
+ return (fTypeMask & kRectStaysRect_Mask) != 0;
+ }
+ // alias for rectStaysRect()
+ bool preservesAxisAlignment() const { return this->rectStaysRect(); }
+
+ /**
+ * Returns true if the matrix contains perspective elements.
+ */
+ bool hasPerspective() const {
+ return SkToBool(this->getPerspectiveTypeMaskOnly() &
+ kPerspective_Mask);
+ }
+
+ /** Returns true if the matrix contains only translation, rotation/reflection or uniform scale
+ Returns false if other transformation types are included or is degenerate
+ */
+ bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const;
+
+ /** Returns true if the matrix contains only translation, rotation/reflection or scale
+ (non-uniform scale is allowed).
+ Returns false if other transformation types are included or is degenerate
+ */
+ bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const;
+
+ enum {
+ kMScaleX,
+ kMSkewX,
+ kMTransX,
+ kMSkewY,
+ kMScaleY,
+ kMTransY,
+ kMPersp0,
+ kMPersp1,
+ kMPersp2
+ };
+
+ /** Affine arrays are in column major order
+ because that's how PDF and XPS like it.
+ */
+ enum {
+ kAScaleX,
+ kASkewY,
+ kASkewX,
+ kAScaleY,
+ kATransX,
+ kATransY
+ };
+
+ SkScalar operator[](int index) const {
+ SkASSERT((unsigned)index < 9);
+ return fMat[index];
+ }
+
+ SkScalar get(int index) const {
+ SkASSERT((unsigned)index < 9);
+ return fMat[index];
+ }
+
+ SkScalar getScaleX() const { return fMat[kMScaleX]; }
+ SkScalar getScaleY() const { return fMat[kMScaleY]; }
+ SkScalar getSkewY() const { return fMat[kMSkewY]; }
+ SkScalar getSkewX() const { return fMat[kMSkewX]; }
+ SkScalar getTranslateX() const { return fMat[kMTransX]; }
+ SkScalar getTranslateY() const { return fMat[kMTransY]; }
+ SkPersp getPerspX() const { return fMat[kMPersp0]; }
+ SkPersp getPerspY() const { return fMat[kMPersp1]; }
+
+ SkScalar& operator[](int index) {
+ SkASSERT((unsigned)index < 9);
+ this->setTypeMask(kUnknown_Mask);
+ return fMat[index];
+ }
+
+ void set(int index, SkScalar value) {
+ SkASSERT((unsigned)index < 9);
+ fMat[index] = value;
+ this->setTypeMask(kUnknown_Mask);
+ }
+
+ void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
+ void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
+ void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
+ void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
+ void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
+ void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
+ void setPerspX(SkPersp v) { this->set(kMPersp0, v); }
+ void setPerspY(SkPersp v) { this->set(kMPersp1, v); }
+
+ void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
+ SkScalar skewY, SkScalar scaleY, SkScalar transY,
+ SkPersp persp0, SkPersp persp1, SkPersp persp2) {
+ fMat[kMScaleX] = scaleX;
+ fMat[kMSkewX] = skewX;
+ fMat[kMTransX] = transX;
+ fMat[kMSkewY] = skewY;
+ fMat[kMScaleY] = scaleY;
+ fMat[kMTransY] = transY;
+ fMat[kMPersp0] = persp0;
+ fMat[kMPersp1] = persp1;
+ fMat[kMPersp2] = persp2;
+ this->setTypeMask(kUnknown_Mask);
+ }
+
+ /** Set the matrix to identity
+ */
+ void reset();
+ // alias for reset()
+ void setIdentity() { this->reset(); }
+
+ /** Set the matrix to translate by (dx, dy).
+ */
+ void setTranslate(SkScalar dx, SkScalar dy);
+ void setTranslate(const SkVector& v) { this->setTranslate(v.fX, v.fY); }
+
+ /** Set the matrix to scale by sx and sy, with a pivot point at (px, py).
+ The pivot point is the coordinate that should remain unchanged by the
+ specified transformation.
+ */
+ void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Set the matrix to scale by sx and sy.
+ */
+ void setScale(SkScalar sx, SkScalar sy);
+ /** Set the matrix to scale by 1/divx and 1/divy. Returns false and doesn't
+ touch the matrix if either divx or divy is zero.
+ */
+ bool setIDiv(int divx, int divy);
+ /** Set the matrix to rotate by the specified number of degrees, with a
+ pivot point at (px, py). The pivot point is the coordinate that should
+ remain unchanged by the specified transformation.
+ */
+ void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Set the matrix to rotate about (0,0) by the specified number of degrees.
+ */
+ void setRotate(SkScalar degrees);
+ /** Set the matrix to rotate by the specified sine and cosine values, with
+ a pivot point at (px, py). The pivot point is the coordinate that
+ should remain unchanged by the specified transformation.
+ */
+ void setSinCos(SkScalar sinValue, SkScalar cosValue,
+ SkScalar px, SkScalar py);
+ /** Set the matrix to rotate by the specified sine and cosine values.
+ */
+ void setSinCos(SkScalar sinValue, SkScalar cosValue);
+ /** Set the matrix to skew by sx and sy, with a pivot point at (px, py).
+ The pivot point is the coordinate that should remain unchanged by the
+ specified transformation.
+ */
+ void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Set the matrix to skew by sx and sy.
+ */
+ void setSkew(SkScalar kx, SkScalar ky);
+ /** Set the matrix to the concatenation of the two specified matrices.
+ Either of the two matrices may also be the target matrix.
+ *this = a * b;
+ */
+ void setConcat(const SkMatrix& a, const SkMatrix& b);
+
+ /** Preconcats the matrix with the specified translation.
+ M' = M * T(dx, dy)
+ */
+ void preTranslate(SkScalar dx, SkScalar dy);
+ /** Preconcats the matrix with the specified scale.
+ M' = M * S(sx, sy, px, py)
+ */
+ void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified scale.
+ M' = M * S(sx, sy)
+ */
+ void preScale(SkScalar sx, SkScalar sy);
+ /** Preconcats the matrix with the specified rotation.
+ M' = M * R(degrees, px, py)
+ */
+ void preRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified rotation.
+ M' = M * R(degrees)
+ */
+ void preRotate(SkScalar degrees);
+ /** Preconcats the matrix with the specified skew.
+ M' = M * K(kx, ky, px, py)
+ */
+ void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified skew.
+ M' = M * K(kx, ky)
+ */
+ void preSkew(SkScalar kx, SkScalar ky);
+ /** Preconcats the matrix with the specified matrix.
+ M' = M * other
+ */
+ void preConcat(const SkMatrix& other);
+
+ /** Postconcats the matrix with the specified translation.
+ M' = T(dx, dy) * M
+ */
+ void postTranslate(SkScalar dx, SkScalar dy);
+ /** Postconcats the matrix with the specified scale.
+ M' = S(sx, sy, px, py) * M
+ */
+ void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified scale.
+ M' = S(sx, sy) * M
+ */
+ void postScale(SkScalar sx, SkScalar sy);
+ /** Postconcats the matrix by dividing it by the specified integers.
+ M' = S(1/divx, 1/divy, 0, 0) * M
+ */
+ bool postIDiv(int divx, int divy);
+ /** Postconcats the matrix with the specified rotation.
+ M' = R(degrees, px, py) * M
+ */
+ void postRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified rotation.
+ M' = R(degrees) * M
+ */
+ void postRotate(SkScalar degrees);
+ /** Postconcats the matrix with the specified skew.
+ M' = K(kx, ky, px, py) * M
+ */
+ void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified skew.
+ M' = K(kx, ky) * M
+ */
+ void postSkew(SkScalar kx, SkScalar ky);
+ /** Postconcats the matrix with the specified matrix.
+ M' = other * M
+ */
+ void postConcat(const SkMatrix& other);
+
+ enum ScaleToFit {
+ /**
+ * Scale in X and Y independently, so that src matches dst exactly.
+ * This may change the aspect ratio of the src.
+ */
+ kFill_ScaleToFit,
+ /**
+ * Compute a scale that will maintain the original src aspect ratio,
+ * but will also ensure that src fits entirely inside dst. At least one
+ * axis (X or Y) will fit exactly. kStart aligns the result to the
+ * left and top edges of dst.
+ */
+ kStart_ScaleToFit,
+ /**
+ * Compute a scale that will maintain the original src aspect ratio,
+ * but will also ensure that src fits entirely inside dst. At least one
+ * axis (X or Y) will fit exactly. The result is centered inside dst.
+ */
+ kCenter_ScaleToFit,
+ /**
+ * Compute a scale that will maintain the original src aspect ratio,
+ * but will also ensure that src fits entirely inside dst. At least one
+ * axis (X or Y) will fit exactly. kEnd aligns the result to the
+ * right and bottom edges of dst.
+ */
+ kEnd_ScaleToFit
+ };
+
+ /** Set the matrix to the scale and translate values that map the source
+ rectangle to the destination rectangle, returning true if the the result
+ can be represented.
+ @param src the source rectangle to map from.
+ @param dst the destination rectangle to map to.
+ @param stf the ScaleToFit option
+ @return true if the matrix can be represented by the rectangle mapping.
+ */
+ bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf);
+
+ /** Set the matrix such that the specified src points would map to the
+ specified dst points. count must be within [0..4].
+ @param src The array of src points
+ @param dst The array of dst points
+ @param count The number of points to use for the transformation
+ @return true if the matrix was set to the specified transformation
+ */
+ bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count);
+
+ /** If this matrix can be inverted, return true and if inverse is not null,
+ set inverse to be the inverse of this matrix. If this matrix cannot be
+ inverted, ignore inverse and return false
+ */
+ bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const {
+ // Allow the trivial case to be inlined.
+ if (this->isIdentity()) {
+ if (inverse) {
+ inverse->reset();
+ }
+ return true;
+ }
+ return this->invertNonIdentity(inverse);
+ }
+
+ /** Fills the passed array with affine identity values
+ in column major order.
+ @param affine The array to fill with affine identity values.
+ Must not be NULL.
+ */
+ static void SetAffineIdentity(SkScalar affine[6]);
+
+ /** Fills the passed array with the affine values in column major order.
+ If the matrix is a perspective transform, returns false
+ and does not change the passed array.
+ @param affine The array to fill with affine values. Ignored if NULL.
+ */
+ bool asAffine(SkScalar affine[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[]
+ @param dst Where the transformed coordinates are written. It must
+ contain at least count entries
+ @param src The original coordinates that are to be transformed. It
+ must contain at least count entries
+ @param count The number of points in src to read, and then transform
+ into dst.
+ */
+ void mapPoints(SkPoint dst[], const SkPoint src[], int count) const;
+
+ /** Apply this matrix to the array of points, overwriting it with the
+ transformed values.
+ dst[] = M * pts[]
+ @param pts The points to be transformed. It must contain at least
+ count entries
+ @param count The number of points in pts.
+ */
+ void mapPoints(SkPoint pts[], int count) const {
+ this->mapPoints(pts, pts, count);
+ }
+
+ /** Like mapPoints but with custom byte stride between the points. Stride
+ * should be a multiple of sizeof(SkScalar).
+ */
+ void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const {
+ SkASSERT(stride >= sizeof(SkPoint));
+ SkASSERT(0 == stride % sizeof(SkScalar));
+ for (int i = 0; i < count; ++i) {
+ this->mapPoints(pts, pts, 1);
+ pts = (SkPoint*)((intptr_t)pts + stride);
+ }
+ }
+
+ /** Like mapPoints but with custom byte stride between the points.
+ */
+ void mapPointsWithStride(SkPoint dst[], SkPoint src[],
+ size_t stride, int count) const {
+ SkASSERT(stride >= sizeof(SkPoint));
+ SkASSERT(0 == stride % sizeof(SkScalar));
+ for (int i = 0; i < count; ++i) {
+ this->mapPoints(dst, src, 1);
+ src = (SkPoint*)((intptr_t)src + stride);
+ dst = (SkPoint*)((intptr_t)dst + stride);
+ }
+ }
+
+ /** Apply this matrix to the array of homogeneous points, specified by src,
+ where a homogeneous point is defined by 3 contiguous scalar values,
+ and write the transformed points into the array of scalars specified by dst.
+ dst[] = M * src[]
+ @param dst Where the transformed coordinates are written. It must
+ contain at least 3 * count entries
+ @param src The original coordinates that are to be transformed. It
+ must contain at least 3 * count entries
+ @param count The number of triples (homogeneous points) in src to read,
+ and then transform into dst.
+ */
+ void mapHomogeneousPoints(SkScalar dst[], const SkScalar src[], int count) const;
+
+ void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
+ SkASSERT(result);
+ this->getMapXYProc()(*this, x, y, result);
+ }
+
+ /** Apply this matrix to the array of vectors specified by src, and write
+ the transformed vectors into the array of vectors specified by dst.
+ This is similar to mapPoints, but ignores any translation in the matrix.
+ @param dst Where the transformed coordinates are written. It must
+ contain at least count entries
+ @param src The original coordinates that are to be transformed. It
+ must contain at least count entries
+ @param count The number of vectors in src to read, and then transform
+ into dst.
+ */
+ void mapVectors(SkVector dst[], const SkVector src[], int count) const;
+
+ /** Apply this matrix to the array of vectors specified by src, and write
+ the transformed vectors into the array of vectors specified by dst.
+ This is similar to mapPoints, but ignores any translation in the matrix.
+ @param vecs The vectors to be transformed. It must contain at least
+ count entries
+ @param count The number of vectors in vecs.
+ */
+ void mapVectors(SkVector vecs[], int count) const {
+ this->mapVectors(vecs, vecs, count);
+ }
+
+ /** Apply this matrix to the src rectangle, and write the transformed
+ rectangle into dst. This is accomplished by transforming the 4 corners
+ of src, and then setting dst to the bounds of those points.
+ @param dst Where the transformed rectangle is written.
+ @param src The original rectangle to be transformed.
+ @return the result of calling rectStaysRect()
+ */
+ bool mapRect(SkRect* dst, const SkRect& src) const;
+
+ /** Apply this matrix to the rectangle, and write the transformed rectangle
+ back into it. This is accomplished by transforming the 4 corners of
+ rect, and then setting it to the bounds of those points
+ @param rect The rectangle to transform.
+ @return the result of calling rectStaysRect()
+ */
+ bool mapRect(SkRect* rect) const {
+ return this->mapRect(rect, *rect);
+ }
+
+ /** Apply this matrix to the src rectangle, and write the four transformed
+ points into dst. The points written to dst will be the original top-left, top-right,
+ bottom-right, and bottom-left points transformed by the matrix.
+ @param dst Where the transformed quad is written.
+ @param rect The original rectangle to be transformed.
+ */
+ void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const {
+ // This could potentially be faster if we only transformed each x and y of the rect once.
+ rect.toQuad(dst);
+ this->mapPoints(dst, 4);
+ }
+
+ /** Return the mean radius of a circle after it has been mapped by
+ this matrix. NOTE: in perspective this value assumes the circle
+ has its center at the origin.
+ */
+ SkScalar mapRadius(SkScalar radius) const;
+
+ typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y,
+ SkPoint* result);
+
+ static MapXYProc GetMapXYProc(TypeMask mask) {
+ SkASSERT((mask & ~kAllMasks) == 0);
+ return gMapXYProcs[mask & kAllMasks];
+ }
+
+ MapXYProc getMapXYProc() const {
+ return GetMapXYProc(this->getType());
+ }
+
+ typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[],
+ const SkPoint src[], int count);
+
+ static MapPtsProc GetMapPtsProc(TypeMask mask) {
+ SkASSERT((mask & ~kAllMasks) == 0);
+ return gMapPtsProcs[mask & kAllMasks];
+ }
+
+ MapPtsProc getMapPtsProc() const {
+ return GetMapPtsProc(this->getType());
+ }
+
+ /** If the matrix can be stepped in X (not complex perspective)
+ then return true and if step[XY] is not null, return the step[XY] value.
+ If it cannot, return false and ignore step.
+ */
+ bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;
+
+ /** Efficient comparison of two matrices. It distinguishes between zero and
+ * negative zero. It will return false when the sign of zero values is the
+ * only difference between the two matrices. It considers NaN values to be
+ * equal to themselves. So a matrix full of NaNs is "cheap equal" to
+ * another matrix full of NaNs iff the NaN values are bitwise identical
+ * while according to strict the strict == test a matrix with a NaN value
+ * is equal to nothing, including itself.
+ */
+ bool cheapEqualTo(const SkMatrix& m) const {
+ return 0 == memcmp(fMat, m.fMat, sizeof(fMat));
+ }
+
+ friend bool operator==(const SkMatrix& a, const SkMatrix& b);
+ friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
+ return !(a == b);
+ }
+
+ enum {
+ // writeTo/readFromMemory will never return a value larger than this
+ kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
+ };
+ // return the number of bytes written, whether or not buffer is null
+ size_t writeToMemory(void* buffer) const;
+ /**
+ * Reads data from the buffer parameter
+ *
+ * @param buffer Memory to read from
+ * @param length Amount of memory available in the buffer
+ * @return number of bytes read (must be a multiple of 4) or
+ * 0 if there was not enough memory available
+ */
+ size_t readFromMemory(const void* buffer, size_t length);
+
+ SkDEVCODE(void dump() const;)
+ SK_TO_STRING_NONVIRT()
+
+ /**
+ * Calculates the minimum scaling factor of the matrix as computed from the SVD of the upper
+ * left 2x2. If the matrix has perspective -1 is returned.
+ *
+ * @return minumum scale factor
+ */
+ SkScalar getMinScale() const;
+
+ /**
+ * Calculates the maximum scaling factor of the matrix as computed from the SVD of the upper
+ * left 2x2. If the matrix has perspective -1 is returned.
+ *
+ * @return maximum scale factor
+ */
+ SkScalar getMaxScale() const;
+
+ /**
+ * Gets both the min and max scale factors. The min scale factor is scaleFactors[0] and the max
+ * is scaleFactors[1]. If the matrix has perspective false will be returned and scaleFactors
+ * will be unchanged.
+ */
+ bool getMinMaxScales(SkScalar scaleFactors[2]) const;
+
+ /**
+ * Return a reference to a const identity matrix
+ */
+ static const SkMatrix& I();
+
+ /**
+ * Return a reference to a const matrix that is "invalid", one that could
+ * never be used.
+ */
+ static const SkMatrix& InvalidMatrix();
+
+ /**
+ * Return the concatenation of two matrices, a * b.
+ */
+ static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) {
+ SkMatrix result;
+ result.setConcat(a, b);
+ return result;
+ }
+
+ /**
+ * Testing routine; the matrix's type cache should never need to be
+ * manually invalidated during normal use.
+ */
+ void dirtyMatrixTypeCache() {
+ this->setTypeMask(kUnknown_Mask);
+ }
+
+private:
+ enum {
+ /** Set if the matrix will map a rectangle to another rectangle. This
+ can be true if the matrix is scale-only, or rotates a multiple of
+ 90 degrees.
+
+ This bit will be set on identity matrices
+ */
+ kRectStaysRect_Mask = 0x10,
+
+ /** Set if the perspective bit is valid even though the rest of
+ the matrix is Unknown.
+ */
+ kOnlyPerspectiveValid_Mask = 0x40,
+
+ kUnknown_Mask = 0x80,
+
+ kORableMasks = kTranslate_Mask |
+ kScale_Mask |
+ kAffine_Mask |
+ kPerspective_Mask,
+
+ kAllMasks = kTranslate_Mask |
+ kScale_Mask |
+ kAffine_Mask |
+ kPerspective_Mask |
+ kRectStaysRect_Mask
+ };
+
+ SkScalar fMat[9];
+ mutable SkTRacy<uint32_t> fTypeMask;
+
+ uint8_t computeTypeMask() const;
+ uint8_t computePerspectiveTypeMask() const;
+
+ void setTypeMask(int mask) {
+ // allow kUnknown or a valid mask
+ SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
+ ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask)
+ == (kUnknown_Mask | kOnlyPerspectiveValid_Mask));
+ fTypeMask = SkToU8(mask);
+ }
+
+ void orTypeMask(int mask) {
+ SkASSERT((mask & kORableMasks) == mask);
+ fTypeMask = SkToU8(fTypeMask | mask);
+ }
+
+ void clearTypeMask(int mask) {
+ // only allow a valid mask
+ SkASSERT((mask & kAllMasks) == mask);
+ fTypeMask = fTypeMask & ~mask;
+ }
+
+ TypeMask getPerspectiveTypeMaskOnly() const {
+ if ((fTypeMask & kUnknown_Mask) &&
+ !(fTypeMask & kOnlyPerspectiveValid_Mask)) {
+ fTypeMask = this->computePerspectiveTypeMask();
+ }
+ return (TypeMask)(fTypeMask & 0xF);
+ }
+
+ /** Returns true if we already know that the matrix is identity;
+ false otherwise.
+ */
+ bool isTriviallyIdentity() const {
+ if (fTypeMask & kUnknown_Mask) {
+ return false;
+ }
+ return ((fTypeMask & 0xF) == 0);
+ }
+
+ bool SK_WARN_UNUSED_RESULT invertNonIdentity(SkMatrix* inverse) const;
+
+ static bool Poly2Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
+ static bool Poly3Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
+ static bool Poly4Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
+
+ static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+ static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
+
+ static const MapXYProc gMapXYProcs[];
+
+ static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int);
+ static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+ static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+ static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
+ int count);
+ static void Rot_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+ static void RotTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
+ int count);
+ static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
+
+ static const MapPtsProc gMapPtsProcs[];
+
+ friend class SkPerspIter;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkMetaData.h b/src/third_party/skia/include/core/SkMetaData.h
new file mode 100644
index 0000000..c8ca7f1
--- /dev/null
+++ b/src/third_party/skia/include/core/SkMetaData.h
@@ -0,0 +1,175 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMetaData_DEFINED
+#define SkMetaData_DEFINED
+
+#include "SkScalar.h"
+
+class SkRefCnt;
+
+class SK_API SkMetaData {
+public:
+ /**
+ * Used to manage the life-cycle of a ptr in the metadata. This is option
+ * in setPtr, and is only invoked when either copying one metadata to
+ * another, or when the metadata is destroyed.
+ *
+ * setPtr(name, ptr, proc) {
+ * fPtr = proc(ptr, true);
+ * }
+ *
+ * copy: A = B {
+ * A.fPtr = B.fProc(B.fPtr, true);
+ * }
+ *
+ * ~SkMetaData {
+ * fProc(fPtr, false);
+ * }
+ */
+ typedef void* (*PtrProc)(void* ptr, bool doRef);
+
+ /**
+ * Implements PtrProc for SkRefCnt pointers
+ */
+ static void* RefCntProc(void* ptr, bool doRef);
+
+ SkMetaData();
+ SkMetaData(const SkMetaData& src);
+ ~SkMetaData();
+
+ SkMetaData& operator=(const SkMetaData& src);
+
+ void reset();
+
+ bool findS32(const char name[], int32_t* value = NULL) const;
+ bool findScalar(const char name[], SkScalar* value = NULL) const;
+ const SkScalar* findScalars(const char name[], int* count,
+ SkScalar values[] = NULL) const;
+ const char* findString(const char name[]) const;
+ bool findPtr(const char name[], void** value = NULL, PtrProc* = NULL) const;
+ bool findBool(const char name[], bool* value = NULL) const;
+ const void* findData(const char name[], size_t* byteCount = NULL) const;
+
+ bool hasS32(const char name[], int32_t value) const {
+ int32_t v;
+ return this->findS32(name, &v) && v == value;
+ }
+ bool hasScalar(const char name[], SkScalar value) const {
+ SkScalar v;
+ return this->findScalar(name, &v) && v == value;
+ }
+ bool hasString(const char name[], const char value[]) const {
+ const char* v = this->findString(name);
+ return (v == NULL && value == NULL) ||
+ (v != NULL && value != NULL && !strcmp(v, value));
+ }
+ bool hasPtr(const char name[], void* value) const {
+ void* v;
+ return this->findPtr(name, &v) && v == value;
+ }
+ bool hasBool(const char name[], bool value) const {
+ bool v;
+ return this->findBool(name, &v) && v == value;
+ }
+ bool hasData(const char name[], const void* data, size_t byteCount) const {
+ size_t len;
+ const void* ptr = this->findData(name, &len);
+ return ptr && len == byteCount && !memcmp(ptr, data, len);
+ }
+
+ void setS32(const char name[], int32_t value);
+ void setScalar(const char name[], SkScalar value);
+ SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL);
+ void setString(const char name[], const char value[]);
+ void setPtr(const char name[], void* value, PtrProc proc = NULL);
+ void setBool(const char name[], bool value);
+ // the data is copied from the input pointer.
+ void setData(const char name[], const void* data, size_t byteCount);
+
+ bool removeS32(const char name[]);
+ bool removeScalar(const char name[]);
+ bool removeString(const char name[]);
+ bool removePtr(const char name[]);
+ bool removeBool(const char name[]);
+ bool removeData(const char name[]);
+
+ // helpers for SkRefCnt
+ bool findRefCnt(const char name[], SkRefCnt** ptr = NULL) {
+ return this->findPtr(name, reinterpret_cast<void**>(ptr));
+ }
+ bool hasRefCnt(const char name[], SkRefCnt* ptr) {
+ return this->hasPtr(name, ptr);
+ }
+ void setRefCnt(const char name[], SkRefCnt* ptr) {
+ this->setPtr(name, ptr, RefCntProc);
+ }
+ bool removeRefCnt(const char name[]) {
+ return this->removePtr(name);
+ }
+
+ enum Type {
+ kS32_Type,
+ kScalar_Type,
+ kString_Type,
+ kPtr_Type,
+ kBool_Type,
+ kData_Type,
+
+ kTypeCount
+ };
+
+ struct Rec;
+ class Iter;
+ friend class Iter;
+
+ class Iter {
+ public:
+ Iter() : fRec(NULL) {}
+ Iter(const SkMetaData&);
+
+ /** Reset the iterator, so that calling next() will return the first
+ data element. This is done implicitly in the constructor.
+ */
+ void reset(const SkMetaData&);
+
+ /** Each time next is called, it returns the name of the next data element,
+ or null when there are no more elements. If non-null is returned, then the
+ element's type is returned (if not null), and the number of data values
+ is returned in count (if not null).
+ */
+ const char* next(Type*, int* count);
+
+ private:
+ Rec* fRec;
+ };
+
+public:
+ struct Rec {
+ Rec* fNext;
+ uint16_t fDataCount; // number of elements
+ uint8_t fDataLen; // sizeof a single element
+ uint8_t fType;
+
+ const void* data() const { return (this + 1); }
+ void* data() { return (this + 1); }
+ const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
+ char* name() { return (char*)this->data() + fDataLen * fDataCount; }
+
+ static Rec* Alloc(size_t);
+ static void Free(Rec*);
+ };
+ Rec* fRec;
+
+ const Rec* find(const char name[], Type) const;
+ void* set(const char name[], const void* data, size_t len, Type, int count);
+ bool remove(const char name[], Type);
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkMultiPictureDraw.h b/src/third_party/skia/include/core/SkMultiPictureDraw.h
new file mode 100644
index 0000000..d8d9cb7
--- /dev/null
+++ b/src/third_party/skia/include/core/SkMultiPictureDraw.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMultiPictureDraw_DEFINED
+#define SkMultiPictureDraw_DEFINED
+
+#include "SkMatrix.h"
+#include "SkTDArray.h"
+
+class SkCanvas;
+class SkPaint;
+class SkPicture;
+
+/** \class SkMultiPictureDraw
+
+ The MultiPictureDraw object accepts several picture/canvas pairs and
+ then attempts to optimally draw the pictures into the canvases, sharing
+ as many resources as possible.
+*/
+class SK_API SkMultiPictureDraw {
+public:
+ /**
+ * Create an object to optimize the drawing of multiple pictures.
+ * @param reserve Hint for the number of add calls expected to be issued
+ */
+ SkMultiPictureDraw(int reserve = 0);
+ ~SkMultiPictureDraw() { this->reset(); }
+
+ /**
+ * Add a canvas/picture pair for later rendering.
+ * @param canvas the canvas in which to draw picture
+ * @param picture the picture to draw into canvas
+ * @param matrix if non-NULL, applied to the CTM when drawing
+ * @param paint if non-NULL, draw picture to a temporary buffer
+ * and then apply the paint when the result is drawn
+ */
+ void add(SkCanvas* canvas,
+ const SkPicture* picture,
+ const SkMatrix* matrix = NULL,
+ const SkPaint* paint = NULL);
+
+ /**
+ * Perform all the previously added draws. This will reset the state
+ * of this object.
+ */
+ void draw();
+
+ /**
+ * Abandon all buffered draws and reset to the initial state.
+ */
+ void reset();
+
+private:
+ struct DrawData {
+ SkCanvas* canvas; // reffed
+ const SkPicture* picture; // reffed
+ SkMatrix matrix;
+ SkPaint* paint; // owned
+ };
+
+ SkTDArray<DrawData> fDrawData;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkOSFile.h b/src/third_party/skia/include/core/SkOSFile.h
new file mode 100644
index 0000000..44247bd
--- /dev/null
+++ b/src/third_party/skia/include/core/SkOSFile.h
@@ -0,0 +1,163 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+// TODO: add unittests for all these operations
+
+#ifndef SkOSFile_DEFINED
+#define SkOSFile_DEFINED
+
+#include "SkString.h"
+
+#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
+ #include <dirent.h>
+#endif
+
+#include <stddef.h> // ptrdiff_t
+
+struct SkFILE;
+
+enum SkFILE_Flags {
+ kRead_SkFILE_Flag = 0x01,
+ kWrite_SkFILE_Flag = 0x02
+};
+
+#ifdef _WIN32
+const static char SkPATH_SEPARATOR = '\\';
+#else
+const static char SkPATH_SEPARATOR = '/';
+#endif
+
+SkFILE* sk_fopen(const char path[], SkFILE_Flags);
+void sk_fclose(SkFILE*);
+
+size_t sk_fgetsize(SkFILE*);
+/** Return true if the file could seek back to the beginning
+*/
+bool sk_frewind(SkFILE*);
+
+size_t sk_fread(void* buffer, size_t byteCount, SkFILE*);
+size_t sk_fwrite(const void* buffer, size_t byteCount, SkFILE*);
+
+char* sk_fgets(char* str, int size, SkFILE* f);
+
+void sk_fflush(SkFILE*);
+
+bool sk_fseek(SkFILE*, size_t);
+bool sk_fmove(SkFILE*, long);
+size_t sk_ftell(SkFILE*);
+
+/** Maps a file into memory. Returns the address and length on success, NULL otherwise.
+ * The mapping is read only.
+ * When finished with the mapping, free the returned pointer with sk_fmunmap.
+ */
+void* sk_fmmap(SkFILE* f, size_t* length);
+
+/** Maps a file descriptor into memory. Returns the address and length on success, NULL otherwise.
+ * The mapping is read only.
+ * When finished with the mapping, free the returned pointer with sk_fmunmap.
+ */
+void* sk_fdmmap(int fd, size_t* length);
+
+/** Unmaps a file previously mapped by sk_fmmap or sk_fdmmap.
+ * The length parameter must be the same as returned from sk_fmmap.
+ */
+void sk_fmunmap(const void* addr, size_t length);
+
+/** Returns true if the two point at the exact same filesystem object. */
+bool sk_fidentical(SkFILE* a, SkFILE* b);
+
+/** Returns the underlying file descriptor for the given file.
+ * The return value will be < 0 on failure.
+ */
+int sk_fileno(SkFILE* f);
+
+/** Returns true if something (file, directory, ???) exists at this path,
+ * and has the specified access flags.
+ */
+bool sk_exists(const char *path, SkFILE_Flags = (SkFILE_Flags)0);
+
+// Returns true if a directory exists at this path.
+bool sk_isdir(const char *path);
+
+// Have we reached the end of the file?
+int sk_feof(SkFILE *);
+
+
+// Create a new directory at this path; returns true if successful.
+// If the directory already existed, this will return true.
+// Description of the error, if any, will be written to stderr.
+bool sk_mkdir(const char* path);
+
+class SkOSFile {
+public:
+ class Iter {
+ public:
+ Iter();
+ Iter(const char path[], const char suffix[] = NULL);
+ ~Iter();
+
+ void reset(const char path[], const char suffix[] = NULL);
+ /** If getDir is true, only returns directories.
+ Results are undefined if true and false calls are
+ interleaved on a single iterator.
+ */
+ bool next(SkString* name, bool getDir = false);
+
+ private:
+#if defined(COBALT)
+ class Pimpl;
+ SkAutoTDelete<Pimpl> fPimpl;
+#elif defined(SK_BUILD_FOR_WIN)
+ HANDLE fHandle;
+ uint16_t* fPath16;
+#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
+ DIR* fDIR;
+ SkString fPath, fSuffix;
+#endif
+ };
+};
+
+/**
+ * Functions for modifying SkStrings which represent paths on the filesystem.
+ */
+class SkOSPath {
+public:
+ /**
+ * Assembles rootPath and relativePath into a single path, like this:
+ * rootPath/relativePath.
+ * It is okay to call with a NULL rootPath and/or relativePath. A path
+ * separator will still be inserted.
+ *
+ * Uses SkPATH_SEPARATOR, to work on all platforms.
+ */
+ static SkString Join(const char* rootPath, const char* relativePath);
+
+ /**
+ * Return the name of the file, ignoring the directory structure.
+ * Behaves like python's os.path.basename. If the fullPath is
+ * /dir/subdir/, an empty string is returned.
+ * @param fullPath Full path to the file.
+ * @return SkString The basename of the file - anything beyond the
+ * final slash, or the full name if there is no slash.
+ */
+ static SkString Basename(const char* fullPath);
+
+ /**
+ * Given a qualified file name returns the directory.
+ * Behaves like python's os.path.dirname. If the fullPath is
+ * /dir/subdir/ the return will be /dir/subdir/
+ * @param fullPath Full path to the file.
+ * @return SkString The dir containing the file - anything preceding the
+ * final slash, or the full name if ending in a slash.
+ */
+ static SkString Dirname(const char* fullPath);
+
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkOnce.h b/src/third_party/skia/include/core/SkOnce.h
new file mode 100644
index 0000000..87bb277
--- /dev/null
+++ b/src/third_party/skia/include/core/SkOnce.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkOnce_DEFINED
+#define SkOnce_DEFINED
+
+// Before trying SkOnce, see if SkLazyPtr or SkLazyFnPtr will work for you.
+// They're smaller and faster, if slightly less versatile.
+
+
+// SkOnce.h defines SK_DECLARE_STATIC_ONCE and SkOnce(), which you can use
+// together to create a threadsafe way to call a function just once. E.g.
+//
+// static void register_my_stuff(GlobalRegistry* registry) {
+// registry->register(...);
+// }
+// ...
+// void EnsureRegistered() {
+// SK_DECLARE_STATIC_ONCE(once);
+// SkOnce(&once, register_my_stuff, GetGlobalRegistry());
+// }
+//
+// No matter how many times you call EnsureRegistered(), register_my_stuff will be called just once.
+// OnceTest.cpp also should serve as a few other simple examples.
+
+#include "SkDynamicAnnotations.h"
+#include "SkThread.h"
+#include "SkTypes.h"
+
+// This must be used in a global or function scope, not as a class member.
+#define SK_DECLARE_STATIC_ONCE(name) static SkOnceFlag name
+
+class SkOnceFlag;
+
+inline void SkOnce(SkOnceFlag* once, void (*f)());
+
+template <typename Arg>
+inline void SkOnce(SkOnceFlag* once, void (*f)(Arg), Arg arg);
+
+// If you've already got a lock and a flag to use, this variant lets you avoid an extra SkOnceFlag.
+template <typename Lock>
+inline void SkOnce(bool* done, Lock* lock, void (*f)());
+
+template <typename Lock, typename Arg>
+inline void SkOnce(bool* done, Lock* lock, void (*f)(Arg), Arg arg);
+
+// ---------------------- Implementation details below here. -----------------------------
+
+// This class has no constructor and must be zero-initialized (the macro above does this).
+class SkOnceFlag {
+public:
+ bool* mutableDone() { return &fDone; }
+
+ void acquire() {
+ // To act as a mutex, this needs an acquire barrier on success.
+ // sk_atomic_cas doesn't guarantee this ...
+ while (!sk_atomic_cas(&fSpinlock, 0, 1)) {
+ // spin
+ }
+ // ... so make sure to issue one of our own.
+ SkAssertResult(sk_acquire_load(&fSpinlock));
+ }
+
+ void release() {
+ // To act as a mutex, this needs a release barrier. sk_atomic_cas guarantees this.
+ SkAssertResult(sk_atomic_cas(&fSpinlock, 1, 0));
+ }
+
+private:
+ bool fDone;
+ int32_t fSpinlock;
+};
+
+// We've pulled a pretty standard double-checked locking implementation apart
+// into its main fast path and a slow path that's called when we suspect the
+// one-time code hasn't run yet.
+
+// This is the guts of the code, called when we suspect the one-time code hasn't been run yet.
+// This should be rarely called, so we separate it from SkOnce and don't mark it as inline.
+// (We don't mind if this is an actual function call, but odds are it'll be inlined anyway.)
+template <typename Lock, typename Arg>
+static void sk_once_slow(bool* done, Lock* lock, void (*f)(Arg), Arg arg) {
+ lock->acquire();
+ if (!*done) {
+ f(arg);
+ // Also known as a store-store/load-store barrier, this makes sure that the writes
+ // done before here---in particular, those done by calling f(arg)---are observable
+ // before the writes after the line, *done = true.
+ //
+ // In version control terms this is like saying, "check in the work up
+ // to and including f(arg), then check in *done=true as a subsequent change".
+ //
+ // We'll use this in the fast path to make sure f(arg)'s effects are
+ // observable whenever we observe *done == true.
+ sk_release_store(done, true);
+ }
+ lock->release();
+}
+
+// This is our fast path, called all the time. We do really want it to be inlined.
+template <typename Lock, typename Arg>
+inline void SkOnce(bool* done, Lock* lock, void (*f)(Arg), Arg arg) {
+ if (!SK_ANNOTATE_UNPROTECTED_READ(*done)) {
+ sk_once_slow(done, lock, f, arg);
+ }
+ // Also known as a load-load/load-store barrier, this acquire barrier makes
+ // sure that anything we read from memory---in particular, memory written by
+ // calling f(arg)---is at least as current as the value we read from done.
+ //
+ // In version control terms, this is a lot like saying "sync up to the
+ // commit where we wrote done = true".
+ //
+ // The release barrier in sk_once_slow guaranteed that done = true
+ // happens after f(arg), so by syncing to done = true here we're
+ // forcing ourselves to also wait until the effects of f(arg) are readble.
+ SkAssertResult(sk_acquire_load(done));
+}
+
+template <typename Arg>
+inline void SkOnce(SkOnceFlag* once, void (*f)(Arg), Arg arg) {
+ return SkOnce(once->mutableDone(), once, f, arg);
+}
+
+// Calls its argument.
+// This lets us use functions that take no arguments with SkOnce methods above.
+// (We pass _this_ as the function and the no-arg function as its argument. Cute eh?)
+static void sk_once_no_arg_adaptor(void (*f)()) {
+ f();
+}
+
+inline void SkOnce(SkOnceFlag* once, void (*func)()) {
+ return SkOnce(once, sk_once_no_arg_adaptor, func);
+}
+
+template <typename Lock>
+inline void SkOnce(bool* done, Lock* lock, void (*func)()) {
+ return SkOnce(done, lock, sk_once_no_arg_adaptor, func);
+}
+
+#endif // SkOnce_DEFINED
diff --git a/src/third_party/skia/include/core/SkPackBits.h b/src/third_party/skia/include/core/SkPackBits.h
new file mode 100644
index 0000000..1e32ee0
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPackBits.h
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPackBits_DEFINED
+#define SkPackBits_DEFINED
+
+#include "SkTypes.h"
+
+class SkPackBits {
+public:
+ /** Given the number of 8bit values that will be passed to Pack8,
+ returns the worst-case size needed for the dst[] buffer.
+ */
+ static size_t ComputeMaxSize8(int count);
+
+ /** Write the src array into a packed format. The packing process may end
+ up writing more bytes than it read, so dst[] must be large enough.
+ @param src Input array of 8bit values
+ @param srcSize Number of entries in src[]
+ @param dst Buffer (allocated by caller) to write the packed data
+ into
+ @param dstSize Number of bytes in the output buffer.
+ @return the number of bytes written to dst[]
+ */
+ static size_t Pack8(const uint8_t src[], size_t srcSize, uint8_t dst[],
+ size_t dstSize);
+
+ /** Unpack the data in src[], and expand it into dst[]. The src[] data was
+ written by a previous call to Pack8.
+ @param src Input data to unpack, previously created by Pack8.
+ @param srcSize Number of bytes of src to unpack
+ @param dst Buffer (allocated by caller) to expand the src[] into.
+ @param dstSize Number of bytes in the output buffer.
+ @return the number of bytes written into dst.
+ */
+ static int Unpack8(const uint8_t src[], size_t srcSize, uint8_t dst[],
+ size_t dstSize);
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPaint.h b/src/third_party/skia/include/core/SkPaint.h
new file mode 100644
index 0000000..9c47f1d
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPaint.h
@@ -0,0 +1,1142 @@
+
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPaint_DEFINED
+#define SkPaint_DEFINED
+
+#include "SkColor.h"
+#include "SkDrawLooper.h"
+#include "SkMatrix.h"
+#include "SkXfermode.h"
+
+class SkAnnotation;
+class SkAutoGlyphCache;
+class SkColorFilter;
+class SkDescriptor;
+struct SkDeviceProperties;
+class SkReadBuffer;
+class SkWriteBuffer;
+struct SkGlyph;
+struct SkRect;
+class SkGlyphCache;
+class SkImageFilter;
+class SkMaskFilter;
+class SkPath;
+class SkPathEffect;
+struct SkPoint;
+class SkRasterizer;
+class SkShader;
+class SkTypeface;
+
+typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
+ SkFixed x, SkFixed y);
+
+typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
+
+#define kBicubicFilterBitmap_Flag kHighQualityFilterBitmap_Flag
+
+/** \class SkPaint
+
+ The SkPaint class holds the style and color information about how to draw
+ geometries, text and bitmaps.
+*/
+
+class SK_API SkPaint {
+public:
+ SkPaint();
+ SkPaint(const SkPaint& paint);
+ ~SkPaint();
+
+ SkPaint& operator=(const SkPaint&);
+
+ /** operator== may give false negatives: two paints that draw equivalently
+ may return false. It will never give false positives: two paints that
+ are not equivalent always return false.
+ */
+ SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
+ friend bool operator!=(const SkPaint& a, const SkPaint& b) {
+ return !(a == b);
+ }
+
+ void flatten(SkWriteBuffer&) const;
+ void unflatten(SkReadBuffer&);
+
+ /** Restores the paint to its initial settings.
+ */
+ void reset();
+
+ /** Specifies the level of hinting to be performed. These names are taken
+ from the Gnome/Cairo names for the same. They are translated into
+ Freetype concepts the same as in cairo-ft-font.c:
+ kNo_Hinting -> FT_LOAD_NO_HINTING
+ kSlight_Hinting -> FT_LOAD_TARGET_LIGHT
+ kNormal_Hinting -> <default, no option>
+ kFull_Hinting -> <same as kNormalHinting, unless we are rendering
+ subpixel glyphs, in which case TARGET_LCD or
+ TARGET_LCD_V is used>
+ */
+ enum Hinting {
+ kNo_Hinting = 0,
+ kSlight_Hinting = 1,
+ kNormal_Hinting = 2, //!< this is the default
+ kFull_Hinting = 3
+ };
+
+ Hinting getHinting() const {
+ return static_cast<Hinting>(fBitfields.fHinting);
+ }
+
+ void setHinting(Hinting hintingLevel);
+
+ /** Specifies the bit values that are stored in the paint's flags.
+ */
+ enum Flags {
+ kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
+ kDither_Flag = 0x04, //!< mask to enable dithering
+ kUnderlineText_Flag = 0x08, //!< mask to enable underline text
+ kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
+ kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
+ kLinearText_Flag = 0x40, //!< mask to enable linear-text
+ kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
+ 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
+ kVerticalText_Flag = 0x1000,
+ kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it
+ kDistanceFieldTextTEMP_Flag = 0x4000, //!< TEMPORARY mask to enable distance fields
+ // currently overrides LCD and subpixel rendering
+ // when adding extra flags, note that the fFlags member is specified
+ // with a bit-width and you'll have to expand it.
+
+ kAllFlags = 0xFFFF
+ };
+
+ /** Return the paint's flags. Use the Flag enum to test flag values.
+ @return the paint's flags (see enums ending in _Flag for bit masks)
+ */
+ uint32_t getFlags() const { return fBitfields.fFlags; }
+
+ /** Set the paint's flags. Use the Flag enum to specific flag values.
+ @param flags The new flag bits for the paint (see Flags enum)
+ */
+ void setFlags(uint32_t flags);
+
+ /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
+ @return true if the antialias bit is set in the paint's flags.
+ */
+ bool isAntiAlias() const {
+ return SkToBool(this->getFlags() & kAntiAlias_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
+ @param aa true to enable antialiasing, false to disable it
+ */
+ void setAntiAlias(bool aa);
+
+ /** Helper for getFlags(), returning true if kDither_Flag bit is set
+ @return true if the dithering bit is set in the paint's flags.
+ */
+ bool isDither() const {
+ return SkToBool(this->getFlags() & kDither_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kDither_Flag bit
+ @param dither true to enable dithering, false to disable it
+ */
+ void setDither(bool dither);
+
+ /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
+ @return true if the lineartext bit is set in the paint's flags
+ */
+ bool isLinearText() const {
+ return SkToBool(this->getFlags() & kLinearText_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
+ @param linearText true to set the linearText bit in the paint's flags,
+ false to clear it.
+ */
+ void setLinearText(bool linearText);
+
+ /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
+ @return true if the lineartext bit is set in the paint's flags
+ */
+ bool isSubpixelText() const {
+ return SkToBool(this->getFlags() & kSubpixelText_Flag);
+ }
+
+ /**
+ * Helper for setFlags(), setting or clearing the kSubpixelText_Flag.
+ * @param subpixelText true to set the subpixelText bit in the paint's
+ * flags, false to clear it.
+ */
+ void setSubpixelText(bool subpixelText);
+
+ bool isLCDRenderText() const {
+ return SkToBool(this->getFlags() & kLCDRenderText_Flag);
+ }
+
+ /**
+ * Helper for setFlags(), setting or clearing the kLCDRenderText_Flag.
+ * Note: antialiasing must also be on for lcd rendering
+ * @param lcdText true to set the LCDRenderText bit in the paint's flags,
+ * false to clear it.
+ */
+ void setLCDRenderText(bool lcdText);
+
+ bool isEmbeddedBitmapText() const {
+ return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kEmbeddedBitmapText_Flag bit
+ @param useEmbeddedBitmapText true to set the kEmbeddedBitmapText bit in the paint's flags,
+ false to clear it.
+ */
+ 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);
+
+ bool isVerticalText() const {
+ return SkToBool(this->getFlags() & kVerticalText_Flag);
+ }
+
+ /**
+ * Helper for setting or clearing the kVerticalText_Flag bit in
+ * setFlags(...).
+ *
+ * If this bit is set, then advances are treated as Y values rather than
+ * X values, and drawText will places its glyphs vertically rather than
+ * horizontally.
+ */
+ void setVerticalText(bool);
+
+ /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
+ @return true if the underlineText bit is set in the paint's flags.
+ */
+ bool isUnderlineText() const {
+ return SkToBool(this->getFlags() & kUnderlineText_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
+ @param underlineText true to set the underlineText bit in the paint's
+ flags, false to clear it.
+ */
+ void setUnderlineText(bool underlineText);
+
+ /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
+ @return true if the strikeThruText bit is set in the paint's flags.
+ */
+ bool isStrikeThruText() const {
+ return SkToBool(this->getFlags() & kStrikeThruText_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
+ @param strikeThruText true to set the strikeThruText bit in the
+ paint's flags, false to clear it.
+ */
+ void setStrikeThruText(bool strikeThruText);
+
+ /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
+ @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
+ */
+ bool isFakeBoldText() const {
+ return SkToBool(this->getFlags() & kFakeBoldText_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
+ @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
+ flags, false to clear it.
+ */
+ void setFakeBoldText(bool fakeBoldText);
+
+ /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
+ @return true if the kernText bit is set in the paint's flags.
+ */
+ bool isDevKernText() const {
+ return SkToBool(this->getFlags() & kDevKernText_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kKernText_Flag bit
+ @param kernText true to set the kKernText_Flag bit in the paint's
+ flags, false to clear it.
+ */
+ void setDevKernText(bool devKernText);
+
+ /** Helper for getFlags(), returns true if kDistanceFieldTextTEMP_Flag bit is set
+ @return true if the distanceFieldText bit is set in the paint's flags.
+ */
+ bool isDistanceFieldTextTEMP() const {
+ return SkToBool(this->getFlags() & kDistanceFieldTextTEMP_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kDistanceFieldTextTEMP_Flag bit
+ @param distanceFieldText true to set the kDistanceFieldTextTEMP_Flag bit in the paint's
+ flags, false to clear it.
+ */
+ void setDistanceFieldTextTEMP(bool distanceFieldText);
+
+ enum FilterLevel {
+ kNone_FilterLevel,
+ kLow_FilterLevel,
+ kMedium_FilterLevel,
+ kHigh_FilterLevel
+ };
+
+ /**
+ * Return the filter level. This affects the quality (and performance) of
+ * drawing scaled images.
+ */
+ FilterLevel getFilterLevel() const {
+ return (FilterLevel)fBitfields.fFilterLevel;
+ }
+
+ /**
+ * Set the filter level. This affects the quality (and performance) of
+ * drawing scaled images.
+ */
+ void setFilterLevel(FilterLevel);
+
+ /**
+ * If the predicate is true, set the filterLevel to Low, else set it to
+ * None.
+ */
+ SK_ATTR_DEPRECATED("use setFilterLevel")
+ void setFilterBitmap(bool doFilter) {
+ this->setFilterLevel(doFilter ? kLow_FilterLevel : kNone_FilterLevel);
+ }
+
+ /**
+ * Returns true if getFilterLevel() returns anything other than None.
+ */
+ SK_ATTR_DEPRECATED("use getFilterLevel")
+ bool isFilterBitmap() const {
+ return kNone_FilterLevel != this->getFilterLevel();
+ }
+
+ /** Styles apply to rect, oval, path, and text.
+ Bitmaps are always drawn in "fill", and lines are always drawn in
+ "stroke".
+
+ Note: strokeandfill implicitly draws the result with
+ SkPath::kWinding_FillType, so if the original path is even-odd, the
+ results may not appear the same as if it was drawn twice, filled and
+ then stroked.
+ */
+ enum Style {
+ kFill_Style, //!< fill the geometry
+ kStroke_Style, //!< stroke the geometry
+ kStrokeAndFill_Style, //!< fill and stroke the geometry
+ };
+ enum {
+ kStyleCount = kStrokeAndFill_Style + 1
+ };
+
+ /** Return the paint's style, used for controlling how primitives'
+ geometries are interpreted (except for drawBitmap, which always assumes
+ kFill_Style).
+ @return the paint's Style
+ */
+ Style getStyle() const { return (Style)fBitfields.fStyle; }
+
+ /** Set the paint's style, used for controlling how primitives'
+ geometries are interpreted (except for drawBitmap, which always assumes
+ Fill).
+ @param style The new style to set in the paint
+ */
+ void setStyle(Style style);
+
+ /** Return the paint's color. Note that the color is a 32bit value
+ containing alpha as well as r,g,b. This 32bit value is not
+ premultiplied, meaning that its alpha can be any value, regardless of
+ the values of r,g,b.
+ @return the paint's color (and alpha).
+ */
+ SkColor getColor() const { return fColor; }
+
+ /** Set the paint's color. Note that the color is a 32bit value containing
+ alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
+ that its alpha can be any value, regardless of the values of r,g,b.
+ @param color The new color (including alpha) to set in the paint.
+ */
+ void setColor(SkColor color);
+
+ /** Helper to getColor() that just returns the color's alpha value.
+ @return the alpha component of the paint's color.
+ */
+ uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
+
+ /** Helper to setColor(), that only assigns the color's alpha value,
+ leaving its r,g,b values unchanged.
+ @param a set the alpha component (0..255) of the paint's color.
+ */
+ void setAlpha(U8CPU a);
+
+ /** Helper to setColor(), that takes a,r,g,b and constructs the color value
+ using SkColorSetARGB()
+ @param a The new alpha component (0..255) of the paint's color.
+ @param r The new red component (0..255) of the paint's color.
+ @param g The new green component (0..255) of the paint's color.
+ @param b The new blue component (0..255) of the paint's color.
+ */
+ void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
+
+ /** Return the width for stroking.
+ <p />
+ A value of 0 strokes in hairline mode.
+ Hairlines always draw 1-pixel wide, regardless of the matrix.
+ @return the paint's stroke width, used whenever the paint's style is
+ Stroke or StrokeAndFill.
+ */
+ SkScalar getStrokeWidth() const { return fWidth; }
+
+ /** Set the width for stroking.
+ Pass 0 to stroke in hairline mode.
+ Hairlines always draw 1-pixel wide, regardless of the matrix.
+ @param width set the paint's stroke width, used whenever the paint's
+ style is Stroke or StrokeAndFill.
+ */
+ void setStrokeWidth(SkScalar width);
+
+ /** Return the paint's stroke miter value. This is used to control the
+ behavior of miter joins when the joins angle is sharp.
+ @return the paint's miter limit, used whenever the paint's style is
+ Stroke or StrokeAndFill.
+ */
+ SkScalar getStrokeMiter() const { return fMiterLimit; }
+
+ /** Set the paint's stroke miter value. This is used to control the
+ behavior of miter joins when the joins angle is sharp. This value must
+ be >= 0.
+ @param miter set the miter limit on the paint, used whenever the
+ paint's style is Stroke or StrokeAndFill.
+ */
+ void setStrokeMiter(SkScalar miter);
+
+ /** Cap enum specifies the settings for the paint's strokecap. This is the
+ treatment that is applied to the beginning and end of each non-closed
+ contour (e.g. lines).
+ */
+ enum Cap {
+ kButt_Cap, //!< begin/end contours with no extension
+ kRound_Cap, //!< begin/end contours with a semi-circle extension
+ kSquare_Cap, //!< begin/end contours with a half square extension
+
+ kCapCount,
+ kDefault_Cap = kButt_Cap
+ };
+
+ /** Join enum specifies the settings for the paint's strokejoin. This is
+ the treatment that is applied to corners in paths and rectangles.
+ */
+ enum Join {
+ kMiter_Join, //!< connect path segments with a sharp join
+ kRound_Join, //!< connect path segments with a round join
+ kBevel_Join, //!< connect path segments with a flat bevel join
+
+ kJoinCount,
+ kDefault_Join = kMiter_Join
+ };
+
+ /** Return the paint's stroke cap type, controlling how the start and end
+ of stroked lines and paths are treated.
+ @return the line cap style for the paint, used whenever the paint's
+ style is Stroke or StrokeAndFill.
+ */
+ Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
+
+ /** Set the paint's stroke cap type.
+ @param cap set the paint's line cap style, used whenever the paint's
+ style is Stroke or StrokeAndFill.
+ */
+ void setStrokeCap(Cap cap);
+
+ /** Return the paint's stroke join type.
+ @return the paint's line join style, used whenever the paint's style is
+ Stroke or StrokeAndFill.
+ */
+ Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
+
+ /** Set the paint's stroke join type.
+ @param join set the paint's line join style, used whenever the paint's
+ style is Stroke or StrokeAndFill.
+ */
+ void setStrokeJoin(Join join);
+
+ /**
+ * Applies any/all effects (patheffect, stroking) to src, returning the
+ * result in dst. The result is that drawing src with this paint will be
+ * the same as drawing dst with a default paint (at least from the
+ * geometric perspective).
+ *
+ * @param src input path
+ * @param dst output path (may be the same as src)
+ * @param cullRect If not null, the dst path may be culled to this rect.
+ * @return true if the path should be filled, or false if it should be
+ * drawn with a hairline (width == 0)
+ */
+ bool getFillPath(const SkPath& src, SkPath* dst,
+ const SkRect* cullRect = NULL) const;
+
+ /** Get the paint's shader object.
+ <p />
+ The shader's reference count is not affected.
+ @return the paint's shader (or NULL)
+ */
+ SkShader* getShader() const { return fShader; }
+
+ /** Set or clear the shader object.
+ * Shaders specify the source color(s) for what is being drawn. If a paint
+ * has no shader, then the paint's color is used. If the paint has a
+ * shader, then the shader's color(s) are use instead, but they are
+ * modulated by the paint's alpha. This makes it easy to create a shader
+ * once (e.g. bitmap tiling or gradient) and then change its transparency
+ * w/o having to modify the original shader... only the paint's alpha needs
+ * to be modified.
+ *
+ * There is an exception to this only-respect-paint's-alpha rule: If the shader only generates
+ * alpha (e.g. SkShader::CreateBitmapShader(bitmap, ...) where bitmap's colortype is kAlpha_8)
+ * then the shader will use the paint's entire color to "colorize" its output (modulating the
+ * bitmap's alpha with the paint's color+alpha).
+ *
+ * Pass NULL to clear any previous shader.
+ * As a convenience, the parameter passed is also returned.
+ * If a previous shader exists, its reference count is decremented.
+ * If shader is not NULL, its reference count is incremented.
+ * @param shader May be NULL. The shader to be installed in the paint
+ * @return shader
+ */
+ SkShader* setShader(SkShader* shader);
+
+ /** Get the paint's colorfilter. If there is a colorfilter, its reference
+ count is not changed.
+ @return the paint's colorfilter (or NULL)
+ */
+ SkColorFilter* getColorFilter() const { return fColorFilter; }
+
+ /** Set or clear the paint's colorfilter, returning the parameter.
+ <p />
+ If the paint already has a filter, its reference count is decremented.
+ If filter is not NULL, its reference count is incremented.
+ @param filter May be NULL. The filter to be installed in the paint
+ @return filter
+ */
+ SkColorFilter* setColorFilter(SkColorFilter* filter);
+
+ /** Get the paint's xfermode object.
+ <p />
+ The xfermode's reference count is not affected.
+ @return the paint's xfermode (or NULL)
+ */
+ SkXfermode* getXfermode() const { return fXfermode; }
+
+ /** Set or clear the xfermode object.
+ <p />
+ Pass NULL to clear any previous xfermode.
+ As a convenience, the parameter passed is also returned.
+ If a previous xfermode exists, its reference count is decremented.
+ If xfermode is not NULL, its reference count is incremented.
+ @param xfermode May be NULL. The new xfermode to be installed in the
+ paint
+ @return xfermode
+ */
+ SkXfermode* setXfermode(SkXfermode* xfermode);
+
+ /** Create an xfermode based on the specified Mode, and assign it into the
+ paint, returning the mode that was set. If the Mode is SrcOver, then
+ the paint's xfermode is set to null.
+ */
+ SkXfermode* setXfermodeMode(SkXfermode::Mode);
+
+ /** Get the paint's patheffect object.
+ <p />
+ The patheffect reference count is not affected.
+ @return the paint's patheffect (or NULL)
+ */
+ SkPathEffect* getPathEffect() const { return fPathEffect; }
+
+ /** Set or clear the patheffect object.
+ <p />
+ Pass NULL to clear any previous patheffect.
+ As a convenience, the parameter passed is also returned.
+ If a previous patheffect exists, its reference count is decremented.
+ If patheffect is not NULL, its reference count is incremented.
+ @param effect May be NULL. The new patheffect to be installed in the
+ paint
+ @return effect
+ */
+ SkPathEffect* setPathEffect(SkPathEffect* effect);
+
+ /** Get the paint's maskfilter object.
+ <p />
+ The maskfilter reference count is not affected.
+ @return the paint's maskfilter (or NULL)
+ */
+ SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
+
+ /** Set or clear the maskfilter object.
+ <p />
+ Pass NULL to clear any previous maskfilter.
+ As a convenience, the parameter passed is also returned.
+ If a previous maskfilter exists, its reference count is decremented.
+ If maskfilter is not NULL, its reference count is incremented.
+ @param maskfilter May be NULL. The new maskfilter to be installed in
+ the paint
+ @return maskfilter
+ */
+ SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
+
+ // These attributes are for text/fonts
+
+ /** Get the paint's typeface object.
+ <p />
+ The typeface object identifies which font to use when drawing or
+ measuring text. The typeface reference count is not affected.
+ @return the paint's typeface (or NULL)
+ */
+ SkTypeface* getTypeface() const { return fTypeface; }
+
+ /** Set or clear the typeface object.
+ <p />
+ Pass NULL to clear any previous typeface.
+ As a convenience, the parameter passed is also returned.
+ If a previous typeface exists, its reference count is decremented.
+ If typeface is not NULL, its reference count is incremented.
+ @param typeface May be NULL. The new typeface to be installed in the
+ paint
+ @return typeface
+ */
+ SkTypeface* setTypeface(SkTypeface* typeface);
+
+ /** Get the paint's rasterizer (or NULL).
+ <p />
+ The raster controls how paths/text are turned into alpha masks.
+ @return the paint's rasterizer (or NULL)
+ */
+ SkRasterizer* getRasterizer() const { return fRasterizer; }
+
+ /** Set or clear the rasterizer object.
+ <p />
+ Pass NULL to clear any previous rasterizer.
+ As a convenience, the parameter passed is also returned.
+ If a previous rasterizer exists in the paint, its reference count is
+ decremented. If rasterizer is not NULL, its reference count is
+ incremented.
+ @param rasterizer May be NULL. The new rasterizer to be installed in
+ the paint.
+ @return rasterizer
+ */
+ SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
+
+ SkImageFilter* getImageFilter() const { return fImageFilter; }
+ SkImageFilter* setImageFilter(SkImageFilter*);
+
+ SkAnnotation* getAnnotation() const { return fAnnotation; }
+ SkAnnotation* setAnnotation(SkAnnotation*);
+
+ /**
+ * Returns true if there is an annotation installed on this paint, and
+ * the annotation specifics no-drawing.
+ */
+ SK_ATTR_DEPRECATED("use getAnnotation and check for non-null")
+ bool isNoDrawAnnotation() const { return this->getAnnotation() != NULL; }
+
+ /**
+ * Return the paint's SkDrawLooper (if any). Does not affect the looper's
+ * reference count.
+ */
+ SkDrawLooper* getLooper() const { return fLooper; }
+
+ /**
+ * Set or clear the looper object.
+ * <p />
+ * Pass NULL to clear any previous looper.
+ * As a convenience, the parameter passed is also returned.
+ * If a previous looper exists in the paint, its reference count is
+ * decremented. If looper is not NULL, its reference count is
+ * incremented.
+ * @param looper May be NULL. The new looper to be installed in the paint.
+ * @return looper
+ */
+ SkDrawLooper* setLooper(SkDrawLooper* looper);
+
+ enum Align {
+ kLeft_Align,
+ kCenter_Align,
+ kRight_Align,
+ };
+ enum {
+ kAlignCount = 3
+ };
+
+ /** Return the paint's Align value for drawing text.
+ @return the paint's Align value for drawing text.
+ */
+ Align getTextAlign() const { return (Align)fBitfields.fTextAlign; }
+
+ /** Set the paint's text alignment.
+ @param align set the paint's Align value for drawing text.
+ */
+ void setTextAlign(Align align);
+
+ /** Return the paint's text size.
+ @return the paint's text size.
+ */
+ SkScalar getTextSize() const { return fTextSize; }
+
+ /** Set the paint's text size. This value must be > 0
+ @param textSize set the paint's text size.
+ */
+ void setTextSize(SkScalar textSize);
+
+ /** Return the paint's horizontal scale factor for text. The default value
+ is 1.0.
+ @return the paint's scale factor in X for drawing/measuring text
+ */
+ SkScalar getTextScaleX() const { return fTextScaleX; }
+
+ /** Set the paint's horizontal scale factor for text. The default value
+ is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
+ stretch the text narrower.
+ @param scaleX set the paint's scale factor in X for drawing/measuring
+ text.
+ */
+ void setTextScaleX(SkScalar scaleX);
+
+ /** Return the paint's horizontal skew factor for text. The default value
+ is 0.
+ @return the paint's skew factor in X for drawing text.
+ */
+ SkScalar getTextSkewX() const { return fTextSkewX; }
+
+ /** Set the paint's horizontal skew factor for text. The default value
+ is 0. For approximating oblique text, use values around -0.25.
+ @param skewX set the paint's skew factor in X for drawing text.
+ */
+ void setTextSkewX(SkScalar skewX);
+
+ /** Describes how to interpret the text parameters that are passed to paint
+ methods like measureText() and getTextWidths().
+ */
+ enum TextEncoding {
+ kUTF8_TextEncoding, //!< the text parameters are UTF8
+ kUTF16_TextEncoding, //!< the text parameters are UTF16
+ kUTF32_TextEncoding, //!< the text parameters are UTF32
+ kGlyphID_TextEncoding //!< the text parameters are glyph indices
+ };
+
+ TextEncoding getTextEncoding() const {
+ return (TextEncoding)fBitfields.fTextEncoding;
+ }
+
+ void setTextEncoding(TextEncoding encoding);
+
+ struct FontMetrics {
+ /** Flags which indicate the confidence level of various metrics.
+ A set flag indicates that the metric may be trusted.
+ */
+ enum FontMetricsFlags {
+ kUnderlineThinknessIsValid_Flag = 1 << 0,
+ kUnderlinePositionIsValid_Flag = 1 << 1,
+ };
+
+ uint32_t fFlags; //!< Bit field to identify which values are unknown
+ SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
+ SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
+ SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
+ SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
+ SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
+ SkScalar fAvgCharWidth; //!< the average character width (>= 0)
+ SkScalar fMaxCharWidth; //!< the max character width (>= 0)
+ SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
+ SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
+ SkScalar fXHeight; //!< The height of an 'x' in px, or 0 if no 'x' in face
+ SkScalar fCapHeight; //!< The cap height (> 0), or 0 if cannot be determined.
+ SkScalar fUnderlineThickness; //!< underline thickness, or 0 if cannot be determined
+
+ /** Underline Position - position of the top of the Underline stroke
+ relative to the baseline, this can have following values
+ - Negative - means underline should be drawn above baseline.
+ - Positive - means below baseline.
+ - Zero - mean underline should be drawn on baseline.
+ */
+ SkScalar fUnderlinePosition; //!< underline position, or 0 if cannot be determined
+
+ /** If the fontmetrics has a valid underlinethickness, return true, and set the
+ thickness param to that value. If it doesn't return false and ignore the
+ thickness param.
+ */
+ bool hasUnderlineThickness(SkScalar* thickness) const {
+ if (SkToBool(fFlags & kUnderlineThinknessIsValid_Flag)) {
+ *thickness = fUnderlineThickness;
+ return true;
+ }
+ return false;
+ }
+
+ /** If the fontmetrics has a valid underlineposition, return true, and set the
+ thickness param to that value. If it doesn't return false and ignore the
+ thickness param.
+ */
+ bool hasUnderlinePosition(SkScalar* position) const {
+ if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
+ *position = fUnderlinePosition;
+ return true;
+ }
+ return false;
+ }
+
+ };
+
+ /** Return the recommend spacing between lines (which will be
+ fDescent - fAscent + fLeading).
+ If metrics is not null, return in it the font metrics for the
+ typeface/pointsize/etc. currently set in the paint.
+ @param metrics If not null, returns the font metrics for the
+ current typeface/pointsize/etc setting in this
+ paint.
+ @param scale If not 0, return width as if the canvas were scaled
+ by this value
+ @param return the recommended spacing between lines
+ */
+ SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
+
+ /** Return the recommend line spacing. This will be
+ fDescent - fAscent + fLeading
+ */
+ SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
+
+ /** Convert the specified text into glyph IDs, returning the number of
+ glyphs ID written. If glyphs is NULL, it is ignore and only the count
+ is returned.
+ */
+ int textToGlyphs(const void* text, size_t byteLength,
+ uint16_t glyphs[]) const;
+
+ /** Return true if all of the specified text has a corresponding non-zero
+ glyph ID. If any of the code-points in the text are not supported in
+ the typeface (i.e. the glyph ID would be zero), then return false.
+
+ If the text encoding for the paint is kGlyph_TextEncoding, then this
+ returns true if all of the specified glyph IDs are non-zero.
+ */
+ bool containsText(const void* text, size_t byteLength) const;
+
+ /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped
+ to zero. Note: this does not look at the text-encoding setting in the
+ paint, only at the typeface.
+ */
+ void glyphsToUnichars(const uint16_t glyphs[], int count,
+ SkUnichar text[]) const;
+
+ /** Return the number of drawable units in the specified text buffer.
+ This looks at the current TextEncoding field of the paint. If you also
+ want to have the text converted into glyph IDs, call textToGlyphs
+ instead.
+ */
+ int countText(const void* text, size_t byteLength) const {
+ return this->textToGlyphs(text, byteLength, NULL);
+ }
+
+ /** Return the width of the text. This will return the vertical measure
+ * if isVerticalText() is true, in which case the returned value should
+ * be treated has a height instead of a width.
+ *
+ * @param text The text to be measured
+ * @param length Number of bytes of text to measure
+ * @param bounds If not NULL, returns the bounds of the text,
+ * relative to (0, 0).
+ * @return The advance width of the text
+ */
+ SkScalar measureText(const void* text, size_t length, SkRect* bounds) const;
+
+ /** Return the width of the text. This will return the vertical measure
+ * if isVerticalText() is true, in which case the returned value should
+ * be treated has a height instead of a width.
+ *
+ * @param text Address of the text
+ * @param length Number of bytes of text to measure
+ * @return The advance width of the text
+ */
+ SkScalar measureText(const void* text, size_t length) const {
+ return this->measureText(text, length, NULL);
+ }
+
+ /** Specify the direction the text buffer should be processed in breakText()
+ */
+ enum TextBufferDirection {
+ /** When measuring text for breakText(), begin at the start of the text
+ buffer and proceed forward through the data. This is the default.
+ */
+ kForward_TextBufferDirection,
+ /** When measuring text for breakText(), begin at the end of the text
+ buffer and proceed backwards through the data.
+ */
+ kBackward_TextBufferDirection
+ };
+
+ /** Return the number of bytes of text that were measured. If
+ * isVerticalText() is true, then the vertical advances are used for
+ * the measurement.
+ *
+ * @param text The text to be measured
+ * @param length Number of bytes of text to measure
+ * @param maxWidth Maximum width. Only the subset of text whose accumulated
+ * widths are <= maxWidth are measured.
+ * @param measuredWidth Optional. If non-null, this returns the actual
+ * width of the measured text.
+ * @param tbd Optional. The direction the text buffer should be
+ * traversed during measuring.
+ * @return The number of bytes of text that were measured. Will be
+ * <= length.
+ */
+ size_t breakText(const void* text, size_t length, SkScalar maxWidth,
+ SkScalar* measuredWidth = NULL,
+ TextBufferDirection tbd = kForward_TextBufferDirection)
+ const;
+
+ /** Return the advances for the text. These will be vertical advances if
+ * isVerticalText() returns true.
+ *
+ * @param text the text
+ * @param byteLength number of bytes to of text
+ * @param widths If not null, returns the array of advances for
+ * the glyphs. If not NULL, must be at least a large
+ * as the number of unichars in the specified text.
+ * @param bounds If not null, returns the bounds for each of
+ * character, relative to (0, 0)
+ * @return the number of unichars in the specified text.
+ */
+ int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
+ SkRect bounds[] = NULL) const;
+
+ /** Return the path (outline) for the specified text.
+ Note: just like SkCanvas::drawText, this will respect the Align setting
+ in the paint.
+ */
+ void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
+ SkPath* path) const;
+
+ void getPosTextPath(const void* text, size_t length,
+ const SkPoint pos[], SkPath* path) const;
+
+#ifdef SK_BUILD_FOR_ANDROID
+ uint32_t getGenerationID() const;
+ void setGenerationID(uint32_t generationID);
+#endif
+
+ // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
+ // mean that we need not draw at all (e.g. SrcOver + 0-alpha)
+ bool nothingToDraw() const;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // would prefer to make these private...
+
+ /** Returns true if the current paint settings allow for fast computation of
+ bounds (i.e. there is nothing complex like a patheffect that would make
+ the bounds computation expensive.
+ */
+ bool canComputeFastBounds() const {
+ if (this->getLooper()) {
+ return this->getLooper()->canComputeFastBounds(*this);
+ }
+ return !this->getRasterizer();
+ }
+
+ /** Only call this if canComputeFastBounds() returned true. This takes a
+ raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
+ effects in the paint (e.g. stroking). If needed, it uses the storage
+ rect parameter. It returns the adjusted bounds that can then be used
+ for quickReject tests.
+
+ The returned rect will either be orig or storage, thus the caller
+ should not rely on storage being set to the result, but should always
+ use the retured value. It is legal for orig and storage to be the same
+ rect.
+
+ e.g.
+ if (paint.canComputeFastBounds()) {
+ SkRect r, storage;
+ path.computeBounds(&r, SkPath::kFast_BoundsType);
+ const SkRect& fastR = paint.computeFastBounds(r, &storage);
+ if (canvas->quickReject(fastR, ...)) {
+ // don't draw the path
+ }
+ }
+ */
+ const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
+ SkPaint::Style style = this->getStyle();
+ // ultra fast-case: filling with no effects that affect geometry
+ if (kFill_Style == style) {
+ uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
+ effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
+ effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
+ effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
+ if (!effects) {
+ return orig;
+ }
+ }
+
+ return this->doComputeFastBounds(orig, storage, style);
+ }
+
+ const SkRect& computeFastStrokeBounds(const SkRect& orig,
+ SkRect* storage) const {
+ return this->doComputeFastBounds(orig, storage, kStroke_Style);
+ }
+
+ // Take the style explicitly, so the caller can force us to be stroked
+ // without having to make a copy of the paint just to change that field.
+ const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
+ Style) const;
+
+ /**
+ * Return a matrix that applies the paint's text values: size, scale, skew
+ */
+ static SkMatrix* SetTextMatrix(SkMatrix* matrix, SkScalar size,
+ SkScalar scaleX, SkScalar skewX) {
+ matrix->setScale(size * scaleX, size);
+ if (skewX) {
+ matrix->postSkew(skewX, 0);
+ }
+ return matrix;
+ }
+
+ SkMatrix* setTextMatrix(SkMatrix* matrix) const {
+ return SetTextMatrix(matrix, fTextSize, fTextScaleX, fTextSkewX);
+ }
+
+ SK_TO_STRING_NONVIRT()
+
+ struct FlatteningTraits {
+ static void Flatten(SkWriteBuffer& buffer, const SkPaint& paint);
+ static void Unflatten(SkReadBuffer& buffer, SkPaint* paint);
+ };
+
+private:
+ SkTypeface* fTypeface;
+ SkPathEffect* fPathEffect;
+ SkShader* fShader;
+ SkXfermode* fXfermode;
+ SkMaskFilter* fMaskFilter;
+ SkColorFilter* fColorFilter;
+ SkRasterizer* fRasterizer;
+ SkDrawLooper* fLooper;
+ SkImageFilter* fImageFilter;
+ SkAnnotation* fAnnotation;
+
+ SkScalar fTextSize;
+ SkScalar fTextScaleX;
+ SkScalar fTextSkewX;
+ SkColor fColor;
+ SkScalar fWidth;
+ SkScalar fMiterLimit;
+ union {
+ struct {
+ // all of these bitfields should add up to 32
+ unsigned fFlags : 16;
+ unsigned fTextAlign : 2;
+ unsigned fCapType : 2;
+ unsigned fJoinType : 2;
+ unsigned fStyle : 2;
+ unsigned fTextEncoding : 2; // 3 values
+ unsigned fHinting : 2;
+ unsigned fFilterLevel : 2;
+ //unsigned fFreeBits : 2;
+ } fBitfields;
+ uint32_t fBitfieldsUInt;
+ };
+ uint32_t fDirtyBits;
+
+ SkDrawCacheProc getDrawCacheProc() const;
+ SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
+ bool needFullMetrics) const;
+
+ SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
+ int* count, SkRect* bounds) const;
+
+ SkGlyphCache* detachCache(const SkDeviceProperties* deviceProperties, const SkMatrix*,
+ bool ignoreGamma) const;
+
+ void descriptorProc(const SkDeviceProperties* deviceProperties, const SkMatrix* deviceMatrix,
+ void (*proc)(SkTypeface*, const SkDescriptor*, void*),
+ void* context, bool ignoreGamma = false) const;
+
+ static void Term();
+
+ enum {
+ /* This is the size we use when we ask for a glyph's path. We then
+ * post-transform it as we draw to match the request.
+ * This is done to try to re-use cache entries for the path.
+ *
+ * This value is somewhat arbitrary. In theory, it could be 1, since
+ * we store paths as floats. However, we get the path from the font
+ * scaler, and it may represent its paths as fixed-point (or 26.6),
+ * so we shouldn't ask for something too big (might overflow 16.16)
+ * or too small (underflow 26.6).
+ *
+ * This value could track kMaxSizeForGlyphCache, assuming the above
+ * constraints, but since we ask for unhinted paths, the two values
+ * need not match per-se.
+ */
+ kCanonicalTextSizeForPaths = 64,
+
+ /*
+ * Above this size (taking into account CTM and textSize), we never use
+ * the cache for bits or metrics (we might overflow), so we just ask
+ * for a caononical size and post-transform that.
+ */
+ kMaxSizeForGlyphCache = 256,
+ };
+
+ static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM);
+
+ // Set flags/hinting/textSize up to use for drawing text as paths.
+ // Returns scale factor to restore the original textSize, since will will
+ // have change it to kCanonicalTextSizeForPaths.
+ SkScalar setupForAsPaths();
+
+ static SkScalar MaxCacheSize2() {
+ static const SkScalar kMaxSize = SkIntToScalar(kMaxSizeForGlyphCache);
+ static const SkScalar kMag2Max = kMaxSize * kMaxSize;
+ return kMag2Max;
+ }
+
+ friend class SkAutoGlyphCache;
+ friend class SkAutoGlyphCacheNoGamma;
+ friend class SkCanvas;
+ friend class SkDraw;
+ friend class SkGraphics; // So Term() can be called.
+ friend class SkPDFDevice;
+ friend class GrBitmapTextContext;
+ friend class GrDistanceFieldTextContext;
+ friend class GrStencilAndCoverTextContext;
+ friend class GrPathRendering;
+ friend class GrGLPathRendering;
+ friend class SkTextToPathIter;
+ friend class SkCanonicalizePaint;
+
+#ifdef SK_BUILD_FOR_ANDROID
+ // In order for the == operator to work properly this must be the last field
+ // in the struct so that we can do a memcmp to this field's offset.
+ uint32_t fGenerationID;
+#endif
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPath.h b/src/third_party/skia/include/core/SkPath.h
new file mode 100644
index 0000000..57da959
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPath.h
@@ -0,0 +1,1051 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPath_DEFINED
+#define SkPath_DEFINED
+
+#include "SkInstCnt.h"
+#include "SkMatrix.h"
+#include "SkPathRef.h"
+#include "SkTDArray.h"
+#include "SkRefCnt.h"
+
+class SkReader32;
+class SkWriter32;
+class SkAutoPathBoundsUpdate;
+class SkString;
+class SkRRect;
+class SkWStream;
+
+/** \class SkPath
+
+ The SkPath class encapsulates compound (multiple contour) geometric paths
+ consisting of straight line segments, quadratic curves, and cubic curves.
+*/
+class SK_API SkPath {
+public:
+ SK_DECLARE_INST_COUNT_ROOT(SkPath);
+
+ SkPath();
+ SkPath(const SkPath&);
+ ~SkPath();
+
+ SkPath& operator=(const SkPath&);
+ friend SK_API bool operator==(const SkPath&, const SkPath&);
+ friend bool operator!=(const SkPath& a, const SkPath& b) {
+ return !(a == b);
+ }
+
+ enum FillType {
+ /** Specifies that "inside" is computed by a non-zero sum of signed
+ edge crossings
+ */
+ kWinding_FillType,
+ /** Specifies that "inside" is computed by an odd number of edge
+ crossings
+ */
+ kEvenOdd_FillType,
+ /** Same as Winding, but draws outside of the path, rather than inside
+ */
+ kInverseWinding_FillType,
+ /** Same as EvenOdd, but draws outside of the path, rather than inside
+ */
+ kInverseEvenOdd_FillType
+ };
+
+ /** Return the path's fill type. This is used to define how "inside" is
+ computed. The default value is kWinding_FillType.
+
+ @return the path's fill type
+ */
+ FillType getFillType() const { return (FillType)fFillType; }
+
+ /** Set the path's fill type. This is used to define how "inside" is
+ computed. The default value is kWinding_FillType.
+
+ @param ft The new fill type for this path
+ */
+ void setFillType(FillType ft) {
+ fFillType = SkToU8(ft);
+ }
+
+ /** Returns true if the filltype is one of the Inverse variants */
+ bool isInverseFillType() const { return IsInverseFillType((FillType)fFillType); }
+
+ /**
+ * Toggle between inverse and normal filltypes. This reverse the return
+ * value of isInverseFillType()
+ */
+ void toggleInverseFillType() {
+ fFillType ^= 2;
+ }
+
+ enum Convexity {
+ kUnknown_Convexity,
+ kConvex_Convexity,
+ kConcave_Convexity
+ };
+
+ /**
+ * Return the path's convexity, as stored in the path. If it is currently unknown,
+ * then this function will attempt to compute the convexity (and cache the result).
+ */
+ Convexity getConvexity() const {
+ if (kUnknown_Convexity != fConvexity) {
+ return static_cast<Convexity>(fConvexity);
+ } else {
+ return this->internalGetConvexity();
+ }
+ }
+
+ /**
+ * Return the currently cached value for convexity, even if that is set to
+ * kUnknown_Convexity. Note: getConvexity() will automatically call
+ * ComputeConvexity and cache its return value if the current setting is
+ * kUnknown.
+ */
+ Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; }
+
+ /**
+ * Store a convexity setting in the path. There is no automatic check to
+ * see if this value actually agrees with the return value that would be
+ * computed by getConvexity().
+ *
+ * Note: even if this is set to a "known" value, if the path is later
+ * changed (e.g. lineTo(), addRect(), etc.) then the cached value will be
+ * reset to kUnknown_Convexity.
+ */
+ void setConvexity(Convexity);
+
+ /**
+ * Returns true if the path is flagged as being convex. This is not a
+ * confirmed by any analysis, it is just the value set earlier.
+ */
+ bool isConvex() const {
+ return kConvex_Convexity == this->getConvexity();
+ }
+
+ /**
+ * Set the isConvex flag to true or false. Convex paths may draw faster if
+ * this flag is set, though setting this to true on a path that is in fact
+ * not convex can give undefined results when drawn. Paths default to
+ * isConvex == false
+ */
+ SK_ATTR_DEPRECATED("use setConvexity")
+ void setIsConvex(bool isConvex) {
+ this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity);
+ }
+
+ /** Returns true if the path is an oval.
+ *
+ * @param rect returns the bounding rect of this oval. It's a circle
+ * if the height and width are the same.
+ *
+ * @return true if this path is an oval.
+ * Tracking whether a path is an oval is considered an
+ * optimization for performance and so some paths that are in
+ * fact ovals can report false.
+ */
+ bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); }
+
+ /** Clear any lines and curves from the path, making it empty. This frees up
+ internal storage associated with those segments.
+ On Android, does not change fSourcePath.
+ */
+ void reset();
+
+ /** Similar to reset(), in that all lines and curves are removed from the
+ path. However, any internal storage for those lines/curves is retained,
+ making reuse of the path potentially faster.
+ On Android, does not change fSourcePath.
+ */
+ void rewind();
+
+ /** Returns true if the path is empty (contains no lines or curves)
+
+ @return true if the path is empty (contains no lines or curves)
+ */
+ bool isEmpty() const {
+ SkDEBUGCODE(this->validate();)
+ return 0 == fPathRef->countVerbs();
+ }
+
+ /**
+ * Returns true if all of the points in this path are finite, meaning there
+ * are no infinities and no NaNs.
+ */
+ bool isFinite() const {
+ SkDEBUGCODE(this->validate();)
+ return fPathRef->isFinite();
+ }
+
+ /** Test a line for zero length
+
+ @return true if the line is of zero length; otherwise false.
+ */
+ static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2) {
+ return p1.equalsWithinTolerance(p2);
+ }
+
+ /** Test a quad for zero length
+
+ @return true if the quad is of zero length; otherwise false.
+ */
+ static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2,
+ const SkPoint& p3) {
+ return p1.equalsWithinTolerance(p2) &&
+ p2.equalsWithinTolerance(p3);
+ }
+
+ /** Test a cubic curve for zero length
+
+ @return true if the cubic is of zero length; otherwise false.
+ */
+ static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
+ const SkPoint& p3, const SkPoint& p4) {
+ return p1.equalsWithinTolerance(p2) &&
+ p2.equalsWithinTolerance(p3) &&
+ p3.equalsWithinTolerance(p4);
+ }
+
+ /**
+ * Returns true if the path specifies a single line (i.e. it contains just
+ * a moveTo and a lineTo). If so, and line[] is not null, it sets the 2
+ * points in line[] to the end-points of the line. If the path is not a
+ * line, returns false and ignores line[].
+ */
+ bool isLine(SkPoint line[2]) const;
+
+ /** Returns true if the path specifies a rectangle. If so, and if rect is
+ not null, set rect to the bounds of the path. If the path does not
+ specify a rectangle, return false and ignore rect.
+
+ @param rect If not null, returns the bounds of the path if it specifies
+ a rectangle
+ @return true if the path specifies a rectangle
+ */
+ bool isRect(SkRect* rect) const;
+
+ /** Return the number of points in the path
+ */
+ int countPoints() const;
+
+ /** Return the point at the specified index. If the index is out of range
+ (i.e. is not 0 <= index < countPoints()) then the returned coordinates
+ will be (0,0)
+ */
+ SkPoint getPoint(int index) const;
+
+ /** Returns the number of points in the path. Up to max points are copied.
+
+ @param points If not null, receives up to max points
+ @param max The maximum number of points to copy into points
+ @return the actual number of points in the path
+ */
+ int getPoints(SkPoint points[], int max) const;
+
+ /** Return the number of verbs in the path
+ */
+ int countVerbs() const;
+
+ /** Returns the number of verbs in the path. Up to max verbs are copied. The
+ verbs are copied as one byte per verb.
+
+ @param verbs If not null, receives up to max verbs
+ @param max The maximum number of verbs to copy into verbs
+ @return the actual number of verbs in the path
+ */
+ int getVerbs(uint8_t verbs[], int max) const;
+
+ //! Swap contents of this and other. Guaranteed not to throw
+ void swap(SkPath& other);
+
+ /** Returns the bounds of the path's points. If the path contains 0 or 1
+ points, the bounds is set to (0,0,0,0), and isEmpty() will return true.
+ Note: this bounds may be larger than the actual shape, since curves
+ do not extend as far as their control points.
+ */
+ const SkRect& getBounds() const {
+ return fPathRef->getBounds();
+ }
+
+ /** Calling this will, if the internal cache of the bounds is out of date,
+ update it so that subsequent calls to getBounds will be instantaneous.
+ This also means that any copies or simple transformations of the path
+ will inherit the cached bounds.
+ */
+ void updateBoundsCache() const {
+ // for now, just calling getBounds() is sufficient
+ this->getBounds();
+ }
+
+ /**
+ * Does a conservative test to see whether a rectangle is inside a path. Currently it only
+ * will ever return true for single convex contour paths. The empty-status of the rect is not
+ * considered (e.g. a rect that is a point can be inside a path). Points or line segments where
+ * the rect edge touches the path border are not considered containment violations.
+ */
+ bool conservativelyContainsRect(const SkRect& rect) const;
+
+ // Construction methods
+
+ /** Hint to the path to prepare for adding more points. This can allow the
+ path to more efficiently grow its storage.
+
+ @param extraPtCount The number of extra points the path should
+ preallocate for.
+ */
+ void incReserve(unsigned extraPtCount);
+
+ /** Set the beginning of the next contour to the point (x,y).
+
+ @param x The x-coordinate of the start of a new contour
+ @param y The y-coordinate of the start of a new contour
+ */
+ void moveTo(SkScalar x, SkScalar y);
+
+ /** Set the beginning of the next contour to the point
+
+ @param p The start of a new contour
+ */
+ void moveTo(const SkPoint& p) {
+ this->moveTo(p.fX, p.fY);
+ }
+
+ /** Set the beginning of the next contour relative to the last point on the
+ previous contour. If there is no previous contour, this is treated the
+ same as moveTo().
+
+ @param dx The amount to add to the x-coordinate of the end of the
+ previous contour, to specify the start of a new contour
+ @param dy The amount to add to the y-coordinate of the end of the
+ previous contour, to specify the start of a new contour
+ */
+ void rMoveTo(SkScalar dx, SkScalar dy);
+
+ /** Add a line from the last point to the specified point (x,y). If no
+ moveTo() call has been made for this contour, the first point is
+ automatically set to (0,0).
+
+ @param x The x-coordinate of the end of a line
+ @param y The y-coordinate of the end of a line
+ */
+ void lineTo(SkScalar x, SkScalar y);
+
+ /** Add a line from the last point to the specified point. If no moveTo()
+ call has been made for this contour, the first point is automatically
+ set to (0,0).
+
+ @param p The end of a line
+ */
+ void lineTo(const SkPoint& p) {
+ this->lineTo(p.fX, p.fY);
+ }
+
+ /** Same as lineTo, but the coordinates are considered relative to the last
+ point on this contour. If there is no previous point, then a moveTo(0,0)
+ is inserted automatically.
+
+ @param dx The amount to add to the x-coordinate of the previous point
+ on this contour, to specify a line
+ @param dy The amount to add to the y-coordinate of the previous point
+ on this contour, to specify a line
+ */
+ void rLineTo(SkScalar dx, SkScalar dy);
+
+ /** Add a quadratic bezier from the last point, approaching control point
+ (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
+ this contour, the first point is automatically set to (0,0).
+
+ @param x1 The x-coordinate of the control point on a quadratic curve
+ @param y1 The y-coordinate of the control point on a quadratic curve
+ @param x2 The x-coordinate of the end point on a quadratic curve
+ @param y2 The y-coordinate of the end point on a quadratic curve
+ */
+ void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
+
+ /** Add a quadratic bezier from the last point, approaching control point
+ p1, and ending at p2. If no moveTo() call has been made for this
+ contour, the first point is automatically set to (0,0).
+
+ @param p1 The control point on a quadratic curve
+ @param p2 The end point on a quadratic curve
+ */
+ void quadTo(const SkPoint& p1, const SkPoint& p2) {
+ this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
+ }
+
+ /** Same as quadTo, but the coordinates are considered relative to the last
+ point on this contour. If there is no previous point, then a moveTo(0,0)
+ is inserted automatically.
+
+ @param dx1 The amount to add to the x-coordinate of the last point on
+ this contour, to specify the control point of a quadratic curve
+ @param dy1 The amount to add to the y-coordinate of the last point on
+ this contour, to specify the control point of a quadratic curve
+ @param dx2 The amount to add to the x-coordinate of the last point on
+ this contour, to specify the end point of a quadratic curve
+ @param dy2 The amount to add to the y-coordinate of the last point on
+ this contour, to specify the end point of a quadratic curve
+ */
+ void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
+
+ void conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
+ SkScalar w);
+ void conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) {
+ this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w);
+ }
+ void rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
+ SkScalar w);
+
+ /** Add a cubic bezier from the last point, approaching control points
+ (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
+ made for this contour, the first point is automatically set to (0,0).
+
+ @param x1 The x-coordinate of the 1st control point on a cubic curve
+ @param y1 The y-coordinate of the 1st control point on a cubic curve
+ @param x2 The x-coordinate of the 2nd control point on a cubic curve
+ @param y2 The y-coordinate of the 2nd control point on a cubic curve
+ @param x3 The x-coordinate of the end point on a cubic curve
+ @param y3 The y-coordinate of the end point on a cubic curve
+ */
+ void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
+ SkScalar x3, SkScalar y3);
+
+ /** Add a cubic bezier from the last point, approaching control points p1
+ and p2, and ending at p3. If no moveTo() call has been made for this
+ contour, the first point is automatically set to (0,0).
+
+ @param p1 The 1st control point on a cubic curve
+ @param p2 The 2nd control point on a cubic curve
+ @param p3 The end point on a cubic curve
+ */
+ void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
+ this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
+ }
+
+ /** Same as cubicTo, but the coordinates are considered relative to the
+ current point on this contour. If there is no previous point, then a
+ moveTo(0,0) is inserted automatically.
+
+ @param dx1 The amount to add to the x-coordinate of the last point on
+ this contour, to specify the 1st control point of a cubic curve
+ @param dy1 The amount to add to the y-coordinate of the last point on
+ this contour, to specify the 1st control point of a cubic curve
+ @param dx2 The amount to add to the x-coordinate of the last point on
+ this contour, to specify the 2nd control point of a cubic curve
+ @param dy2 The amount to add to the y-coordinate of the last point on
+ this contour, to specify the 2nd control point of a cubic curve
+ @param dx3 The amount to add to the x-coordinate of the last point on
+ this contour, to specify the end point of a cubic curve
+ @param dy3 The amount to add to the y-coordinate of the last point on
+ this contour, to specify the end point of a cubic curve
+ */
+ void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
+ SkScalar x3, SkScalar y3);
+
+ /** Append the specified arc to the path as a new contour. If the start of
+ the path is different from the path's current last point, then an
+ automatic lineTo() is added to connect the current contour to the start
+ of the arc. However, if the path is empty, then we call moveTo() with
+ the first point of the arc. The sweep angle is treated mod 360.
+
+ @param oval The bounding oval defining the shape and size of the arc
+ @param startAngle Starting angle (in degrees) where the arc begins
+ @param sweepAngle Sweep angle (in degrees) measured clockwise. This is
+ treated mod 360.
+ @param forceMoveTo If true, always begin a new contour with the arc
+ */
+ void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
+ bool forceMoveTo);
+
+ /** Append a line and arc to the current path. This is the same as the
+ PostScript call "arct".
+ */
+ void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
+ SkScalar radius);
+
+ /** Append a line and arc to the current path. This is the same as the
+ PostScript call "arct".
+ */
+ void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
+ this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
+ }
+
+ /** Close the current contour. If the current point is not equal to the
+ first point of the contour, a line segment is automatically added.
+ */
+ void close();
+
+ enum Direction {
+ /** Direction either has not been or could not be computed */
+ kUnknown_Direction,
+ /** clockwise direction for adding closed contours */
+ kCW_Direction,
+ /** counter-clockwise direction for adding closed contours */
+ kCCW_Direction,
+ };
+
+ /**
+ * Return the opposite of the specified direction. kUnknown is its own
+ * opposite.
+ */
+ static Direction OppositeDirection(Direction dir) {
+ static const Direction gOppositeDir[] = {
+ kUnknown_Direction, kCCW_Direction, kCW_Direction
+ };
+ return gOppositeDir[dir];
+ }
+
+ /**
+ * Returns whether or not a fill type is inverted
+ *
+ * kWinding_FillType -> false
+ * kEvenOdd_FillType -> false
+ * kInverseWinding_FillType -> true
+ * kInverseEvenOdd_FillType -> true
+ */
+ static bool IsInverseFillType(FillType fill) {
+ SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch);
+ return (fill & 2) != 0;
+ }
+
+ /**
+ * Returns the equivalent non-inverted fill type to the given fill type
+ *
+ * kWinding_FillType -> kWinding_FillType
+ * kEvenOdd_FillType -> kEvenOdd_FillType
+ * kInverseWinding_FillType -> kWinding_FillType
+ * kInverseEvenOdd_FillType -> kEvenOdd_FillType
+ */
+ static FillType ConvertToNonInverseFillType(FillType fill) {
+ SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch);
+ SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch);
+ return (FillType)(fill & 1);
+ }
+
+ /**
+ * Tries to quickly compute the direction of the first non-degenerate
+ * contour. If it can be computed, return true and set dir to that
+ * direction. If it cannot be (quickly) determined, return false and ignore
+ * the dir parameter. If the direction was determined, it is cached to make
+ * subsequent calls return quickly.
+ */
+ bool cheapComputeDirection(Direction* dir) const;
+
+ /**
+ * Returns true if the path's direction can be computed via
+ * cheapComputDirection() and if that computed direction matches the
+ * specified direction. If dir is kUnknown, returns true if the direction
+ * cannot be computed.
+ */
+ bool cheapIsDirection(Direction dir) const {
+ Direction computedDir = kUnknown_Direction;
+ (void)this->cheapComputeDirection(&computedDir);
+ return computedDir == dir;
+ }
+
+ enum PathAsRect {
+ /** The path can not draw the same as its bounds. */
+ kNone_PathAsRect,
+ /** The path draws the same as its bounds when filled. */
+ kFill_PathAsRect,
+ /** The path draws the same as its bounds when stroked or filled. */
+ kStroke_PathAsRect,
+ };
+
+ /** Returns kFill_PathAsRect or kStroke_PathAsRect if drawing the path (either filled or
+ stroked) will be equivalent to filling/stroking the path's bounding rect. If
+ either is true, and direction is not null, sets the direction of the contour. If the
+ path is not drawn equivalent to a rect, returns kNone_PathAsRect and ignores direction.
+
+ @param direction If not null, set to the contour's direction when it is drawn as a rect
+ @return the path's PathAsRect type
+ */
+ PathAsRect asRect(Direction* direction = NULL) const;
+
+ /** Returns true if the path specifies a rectangle. If so, and if isClosed is
+ not null, set isClosed to true if the path is closed. Also, if returning true
+ and direction is not null, return the rect direction. If the path does not
+ specify a rectangle, return false and ignore isClosed and direction.
+
+ @param isClosed If not null, set to true if the path is closed
+ @param direction If not null, set to the rectangle's direction
+ @return true if the path specifies a rectangle
+ */
+ bool isRect(bool* isClosed, Direction* direction) const;
+
+ /** Returns true if the path specifies a pair of nested rectangles. If so, and if
+ rect is not null, set rect[0] to the outer rectangle and rect[1] to the inner
+ rectangle. If so, and dirs is not null, set dirs[0] to the direction of
+ the outer rectangle and dirs[1] to the direction of the inner rectangle. If
+ the path does not specify a pair of nested rectangles, return
+ false and ignore rect and dirs.
+
+ @param rect If not null, returns the path as a pair of nested rectangles
+ @param dirs If not null, returns the direction of the rects
+ @return true if the path describes a pair of nested rectangles
+ */
+ bool isNestedRects(SkRect rect[2], Direction dirs[2] = NULL) const;
+
+ /**
+ * Add a closed rectangle contour to the path
+ * @param rect The rectangle to add as a closed contour to the path
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ */
+ void addRect(const SkRect& rect, Direction dir = kCW_Direction);
+
+ /**
+ * Add a closed rectangle contour to the path
+ *
+ * @param left The left side of a rectangle to add as a closed contour
+ * to the path
+ * @param top The top of a rectangle to add as a closed contour to the
+ * path
+ * @param right The right side of a rectangle to add as a closed contour
+ * to the path
+ * @param bottom The bottom of a rectangle to add as a closed contour to
+ * the path
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ */
+ void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
+ Direction dir = kCW_Direction);
+
+ /**
+ * Add a closed oval contour to the path
+ *
+ * @param oval The bounding oval to add as a closed contour to the path
+ * @param dir The direction to wind the oval's contour. Cannot be
+ * kUnknown_Direction.
+ */
+ void addOval(const SkRect& oval, Direction dir = kCW_Direction);
+
+ /**
+ * Add a closed circle contour to the path
+ *
+ * @param x The x-coordinate of the center of a circle to add as a
+ * closed contour to the path
+ * @param y The y-coordinate of the center of a circle to add as a
+ * closed contour to the path
+ * @param radius The radius of a circle to add as a closed contour to the
+ * path
+ * @param dir The direction to wind the circle's contour. Cannot be
+ * kUnknown_Direction.
+ */
+ void addCircle(SkScalar x, SkScalar y, SkScalar radius,
+ Direction dir = kCW_Direction);
+
+ /** Add the specified arc to the path as a new contour.
+
+ @param oval The bounds of oval used to define the size of the arc
+ @param startAngle Starting angle (in degrees) where the arc begins
+ @param sweepAngle Sweep angle (in degrees) measured clockwise
+ */
+ void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
+
+ /**
+ * Add a closed round-rectangle contour to the path
+ * @param rect The bounds of a round-rectangle to add as a closed contour
+ * @param rx The x-radius of the rounded corners on the round-rectangle
+ * @param ry The y-radius of the rounded corners on the round-rectangle
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ */
+ void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
+ Direction dir = kCW_Direction);
+
+ /**
+ * Add a closed round-rectangle contour to the path. Each corner receives
+ * two radius values [X, Y]. The corners are ordered top-left, top-right,
+ * bottom-right, bottom-left.
+ * @param rect The bounds of a round-rectangle to add as a closed contour
+ * @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ * Note: The radii here now go through the same constraint handling as the
+ * SkRRect radii (i.e., either radii at a corner being 0 implies a
+ * sqaure corner and oversized radii are proportionally scaled down).
+ */
+ void addRoundRect(const SkRect& rect, const SkScalar radii[],
+ Direction dir = kCW_Direction);
+
+ /**
+ * Add an SkRRect contour to the path
+ * @param rrect The rounded rect to add as a closed contour
+ * @param dir The winding direction for the new contour. Cannot be
+ * kUnknown_Direction.
+ */
+ void addRRect(const SkRRect& rrect, Direction dir = kCW_Direction);
+
+ /**
+ * Add a new contour made of just lines. This is just a fast version of
+ * the following:
+ * this->moveTo(pts[0]);
+ * for (int i = 1; i < count; ++i) {
+ * this->lineTo(pts[i]);
+ * }
+ * if (close) {
+ * this->close();
+ * }
+ */
+ void addPoly(const SkPoint pts[], int count, bool close);
+
+ enum AddPathMode {
+ /** Source path contours are added as new contours.
+ */
+ kAppend_AddPathMode,
+ /** Path is added by extending the last contour of the destination path
+ with the first contour of the source path. If the last contour of
+ the destination path is closed, then it will not be extended.
+ Instead, the start of source path will be extended by a straight
+ line to the end point of the destination path.
+ */
+ kExtend_AddPathMode
+ };
+
+ /** Add a copy of src to the path, offset by (dx,dy)
+ @param src The path to add as a new contour
+ @param dx The amount to translate the path in X as it is added
+ @param dx The amount to translate the path in Y as it is added
+ */
+ void addPath(const SkPath& src, SkScalar dx, SkScalar dy,
+ AddPathMode mode = kAppend_AddPathMode);
+
+ /** Add a copy of src to the path
+ */
+ void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
+ SkMatrix m;
+ m.reset();
+ this->addPath(src, m, mode);
+ }
+
+ /** Add a copy of src to the path, transformed by matrix
+ @param src The path to add as a new contour
+ @param matrix Transform applied to src
+ @param mode Determines how path is added
+ */
+ void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode);
+
+ /**
+ * Same as addPath(), but reverses the src input
+ */
+ void reverseAddPath(const SkPath& src);
+
+ /** Offset the path by (dx,dy), returning true on success
+
+ @param dx The amount in the X direction to offset the entire path
+ @param dy The amount in the Y direction to offset the entire path
+ @param dst The translated path is written here
+ */
+ void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
+
+ /** Offset the path by (dx,dy), returning true on success
+
+ @param dx The amount in the X direction to offset the entire path
+ @param dy The amount in the Y direction to offset the entire path
+ */
+ void offset(SkScalar dx, SkScalar dy) {
+ this->offset(dx, dy, this);
+ }
+
+ /** Transform the points in this path by matrix, and write the answer into
+ dst.
+
+ @param matrix The matrix to apply to the path
+ @param dst The transformed path is written here
+ */
+ void transform(const SkMatrix& matrix, SkPath* dst) const;
+
+ /** Transform the points in this path by matrix
+
+ @param matrix The matrix to apply to the path
+ */
+ void transform(const SkMatrix& matrix) {
+ this->transform(matrix, this);
+ }
+
+ /** Return the last point on the path. If no points have been added, (0,0)
+ is returned. If there are no points, this returns false, otherwise it
+ returns true.
+
+ @param lastPt The last point on the path is returned here
+ */
+ bool getLastPt(SkPoint* lastPt) const;
+
+ /** Set the last point on the path. If no points have been added,
+ moveTo(x,y) is automatically called.
+
+ @param x The new x-coordinate for the last point
+ @param y The new y-coordinate for the last point
+ */
+ void setLastPt(SkScalar x, SkScalar y);
+
+ /** Set the last point on the path. If no points have been added, moveTo(p)
+ is automatically called.
+
+ @param p The new location for the last point
+ */
+ void setLastPt(const SkPoint& p) {
+ this->setLastPt(p.fX, p.fY);
+ }
+
+ enum SegmentMask {
+ kLine_SegmentMask = 1 << 0,
+ kQuad_SegmentMask = 1 << 1,
+ kConic_SegmentMask = 1 << 2,
+ kCubic_SegmentMask = 1 << 3,
+ };
+
+ /**
+ * Returns a mask, where each bit corresponding to a SegmentMask is
+ * set if the path contains 1 or more segments of that type.
+ * Returns 0 for an empty path (no segments).
+ */
+ uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); }
+
+ enum Verb {
+ kMove_Verb, //!< iter.next returns 1 point
+ kLine_Verb, //!< iter.next returns 2 points
+ kQuad_Verb, //!< iter.next returns 3 points
+ kConic_Verb, //!< iter.next returns 3 points + iter.conicWeight()
+ kCubic_Verb, //!< iter.next returns 4 points
+ kClose_Verb, //!< iter.next returns 1 point (contour's moveTo pt)
+ kDone_Verb, //!< iter.next returns 0 points
+ };
+
+ /** Iterate through all of the segments (lines, quadratics, cubics) of
+ each contours in a path.
+
+ The iterator cleans up the segments along the way, removing degenerate
+ segments and adding close verbs where necessary. When the forceClose
+ argument is provided, each contour (as defined by a new starting
+ move command) will be completed with a close verb regardless of the
+ contour's contents.
+ */
+ class SK_API Iter {
+ public:
+ Iter();
+ Iter(const SkPath&, bool forceClose);
+
+ void setPath(const SkPath&, bool forceClose);
+
+ /** Return the next verb in this iteration of the path. When all
+ segments have been visited, return kDone_Verb.
+
+ @param pts The points representing the current verb and/or segment
+ @param doConsumeDegerates If true, first scan for segments that are
+ deemed degenerate (too short) and skip those.
+ @return The verb for the current segment
+ */
+ Verb next(SkPoint pts[4], bool doConsumeDegerates = true) {
+ if (doConsumeDegerates) {
+ this->consumeDegenerateSegments();
+ }
+ return this->doNext(pts);
+ }
+
+ /**
+ * Return the weight for the current conic. Only valid if the current
+ * segment return by next() was a conic.
+ */
+ SkScalar conicWeight() const { return *fConicWeights; }
+
+ /** If next() returns kLine_Verb, then this query returns true if the
+ line was the result of a close() command (i.e. the end point is the
+ initial moveto for this contour). If next() returned a different
+ verb, this returns an undefined value.
+
+ @return If the last call to next() returned kLine_Verb, return true
+ if it was the result of an explicit close command.
+ */
+ bool isCloseLine() const { return SkToBool(fCloseLine); }
+
+ /** Returns true if the current contour is closed (has a kClose_Verb)
+ @return true if the current contour is closed (has a kClose_Verb)
+ */
+ bool isClosedContour() const;
+
+ private:
+ const SkPoint* fPts;
+ const uint8_t* fVerbs;
+ const uint8_t* fVerbStop;
+ const SkScalar* fConicWeights;
+ SkPoint fMoveTo;
+ SkPoint fLastPt;
+ SkBool8 fForceClose;
+ SkBool8 fNeedClose;
+ SkBool8 fCloseLine;
+ SkBool8 fSegmentState;
+
+ inline const SkPoint& cons_moveTo();
+ Verb autoClose(SkPoint pts[2]);
+ void consumeDegenerateSegments();
+ Verb doNext(SkPoint pts[4]);
+ };
+
+ /** Iterate through the verbs in the path, providing the associated points.
+ */
+ class SK_API RawIter {
+ public:
+ RawIter();
+ RawIter(const SkPath&);
+
+ void setPath(const SkPath&);
+
+ /** Return the next verb in this iteration of the path. When all
+ segments have been visited, return kDone_Verb.
+
+ @param pts The points representing the current verb and/or segment
+ This must not be NULL.
+ @return The verb for the current segment
+ */
+ Verb next(SkPoint pts[4]);
+
+ SkScalar conicWeight() const { return *fConicWeights; }
+
+ private:
+ const SkPoint* fPts;
+ const uint8_t* fVerbs;
+ const uint8_t* fVerbStop;
+ const SkScalar* fConicWeights;
+ SkPoint fMoveTo;
+ SkPoint fLastPt;
+ };
+
+ /**
+ * Returns true if the point { x, y } is contained by the path, taking into
+ * account the FillType.
+ */
+ bool contains(SkScalar x, SkScalar y) const;
+
+ void dump(SkWStream* , bool forceClose, bool dumpAsHex) const;
+ void dump() const;
+ void dumpHex() const;
+
+ /**
+ * Write the path to the buffer, and return the number of bytes written.
+ * If buffer is NULL, it still returns the number of bytes.
+ */
+ size_t writeToMemory(void* buffer) const;
+ /**
+ * Initializes the path from the buffer
+ *
+ * @param buffer Memory to read from
+ * @param length Amount of memory available in the buffer
+ * @return number of bytes read (must be a multiple of 4) or
+ * 0 if there was not enough memory available
+ */
+ size_t readFromMemory(const void* buffer, size_t length);
+
+ /** Returns a non-zero, globally unique value corresponding to the set of verbs
+ and points in the path (but not the fill type [except on Android skbug.com/1762]).
+ Each time the path is modified, a different generation ID will be returned.
+ */
+ uint32_t getGenerationID() const;
+
+#ifdef SK_BUILD_FOR_ANDROID
+ static const int kPathRefGenIDBitCnt = 30; // leave room for the fill type (skbug.com/1762)
+ const SkPath* getSourcePath() const;
+ void setSourcePath(const SkPath* path);
+#else
+ static const int kPathRefGenIDBitCnt = 32;
+#endif
+
+ SkDEBUGCODE(void validate() const;)
+
+private:
+ enum SerializationOffsets {
+ // 1 free bit at 29
+ kUnused1_SerializationShift = 28, // 1 free bit
+ kDirection_SerializationShift = 26, // requires 2 bits
+ kUnused2_SerializationShift = 25, // 1 free bit
+ // 1 free bit at 24
+ kConvexity_SerializationShift = 16, // requires 8 bits
+ kFillType_SerializationShift = 8, // requires 8 bits
+ // 8 free bits at 0
+ };
+
+ SkAutoTUnref<SkPathRef> fPathRef;
+
+ int fLastMoveToIndex;
+ uint8_t fFillType;
+ mutable uint8_t fConvexity;
+ mutable uint8_t fDirection;
+#ifdef SK_BUILD_FOR_ANDROID
+ const SkPath* fSourcePath;
+#endif
+
+ /** Resets all fields other than fPathRef to their initial 'empty' values.
+ * Assumes the caller has already emptied fPathRef.
+ * On Android increments fGenerationID without reseting it.
+ */
+ void resetFields();
+
+ /** Sets all fields other than fPathRef to the values in 'that'.
+ * Assumes the caller has already set fPathRef.
+ * Doesn't change fGenerationID or fSourcePath on Android.
+ */
+ void copyFields(const SkPath& that);
+
+ friend class Iter;
+
+ friend class SkPathStroker;
+
+ /* Append, in reverse order, the first contour of path, ignoring path's
+ last point. If no moveTo() call has been made for this contour, the
+ first point is automatically set to (0,0).
+ */
+ void reversePathTo(const SkPath&);
+
+ // called before we add points for lineTo, quadTo, cubicTo, checking to see
+ // if we need to inject a leading moveTo first
+ //
+ // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0)
+ // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
+ //
+ inline void injectMoveToIfNeeded();
+
+ inline bool hasOnlyMoveTos() const;
+
+ Convexity internalGetConvexity() const;
+
+ bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
+ bool* isClosed, Direction* direction) const;
+
+ /** Returns if the path can return a bound at no cost (true) or will have to
+ perform some computation (false).
+ */
+ bool hasComputedBounds() const {
+ SkDEBUGCODE(this->validate();)
+ return fPathRef->hasComputedBounds();
+ }
+
+
+ // 'rect' needs to be sorted
+ void setBounds(const SkRect& rect) {
+ SkPathRef::Editor ed(&fPathRef);
+
+ ed.setBounds(rect);
+ }
+
+ friend class SkAutoPathBoundsUpdate;
+ friend class SkAutoDisableOvalCheck;
+ friend class SkAutoDisableDirectionCheck;
+ friend class SkBench_AddPathTest; // perf test reversePathTo
+ friend class PathTest_Private; // unit test reversePathTo
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPathEffect.h b/src/third_party/skia/include/core/SkPathEffect.h
new file mode 100644
index 0000000..454614a
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPathEffect.h
@@ -0,0 +1,249 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPathEffect_DEFINED
+#define SkPathEffect_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+#include "SkStrokeRec.h"
+#include "SkTDArray.h"
+
+class SkPath;
+
+/** \class SkPathEffect
+
+ SkPathEffect is the base class for objects in the SkPaint that affect
+ the geometry of a drawing primitive before it is transformed by the
+ canvas' matrix and drawn.
+
+ Dashing is implemented as a subclass of SkPathEffect.
+*/
+class SK_API SkPathEffect : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkPathEffect)
+
+ /**
+ * Given a src path (input) and a stroke-rec (input and output), apply
+ * this effect to the src path, returning the new path in dst, and return
+ * true. If this effect cannot be applied, return false and ignore dst
+ * and stroke-rec.
+ *
+ * The stroke-rec specifies the initial request for stroking (if any).
+ * The effect can treat this as input only, or it can choose to change
+ * the rec as well. For example, the effect can decide to change the
+ * stroke's width or join, or the effect can change the rec from stroke
+ * to fill (or fill to stroke) in addition to returning a new (dst) path.
+ *
+ * If this method returns true, the caller will apply (as needed) the
+ * resulting stroke-rec to dst and then draw.
+ */
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect* cullR) const = 0;
+
+ /**
+ * Compute a conservative bounds for its effect, given the src bounds.
+ * The baseline implementation just assigns src to dst.
+ */
+ virtual void computeFastBounds(SkRect* dst, const SkRect& src) const;
+
+ /** \class PointData
+
+ PointData aggregates all the information needed to draw the point
+ primitives returned by an 'asPoints' call.
+ */
+ class PointData {
+ public:
+ PointData()
+ : fFlags(0)
+ , fPoints(NULL)
+ , fNumPoints(0) {
+ fSize.set(SK_Scalar1, SK_Scalar1);
+ // 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets
+ // the kUseClip flag
+ };
+ ~PointData() {
+ delete [] fPoints;
+ }
+
+ // TODO: consider using passed-in flags to limit the work asPoints does.
+ // For example, a kNoPath flag could indicate don't bother generating
+ // stamped solutions.
+
+ // Currently none of these flags are supported.
+ enum PointFlags {
+ kCircles_PointFlag = 0x01, // draw points as circles (instead of rects)
+ kUsePath_PointFlag = 0x02, // draw points as stamps of the returned path
+ kUseClip_PointFlag = 0x04, // apply 'fClipRect' before drawing the points
+ };
+
+ uint32_t fFlags; // flags that impact the drawing of the points
+ SkPoint* fPoints; // the center point of each generated point
+ int fNumPoints; // number of points in fPoints
+ SkVector fSize; // the size to draw the points
+ SkRect fClipRect; // clip required to draw the points (if kUseClip is set)
+ SkPath fPath; // 'stamp' to be used at each point (if kUsePath is set)
+
+ SkPath fFirst; // If not empty, contains geometry for first point
+ SkPath fLast; // If not empty, contains geometry for last point
+ };
+
+ /**
+ * Does applying this path effect to 'src' yield a set of points? If so,
+ * optionally return the points in 'results'.
+ */
+ virtual bool asPoints(PointData* results, const SkPath& src,
+ const SkStrokeRec&, const SkMatrix&,
+ const SkRect* cullR) const;
+
+ /**
+ * If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType
+ * and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled
+ * in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or
+ * greater to that of the effect, it will memcpy the values of the dash intervals into the
+ * info. Thus the general approach will be call asADash once with default info to get DashType
+ * and fCount. If effect can be represented as a dash pattern, allocate space for the intervals
+ * in info, then call asADash again with the same info and the intervals will get copied in.
+ */
+
+ enum DashType {
+ kNone_DashType, //!< ignores the info parameter
+ kDash_DashType, //!< fills in all of the info parameter
+ };
+
+ struct DashInfo {
+ DashInfo() : fIntervals(NULL), fCount(0), fPhase(0) {}
+
+ SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines
+ // Even values represent ons, and odds offs
+ int32_t fCount; //!< Number of intervals in the dash. Should be even number
+ SkScalar fPhase; //!< Offset into the dashed interval pattern
+ // mod the sum of all intervals
+ };
+
+ virtual DashType asADash(DashInfo* info) const;
+
+ SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect)
+
+protected:
+ SkPathEffect() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+private:
+ // illegal
+ SkPathEffect(const SkPathEffect&);
+ SkPathEffect& operator=(const SkPathEffect&);
+
+ typedef SkFlattenable INHERITED;
+};
+
+/** \class SkPairPathEffect
+
+ Common baseclass for Compose and Sum. This subclass manages two pathEffects,
+ including flattening them. It does nothing in filterPath, and is only useful
+ for managing the lifetimes of its two arguments.
+*/
+class SkPairPathEffect : public SkPathEffect {
+public:
+ virtual ~SkPairPathEffect();
+
+protected:
+ SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkPairPathEffect(SkReadBuffer&);
+#endif
+
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ // these are visible to our subclasses
+ SkPathEffect* fPE0, *fPE1;
+
+private:
+ typedef SkPathEffect INHERITED;
+};
+
+/** \class SkComposePathEffect
+
+ This subclass of SkPathEffect composes its two arguments, to create
+ a compound pathEffect.
+*/
+class SkComposePathEffect : public SkPairPathEffect {
+public:
+ /** Construct a pathEffect whose effect is to apply first the inner pathEffect
+ and the the outer pathEffect (e.g. outer(inner(path)))
+ The reference counts for outer and inner are both incremented in the constructor,
+ and decremented in the destructor.
+ */
+ static SkComposePathEffect* Create(SkPathEffect* outer, SkPathEffect* inner) {
+ return SkNEW_ARGS(SkComposePathEffect, (outer, inner));
+ }
+
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
+
+protected:
+ SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
+ : INHERITED(outer, inner) {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+private:
+ // illegal
+ SkComposePathEffect(const SkComposePathEffect&);
+ SkComposePathEffect& operator=(const SkComposePathEffect&);
+
+ typedef SkPairPathEffect INHERITED;
+};
+
+/** \class SkSumPathEffect
+
+ This subclass of SkPathEffect applies two pathEffects, one after the other.
+ Its filterPath() returns true if either of the effects succeeded.
+*/
+class SkSumPathEffect : public SkPairPathEffect {
+public:
+ /** Construct a pathEffect whose effect is to apply two effects, in sequence.
+ (e.g. first(path) + second(path))
+ The reference counts for first and second are both incremented in the constructor,
+ and decremented in the destructor.
+ */
+ static SkSumPathEffect* Create(SkPathEffect* first, SkPathEffect* second) {
+ return SkNEW_ARGS(SkSumPathEffect, (first, second));
+ }
+
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
+
+protected:
+ SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
+ : INHERITED(first, second) {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+private:
+ // illegal
+ SkSumPathEffect(const SkSumPathEffect&);
+ SkSumPathEffect& operator=(const SkSumPathEffect&);
+
+ typedef SkPairPathEffect INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPathMeasure.h b/src/third_party/skia/include/core/SkPathMeasure.h
new file mode 100644
index 0000000..bc46b4a
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPathMeasure.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPathMeasure_DEFINED
+#define SkPathMeasure_DEFINED
+
+#include "SkPath.h"
+#include "SkTDArray.h"
+
+class SK_API SkPathMeasure : SkNoncopyable {
+public:
+ SkPathMeasure();
+ /** Initialize the pathmeasure with the specified path. The path must remain valid
+ for the lifetime of the measure object, or until setPath() is called with
+ a different path (or null), since the measure object keeps a pointer to the
+ path object (does not copy its data).
+ */
+ SkPathMeasure(const SkPath& path, bool forceClosed);
+ ~SkPathMeasure();
+
+ /** Reset the pathmeasure with the specified path. The path must remain valid
+ for the lifetime of the measure object, or until setPath() is called with
+ a different path (or null), since the measure object keeps a pointer to the
+ path object (does not copy its data).
+ */
+ void setPath(const SkPath*, bool forceClosed);
+
+ /** Return the total length of the current contour, or 0 if no path
+ is associated (e.g. resetPath(null))
+ */
+ SkScalar getLength();
+
+ /** Pins distance to 0 <= distance <= getLength(), and then computes
+ the corresponding position and tangent.
+ Returns false if there is no path, or a zero-length path was specified, in which case
+ position and tangent are unchanged.
+ */
+ bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position,
+ SkVector* tangent);
+
+ enum MatrixFlags {
+ kGetPosition_MatrixFlag = 0x01,
+ kGetTangent_MatrixFlag = 0x02,
+ kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
+ };
+
+ /** Pins distance to 0 <= distance <= getLength(), and then computes
+ the corresponding matrix (by calling getPosTan).
+ Returns false if there is no path, or a zero-length path was specified, in which case
+ matrix is unchanged.
+ */
+ bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix,
+ MatrixFlags flags = kGetPosAndTan_MatrixFlag);
+
+ /** Given a start and stop distance, return in dst the intervening segment(s).
+ If the segment is zero-length, return false, else return true.
+ startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
+ then return false (and leave dst untouched).
+ Begin the segment with a moveTo if startWithMoveTo is true
+ */
+ bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
+
+ /** Return true if the current contour is closed()
+ */
+ bool isClosed();
+
+ /** Move to the next contour in the path. Return true if one exists, or false if
+ we're done with the path.
+ */
+ bool nextContour();
+
+#ifdef SK_DEBUG
+ void dump();
+#endif
+
+private:
+ SkPath::Iter fIter;
+ const SkPath* fPath;
+ SkScalar fLength; // relative to the current contour
+ int fFirstPtIndex; // relative to the current contour
+ bool fIsClosed; // relative to the current contour
+ bool fForceClosed;
+
+ struct Segment {
+ SkScalar fDistance; // total distance up to this point
+ unsigned fPtIndex : 15; // index into the fPts array
+ unsigned fTValue : 15;
+ unsigned fType : 2;
+
+ SkScalar getScalarT() const;
+ };
+ SkTDArray<Segment> fSegments;
+ SkTDArray<SkPoint> fPts; // Points used to define the segments
+
+ static const Segment* NextSegment(const Segment*);
+
+ void buildSegments();
+ SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
+ int mint, int maxt, int ptIndex);
+ SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
+ int mint, int maxt, int ptIndex);
+ const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPathRef.h b/src/third_party/skia/include/core/SkPathRef.h
new file mode 100644
index 0000000..0b661b4
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPathRef.h
@@ -0,0 +1,462 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPathRef_DEFINED
+#define SkPathRef_DEFINED
+
+#include "SkDynamicAnnotations.h"
+#include "SkMatrix.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+#include <stddef.h> // ptrdiff_t
+
+class SkRBuffer;
+class SkWBuffer;
+
+/**
+ * Holds the path verbs and points. It is versioned by a generation ID. None of its public methods
+ * modify the contents. To modify or append to the verbs/points wrap the SkPathRef in an
+ * SkPathRef::Editor object. Installing the editor resets the generation ID. It also performs
+ * copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller passes the Editor's
+ * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef after the editor's
+ * constructor returns.
+ *
+ * The points and verbs are stored in a single allocation. The points are at the begining of the
+ * allocation while the verbs are stored at end of the allocation, in reverse order. Thus the points
+ * and verbs both grow into the middle of the allocation until the meet. To access verb i in the
+ * verb array use ref.verbs()[~i] (because verbs() returns a pointer just beyond the first
+ * logical verb or the last verb in memory).
+ */
+
+class SK_API SkPathRef : public ::SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkPathRef);
+
+ class Editor {
+ public:
+ Editor(SkAutoTUnref<SkPathRef>* pathRef,
+ int incReserveVerbs = 0,
+ int incReservePoints = 0);
+
+ ~Editor() { SkDEBUGCODE(sk_atomic_dec(&fPathRef->fEditorsAttached);) }
+
+ /**
+ * Returns the array of points.
+ */
+ SkPoint* points() { return fPathRef->getPoints(); }
+ const SkPoint* points() const { return fPathRef->points(); }
+
+ /**
+ * Gets the ith point. Shortcut for this->points() + i
+ */
+ SkPoint* atPoint(int i) {
+ SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt);
+ return this->points() + i;
+ };
+ const SkPoint* atPoint(int i) const {
+ SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt);
+ return this->points() + i;
+ };
+
+ /**
+ * Adds the verb and allocates space for the number of points indicated by the verb. The
+ * return value is a pointer to where the points for the verb should be written.
+ * 'weight' is only used if 'verb' is kConic_Verb
+ */
+ SkPoint* growForVerb(int /*SkPath::Verb*/ verb, SkScalar weight = 0) {
+ SkDEBUGCODE(fPathRef->validate();)
+ return fPathRef->growForVerb(verb, weight);
+ }
+
+ /**
+ * Allocates space for multiple instances of a particular verb and the
+ * requisite points & weights.
+ * The return pointer points at the first new point (indexed normally [<i>]).
+ * If 'verb' is kConic_Verb, 'weights' will return a pointer to the
+ * space for the conic weights (indexed normally).
+ */
+ SkPoint* growForRepeatedVerb(int /*SkPath::Verb*/ verb,
+ int numVbs,
+ SkScalar** weights = NULL) {
+ return fPathRef->growForRepeatedVerb(verb, numVbs, weights);
+ }
+
+ /**
+ * Resets the path ref to a new verb and point count. The new verbs and points are
+ * uninitialized.
+ */
+ void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) {
+ fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount);
+ }
+
+ /**
+ * Gets the path ref that is wrapped in the Editor.
+ */
+ SkPathRef* pathRef() { return fPathRef; }
+
+ void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); }
+
+ void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); }
+
+ private:
+ SkPathRef* fPathRef;
+ };
+
+public:
+ /**
+ * Gets a path ref with no verbs or points.
+ */
+ static SkPathRef* CreateEmpty();
+
+ /**
+ * Returns true if all of the points in this path are finite, meaning there
+ * are no infinities and no NaNs.
+ */
+ bool isFinite() const {
+ if (fBoundsIsDirty) {
+ this->computeBounds();
+ }
+ return SkToBool(fIsFinite);
+ }
+
+ /**
+ * Returns a mask, where each bit corresponding to a SegmentMask is
+ * set if the path contains 1 or more segments of that type.
+ * Returns 0 for an empty path (no segments).
+ */
+ uint32_t getSegmentMasks() const { return fSegmentMask; }
+
+ /** Returns true if the path is an oval.
+ *
+ * @param rect returns the bounding rect of this oval. It's a circle
+ * if the height and width are the same.
+ *
+ * @return true if this path is an oval.
+ * Tracking whether a path is an oval is considered an
+ * optimization for performance and so some paths that are in
+ * fact ovals can report false.
+ */
+ bool isOval(SkRect* rect) const {
+ if (fIsOval && rect) {
+ *rect = getBounds();
+ }
+
+ return SkToBool(fIsOval);
+ }
+
+ bool hasComputedBounds() const {
+ return !fBoundsIsDirty;
+ }
+
+ /** Returns the bounds of the path's points. If the path contains 0 or 1
+ points, the bounds is set to (0,0,0,0), and isEmpty() will return true.
+ Note: this bounds may be larger than the actual shape, since curves
+ do not extend as far as their control points.
+ */
+ const SkRect& getBounds() const {
+ if (fBoundsIsDirty) {
+ this->computeBounds();
+ }
+ return fBounds;
+ }
+
+ /**
+ * Transforms a path ref by a matrix, allocating a new one only if necessary.
+ */
+ static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst,
+ const SkPathRef& src,
+ const SkMatrix& matrix);
+
+ static SkPathRef* CreateFromBuffer(SkRBuffer* buffer);
+
+ /**
+ * Rollsback a path ref to zero verbs and points with the assumption that the path ref will be
+ * repopulated with approximately the same number of verbs and points. A new path ref is created
+ * only if necessary.
+ */
+ static void Rewind(SkAutoTUnref<SkPathRef>* pathRef);
+
+ virtual ~SkPathRef() {
+ SkDEBUGCODE(this->validate();)
+ sk_free(fPoints);
+
+ SkDEBUGCODE(fPoints = NULL;)
+ SkDEBUGCODE(fVerbs = NULL;)
+ SkDEBUGCODE(fVerbCnt = 0x9999999;)
+ SkDEBUGCODE(fPointCnt = 0xAAAAAAA;)
+ SkDEBUGCODE(fPointCnt = 0xBBBBBBB;)
+ SkDEBUGCODE(fGenerationID = 0xEEEEEEEE;)
+ SkDEBUGCODE(fEditorsAttached = 0x7777777;)
+ }
+
+ int countPoints() const { SkDEBUGCODE(this->validate();) return fPointCnt; }
+ int countVerbs() const { SkDEBUGCODE(this->validate();) return fVerbCnt; }
+ int countWeights() const { SkDEBUGCODE(this->validate();) return fConicWeights.count(); }
+
+ /**
+ * Returns a pointer one beyond the first logical verb (last verb in memory order).
+ */
+ const uint8_t* verbs() const { SkDEBUGCODE(this->validate();) return fVerbs; }
+
+ /**
+ * Returns a const pointer to the first verb in memory (which is the last logical verb).
+ */
+ const uint8_t* verbsMemBegin() const { return this->verbs() - fVerbCnt; }
+
+ /**
+ * Returns a const pointer to the first point.
+ */
+ const SkPoint* points() const { SkDEBUGCODE(this->validate();) return fPoints; }
+
+ /**
+ * Shortcut for this->points() + this->countPoints()
+ */
+ const SkPoint* pointsEnd() const { return this->points() + this->countPoints(); }
+
+ const SkScalar* conicWeights() const { SkDEBUGCODE(this->validate();) return fConicWeights.begin(); }
+ const SkScalar* conicWeightsEnd() const { SkDEBUGCODE(this->validate();) return fConicWeights.end(); }
+
+ /**
+ * Convenience methods for getting to a verb or point by index.
+ */
+ uint8_t atVerb(int index) const {
+ SkASSERT((unsigned) index < (unsigned) fVerbCnt);
+ return this->verbs()[~index];
+ }
+ const SkPoint& atPoint(int index) const {
+ SkASSERT((unsigned) index < (unsigned) fPointCnt);
+ return this->points()[index];
+ }
+
+ bool operator== (const SkPathRef& ref) const;
+
+ /**
+ * Writes the path points and verbs to a buffer.
+ */
+ void writeToBuffer(SkWBuffer* buffer) const;
+
+ /**
+ * Gets the number of bytes that would be written in writeBuffer()
+ */
+ uint32_t writeSize() const;
+
+ /**
+ * Gets an ID that uniquely identifies the contents of the path ref. If two path refs have the
+ * same ID then they have the same verbs and points. However, two path refs may have the same
+ * contents but different genIDs.
+ */
+ uint32_t genID() const;
+
+private:
+ enum SerializationOffsets {
+ kIsFinite_SerializationShift = 25, // requires 1 bit
+ kIsOval_SerializationShift = 24, // requires 1 bit
+ kSegmentMask_SerializationShift = 0 // requires 4 bits
+ };
+
+ SkPathRef() {
+ fBoundsIsDirty = true; // this also invalidates fIsFinite
+ fPointCnt = 0;
+ fVerbCnt = 0;
+ fVerbs = NULL;
+ fPoints = NULL;
+ fFreeSpace = 0;
+ fGenerationID = kEmptyGenID;
+ fSegmentMask = 0;
+ fIsOval = false;
+ SkDEBUGCODE(fEditorsAttached = 0;)
+ SkDEBUGCODE(this->validate();)
+ }
+
+ void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalReservePoints);
+
+ // Return true if the computed bounds are finite.
+ static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) {
+ int count = ref.countPoints();
+ if (count <= 1) { // we ignore just 1 point (moveto)
+ bounds->setEmpty();
+ return count ? ref.points()->isFinite() : true;
+ } else {
+ return bounds->setBoundsCheck(ref.points(), count);
+ }
+ }
+
+ // called, if dirty, by getBounds()
+ void computeBounds() const {
+ SkDEBUGCODE(this->validate();)
+ // TODO(mtklein): remove fBoundsIsDirty and fIsFinite,
+ // using an inverted rect instead of fBoundsIsDirty and always recalculating fIsFinite.
+ //SkASSERT(fBoundsIsDirty);
+
+ fIsFinite = ComputePtBounds(fBounds.get(), *this);
+ fBoundsIsDirty = false;
+ }
+
+ void setBounds(const SkRect& rect) {
+ SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
+ fBounds = rect;
+ fBoundsIsDirty = false;
+ fIsFinite = fBounds->isFinite();
+ }
+
+ /** Makes additional room but does not change the counts or change the genID */
+ void incReserve(int additionalVerbs, int additionalPoints) {
+ SkDEBUGCODE(this->validate();)
+ size_t space = additionalVerbs * sizeof(uint8_t) + additionalPoints * sizeof (SkPoint);
+ this->makeSpace(space);
+ SkDEBUGCODE(this->validate();)
+ }
+
+ /** Resets the path ref with verbCount verbs and pointCount points, all uninitialized. Also
+ * allocates space for reserveVerb additional verbs and reservePoints additional points.*/
+ void resetToSize(int verbCount, int pointCount, int conicCount,
+ int reserveVerbs = 0, int reservePoints = 0) {
+ SkDEBUGCODE(this->validate();)
+ fBoundsIsDirty = true; // this also invalidates fIsFinite
+ fGenerationID = 0;
+
+ fSegmentMask = 0;
+ fIsOval = false;
+
+ size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount;
+ size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * reservePoints;
+ size_t minSize = newSize + newReserve;
+
+ ptrdiff_t sizeDelta = this->currSize() - minSize;
+
+ if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) {
+ sk_free(fPoints);
+ fPoints = NULL;
+ fVerbs = NULL;
+ fFreeSpace = 0;
+ fVerbCnt = 0;
+ fPointCnt = 0;
+ this->makeSpace(minSize);
+ fVerbCnt = verbCount;
+ fPointCnt = pointCount;
+ fFreeSpace -= newSize;
+ } else {
+ fPointCnt = pointCount;
+ fVerbCnt = verbCount;
+ fFreeSpace = this->currSize() - minSize;
+ }
+ fConicWeights.setCount(conicCount);
+ SkDEBUGCODE(this->validate();)
+ }
+
+ /**
+ * Increases the verb count by numVbs and point count by the required amount.
+ * The new points are uninitialized. All the new verbs are set to the specified
+ * verb. If 'verb' is kConic_Verb, 'weights' will return a pointer to the
+ * uninitialized conic weights.
+ */
+ SkPoint* growForRepeatedVerb(int /*SkPath::Verb*/ verb, int numVbs, SkScalar** weights);
+
+ /**
+ * Increases the verb count 1, records the new verb, and creates room for the requisite number
+ * of additional points. A pointer to the first point is returned. Any new points are
+ * uninitialized.
+ */
+ SkPoint* growForVerb(int /*SkPath::Verb*/ verb, SkScalar weight);
+
+ /**
+ * Ensures that the free space available in the path ref is >= size. The verb and point counts
+ * are not changed.
+ */
+ void makeSpace(size_t size) {
+ SkDEBUGCODE(this->validate();)
+ ptrdiff_t growSize = size - fFreeSpace;
+ if (growSize <= 0) {
+ return;
+ }
+ size_t oldSize = this->currSize();
+ // round to next multiple of 8 bytes
+ growSize = (growSize + 7) & ~static_cast<size_t>(7);
+ // we always at least double the allocation
+ if (static_cast<size_t>(growSize) < oldSize) {
+ growSize = oldSize;
+ }
+ if (growSize < kMinSize) {
+ growSize = kMinSize;
+ }
+ size_t newSize = oldSize + growSize;
+ // Note that realloc could memcpy more than we need. It seems to be a win anyway. TODO:
+ // encapsulate this.
+ fPoints = reinterpret_cast<SkPoint*>(sk_realloc_throw(fPoints, newSize));
+ size_t oldVerbSize = fVerbCnt * sizeof(uint8_t);
+ void* newVerbsDst = reinterpret_cast<void*>(
+ reinterpret_cast<intptr_t>(fPoints) + newSize - oldVerbSize);
+ void* oldVerbsSrc = reinterpret_cast<void*>(
+ reinterpret_cast<intptr_t>(fPoints) + oldSize - oldVerbSize);
+ memmove(newVerbsDst, oldVerbsSrc, oldVerbSize);
+ fVerbs = reinterpret_cast<uint8_t*>(reinterpret_cast<intptr_t>(fPoints) + newSize);
+ fFreeSpace += growSize;
+ SkDEBUGCODE(this->validate();)
+ }
+
+ /**
+ * Private, non-const-ptr version of the public function verbsMemBegin().
+ */
+ uint8_t* verbsMemWritable() {
+ SkDEBUGCODE(this->validate();)
+ return fVerbs - fVerbCnt;
+ }
+
+ /**
+ * Gets the total amount of space allocated for verbs, points, and reserve.
+ */
+ size_t currSize() const {
+ return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(fPoints);
+ }
+
+ SkDEBUGCODE(void validate() const;)
+
+ /**
+ * Called the first time someone calls CreateEmpty to actually create the singleton.
+ */
+ static SkPathRef* CreateEmptyImpl();
+
+ void setIsOval(bool isOval) { fIsOval = isOval; }
+
+ SkPoint* getPoints() {
+ SkDEBUGCODE(this->validate();)
+ fIsOval = false;
+ return fPoints;
+ }
+
+ enum {
+ kMinSize = 256,
+ };
+
+ mutable SkTRacyReffable<SkRect> fBounds;
+ mutable SkTRacy<uint8_t> fBoundsIsDirty;
+ mutable SkTRacy<SkBool8> fIsFinite; // only meaningful if bounds are valid
+
+ SkBool8 fIsOval;
+ uint8_t fSegmentMask;
+
+ SkPoint* fPoints; // points to begining of the allocation
+ uint8_t* fVerbs; // points just past the end of the allocation (verbs grow backwards)
+ int fVerbCnt;
+ int fPointCnt;
+ size_t fFreeSpace; // redundant but saves computation
+ SkTDArray<SkScalar> fConicWeights;
+
+ enum {
+ kEmptyGenID = 1, // GenID reserved for path ref with zero points and zero verbs.
+ };
+ mutable uint32_t fGenerationID;
+ SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use at any time.
+
+ friend class PathRefTest_Private;
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPicture.h b/src/third_party/skia/include/core/SkPicture.h
new file mode 100644
index 0000000..d8aced1
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPicture.h
@@ -0,0 +1,331 @@
+
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPicture_DEFINED
+#define SkPicture_DEFINED
+
+#include "SkBitmap.h"
+#include "SkDrawPictureCallback.h"
+#include "SkImageDecoder.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+#if SK_SUPPORT_GPU
+class GrContext;
+#endif
+
+class SkBBoxHierarchy;
+class SkCanvas;
+class SkData;
+class SkPictureData;
+class SkPictureRecord;
+class SkStream;
+class SkWStream;
+
+struct SkPictInfo;
+
+class SkRecord;
+
+/** \class SkPicture
+
+ The SkPicture class records the drawing commands made to a canvas, to
+ be played back at a later time.
+*/
+class SK_API SkPicture : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkPicture)
+
+ // AccelData provides a base class for device-specific acceleration
+ // data. It is added to the picture via a call to a device's optimize
+ // method.
+ class AccelData : public SkRefCnt {
+ public:
+ typedef uint8_t Domain;
+ typedef uint32_t Key;
+
+ AccelData(Key key) : fKey(key) { }
+
+ const Key& getKey() const { return fKey; }
+
+ // This entry point allows user's to get a unique domain prefix
+ // for their keys
+ static Domain GenerateDomain();
+ private:
+ Key fKey;
+
+ typedef SkRefCnt INHERITED;
+ };
+
+ /** PRIVATE / EXPERIMENTAL -- do not call */
+ void EXPERIMENTAL_addAccelData(const AccelData*) const;
+
+ /** PRIVATE / EXPERIMENTAL -- do not call */
+ const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key) const;
+
+ /**
+ * Function signature defining a function that sets up an SkBitmap from encoded data. On
+ * success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set.
+ * If the installed pixelref has decoded the data into pixels, then the src buffer need not be
+ * copied. If the pixelref defers the actual decode until its lockPixels() is called, then it
+ * must make a copy of the src buffer.
+ * @param src Encoded data.
+ * @param length Size of the encoded data, in bytes.
+ * @param dst SkBitmap to install the pixel ref on.
+ * @param bool Whether or not a pixel ref was successfully installed.
+ */
+ typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst);
+
+ /**
+ * Recreate a picture that was serialized into a stream.
+ * @param SkStream Serialized picture data.
+ * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
+ * encoded bitmap data from the stream.
+ * @return A new SkPicture representing the serialized data, or NULL if the stream is
+ * invalid.
+ */
+ static SkPicture* CreateFromStream(SkStream*,
+ InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory);
+
+ /**
+ * Recreate a picture that was serialized into a buffer. If the creation requires bitmap
+ * decoding, the decoder must be set on the SkReadBuffer parameter by calling
+ * SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer().
+ * @param SkReadBuffer Serialized picture data.
+ * @return A new SkPicture representing the serialized data, or NULL if the buffer is
+ * invalid.
+ */
+ static SkPicture* CreateFromBuffer(SkReadBuffer&);
+
+ virtual ~SkPicture();
+
+#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
+ /**
+ * Creates a thread-safe clone of the picture that is ready for playback.
+ */
+ SkPicture* clone() const;
+#endif
+
+ /** Replays the drawing commands on the specified canvas. Note that
+ this has the effect of unfurling this picture into the destination
+ canvas. Using the SkCanvas::drawPicture entry point gives the destination
+ canvas the option of just taking a ref.
+ @param canvas the canvas receiving the drawing commands.
+ @param callback a callback that allows interruption of playback
+ */
+ void playback(SkCanvas* canvas, SkDrawPictureCallback* = NULL) const;
+
+#ifdef SK_LEGACY_PICTURE_DRAW_API
+ void draw(SkCanvas* canvas, SkDrawPictureCallback* callback = NULL) const {
+ this->playback(canvas, callback);
+ }
+#endif
+
+#ifdef SK_LEGACY_PICTURE_SIZE_API
+ int width() const { return SkScalarCeilToInt(fCullWidth); }
+ int height() const { return SkScalarCeilToInt(fCullHeight); }
+#endif
+
+ /** Return the cull rect used when creating this picture: { 0, 0, cullWidth, cullHeight }.
+ It does not necessarily reflect the bounds of what has been recorded into the picture.
+ @return the cull rect used to create this picture
+ */
+ const SkRect cullRect() const { return SkRect::MakeWH(fCullWidth, fCullHeight); }
+
+ /** Return a non-zero, unique value representing the picture. This call is
+ only valid when not recording. Between a beginRecording/endRecording
+ pair it will just return 0 (the invalid ID). Each beginRecording/
+ endRecording pair will cause a different generation ID to be returned.
+ */
+ uint32_t uniqueID() const;
+
+ /**
+ * Function to encode an SkBitmap to an SkData. A function with this
+ * signature can be passed to serialize() and SkWriteBuffer.
+ * Returning NULL will tell the SkWriteBuffer to use
+ * SkBitmap::flatten() to store the bitmap.
+ *
+ * @param pixelRefOffset DEPRECATED -- caller assumes it will return 0.
+ * @return SkData If non-NULL, holds encoded data representing the passed
+ * in bitmap. The caller is responsible for calling unref().
+ */
+ typedef SkData* (*EncodeBitmap)(size_t* pixelRefOffset, const SkBitmap& bm);
+
+ /**
+ * Serialize to a stream. If non NULL, encoder will be used to encode
+ * any bitmaps in the picture.
+ * encoder will never be called with a NULL pixelRefOffset.
+ */
+ void serialize(SkWStream*, EncodeBitmap encoder = NULL) const;
+
+ /**
+ * Serialize to a buffer.
+ */
+ void flatten(SkWriteBuffer&) const;
+
+ /**
+ * Returns true if any bitmaps may be produced when this SkPicture
+ * is replayed.
+ */
+ bool willPlayBackBitmaps() const;
+
+ /** Return true if the SkStream/Buffer represents a serialized picture, and
+ fills out SkPictInfo. After this function returns, the data source is not
+ rewound so it will have to be manually reset before passing to
+ CreateFromStream or CreateFromBuffer. Note, CreateFromStream and
+ CreateFromBuffer perform this check internally so these entry points are
+ intended for stand alone tools.
+ If false is returned, SkPictInfo is unmodified.
+ */
+ static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
+ static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*);
+
+ /** Return true if the picture is suitable for rendering on the GPU.
+ */
+
+#if SK_SUPPORT_GPU
+ bool suitableForGpuRasterization(GrContext*, const char ** = NULL) const;
+#endif
+
+ class DeletionListener : public SkRefCnt {
+ public:
+ virtual void onDeletion(uint32_t pictureID) = 0;
+ };
+
+ // Takes ref on listener.
+ void addDeletionListener(DeletionListener* listener) const;
+
+ /** Return the approximate number of operations in this picture. This
+ * number may be greater or less than the number of SkCanvas calls
+ * recorded: some calls may be recorded as more than one operation, or some
+ * calls may be optimized away.
+ */
+ int approximateOpCount() const;
+
+ /** Return true if this picture contains text.
+ */
+ bool hasText() const;
+
+private:
+ // V2 : adds SkPixelRef's generation ID.
+ // V3 : PictInfo tag at beginning, and EOF tag at the end
+ // V4 : move SkPictInfo to be the header
+ // V5 : don't read/write FunctionPtr on cross-process (we can detect that)
+ // V6 : added serialization of SkPath's bounds (and packed its flags tighter)
+ // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect)
+ // V8 : Add an option for encoding bitmaps
+ // V9 : Allow the reader and writer of an SKP disagree on whether to support
+ // SK_SUPPORT_HINTING_SCALE_FACTOR
+ // V10: add drawRRect, drawOval, clipRRect
+ // V11: modify how readBitmap and writeBitmap store their info.
+ // V12: add conics to SkPath, use new SkPathRef flattening
+ // V13: add flag to drawBitmapRectToRect
+ // parameterize blurs by sigma rather than radius
+ // V14: Add flags word to PathRef serialization
+ // V15: Remove A1 bitmap config (and renumber remaining configs)
+ // V16: Move SkPath's isOval flag to SkPathRef
+ // V17: SkPixelRef now writes SkImageInfo
+ // V18: SkBitmap now records x,y for its pixelref origin, instead of offset.
+ // V19: encode matrices and regions into the ops stream
+ // V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization)
+ // V21: add pushCull, popCull
+ // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes
+ // V23: SkPaint::FilterLevel became a real enum
+ // V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping
+ // V25: SkDashPathEffect now only writes phase and interval array when flattening
+ // V26: Removed boolean from SkColorShader for inheriting color from SkPaint.
+ // V27: Remove SkUnitMapper from gradients (and skia).
+ // V28: No longer call bitmap::flatten inside SkWriteBuffer::writeBitmap.
+ // V29: Removed SaveFlags parameter from save().
+ // V30: Remove redundant SkMatrix from SkLocalMatrixShader.
+ // V31: Add a serialized UniqueID to SkImageFilter.
+ // V32: Removed SkPaintOptionsAndroid from SkPaint
+ // V33: Serialize only public API of effects.
+ // V34: Add SkTextBlob serialization.
+ // V35: Store SkRect (rather then width & height) in header
+
+ // Note: If the picture version needs to be increased then please follow the
+ // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
+
+ // Only SKPs within the min/current picture version range (inclusive) can be read.
+ static const uint32_t MIN_PICTURE_VERSION = 19;
+ static const uint32_t CURRENT_PICTURE_VERSION = 35;
+
+ mutable uint32_t fUniqueID;
+
+ // TODO: make SkPictureData const when clone method goes away
+ SkAutoTDelete<SkPictureData> fData;
+ const SkScalar fCullWidth;
+ const SkScalar fCullHeight;
+ mutable SkAutoTUnref<const AccelData> fAccelData;
+
+ mutable SkTDArray<DeletionListener*> fDeletionListeners; // pointers are refed
+
+ void needsNewGenID() { fUniqueID = SK_InvalidGenID; }
+ void callDeletionListeners();
+
+ // Create a new SkPicture from an existing SkPictureData. The new picture
+ // takes ownership of 'data'.
+ SkPicture(SkPictureData* data, SkScalar width, SkScalar height);
+
+ SkPicture(SkScalar width, SkScalar height, const SkPictureRecord& record, bool deepCopyOps);
+
+ // An OperationList encapsulates a set of operation offsets into the picture byte
+ // stream along with the CTMs needed for those operation.
+ class OperationList : ::SkNoncopyable {
+ public:
+ // The following three entry points should only be accessed if
+ // 'valid' returns true.
+ int numOps() const { return fOps.count(); }
+ // The offset in the picture of the operation to execute.
+ uint32_t offset(int index) const;
+ // The CTM that must be installed for the operation to behave correctly
+ const SkMatrix& matrix(int index) const;
+
+ SkTDArray<void*> fOps;
+ };
+
+ void createHeader(SkPictInfo* info) const;
+ static bool IsValidPictInfo(const SkPictInfo& info);
+
+ friend class SkPictureData; // to access OperationList
+ friend class SkPictureRecorder; // just for SkPicture-based constructor
+ friend class SkGpuDevice; // for fData access
+ friend class GrLayerHoister; // access to fRecord
+ friend class CollectLayers; // access to fRecord
+ friend class SkPicturePlayback; // to get fData & OperationList
+ friend class SkPictureReplacementPlayback; // to access OperationList
+
+ typedef SkRefCnt INHERITED;
+
+ // Takes ownership of the SkRecord, refs the (optional) BBH.
+ SkPicture(SkScalar width, SkScalar height, SkRecord*, SkBBoxHierarchy*);
+ // Return as a new SkPicture that's backed by SkRecord.
+ static SkPicture* Forwardport(const SkPicture&);
+
+ SkAutoTDelete<SkRecord> fRecord;
+ SkAutoTUnref<SkBBoxHierarchy> fBBH;
+
+ struct PathCounter;
+
+ struct Analysis {
+ Analysis() {} // Only used by SkPictureData codepath.
+ explicit Analysis(const SkRecord&);
+
+ bool suitableForGpuRasterization(const char** reason, int sampleCount) const;
+
+ bool fWillPlaybackBitmaps;
+ bool fHasText;
+ int fNumPaintWithPathEffectUses;
+ int fNumFastPathDashEffects;
+ int fNumAAConcavePaths;
+ int fNumAAHairlineConcavePaths;
+ } fAnalysis;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPictureRecorder.h b/src/third_party/skia/include/core/SkPictureRecorder.h
new file mode 100644
index 0000000..a3f7d48
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPictureRecorder.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPictureRecorder_DEFINED
+#define SkPictureRecorder_DEFINED
+
+#include "SkBBHFactory.h"
+#include "SkPicture.h"
+#include "SkRefCnt.h"
+
+#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
+namespace android {
+ class Picture;
+};
+#endif
+
+class SkCanvas;
+class SkPictureRecord;
+class SkRecord;
+class SkRecorder;
+
+class SK_API SkPictureRecorder : SkNoncopyable {
+public:
+ SkPictureRecorder();
+ ~SkPictureRecorder();
+
+#ifdef SK_LEGACY_PICTURE_SIZE_API
+ SkCanvas* beginRecording(int width, int height,
+ SkBBHFactory* bbhFactory = NULL,
+ uint32_t recordFlags = 0) {
+ return this->beginRecording(SkIntToScalar(width), SkIntToScalar(height),
+ bbhFactory, recordFlags);
+ }
+#endif
+
+ /** Returns the canvas that records the drawing commands.
+ @param width the width of the cull rect used when recording this picture.
+ @param height the height of the cull rect used when recording this picture.
+ @param bbhFactory factory to create desired acceleration structure
+ @param recordFlags optional flags that control recording.
+ @return the canvas.
+ */
+ SkCanvas* beginRecording(SkScalar width, SkScalar height,
+ SkBBHFactory* bbhFactory = NULL,
+ uint32_t recordFlags = 0);
+
+ // As usual, we have a deprecated old version and a maybe almost working
+ // new version. We currently point beginRecording() to
+ // DEPRECATED_beginRecording() unless SK_PICTURE_USE_SK_RECORD is defined,
+ // then we use EXPERIMENTAL_beginRecording().
+
+ // Old slower backend.
+ SkCanvas* DEPRECATED_beginRecording(SkScalar width, SkScalar height,
+ SkBBHFactory* bbhFactory = NULL,
+ uint32_t recordFlags = 0);
+
+ // New faster backend.
+ SkCanvas* EXPERIMENTAL_beginRecording(SkScalar width, SkScalar height,
+ SkBBHFactory* bbhFactory = NULL);
+
+ /** Returns the recording canvas if one is active, or NULL if recording is
+ not active. This does not alter the refcnt on the canvas (if present).
+ */
+ SkCanvas* getRecordingCanvas();
+
+ /** Signal that the caller is done recording. This invalidates the canvas
+ returned by beginRecording/getRecordingCanvas, and returns the
+ created SkPicture. Note that the returned picture has its creation
+ ref which the caller must take ownership of.
+ */
+ SkPicture* endRecording();
+
+ /** Enable/disable all the picture recording optimizations (i.e.,
+ those in SkPictureRecord). It is mainly intended for testing the
+ existing optimizations (i.e., to actually have the pattern
+ appear in an .skp we have to disable the optimization). Call right
+ after 'beginRecording'.
+ */
+ void internalOnly_EnableOpts(bool enableOpts);
+
+private:
+ void reset();
+
+ /** Replay the current (partially recorded) operation stream into
+ canvas. This call doesn't close the current recording.
+ */
+#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
+ friend class android::Picture;
+#endif
+ friend class SkPictureRecorderReplayTester; // for unit testing
+ void partialReplay(SkCanvas* canvas) const;
+
+ SkScalar fCullWidth;
+ SkScalar fCullHeight;
+ SkAutoTUnref<SkBBoxHierarchy> fBBH;
+
+ // One of these two canvases will be non-NULL.
+ SkAutoTUnref<SkPictureRecord> fPictureRecord; // beginRecording()
+ SkAutoTUnref<SkRecorder> fRecorder; // EXPERIMENTAL_beginRecording()
+
+ // Used by EXPERIMENTAL_beginRecording().
+ SkAutoTDelete<SkRecord> fRecord;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPixelRef.h b/src/third_party/skia/include/core/SkPixelRef.h
new file mode 100644
index 0000000..02d696e
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPixelRef.h
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPixelRef_DEFINED
+#define SkPixelRef_DEFINED
+
+#include "SkBitmap.h"
+#include "SkDynamicAnnotations.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+#include "SkImageInfo.h"
+#include "SkSize.h"
+#include "SkTDArray.h"
+
+//#define xed
+
+#ifdef SK_DEBUG
+ /**
+ * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref
+ * subclasses to correctly handle lock/unlock pixels. For performance
+ * reasons, simple malloc-based subclasses call setPreLocked() to skip
+ * the overhead of implementing these calls.
+ *
+ * This build-flag disables that optimization, to add in debugging our
+ * call-sites, to ensure that they correctly balance their calls of
+ * lock and unlock.
+ */
+// #define SK_IGNORE_PIXELREF_SETPRELOCKED
+#endif
+
+class SkColorTable;
+class SkData;
+struct SkIRect;
+class SkMutex;
+
+class GrTexture;
+
+/** \class SkPixelRef
+
+ This class is the smart container for pixel memory, and is used with
+ SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
+ access the actual pixel memory by calling lockPixels/unlockPixels.
+
+ This class can be shared/accessed between multiple threads.
+*/
+class SK_API SkPixelRef : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkPixelRef)
+
+ explicit SkPixelRef(const SkImageInfo&);
+ SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex);
+ virtual ~SkPixelRef();
+
+ const SkImageInfo& info() const {
+ return fInfo;
+ }
+
+ /** Return the pixel memory returned from lockPixels, or null if the
+ lockCount is 0.
+ */
+ void* pixels() const { return fRec.fPixels; }
+
+ /** Return the current colorTable (if any) if pixels are locked, or null.
+ */
+ SkColorTable* colorTable() const { return fRec.fColorTable; }
+
+ size_t rowBytes() const { return fRec.fRowBytes; }
+
+ /**
+ * To access the actual pixels of a pixelref, it must be "locked".
+ * Calling lockPixels returns a LockRec struct (on success).
+ */
+ struct LockRec {
+ void* fPixels;
+ SkColorTable* fColorTable;
+ size_t fRowBytes;
+
+ void zero() { sk_bzero(this, sizeof(*this)); }
+
+ bool isZero() const {
+ return NULL == fPixels && NULL == fColorTable && 0 == fRowBytes;
+ }
+ };
+
+ /**
+ * Returns true if the lockcount > 0
+ */
+ bool isLocked() const { return fLockCount > 0; }
+
+ SkDEBUGCODE(int getLockCount() const { return fLockCount; })
+
+ /**
+ * Call to access the pixel memory. Return true on success. Balance this
+ * with a call to unlockPixels().
+ */
+ bool lockPixels();
+
+ /**
+ * Call to access the pixel memory. On success, return true and fill out
+ * the specified rec. On failure, return false and ignore the rec parameter.
+ * Balance this with a call to unlockPixels().
+ */
+ bool lockPixels(LockRec* rec);
+
+ /** Call to balanace a previous call to lockPixels(). Returns the pixels
+ (or null) after the unlock. NOTE: lock calls can be nested, but the
+ matching number of unlock calls must be made in order to free the
+ memory (if the subclass implements caching/deferred-decoding.)
+ */
+ void unlockPixels();
+
+ /**
+ * Some bitmaps can return a copy of their pixels for lockPixels(), but
+ * that copy, if modified, will not be pushed back. These bitmaps should
+ * not be used as targets for a raster device/canvas (since all pixels
+ * modifications will be lost when unlockPixels() is called.)
+ */
+ bool lockPixelsAreWritable() const;
+
+ /** Returns a non-zero, unique value corresponding to the pixels in this
+ pixelref. Each time the pixels are changed (and notifyPixelsChanged is
+ called), a different generation ID will be returned.
+ */
+ uint32_t getGenerationID() const;
+
+ /**
+ * Call this if you have changed the contents of the pixels. This will in-
+ * turn cause a different generation ID value to be returned from
+ * getGenerationID().
+ */
+ void notifyPixelsChanged();
+
+ /**
+ * Change the info's AlphaType. Note that this does not automatically
+ * invalidate the generation ID. If the pixel values themselves have
+ * changed, then you must explicitly call notifyPixelsChanged() as well.
+ */
+ void changeAlphaType(SkAlphaType at);
+
+ /** Returns true if this pixelref is marked as immutable, meaning that the
+ contents of its pixels will not change for the lifetime of the pixelref.
+ */
+ bool isImmutable() const { return fIsImmutable; }
+
+ /** Marks this pixelref is immutable, meaning that the contents of its
+ pixels will not change for the lifetime of the pixelref. This state can
+ be set on a pixelref, but it cannot be cleared once it is set.
+ */
+ void setImmutable();
+
+ /** Return the optional URI string associated with this pixelref. May be
+ null.
+ */
+ const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
+
+ /** Copy a URI string to this pixelref, or clear the URI if the uri is null
+ */
+ void setURI(const char uri[]) {
+ fURI.set(uri);
+ }
+
+ /** Copy a URI string to this pixelref
+ */
+ void setURI(const char uri[], size_t len) {
+ fURI.set(uri, len);
+ }
+
+ /** Assign a URI string to this pixelref.
+ */
+ void setURI(const SkString& uri) { fURI = uri; }
+
+ /**
+ * If the pixelRef has an encoded (i.e. compressed) representation,
+ * return a ref to its data. If the pixelRef
+ * is uncompressed or otherwise does not have this form, return NULL.
+ *
+ * If non-null is returned, the caller is responsible for calling unref()
+ * on the data when it is finished.
+ */
+ SkData* refEncodedData() {
+ return this->onRefEncodedData();
+ }
+
+ /**
+ * Experimental -- tells the caller if it is worth it to call decodeInto().
+ * Just an optimization at this point, to avoid checking the cache first.
+ * We may remove/change this call in the future.
+ */
+ bool implementsDecodeInto() {
+ return this->onImplementsDecodeInto();
+ }
+
+ /**
+ * Return a decoded instance of this pixelRef in bitmap. If this cannot be
+ * done, return false and the bitmap parameter is ignored/unchanged.
+ *
+ * pow2 is the requeste power-of-two downscale that the caller needs. This
+ * can be ignored, and the "original" size can be returned, but if the
+ * underlying codec can efficiently return a smaller size, that should be
+ * done. Some examples:
+ *
+ * To request the "base" version (original scale), pass 0 for pow2
+ * To request 1/2 scale version (1/2 width, 1/2 height), pass 1 for pow2
+ * To request 1/4 scale version (1/4 width, 1/4 height), pass 2 for pow2
+ * ...
+ *
+ * If this returns true, then bitmap must be "locked" such that
+ * bitmap->getPixels() will return the correct address.
+ */
+ bool decodeInto(int pow2, SkBitmap* bitmap) {
+ SkASSERT(pow2 >= 0);
+ return this->onDecodeInto(pow2, bitmap);
+ }
+
+ /** Are we really wrapping a texture instead of a bitmap?
+ */
+ virtual GrTexture* getTexture() { return NULL; }
+
+ /**
+ * If any planes or rowBytes is NULL, this should output the sizes and return true
+ * if it can efficiently return YUV planar data. If it cannot, it should return false.
+ *
+ * If all planes and rowBytes are not NULL, then it should copy the associated Y,U,V data
+ * into those planes of memory supplied by the caller. It should validate that the sizes
+ * match what it expected. If the sizes do not match, it should return false.
+ *
+ * If colorSpace is not NULL, the YUV color space of the data should be stored in the address
+ * it points at.
+ */
+ bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace) {
+ return this->onGetYUV8Planes(sizes, planes, rowBytes, colorSpace);
+ }
+
+ bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
+
+ /**
+ * Makes a deep copy of this PixelRef, respecting the requested config.
+ * @param colorType Desired colortype.
+ * @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of
+ * of this PixelRef.
+ * @return A new SkPixelRef, or NULL if either there is an error (e.g. the destination could
+ * not be created with the given config), or this PixelRef does not support deep
+ * copies.
+ */
+ virtual SkPixelRef* deepCopy(SkColorType colortype, const SkIRect* subset) {
+ return NULL;
+ }
+
+#ifdef SK_BUILD_FOR_ANDROID
+ /**
+ * Acquire a "global" ref on this object.
+ * The default implementation just calls ref(), but subclasses can override
+ * this method to implement additional behavior.
+ */
+ virtual void globalRef(void* data=NULL);
+
+ /**
+ * Release a "global" ref on this object.
+ * The default implementation just calls unref(), but subclasses can override
+ * this method to implement additional behavior.
+ */
+ virtual void globalUnref();
+#endif
+
+ // Register a listener that may be called the next time our generation ID changes.
+ //
+ // We'll only call the listener if we're confident that we are the only SkPixelRef with this
+ // generation ID. If our generation ID changes and we decide not to call the listener, we'll
+ // never call it: you must add a new listener for each generation ID change. We also won't call
+ // the listener when we're certain no one knows what our generation ID is.
+ //
+ // This can be used to invalidate caches keyed by SkPixelRef generation ID.
+ struct GenIDChangeListener {
+ virtual ~GenIDChangeListener() {}
+ virtual void onChange() = 0;
+ };
+
+ // Takes ownership of listener.
+ void addGenIDChangeListener(GenIDChangeListener* listener);
+
+protected:
+ /**
+ * On success, returns true and fills out the LockRec for the pixels. On
+ * failure returns false and ignores the LockRec parameter.
+ *
+ * The caller will have already acquired a mutex for thread safety, so this
+ * method need not do that.
+ */
+ virtual bool onNewLockPixels(LockRec*) = 0;
+
+ /**
+ * Balancing the previous successful call to onNewLockPixels. The locked
+ * pixel address will no longer be referenced, so the subclass is free to
+ * move or discard that memory.
+ *
+ * The caller will have already acquired a mutex for thread safety, so this
+ * method need not do that.
+ */
+ virtual void onUnlockPixels() = 0;
+
+ /** Default impl returns true */
+ virtual bool onLockPixelsAreWritable() const;
+
+ // returns false;
+ virtual bool onImplementsDecodeInto();
+ // returns false;
+ virtual bool onDecodeInto(int pow2, SkBitmap* bitmap);
+
+ /**
+ * For pixelrefs that don't have access to their raw pixels, they may be
+ * able to make a copy of them (e.g. if the pixels are on the GPU).
+ *
+ * The base class implementation returns false;
+ */
+ virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
+
+ // default impl returns NULL.
+ virtual SkData* onRefEncodedData();
+
+ // default impl returns false.
+ virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
+ SkYUVColorSpace* colorSpace);
+
+ /**
+ * Returns the size (in bytes) of the internally allocated memory.
+ * This should be implemented in all serializable SkPixelRef derived classes.
+ * SkBitmap::fPixelRefOffset + SkBitmap::getSafeSize() should never overflow this value,
+ * otherwise the rendering code may attempt to read memory out of bounds.
+ *
+ * @return default impl returns 0.
+ */
+ virtual size_t getAllocatedSizeInBytes() const;
+
+ /** Return the mutex associated with this pixelref. This value is assigned
+ in the constructor, and cannot change during the lifetime of the object.
+ */
+ SkBaseMutex* mutex() const { return fMutex; }
+
+ // only call from constructor. Flags this to always be locked, removing
+ // the need to grab the mutex and call onLockPixels/onUnlockPixels.
+ // Performance tweak to avoid those calls (esp. in multi-thread use case).
+ void setPreLocked(void*, size_t rowBytes, SkColorTable*);
+
+private:
+ SkBaseMutex* fMutex; // must remain in scope for the life of this object
+
+ // mostly const. fInfo.fAlpahType can be changed at runtime.
+ const SkImageInfo fInfo;
+
+ // LockRec is only valid if we're in a locked state (isLocked())
+ LockRec fRec;
+ int fLockCount;
+
+ mutable SkTRacy<uint32_t> fGenerationID;
+ mutable SkTRacy<bool> fUniqueGenerationID;
+
+ SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned
+
+ SkString fURI;
+
+ // can go from false to true, but never from true to false
+ bool fIsImmutable;
+ // only ever set in constructor, const after that
+ bool fPreLocked;
+
+ void needsNewGenID();
+ void callGenIDChangeListeners();
+
+ void setMutex(SkBaseMutex* mutex);
+
+ // When copying a bitmap to another with the same shape and config, we can safely
+ // clone the pixelref generation ID too, which makes them equivalent under caching.
+ friend class SkBitmap; // only for cloneGenID
+ void cloneGenID(const SkPixelRef&);
+
+ typedef SkRefCnt INHERITED;
+};
+
+class SkPixelRefFactory : public SkRefCnt {
+public:
+ /**
+ * Allocate a new pixelref matching the specified ImageInfo, allocating
+ * the memory for the pixels. If the ImageInfo requires a ColorTable,
+ * the pixelref will ref() the colortable.
+ * On failure return NULL.
+ */
+ virtual SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) = 0;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPoint.h b/src/third_party/skia/include/core/SkPoint.h
new file mode 100644
index 0000000..6f32d98
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPoint.h
@@ -0,0 +1,533 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPoint_DEFINED
+#define SkPoint_DEFINED
+
+#include "SkMath.h"
+#include "SkScalar.h"
+
+/** \struct SkIPoint16
+
+ SkIPoint holds two 16 bit integer coordinates
+*/
+struct SkIPoint16 {
+ int16_t fX, fY;
+
+ static SkIPoint16 Make(int x, int y) {
+ SkIPoint16 pt;
+ pt.set(x, y);
+ return pt;
+ }
+
+ int16_t x() const { return fX; }
+ int16_t y() const { return fY; }
+
+ void set(int x, int y) {
+ fX = SkToS16(x);
+ fY = SkToS16(y);
+ }
+};
+
+/** \struct SkIPoint
+
+ SkIPoint holds two 32 bit integer coordinates
+*/
+struct SkIPoint {
+ int32_t fX, fY;
+
+ static SkIPoint Make(int32_t x, int32_t y) {
+ SkIPoint pt;
+ pt.set(x, y);
+ return pt;
+ }
+
+ int32_t x() const { return fX; }
+ int32_t y() const { return fY; }
+ void setX(int32_t x) { fX = x; }
+ void setY(int32_t y) { fY = y; }
+
+ /**
+ * Returns true iff fX and fY are both zero.
+ */
+ bool isZero() const { return (fX | fY) == 0; }
+
+ /**
+ * Set both fX and fY to zero. Same as set(0, 0)
+ */
+ void setZero() { fX = fY = 0; }
+
+ /** Set the x and y values of the point. */
+ void set(int32_t x, int32_t y) { fX = x; fY = y; }
+
+ /** Rotate the point clockwise, writing the new point into dst
+ It is legal for dst == this
+ */
+ void rotateCW(SkIPoint* dst) const;
+
+ /** Rotate the point clockwise, writing the new point back into the point
+ */
+
+ void rotateCW() { this->rotateCW(this); }
+
+ /** Rotate the point counter-clockwise, writing the new point into dst.
+ It is legal for dst == this
+ */
+ void rotateCCW(SkIPoint* dst) const;
+
+ /** Rotate the point counter-clockwise, writing the new point back into
+ the point
+ */
+ void rotateCCW() { this->rotateCCW(this); }
+
+ /** Negate the X and Y coordinates of the point.
+ */
+ void negate() { fX = -fX; fY = -fY; }
+
+ /** Return a new point whose X and Y coordinates are the negative of the
+ original point's
+ */
+ SkIPoint operator-() const {
+ SkIPoint neg;
+ neg.fX = -fX;
+ neg.fY = -fY;
+ return neg;
+ }
+
+ /** Add v's coordinates to this point's */
+ void operator+=(const SkIPoint& v) {
+ fX += v.fX;
+ fY += v.fY;
+ }
+
+ /** Subtract v's coordinates from this point's */
+ void operator-=(const SkIPoint& v) {
+ fX -= v.fX;
+ fY -= v.fY;
+ }
+
+ /** Returns true if the point's coordinates equal (x,y) */
+ bool equals(int32_t x, int32_t y) const {
+ return fX == x && fY == y;
+ }
+
+ friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
+ return a.fX == b.fX && a.fY == b.fY;
+ }
+
+ friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
+ return a.fX != b.fX || a.fY != b.fY;
+ }
+
+ /** Returns a new point whose coordinates are the difference between
+ a and b (i.e. a - b)
+ */
+ friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) {
+ SkIPoint v;
+ v.set(a.fX - b.fX, a.fY - b.fY);
+ return v;
+ }
+
+ /** Returns a new point whose coordinates are the sum of a and b (a + b)
+ */
+ friend SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) {
+ SkIPoint v;
+ v.set(a.fX + b.fX, a.fY + b.fY);
+ return v;
+ }
+
+ /** Returns the dot product of a and b, treating them as 2D vectors
+ */
+ static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) {
+ return a.fX * b.fX + a.fY * b.fY;
+ }
+
+ /** Returns the cross product of a and b, treating them as 2D vectors
+ */
+ static int32_t CrossProduct(const SkIPoint& a, const SkIPoint& b) {
+ return a.fX * b.fY - a.fY * b.fX;
+ }
+};
+
+struct SK_API SkPoint {
+ SkScalar fX, fY;
+
+ static SkPoint Make(SkScalar x, SkScalar y) {
+ SkPoint pt;
+ pt.set(x, y);
+ return pt;
+ }
+
+ SkScalar x() const { return fX; }
+ SkScalar y() const { return fY; }
+
+ /**
+ * Returns true iff fX and fY are both zero.
+ */
+ bool isZero() const { return (0 == fX) & (0 == fY); }
+
+ /** Set the point's X and Y coordinates */
+ void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
+
+ /** Set the point's X and Y coordinates by automatically promoting (x,y) to
+ SkScalar values.
+ */
+ void iset(int32_t x, int32_t y) {
+ fX = SkIntToScalar(x);
+ fY = SkIntToScalar(y);
+ }
+
+ /** Set the point's X and Y coordinates by automatically promoting p's
+ coordinates to SkScalar values.
+ */
+ void iset(const SkIPoint& p) {
+ fX = SkIntToScalar(p.fX);
+ fY = SkIntToScalar(p.fY);
+ }
+
+ void setAbs(const SkPoint& pt) {
+ fX = SkScalarAbs(pt.fX);
+ fY = SkScalarAbs(pt.fY);
+ }
+
+ // counter-clockwise fan
+ void setIRectFan(int l, int t, int r, int b) {
+ SkPoint* v = this;
+ v[0].set(SkIntToScalar(l), SkIntToScalar(t));
+ v[1].set(SkIntToScalar(l), SkIntToScalar(b));
+ v[2].set(SkIntToScalar(r), SkIntToScalar(b));
+ v[3].set(SkIntToScalar(r), SkIntToScalar(t));
+ }
+ void setIRectFan(int l, int t, int r, int b, size_t stride);
+
+ // counter-clockwise fan
+ void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
+ SkPoint* v = this;
+ v[0].set(l, t);
+ v[1].set(l, b);
+ v[2].set(r, b);
+ v[3].set(r, t);
+ }
+ void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b, size_t stride);
+
+ static void Offset(SkPoint points[], int count, const SkPoint& offset) {
+ Offset(points, count, offset.fX, offset.fY);
+ }
+
+ static void Offset(SkPoint points[], int count, SkScalar dx, SkScalar dy) {
+ for (int i = 0; i < count; ++i) {
+ points[i].offset(dx, dy);
+ }
+ }
+
+ void offset(SkScalar dx, SkScalar dy) {
+ fX += dx;
+ fY += dy;
+ }
+
+ /** Return the euclidian distance from (0,0) to the point
+ */
+ SkScalar length() const { return SkPoint::Length(fX, fY); }
+ SkScalar distanceToOrigin() const { return this->length(); }
+
+ /**
+ * Return true if the computed length of the vector is >= the internal
+ * tolerance (used to avoid dividing by tiny values).
+ */
+ static bool CanNormalize(SkScalar dx, SkScalar dy) {
+ // Simple enough (and performance critical sometimes) so we inline it.
+ return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero);
+ }
+
+ bool canNormalize() const {
+ return CanNormalize(fX, fY);
+ }
+
+ /** Set the point (vector) to be unit-length in the same direction as it
+ already points. If the point has a degenerate length (i.e. nearly 0)
+ then return false and do nothing; otherwise return true.
+ */
+ bool normalize();
+
+ /** Set the point (vector) to be unit-length in the same direction as the
+ x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0)
+ then return false and do nothing, otherwise return true.
+ */
+ bool setNormalize(SkScalar x, SkScalar y);
+
+ /** Scale the point (vector) to have the specified length, and return that
+ length. If the original length is degenerately small (nearly zero),
+ do nothing and return false, otherwise return true.
+ */
+ bool setLength(SkScalar length);
+
+ /** Set the point (vector) to have the specified length in the same
+ direction as (x,y). If the vector (x,y) has a degenerate length
+ (i.e. nearly 0) then return false and do nothing, otherwise return true.
+ */
+ bool setLength(SkScalar x, SkScalar y, SkScalar length);
+
+ /** Same as setLength, but favoring speed over accuracy.
+ */
+ bool setLengthFast(SkScalar length);
+
+ /** Same as setLength, but favoring speed over accuracy.
+ */
+ bool setLengthFast(SkScalar x, SkScalar y, SkScalar length);
+
+ /** Scale the point's coordinates by scale, writing the answer into dst.
+ It is legal for dst == this.
+ */
+ void scale(SkScalar scale, SkPoint* dst) const;
+
+ /** Scale the point's coordinates by scale, writing the answer back into
+ the point.
+ */
+ void scale(SkScalar value) { this->scale(value, this); }
+
+ /** Rotate the point clockwise by 90 degrees, writing the answer into dst.
+ It is legal for dst == this.
+ */
+ void rotateCW(SkPoint* dst) const;
+
+ /** Rotate the point clockwise by 90 degrees, writing the answer back into
+ the point.
+ */
+ void rotateCW() { this->rotateCW(this); }
+
+ /** Rotate the point counter-clockwise by 90 degrees, writing the answer
+ into dst. It is legal for dst == this.
+ */
+ void rotateCCW(SkPoint* dst) const;
+
+ /** Rotate the point counter-clockwise by 90 degrees, writing the answer
+ back into the point.
+ */
+ void rotateCCW() { this->rotateCCW(this); }
+
+ /** Negate the point's coordinates
+ */
+ void negate() {
+ fX = -fX;
+ fY = -fY;
+ }
+
+ /** Returns a new point whose coordinates are the negative of the point's
+ */
+ SkPoint operator-() const {
+ SkPoint neg;
+ neg.fX = -fX;
+ neg.fY = -fY;
+ return neg;
+ }
+
+ /** Add v's coordinates to the point's
+ */
+ void operator+=(const SkPoint& v) {
+ fX += v.fX;
+ fY += v.fY;
+ }
+
+ /** Subtract v's coordinates from the point's
+ */
+ void operator-=(const SkPoint& v) {
+ fX -= v.fX;
+ fY -= v.fY;
+ }
+
+ /**
+ * Returns true if both X and Y are finite (not infinity or NaN)
+ */
+ bool isFinite() const {
+ SkScalar accum = 0;
+ accum *= fX;
+ accum *= fY;
+
+ // accum is either NaN or it is finite (zero).
+ SkASSERT(0 == accum || !(accum == accum));
+
+ // value==value will be true iff value is not NaN
+ // TODO: is it faster to say !accum or accum==accum?
+ return accum == accum;
+ }
+
+ /**
+ * Returns true if the point's coordinates equal (x,y)
+ */
+ bool equals(SkScalar x, SkScalar y) const {
+ return fX == x && fY == y;
+ }
+
+ friend bool operator==(const SkPoint& a, const SkPoint& b) {
+ return a.fX == b.fX && a.fY == b.fY;
+ }
+
+ friend bool operator!=(const SkPoint& a, const SkPoint& b) {
+ return a.fX != b.fX || a.fY != b.fY;
+ }
+
+ /** Return true if this point and the given point are far enough apart
+ such that a vector between them would be non-degenerate.
+
+ WARNING: Unlike the explicit tolerance version,
+ this method does not use componentwise comparison. Instead, it
+ uses a comparison designed to match judgments elsewhere regarding
+ degeneracy ("points A and B are so close that the vector between them
+ is essentially zero").
+ */
+ bool equalsWithinTolerance(const SkPoint& p) const {
+ return !CanNormalize(fX - p.fX, fY - p.fY);
+ }
+
+ /** WARNING: There is no guarantee that the result will reflect judgments
+ elsewhere regarding degeneracy ("points A and B are so close that the
+ vector between them is essentially zero").
+ */
+ bool equalsWithinTolerance(const SkPoint& p, SkScalar tol) const {
+ return SkScalarNearlyZero(fX - p.fX, tol)
+ && SkScalarNearlyZero(fY - p.fY, tol);
+ }
+
+ /** Returns a new point whose coordinates are the difference between
+ a's and b's (a - b)
+ */
+ friend SkPoint operator-(const SkPoint& a, const SkPoint& b) {
+ SkPoint v;
+ v.set(a.fX - b.fX, a.fY - b.fY);
+ return v;
+ }
+
+ /** Returns a new point whose coordinates are the sum of a's and b's (a + b)
+ */
+ friend SkPoint operator+(const SkPoint& a, const SkPoint& b) {
+ SkPoint v;
+ v.set(a.fX + b.fX, a.fY + b.fY);
+ return v;
+ }
+
+ /** Returns the euclidian distance from (0,0) to (x,y)
+ */
+ static SkScalar Length(SkScalar x, SkScalar y);
+
+ /** Normalize pt, returning its previous length. If the prev length is too
+ small (degenerate), return 0 and leave pt unchanged. This uses the same
+ tolerance as CanNormalize.
+
+ Note that this method may be significantly more expensive than
+ the non-static normalize(), because it has to return the previous length
+ of the point. If you don't need the previous length, call the
+ non-static normalize() method instead.
+ */
+ static SkScalar Normalize(SkPoint* pt);
+
+ /** Returns the euclidian distance between a and b
+ */
+ static SkScalar Distance(const SkPoint& a, const SkPoint& b) {
+ return Length(a.fX - b.fX, a.fY - b.fY);
+ }
+
+ /** Returns the dot product of a and b, treating them as 2D vectors
+ */
+ static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) {
+ return a.fX * b.fX + a.fY * b.fY;
+ }
+
+ /** Returns the cross product of a and b, treating them as 2D vectors
+ */
+ static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) {
+ return a.fX * b.fY - a.fY * b.fX;
+ }
+
+ SkScalar cross(const SkPoint& vec) const {
+ return CrossProduct(*this, vec);
+ }
+
+ SkScalar dot(const SkPoint& vec) const {
+ return DotProduct(*this, vec);
+ }
+
+ SkScalar lengthSqd() const {
+ return DotProduct(*this, *this);
+ }
+
+ SkScalar distanceToSqd(const SkPoint& pt) const {
+ SkScalar dx = fX - pt.fX;
+ SkScalar dy = fY - pt.fY;
+ return dx * dx + dy * dy;
+ }
+
+ /**
+ * The side of a point relative to a line. If the line is from a to b then
+ * the values are consistent with the sign of (b-a) cross (pt-a)
+ */
+ enum Side {
+ kLeft_Side = -1,
+ kOn_Side = 0,
+ kRight_Side = 1
+ };
+
+ /**
+ * Returns the squared distance to the infinite line between two pts. Also
+ * optionally returns the side of the line that the pt falls on (looking
+ * along line from a to b)
+ */
+ SkScalar distanceToLineBetweenSqd(const SkPoint& a,
+ const SkPoint& b,
+ Side* side = NULL) const;
+
+ /**
+ * Returns the distance to the infinite line between two pts. Also
+ * optionally returns the side of the line that the pt falls on (looking
+ * along the line from a to b)
+ */
+ SkScalar distanceToLineBetween(const SkPoint& a,
+ const SkPoint& b,
+ Side* side = NULL) const {
+ return SkScalarSqrt(this->distanceToLineBetweenSqd(a, b, side));
+ }
+
+ /**
+ * Returns the squared distance to the line segment between pts a and b
+ */
+ SkScalar distanceToLineSegmentBetweenSqd(const SkPoint& a,
+ const SkPoint& b) const;
+
+ /**
+ * Returns the distance to the line segment between pts a and b.
+ */
+ SkScalar distanceToLineSegmentBetween(const SkPoint& a,
+ const SkPoint& b) const {
+ return SkScalarSqrt(this->distanceToLineSegmentBetweenSqd(a, b));
+ }
+
+ /**
+ * Make this vector be orthogonal to vec. Looking down vec the
+ * new vector will point in direction indicated by side (which
+ * must be kLeft_Side or kRight_Side).
+ */
+ void setOrthog(const SkPoint& vec, Side side = kLeft_Side) {
+ // vec could be this
+ SkScalar tmp = vec.fX;
+ if (kRight_Side == side) {
+ fX = -vec.fY;
+ fY = tmp;
+ } else {
+ SkASSERT(kLeft_Side == side);
+ fX = vec.fY;
+ fY = -tmp;
+ }
+ }
+
+ /**
+ * cast-safe way to treat the point as an array of (2) SkScalars.
+ */
+ const SkScalar* asScalars() const { return &fX; }
+};
+
+typedef SkPoint SkVector;
+
+#endif
diff --git a/src/third_party/skia/include/core/SkPostConfig.h b/src/third_party/skia/include/core/SkPostConfig.h
new file mode 100644
index 0000000..3795a78
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPostConfig.h
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPostConfig_DEFINED
+#define SkPostConfig_DEFINED
+
+#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
+# define SK_BUILD_FOR_WIN
+#endif
+
+#if defined(SK_DEBUG) && defined(SK_RELEASE)
+# error "cannot define both SK_DEBUG and SK_RELEASE"
+#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
+# error "must define either SK_DEBUG or SK_RELEASE"
+#endif
+
+#if defined(SK_SUPPORT_UNITTEST) && !defined(SK_DEBUG)
+# error "can't have unittests without debug"
+#endif
+
+/**
+ * Matrix calculations may be float or double.
+ * The default is double, as that is faster given our impl uses doubles
+ * for intermediate calculations.
+ */
+#if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT)
+# error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT"
+#elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT)
+# define SK_MSCALAR_IS_DOUBLE
+#endif
+
+#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
+# error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
+#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
+# error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
+#endif
+
+/**
+ * Ensure the port has defined all of SK_X32_SHIFT, or none of them.
+ */
+#ifdef SK_A32_SHIFT
+# if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
+# error "all or none of the 32bit SHIFT amounts must be defined"
+# endif
+#else
+# if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
+# error "all or none of the 32bit SHIFT amounts must be defined"
+# endif
+#endif
+
+#if !defined(SK_HAS_COMPILER_FEATURE)
+# if defined(__has_feature)
+# define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
+# else
+# define SK_HAS_COMPILER_FEATURE(x) 0
+# endif
+#endif
+
+#if !defined(SK_ATTRIBUTE)
+# if defined(__clang__) || defined(__GNUC__)
+# define SK_ATTRIBUTE(attr) __attribute__((attr))
+# else
+# define SK_ATTRIBUTE(attr)
+# endif
+#endif
+
+#if !defined(SK_SUPPORT_GPU)
+# define SK_SUPPORT_GPU 1
+#endif
+
+/**
+ * The clang static analyzer likes to know that when the program is not
+ * expected to continue (crash, assertion failure, etc). It will notice that
+ * some combination of parameters lead to a function call that does not return.
+ * It can then make appropriate assumptions about the parameters in code
+ * executed only if the non-returning function was *not* called.
+ */
+#if !defined(SkNO_RETURN_HINT)
+# if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
+ static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
+ static inline void SkNO_RETURN_HINT() {}
+# else
+# define SkNO_RETURN_HINT() do {} while (false)
+# endif
+#endif
+
+#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB)
+# error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB"
+#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB)
+# define SK_HAS_ZLIB
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef SkNEW
+# define SkNEW(type_name) (new type_name)
+# define SkNEW_ARGS(type_name, args) (new type_name args)
+# define SkNEW_ARRAY(type_name, count) (new type_name[(count)])
+# define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name)
+# define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args)
+# define SkDELETE(obj) (delete (obj))
+# define SkDELETE_ARRAY(array) (delete[] (array))
+#endif
+
+#ifndef SK_CRASH
+# ifdef SK_BUILD_FOR_WIN
+# define SK_CRASH() __debugbreak()
+# else
+# if 1 // set to 0 for infinite loop, which can help connecting gdb
+# define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
+# else
+# define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
+# endif
+# endif
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects
+ * are still held on exit.
+ * Defaults to 1 in DEBUG and 0 in RELEASE.
+ */
+#ifndef SK_ENABLE_INST_COUNT
+# ifdef SK_DEBUG
+// Only enabled for static builds, because instance counting relies on static
+// variables in functions defined in header files.
+# if defined(SKIA_DLL)
+# define SK_ENABLE_INST_COUNT 0
+# else
+# define SK_ENABLE_INST_COUNT 1
+# endif
+# else
+# define SK_ENABLE_INST_COUNT 0
+# endif
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_BUILD_FOR_WIN
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
+# endif
+# ifndef NOMINMAX
+# define NOMINMAX
+# define NOMINMAX_WAS_LOCALLY_DEFINED
+# endif
+#
+# include <windows.h>
+#
+# ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
+# undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
+# undef WIN32_LEAN_AND_MEAN
+# endif
+# ifdef NOMINMAX_WAS_LOCALLY_DEFINED
+# undef NOMINMAX_WAS_LOCALLY_DEFINED
+# undef NOMINMAX
+# 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
+#
+#endif
+
+#ifndef SK_ALWAYSBREAK
+# ifdef SK_DEBUG
+# define SK_ALWAYSBREAK(cond) do { \
+ if (cond) break; \
+ SkNO_RETURN_HINT(); \
+ SkDebugf("%s:%d: failed assertion \"%s\"\n", __FILE__, __LINE__, #cond); \
+ SK_CRASH(); \
+ } while (false)
+# else
+# define SK_ALWAYSBREAK(cond) do { if (cond) break; SK_CRASH(); } while (false)
+# endif
+#endif
+
+/**
+ * We check to see if the SHIFT value has already been defined.
+ * if not, we define it ourself to some default values. We default to OpenGL
+ * order (in memory: r,g,b,a)
+ */
+#ifndef SK_A32_SHIFT
+# ifdef SK_CPU_BENDIAN
+# define SK_R32_SHIFT 24
+# define SK_G32_SHIFT 16
+# define SK_B32_SHIFT 8
+# define SK_A32_SHIFT 0
+# else
+# define SK_R32_SHIFT 0
+# define SK_G32_SHIFT 8
+# define SK_B32_SHIFT 16
+# define SK_A32_SHIFT 24
+# endif
+#endif
+
+/**
+ * SkColor has well defined shift values, but SkPMColor is configurable. This
+ * macro is a convenience that returns true if the shift values are equal while
+ * ignoring the machine's endianness.
+ */
+#define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \
+ (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0)
+
+/**
+ * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
+ * relationship between the byte order and shift values depends on machine endianness. If the shift
+ * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
+ * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
+ * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
+ * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
+ */
+#ifdef SK_CPU_BENDIAN
+# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
+ (SK_ ## C3 ## 32_SHIFT == 0 && \
+ SK_ ## C2 ## 32_SHIFT == 8 && \
+ SK_ ## C1 ## 32_SHIFT == 16 && \
+ SK_ ## C0 ## 32_SHIFT == 24)
+#else
+# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
+ (SK_ ## C0 ## 32_SHIFT == 0 && \
+ SK_ ## C1 ## 32_SHIFT == 8 && \
+ SK_ ## C2 ## 32_SHIFT == 16 && \
+ SK_ ## C3 ## 32_SHIFT == 24)
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+// TODO: rebaseline as needed so we can remove this flag entirely.
+// - all platforms have int64_t now
+// - we have slightly different fixed math results because of this check
+// since we don't define this for linux/android
+#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
+# ifndef SkLONGLONG
+# define SkLONGLONG int64_t
+# endif
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+#ifndef SK_BUILD_FOR_WINCE
+# include <string.h>
+# include <stdlib.h>
+#else
+# define _CMNINTRIN_DECLARE_ONLY
+# include "cmnintrin.h"
+#endif
+
+#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 && !defined(COBALT_WIN)
+# ifdef free
+# undef free
+# endif
+# include <crtdbg.h>
+# undef free
+#
+# ifdef SK_DEBUGx
+# if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
+ void * operator new(
+ size_t cb,
+ int nBlockUse,
+ const char * szFileName,
+ int nLine,
+ int foo
+ );
+ void * operator new[](
+ size_t cb,
+ int nBlockUse,
+ const char * szFileName,
+ int nLine,
+ int foo
+ );
+ void operator delete(
+ void *pUserData,
+ int, const char*, int, int
+ );
+ void operator delete(
+ void *pUserData
+ );
+ void operator delete[]( void * p );
+# define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
+# else
+# define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
+# endif
+# define new DEBUG_CLIENTBLOCK
+# else
+# define DEBUG_CLIENTBLOCK
+# endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SK_OVERRIDE
+# if defined(_MSC_VER)
+# define SK_OVERRIDE override
+# elif defined(__clang__)
+ // Using __attribute__((override)) on clang does not appear to always work.
+ // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no
+ // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing
+ // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma).
+# pragma clang diagnostic ignored "-Wc++11-extensions"
+#
+# if __has_feature(cxx_override_control)
+# define SK_OVERRIDE override
+# elif defined(__has_extension) && __has_extension(cxx_override_control)
+# define SK_OVERRIDE override
+# endif
+# endif
+# ifndef SK_OVERRIDE
+# define SK_OVERRIDE
+# endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_UNUSED)
+# define SK_UNUSED SK_ATTRIBUTE(unused)
+#endif
+
+#if !defined(SK_ATTR_DEPRECATED)
+ // FIXME: we ignore msg for now...
+# define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated)
+#endif
+
+#if !defined(SK_ATTR_EXTERNALLY_DEPRECATED)
+# if !defined(SK_INTERNAL)
+# define SK_ATTR_EXTERNALLY_DEPRECATED(msg) SK_ATTR_DEPRECATED(msg)
+# else
+# define SK_ATTR_EXTERNALLY_DEPRECATED(msg)
+# endif
+#endif
+
+/**
+ * If your judgment is better than the compiler's (i.e. you've profiled it),
+ * you can use SK_ALWAYS_INLINE to force inlining. E.g.
+ * inline void someMethod() { ... } // may not be inlined
+ * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined
+ */
+#if !defined(SK_ALWAYS_INLINE)
+# if defined(SK_BUILD_FOR_WIN)
+# define SK_ALWAYS_INLINE __forceinline
+# else
+# define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline
+# endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if defined(__clang__) || defined(__GNUC__)
+# define SK_PREFETCH(ptr) __builtin_prefetch(ptr)
+# define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1)
+#else
+# define SK_PREFETCH(ptr)
+# define SK_WRITE_PREFETCH(ptr)
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SK_PRINTF_LIKE
+# if defined(__clang__) || defined(__GNUC__)
+# define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
+# else
+# define SK_PRINTF_LIKE(A, B)
+# endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SK_SIZE_T_SPECIFIER
+# if defined(_MSC_VER)
+# define SK_SIZE_T_SPECIFIER "%Iu"
+# else
+# define SK_SIZE_T_SPECIFIER "%zu"
+# endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+# define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SK_ATOMICS_PLATFORM_H
+# if defined(_MSC_VER)
+# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h"
+# else
+# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h"
+# endif
+#endif
+
+#ifndef SK_MUTEX_PLATFORM_H
+# if defined(SK_BUILD_FOR_WIN)
+# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h"
+# else
+# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h"
+# endif
+#endif
+
+#ifndef SK_BARRIERS_PLATFORM_H
+# if SK_HAS_COMPILER_FEATURE(thread_sanitizer)
+# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_tsan.h"
+# elif defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64)
+# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_arm.h"
+# else
+# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_x86.h"
+# endif
+#endif
+
+
+//////////////////////////////////////////////////////////////////////
+
+#if defined(SK_GAMMA_EXPONENT) && defined(SK_GAMMA_SRGB)
+# error "cannot define both SK_GAMMA_EXPONENT and SK_GAMMA_SRGB"
+#elif defined(SK_GAMMA_SRGB)
+# define SK_GAMMA_EXPONENT (0.0f)
+#elif !defined(SK_GAMMA_EXPONENT)
+# define SK_GAMMA_EXPONENT (2.2f)
+#endif
+
+#endif // SkPostConfig_DEFINED
diff --git a/src/third_party/skia/include/core/SkPreConfig.h b/src/third_party/skia/include/core/SkPreConfig.h
new file mode 100644
index 0000000..4ae9409
--- /dev/null
+++ b/src/third_party/skia/include/core/SkPreConfig.h
@@ -0,0 +1,284 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPreConfig_DEFINED
+#define SkPreConfig_DEFINED
+
+#ifdef WEBKIT_VERSION_MIN_REQUIRED
+ #include "config.h"
+#endif
+
+// Allows embedders that want to disable macros that take arguments to just
+// define that symbol to be one of these
+//
+#define SK_NOTHING_ARG1(arg1)
+#define SK_NOTHING_ARG2(arg1, arg2)
+#define SK_NOTHING_ARG3(arg1, arg2, arg3)
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW) && !defined(SK_BUILD_FOR_NACL) && !defined(SK_BUILD_FOR_STARBOARD)
+
+ #ifdef __APPLE__
+ #include "TargetConditionals.h"
+ #endif
+
+ #if defined(STARBOARD)
+ #define SK_BUILD_FOR_STARBOARD
+ #elif defined(PALMOS_SDK_VERSION)
+ #define SK_BUILD_FOR_PALM
+ #elif defined(UNDER_CE)
+ #define SK_BUILD_FOR_WINCE
+ #elif defined(WIN32)
+ #define SK_BUILD_FOR_WIN32
+ #elif defined(__SYMBIAN32__)
+ #define SK_BUILD_FOR_WIN32
+ #elif defined(ANDROID)
+ #define SK_BUILD_FOR_ANDROID
+ #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
+ defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) || \
+ defined(__GLIBC__) || defined(__GNU__)
+ #define SK_BUILD_FOR_UNIX
+ #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ #define SK_BUILD_FOR_IOS
+ #else
+ #define SK_BUILD_FOR_MAC
+ #endif
+
+#endif
+
+/* Even if the user only defined the framework variant we still need to build
+ * the default (NDK-compliant) Android code. Therefore, when attempting to
+ * include/exclude something from the framework variant check first that we are
+ * building for Android then check the status of the framework define.
+ */
+#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && !defined(SK_BUILD_FOR_ANDROID)
+ #define SK_BUILD_FOR_ANDROID
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
+ #ifdef NDEBUG
+ #define SK_RELEASE
+ #else
+ #define SK_DEBUG
+ #endif
+#endif
+
+#ifdef SK_BUILD_FOR_WIN32
+ #if !defined(SK_RESTRICT)
+ #define SK_RESTRICT __restrict
+ #endif
+ #if !defined(SK_WARN_UNUSED_RESULT)
+ #define SK_WARN_UNUSED_RESULT
+ #endif
+#endif
+
+#ifdef SK_BUILD_FOR_STARBOARD
+ #include "starboard/configuration.h"
+
+ #if !defined(SK_RESTRICT)
+ #define SK_RESTRICT SB_RESTRICT
+ #endif
+ #if !defined(SK_WARN_UNUSED_RESULT)
+ #define SK_WARN_UNUSED_RESULT SB_WARN_UNUSED_RESULT
+ #endif
+ #if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
+ #if SB_IS(BIG_ENDIAN)
+ #define SK_CPU_BENDIAN
+ #else
+ #define SK_CPU_LENDIAN
+ #endif
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_RESTRICT)
+ #define SK_RESTRICT __restrict__
+#endif
+
+#if !defined(SK_WARN_UNUSED_RESULT)
+ #define SK_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
+ #if defined(__sparc) || defined(__sparc__) || \
+ defined(_POWER) || defined(__powerpc__) || \
+ defined(__ppc__) || defined(__hppa) || \
+ defined(__PPC__) || defined(__PPC64__) || \
+ defined(_MIPSEB) || defined(__ARMEB__) || \
+ defined(__s390__) || \
+ (defined(__sh__) && defined(__BIG_ENDIAN__)) || \
+ (defined(__ia64) && defined(__BIG_ENDIAN__))
+ #define SK_CPU_BENDIAN
+ #else
+ #define SK_CPU_LENDIAN
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+ #define SK_CPU_X86 1
+#endif
+
+/**
+ * SK_CPU_SSE_LEVEL
+ *
+ * If defined, SK_CPU_SSE_LEVEL should be set to the highest supported level.
+ * On non-intel CPU this should be undefined.
+ */
+
+#define SK_CPU_SSE_LEVEL_SSE1 10
+#define SK_CPU_SSE_LEVEL_SSE2 20
+#define SK_CPU_SSE_LEVEL_SSE3 30
+#define SK_CPU_SSE_LEVEL_SSSE3 31
+#define SK_CPU_SSE_LEVEL_SSE41 41
+#define SK_CPU_SSE_LEVEL_SSE42 42
+
+// Are we in GCC?
+#ifndef SK_CPU_SSE_LEVEL
+ // These checks must be done in descending order to ensure we set the highest
+ // available SSE level.
+ #if defined(__SSE4_2__)
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE42
+ #elif defined(__SSE4_1__)
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE41
+ #elif defined(__SSSE3__)
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3
+ #elif defined(__SSE3__)
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3
+ #elif defined(__SSE2__)
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
+ #endif
+#endif
+
+// Are we in VisualStudio?
+#ifndef SK_CPU_SSE_LEVEL
+ // These checks must be done in descending order to ensure we set the highest
+ // available SSE level. 64-bit intel guarantees at least SSE2 support.
+ #if defined(_M_X64) || defined(_M_AMD64)
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
+ #elif defined (_M_IX86_FP)
+ #if _M_IX86_FP >= 2
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
+ #elif _M_IX86_FP == 1
+ #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1
+ #endif
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// ARM defines
+
+#if defined(__arm__) && (!defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR)
+ #define SK_CPU_ARM32
+
+ #if defined(__GNUC__)
+ #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
+ #define SK_ARM_ARCH 7
+ #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
+ || defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
+ #define SK_ARM_ARCH 6
+ #elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
+ #define SK_ARM_ARCH 5
+ #elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(_ARM_ARCH_4)
+ #define SK_ARM_ARCH 4
+ #else
+ #define SK_ARM_ARCH 3
+ #endif
+
+ #if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \
+ || !defined(__thumb__) && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \
+ || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__))
+ #define SK_ARM_HAS_EDSP
+ #endif
+ #endif
+#endif
+
+// Disable ARM64 optimizations for iOS due to complications regarding gyp and iOS.
+#if defined(__aarch64__) && !defined(SK_BUILD_FOR_IOS)
+ #define SK_CPU_ARM64
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SKIA_IMPLEMENTATION)
+ #define SKIA_IMPLEMENTATION 0
+#endif
+
+#if defined(SKIA_DLL)
+ #if defined(WIN32)
+ #if SKIA_IMPLEMENTATION
+ #define SK_API __declspec(dllexport)
+ #else
+ #define SK_API __declspec(dllimport)
+ #endif
+ #else
+ #define SK_API __attribute__((visibility("default")))
+ #endif
+#else
+ #define SK_API
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * Use SK_PURE_FUNC as an attribute to indicate that a function's
+ * return value only depends on the value of its parameters. This
+ * can help the compiler optimize out successive calls.
+ *
+ * Usage:
+ * void function(int params) SK_PURE_FUNC;
+ */
+#if defined(__GNUC__)
+# define SK_PURE_FUNC __attribute__((pure))
+#else
+# define SK_PURE_FUNC /* nothing */
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * SK_HAS_ATTRIBUTE(<name>) should return true iff the compiler
+ * supports __attribute__((<name>)). Mostly important because
+ * Clang doesn't support all of GCC attributes.
+ */
+#if defined(__has_attribute)
+# define SK_HAS_ATTRIBUTE(x) __has_attribute(x)
+#elif defined(__GNUC__)
+# define SK_HAS_ATTRIBUTE(x) 1
+#else
+# define SK_HAS_ATTRIBUTE(x) 0
+#endif
+
+/**
+ * SK_ATTRIBUTE_OPTIMIZE_O1 can be used as a function attribute
+ * to specify individual optimization level of -O1, if the compiler
+ * supports it.
+ *
+ * NOTE: Clang/ARM (r161757) does not support the 'optimize' attribute.
+ */
+#if SK_HAS_ATTRIBUTE(optimize)
+# define SK_ATTRIBUTE_OPTIMIZE_O1 __attribute__((optimize("O1")))
+#else
+# define SK_ATTRIBUTE_OPTIMIZE_O1 /* nothing */
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/core/SkRRect.h b/src/third_party/skia/include/core/SkRRect.h
new file mode 100644
index 0000000..d3f48cd
--- /dev/null
+++ b/src/third_party/skia/include/core/SkRRect.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRRect_DEFINED
+#define SkRRect_DEFINED
+
+#include "SkRect.h"
+#include "SkPoint.h"
+
+class SkPath;
+class SkMatrix;
+
+// Path forward:
+// core work
+// add validate method (all radii positive, all radii sums < rect size, etc.)
+// add contains(SkRect&) - for clip stack
+// add contains(SkRRect&) - for clip stack
+// add heart rect computation (max rect inside RR)
+// add 9patch rect computation
+// add growToInclude(SkPath&)
+// analysis
+// use growToInclude to fit skp round rects & generate stats (RRs vs. real paths)
+// check on # of rectorus's the RRs could handle
+// rendering work
+// update SkPath.addRRect() to only use quads
+// add GM and bench
+// further out
+// detect and triangulate RRectorii rather than falling back to SW in Ganesh
+//
+
+/** \class SkRRect
+
+ The SkRRect class represents a rounded rect with a potentially different
+ radii for each corner. It does not have a constructor so must be
+ initialized with one of the initialization functions (e.g., setEmpty,
+ setRectRadii, etc.)
+
+ This class is intended to roughly match CSS' border-*-*-radius capabilities.
+ This means:
+ If either of a corner's radii are 0 the corner will be square.
+ Negative radii are not allowed (they are clamped to zero).
+ If the corner curves overlap they will be proportionally reduced to fit.
+*/
+class SK_API SkRRect {
+public:
+ /**
+ * Enum to capture the various possible subtypes of RR. Accessed
+ * by type(). The subtypes become progressively less restrictive.
+ */
+ enum Type {
+ // !< Internal indicator that the sub type must be computed.
+ kUnknown_Type = -1,
+
+ // !< The RR is empty
+ kEmpty_Type,
+
+ //!< The RR is actually a (non-empty) rect (i.e., at least one radius
+ //!< at each corner is zero)
+ kRect_Type,
+
+ //!< The RR is actually a (non-empty) oval (i.e., all x radii are equal
+ //!< and >= width/2 and all the y radii are equal and >= height/2
+ kOval_Type,
+
+ //!< The RR is non-empty and all the x radii are equal & all y radii
+ //!< are equal but it is not an oval (i.e., there are lines between
+ //!< the curves) nor a rect (i.e., both radii are non-zero)
+ kSimple_Type,
+
+ //!< The RR is non-empty and the two left x radii are equal, the two top
+ //!< y radii are equal, and the same for the right and bottom but it is
+ //!< neither an rect, oval, nor a simple RR. It is called "nine patch"
+ //!< because the centers of the corner ellipses form an axis aligned
+ //!< rect with edges that divide the RR into an 9 rectangular patches:
+ //!< an interior patch, four edge patches, and four corner patches.
+ kNinePatch_Type,
+
+ //!< A fully general (non-empty) RR. Some of the x and/or y radii are
+ //!< different from the others and there must be one corner where
+ //!< both radii are non-zero.
+ kComplex_Type,
+ };
+
+ /**
+ * Returns the RR's sub type.
+ */
+ Type getType() const {
+ SkDEBUGCODE(this->validate();)
+
+ if (kUnknown_Type == fType) {
+ this->computeType();
+ }
+ SkASSERT(kUnknown_Type != fType);
+ return fType;
+ }
+
+ Type type() const { return this->getType(); }
+
+ inline bool isEmpty() const { return kEmpty_Type == this->getType(); }
+ inline bool isRect() const { return kRect_Type == this->getType(); }
+ inline bool isOval() const { return kOval_Type == this->getType(); }
+ inline bool isSimple() const { return kSimple_Type == this->getType(); }
+ inline bool isSimpleCircular() const {
+ return this->isSimple() && fRadii[0].fX == fRadii[0].fY;
+ }
+ inline bool isNinePatch() const { return kNinePatch_Type == this->getType(); }
+ inline bool isComplex() const { return kComplex_Type == this->getType(); }
+
+ bool allCornersCircular() const;
+
+ SkScalar width() const { return fRect.width(); }
+ SkScalar height() const { return fRect.height(); }
+
+ /**
+ * Set this RR to the empty rectangle (0,0,0,0) with 0 x & y radii.
+ */
+ void setEmpty() {
+ fRect.setEmpty();
+ memset(fRadii, 0, sizeof(fRadii));
+ fType = kEmpty_Type;
+
+ SkDEBUGCODE(this->validate();)
+ }
+
+ /**
+ * Set this RR to match the supplied rect. All radii will be 0.
+ */
+ void setRect(const SkRect& rect) {
+ if (rect.isEmpty()) {
+ this->setEmpty();
+ return;
+ }
+
+ fRect = rect;
+ memset(fRadii, 0, sizeof(fRadii));
+ fType = kRect_Type;
+
+ SkDEBUGCODE(this->validate();)
+ }
+
+ /**
+ * Set this RR to match the supplied oval. All x radii will equal half the
+ * width and all y radii will equal half the height.
+ */
+ void setOval(const SkRect& oval) {
+ if (oval.isEmpty()) {
+ this->setEmpty();
+ return;
+ }
+
+ SkScalar xRad = SkScalarHalf(oval.width());
+ SkScalar yRad = SkScalarHalf(oval.height());
+
+ fRect = oval;
+ for (int i = 0; i < 4; ++i) {
+ fRadii[i].set(xRad, yRad);
+ }
+ fType = kOval_Type;
+
+ SkDEBUGCODE(this->validate();)
+ }
+
+ /**
+ * Initialize the RR with the same radii for all four corners.
+ */
+ void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad);
+
+ /**
+ * Initialize the rr with one radius per-side.
+ */
+ void setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad,
+ SkScalar rightRad, SkScalar bottomRad);
+
+ /**
+ * Initialize the RR with potentially different radii for all four corners.
+ */
+ void setRectRadii(const SkRect& rect, const SkVector radii[4]);
+
+ // The radii are stored in UL, UR, LR, LL order.
+ enum Corner {
+ kUpperLeft_Corner,
+ kUpperRight_Corner,
+ kLowerRight_Corner,
+ kLowerLeft_Corner
+ };
+
+ const SkRect& rect() const { return fRect; }
+ const SkVector& radii(Corner corner) const { return fRadii[corner]; }
+ const SkRect& getBounds() const { return fRect; }
+
+ /**
+ * When a rrect is simple, all of its radii are equal. This returns one
+ * of those radii. This call requires the rrect to be non-complex.
+ */
+ const SkVector& getSimpleRadii() const {
+ SkASSERT(!this->isComplex());
+ return fRadii[0];
+ }
+
+ friend bool operator==(const SkRRect& a, const SkRRect& b) {
+ return a.fRect == b.fRect &&
+ SkScalarsEqual(a.fRadii[0].asScalars(),
+ b.fRadii[0].asScalars(), 8);
+ }
+
+ friend bool operator!=(const SkRRect& a, const SkRRect& b) {
+ return a.fRect != b.fRect ||
+ !SkScalarsEqual(a.fRadii[0].asScalars(),
+ b.fRadii[0].asScalars(), 8);
+ }
+
+ /**
+ * Call inset on the bounds, and adjust the radii to reflect what happens
+ * in stroking: If the corner is sharp (no curvature), leave it alone,
+ * otherwise we grow/shrink the radii by the amount of the inset. If a
+ * given radius becomes negative, it is pinned to 0.
+ *
+ * It is valid for dst == this.
+ */
+ void inset(SkScalar dx, SkScalar dy, SkRRect* dst) const;
+
+ void inset(SkScalar dx, SkScalar dy) {
+ this->inset(dx, dy, this);
+ }
+
+ /**
+ * Call outset on the bounds, and adjust the radii to reflect what happens
+ * in stroking: If the corner is sharp (no curvature), leave it alone,
+ * otherwise we grow/shrink the radii by the amount of the inset. If a
+ * given radius becomes negative, it is pinned to 0.
+ *
+ * It is valid for dst == this.
+ */
+ void outset(SkScalar dx, SkScalar dy, SkRRect* dst) const {
+ this->inset(-dx, -dy, dst);
+ }
+ void outset(SkScalar dx, SkScalar dy) {
+ this->inset(-dx, -dy, this);
+ }
+
+ /**
+ * Translate the rrect by (dx, dy).
+ */
+ void offset(SkScalar dx, SkScalar dy) {
+ fRect.offset(dx, dy);
+ }
+
+ /**
+ * Returns true if 'rect' is wholy inside the RR, and both
+ * are not empty.
+ */
+ bool contains(const SkRect& rect) const;
+
+ SkDEBUGCODE(void validate() const;)
+
+ enum {
+ kSizeInMemory = 12 * sizeof(SkScalar)
+ };
+
+ /**
+ * Write the rrect into the specified buffer. This is guaranteed to always
+ * write kSizeInMemory bytes, and that value is guaranteed to always be
+ * a multiple of 4. Return kSizeInMemory.
+ */
+ size_t writeToMemory(void* buffer) const;
+
+ /**
+ * Reads the rrect from the specified buffer
+ *
+ * If the specified buffer is large enough, this will read kSizeInMemory bytes,
+ * and that value is guaranteed to always be a multiple of 4.
+ *
+ * @param buffer Memory to read from
+ * @param length Amount of memory available in the buffer
+ * @return number of bytes read (must be a multiple of 4) or
+ * 0 if there was not enough memory available
+ */
+ size_t readFromMemory(const void* buffer, size_t length);
+
+ /**
+ * Transform by the specified matrix, and put the result in dst.
+ *
+ * @param matrix SkMatrix specifying the transform. Must only contain
+ * scale and/or translate, or this call will fail.
+ * @param dst SkRRect to store the result. It is an error to use this,
+ * which would make this function no longer const.
+ * @return true on success, false on failure. If false, dst is unmodified.
+ */
+ bool transform(const SkMatrix& matrix, SkRRect* dst) const;
+
+#ifdef SK_DEVELOPER
+ /**
+ * Prints the rrect using SkDebugf. This is intended for Skia development debugging. Don't
+ * rely on the existence of this function or the formatting of its output.
+ */
+ void dump() const;
+#endif
+
+private:
+ SkRect fRect;
+ // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[]
+ SkVector fRadii[4];
+ mutable Type fType;
+ // TODO: add padding so we can use memcpy for flattening and not copy
+ // uninitialized data
+
+ void computeType() const;
+ bool checkCornerContainment(SkScalar x, SkScalar y) const;
+
+ // to access fRadii directly
+ friend class SkPath;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkRasterizer.h b/src/third_party/skia/include/core/SkRasterizer.h
new file mode 100644
index 0000000..3280f42
--- /dev/null
+++ b/src/third_party/skia/include/core/SkRasterizer.h
@@ -0,0 +1,47 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkRasterizer_DEFINED
+#define SkRasterizer_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkMask.h"
+
+class SkMaskFilter;
+class SkMatrix;
+class SkPath;
+struct SkIRect;
+
+class SK_API SkRasterizer : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkRasterizer)
+
+ /** Turn the path into a mask, respecting the specified local->device matrix.
+ */
+ bool rasterize(const SkPath& path, const SkMatrix& matrix,
+ const SkIRect* clipBounds, SkMaskFilter* filter,
+ SkMask* mask, SkMask::CreateMode mode) const;
+
+ SK_DEFINE_FLATTENABLE_TYPE(SkRasterizer)
+
+protected:
+ SkRasterizer() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkRasterizer(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+ virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
+ const SkIRect* clipBounds,
+ SkMask* mask, SkMask::CreateMode mode) const;
+
+private:
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkRect.h b/src/third_party/skia/include/core/SkRect.h
new file mode 100644
index 0000000..c8fc7c6
--- /dev/null
+++ b/src/third_party/skia/include/core/SkRect.h
@@ -0,0 +1,847 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkRect_DEFINED
+#define SkRect_DEFINED
+
+#include "SkPoint.h"
+#include "SkSize.h"
+
+/** \struct SkIRect
+
+ SkIRect holds four 32 bit integer coordinates for a rectangle
+*/
+struct SK_API SkIRect {
+ int32_t fLeft, fTop, fRight, fBottom;
+
+ static SkIRect SK_WARN_UNUSED_RESULT MakeEmpty() {
+ SkIRect r;
+ r.setEmpty();
+ return r;
+ }
+
+ static SkIRect SK_WARN_UNUSED_RESULT MakeLargest() {
+ SkIRect r;
+ r.setLargest();
+ return r;
+ }
+
+ static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h) {
+ SkIRect r;
+ r.set(0, 0, w, h);
+ return r;
+ }
+
+ static SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size) {
+ SkIRect r;
+ r.set(0, 0, size.width(), size.height());
+ return r;
+ }
+
+ static SkIRect SK_WARN_UNUSED_RESULT 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 SK_WARN_UNUSED_RESULT 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;
+ }
+
+ int left() const { return fLeft; }
+ int top() const { return fTop; }
+ int right() const { return fRight; }
+ int bottom() const { return fBottom; }
+
+ /** return the left edge of the rect */
+ int x() const { return fLeft; }
+ /** return the top edge of the rect */
+ int y() const { return fTop; }
+ /**
+ * Returns the rectangle's width. This does not check for a valid rect
+ * (i.e. left <= right) so the result may be negative.
+ */
+ int width() const { return fRight - fLeft; }
+
+ /**
+ * Returns the rectangle's height. This does not check for a valid rect
+ * (i.e. top <= bottom) so the result may be negative.
+ */
+ int height() const { return fBottom - fTop; }
+
+ /**
+ * Since the center of an integer rect may fall on a factional value, this
+ * method is defined to return (right + left) >> 1.
+ *
+ * This is a specific "truncation" of the average, which is different than
+ * (right + left) / 2 when the sum is negative.
+ */
+ int centerX() const { return (fRight + fLeft) >> 1; }
+
+ /**
+ * Since the center of an integer rect may fall on a factional value, this
+ * method is defined to return (bottom + top) >> 1
+ *
+ * This is a specific "truncation" of the average, which is different than
+ * (bottom + top) / 2 when the sum is negative.
+ */
+ int centerY() const { return (fBottom + fTop) >> 1; }
+
+ /**
+ * Return true if the rectangle's width or height are <= 0
+ */
+ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+
+ bool isLargest() const { return SK_MinS32 == fLeft &&
+ SK_MinS32 == fTop &&
+ SK_MaxS32 == fRight &&
+ SK_MaxS32 == fBottom; }
+
+ friend bool operator==(const SkIRect& a, const SkIRect& b) {
+ return !memcmp(&a, &b, sizeof(a));
+ }
+
+ friend bool operator!=(const SkIRect& a, const SkIRect& b) {
+ return !(a == b);
+ }
+
+ bool is16Bit() const {
+ return SkIsS16(fLeft) && SkIsS16(fTop) &&
+ SkIsS16(fRight) && SkIsS16(fBottom);
+ }
+
+ /** Set the rectangle to (0,0,0,0)
+ */
+ void setEmpty() { memset(this, 0, sizeof(*this)); }
+
+ void set(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ fLeft = left;
+ fTop = top;
+ fRight = right;
+ fBottom = bottom;
+ }
+ // alias for set(l, t, r, b)
+ void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ this->set(left, top, right, bottom);
+ }
+
+ void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) {
+ fLeft = x;
+ fTop = y;
+ fRight = x + width;
+ fBottom = y + height;
+ }
+
+ /**
+ * Make the largest representable rectangle
+ */
+ void setLargest() {
+ fLeft = fTop = SK_MinS32;
+ fRight = fBottom = SK_MaxS32;
+ }
+
+ /**
+ * Make the largest representable rectangle, but inverted (e.g. fLeft will
+ * be max 32bit and right will be min 32bit).
+ */
+ void setLargestInverted() {
+ fLeft = fTop = SK_MaxS32;
+ fRight = fBottom = SK_MinS32;
+ }
+
+ /**
+ * Return a new IRect, built as an offset of this rect.
+ */
+ SkIRect makeOffset(int dx, int dy) const {
+ return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy);
+ }
+
+ /**
+ * Return a new IRect, built as an inset of this rect.
+ */
+ SkIRect makeInset(int dx, int dy) const {
+ return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy);
+ }
+
+ /** Offset set the rectangle by adding dx to its left and right,
+ and adding dy to its top and bottom.
+ */
+ void offset(int32_t dx, int32_t dy) {
+ fLeft += dx;
+ fTop += dy;
+ fRight += dx;
+ fBottom += dy;
+ }
+
+ void offset(const SkIPoint& delta) {
+ this->offset(delta.fX, delta.fY);
+ }
+
+ /**
+ * Offset this rect such its new x() and y() will equal newX and newY.
+ */
+ void offsetTo(int32_t newX, int32_t newY) {
+ fRight += newX - fLeft;
+ fBottom += newY - fTop;
+ fLeft = newX;
+ fTop = newY;
+ }
+
+ /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
+ making the rectangle narrower. If dx is negative, then the sides are moved outwards,
+ making the rectangle wider. The same holds true for dy and the top and bottom.
+ */
+ void inset(int32_t dx, int32_t dy) {
+ fLeft += dx;
+ fTop += dy;
+ fRight -= dx;
+ fBottom -= dy;
+ }
+
+ /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
+ moved outwards, making the rectangle wider. If dx is negative, then the
+ sides are moved inwards, making the rectangle narrower. The same holds
+ true for dy and the top and bottom.
+ */
+ void outset(int32_t dx, int32_t dy) { this->inset(-dx, -dy); }
+
+ bool quickReject(int l, int t, int r, int b) const {
+ return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
+ }
+
+ /** Returns true if (x,y) is inside the rectangle and the rectangle is not
+ empty. The left and top are considered to be inside, while the right
+ and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
+ points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not.
+ */
+ bool contains(int32_t x, int32_t y) const {
+ return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) &&
+ (unsigned)(y - fTop) < (unsigned)(fBottom - fTop);
+ }
+
+ /** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle.
+ If either rectangle is empty, contains() returns false.
+ */
+ bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const {
+ return left < right && top < bottom && !this->isEmpty() && // check for empties
+ fLeft <= left && fTop <= top &&
+ fRight >= right && fBottom >= bottom;
+ }
+
+ /** Returns true if the specified rectangle r is inside or equal to this rectangle.
+ */
+ bool contains(const SkIRect& r) const {
+ return !r.isEmpty() && !this->isEmpty() && // check for empties
+ fLeft <= r.fLeft && fTop <= r.fTop &&
+ fRight >= r.fRight && fBottom >= r.fBottom;
+ }
+
+ /** Return true if this rectangle contains the specified rectangle.
+ For speed, this method does not check if either this or the specified
+ rectangles are empty, and if either is, its return value is undefined.
+ In the debugging build however, we assert that both this and the
+ specified rectangles are non-empty.
+ */
+ bool containsNoEmptyCheck(int32_t left, int32_t top,
+ int32_t right, int32_t bottom) const {
+ SkASSERT(fLeft < fRight && fTop < fBottom);
+ SkASSERT(left < right && top < bottom);
+
+ return fLeft <= left && fTop <= top &&
+ fRight >= right && fBottom >= bottom;
+ }
+
+ bool containsNoEmptyCheck(const SkIRect& r) const {
+ return containsNoEmptyCheck(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ }
+
+ /** If r intersects this rectangle, return true and set this rectangle to that
+ intersection, otherwise return false and do not change this rectangle.
+ If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(const SkIRect& r) {
+ SkASSERT(&r);
+ return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ }
+
+ /** If rectangles a and b intersect, return true and set this rectangle to
+ that intersection, otherwise return false and do not change this
+ rectangle. If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(const SkIRect& a, const SkIRect& b) {
+
+ if (!a.isEmpty() && !b.isEmpty() &&
+ a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom) {
+ fLeft = SkMax32(a.fLeft, b.fLeft);
+ fTop = SkMax32(a.fTop, b.fTop);
+ fRight = SkMin32(a.fRight, b.fRight);
+ fBottom = SkMin32(a.fBottom, b.fBottom);
+ return true;
+ }
+ return false;
+ }
+
+ /** If rectangles a and b intersect, return true and set this rectangle to
+ that intersection, otherwise return false and do not change this
+ rectangle. For speed, no check to see if a or b are empty is performed.
+ If either is, then the return result is undefined. In the debug build,
+ we assert that both rectangles are non-empty.
+ */
+ bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) {
+ SkASSERT(!a.isEmpty() && !b.isEmpty());
+
+ if (a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom) {
+ fLeft = SkMax32(a.fLeft, b.fLeft);
+ fTop = SkMax32(a.fTop, b.fTop);
+ fRight = SkMin32(a.fRight, b.fRight);
+ fBottom = SkMin32(a.fBottom, b.fBottom);
+ return true;
+ }
+ return false;
+ }
+
+ /** If the rectangle specified by left,top,right,bottom intersects this rectangle,
+ return true and set this rectangle to that intersection,
+ otherwise return false and do not change this rectangle.
+ If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ if (left < right && top < bottom && !this->isEmpty() &&
+ fLeft < right && left < fRight && fTop < bottom && top < fBottom) {
+ if (fLeft < left) fLeft = left;
+ if (fTop < top) fTop = top;
+ if (fRight > right) fRight = right;
+ if (fBottom > bottom) fBottom = bottom;
+ return true;
+ }
+ return false;
+ }
+
+ /** Returns true if a and b are not empty, and they intersect
+ */
+ static bool Intersects(const SkIRect& a, const SkIRect& b) {
+ return !a.isEmpty() && !b.isEmpty() && // check for empties
+ a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom;
+ }
+
+ /**
+ * Returns true if a and b intersect. debug-asserts that neither are empty.
+ */
+ static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b) {
+ SkASSERT(!a.isEmpty());
+ SkASSERT(!b.isEmpty());
+ return a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom;
+ }
+
+ /** Update this rectangle to enclose itself and the specified rectangle.
+ If this rectangle is empty, just set it to the specified rectangle. If the specified
+ rectangle is empty, do nothing.
+ */
+ void join(int32_t left, int32_t top, int32_t right, int32_t bottom);
+
+ /** Update this rectangle to enclose itself and the specified rectangle.
+ If this rectangle is empty, just set it to the specified rectangle. If the specified
+ rectangle is empty, do nothing.
+ */
+ void join(const SkIRect& r) {
+ this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ }
+
+ /** Swap top/bottom or left/right if there are flipped.
+ This can be called if the edges are computed separately,
+ and may have crossed over each other.
+ When this returns, left <= right && top <= bottom
+ */
+ void sort();
+
+ static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect() {
+ static const SkIRect gEmpty = { 0, 0, 0, 0 };
+ return gEmpty;
+ }
+};
+
+/** \struct SkRect
+*/
+struct SK_API SkRect {
+ SkScalar fLeft, fTop, fRight, fBottom;
+
+ static SkRect SK_WARN_UNUSED_RESULT MakeEmpty() {
+ SkRect r;
+ r.setEmpty();
+ return r;
+ }
+
+ static SkRect SK_WARN_UNUSED_RESULT MakeLargest() {
+ SkRect r;
+ r.setLargest();
+ return r;
+ }
+
+ static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h) {
+ SkRect r;
+ r.set(0, 0, w, h);
+ return r;
+ }
+
+ static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) {
+ SkRect r;
+ r.set(0, 0, size.width(), size.height());
+ return r;
+ }
+
+ static SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
+ SkRect rect;
+ rect.set(l, t, r, b);
+ return rect;
+ }
+
+ static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) {
+ SkRect r;
+ r.set(x, y, x + w, y + h);
+ return r;
+ }
+
+ SK_ATTR_DEPRECATED("use Make()")
+ static SkRect SK_WARN_UNUSED_RESULT MakeFromIRect(const SkIRect& irect) {
+ SkRect r;
+ r.set(SkIntToScalar(irect.fLeft),
+ SkIntToScalar(irect.fTop),
+ SkIntToScalar(irect.fRight),
+ SkIntToScalar(irect.fBottom));
+ return r;
+ }
+
+ static SkRect SK_WARN_UNUSED_RESULT Make(const SkIRect& irect) {
+ SkRect r;
+ r.set(SkIntToScalar(irect.fLeft),
+ SkIntToScalar(irect.fTop),
+ SkIntToScalar(irect.fRight),
+ SkIntToScalar(irect.fBottom));
+ return r;
+ }
+
+ /**
+ * Return true if the rectangle's width or height are <= 0
+ */
+ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+
+ bool isLargest() const { return SK_ScalarMin == fLeft &&
+ SK_ScalarMin == fTop &&
+ SK_ScalarMax == fRight &&
+ SK_ScalarMax == fBottom; }
+
+ /**
+ * Returns true iff all values in the rect are finite. If any are
+ * infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this
+ * returns false.
+ */
+ bool isFinite() const {
+ float accum = 0;
+ accum *= fLeft;
+ accum *= fTop;
+ accum *= fRight;
+ accum *= fBottom;
+
+ // accum is either NaN or it is finite (zero).
+ SkASSERT(0 == accum || !(accum == accum));
+
+ // value==value will be true iff value is not NaN
+ // TODO: is it faster to say !accum or accum==accum?
+ return accum == accum;
+ }
+
+ SkScalar x() const { return fLeft; }
+ SkScalar y() const { return fTop; }
+ SkScalar left() const { return fLeft; }
+ SkScalar top() const { return fTop; }
+ SkScalar right() const { return fRight; }
+ SkScalar bottom() const { return fBottom; }
+ SkScalar width() const { return fRight - fLeft; }
+ SkScalar height() const { return fBottom - fTop; }
+ SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); }
+ SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); }
+
+ friend bool operator==(const SkRect& a, const SkRect& b) {
+ return SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4);
+ }
+
+ friend bool operator!=(const SkRect& a, const SkRect& b) {
+ return !SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4);
+ }
+
+ /** return the 4 points that enclose the rectangle (top-left, top-right, bottom-right,
+ bottom-left). TODO: Consider adding param to control whether quad is CW or CCW.
+ */
+ void toQuad(SkPoint quad[4]) const;
+
+ /** Set this rectangle to the empty rectangle (0,0,0,0)
+ */
+ void setEmpty() { memset(this, 0, sizeof(*this)); }
+
+ void set(const SkIRect& src) {
+ fLeft = SkIntToScalar(src.fLeft);
+ fTop = SkIntToScalar(src.fTop);
+ fRight = SkIntToScalar(src.fRight);
+ fBottom = SkIntToScalar(src.fBottom);
+ }
+
+ void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
+ fLeft = left;
+ fTop = top;
+ fRight = right;
+ fBottom = bottom;
+ }
+ // alias for set(l, t, r, b)
+ void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
+ this->set(left, top, right, bottom);
+ }
+
+ /** Initialize the rect with the 4 specified integers. The routine handles
+ converting them to scalars (by calling SkIntToScalar)
+ */
+ void iset(int left, int top, int right, int bottom) {
+ fLeft = SkIntToScalar(left);
+ fTop = SkIntToScalar(top);
+ fRight = SkIntToScalar(right);
+ fBottom = SkIntToScalar(bottom);
+ }
+
+ /**
+ * Set this rectangle to be left/top at 0,0, and have the specified width
+ * and height (automatically converted to SkScalar).
+ */
+ void isetWH(int width, int height) {
+ fLeft = fTop = 0;
+ fRight = SkIntToScalar(width);
+ fBottom = SkIntToScalar(height);
+ }
+
+ /** Set this rectangle to be the bounds of the array of points.
+ If the array is empty (count == 0), then set this rectangle
+ to the empty rectangle (0,0,0,0)
+ */
+ void set(const SkPoint pts[], int count) {
+ // set() had been checking for non-finite values, so keep that behavior
+ // for now. Now that we have setBoundsCheck(), we may decide to make
+ // set() be simpler/faster, and not check for those.
+ (void)this->setBoundsCheck(pts, count);
+ }
+
+ // alias for set(pts, count)
+ void setBounds(const SkPoint pts[], int count) {
+ (void)this->setBoundsCheck(pts, count);
+ }
+
+ /**
+ * Compute the bounds of the array of points, and set this rect to that
+ * bounds and return true... unless a non-finite value is encountered,
+ * in which case this rect is set to empty and false is returned.
+ */
+ bool setBoundsCheck(const SkPoint pts[], int count);
+
+ void set(const SkPoint& p0, const SkPoint& p1) {
+ fLeft = SkMinScalar(p0.fX, p1.fX);
+ fRight = SkMaxScalar(p0.fX, p1.fX);
+ fTop = SkMinScalar(p0.fY, p1.fY);
+ fBottom = SkMaxScalar(p0.fY, p1.fY);
+ }
+
+ void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) {
+ fLeft = x;
+ fTop = y;
+ fRight = x + width;
+ fBottom = y + height;
+ }
+
+ void setWH(SkScalar width, SkScalar height) {
+ fLeft = 0;
+ fTop = 0;
+ fRight = width;
+ fBottom = height;
+ }
+
+ /**
+ * Make the largest representable rectangle
+ */
+ void setLargest() {
+ fLeft = fTop = SK_ScalarMin;
+ fRight = fBottom = SK_ScalarMax;
+ }
+
+ /**
+ * Make the largest representable rectangle, but inverted (e.g. fLeft will
+ * be max and right will be min).
+ */
+ void setLargestInverted() {
+ fLeft = fTop = SK_ScalarMax;
+ fRight = fBottom = SK_ScalarMin;
+ }
+
+ /**
+ * Return a new Rect, built as an offset of this rect.
+ */
+ SkRect makeOffset(SkScalar dx, SkScalar dy) const {
+ return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy);
+ }
+
+ /**
+ * Return a new Rect, built as an inset of this rect.
+ */
+ SkRect makeInset(SkScalar dx, SkScalar dy) const {
+ return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy);
+ }
+
+ /** Offset set the rectangle by adding dx to its left and right,
+ and adding dy to its top and bottom.
+ */
+ void offset(SkScalar dx, SkScalar dy) {
+ fLeft += dx;
+ fTop += dy;
+ fRight += dx;
+ fBottom += dy;
+ }
+
+ void offset(const SkPoint& delta) {
+ this->offset(delta.fX, delta.fY);
+ }
+
+ /**
+ * Offset this rect such its new x() and y() will equal newX and newY.
+ */
+ void offsetTo(SkScalar newX, SkScalar newY) {
+ fRight += newX - fLeft;
+ fBottom += newY - fTop;
+ fLeft = newX;
+ fTop = newY;
+ }
+
+ /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are
+ moved inwards, making the rectangle narrower. If dx is negative, then
+ the sides are moved outwards, making the rectangle wider. The same holds
+ true for dy and the top and bottom.
+ */
+ void inset(SkScalar dx, SkScalar dy) {
+ fLeft += dx;
+ fTop += dy;
+ fRight -= dx;
+ fBottom -= dy;
+ }
+
+ /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
+ moved outwards, making the rectangle wider. If dx is negative, then the
+ sides are moved inwards, making the rectangle narrower. The same holds
+ true for dy and the top and bottom.
+ */
+ void outset(SkScalar dx, SkScalar dy) { this->inset(-dx, -dy); }
+
+ /** If this rectangle intersects r, return true and set this rectangle to that
+ intersection, otherwise return false and do not change this rectangle.
+ If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(const SkRect& r);
+ bool intersect2(const SkRect& r);
+
+ /** If this rectangle intersects the rectangle specified by left, top, right, bottom,
+ return true and set this rectangle to that intersection, otherwise return false
+ and do not change this rectangle.
+ If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
+
+ /**
+ * Return true if this rectangle is not empty, and the specified sides of
+ * a rectangle are not empty, and they intersect.
+ */
+ bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const {
+ return // first check that both are not empty
+ left < right && top < bottom &&
+ fLeft < fRight && fTop < fBottom &&
+ // now check for intersection
+ fLeft < right && left < fRight &&
+ fTop < bottom && top < fBottom;
+ }
+
+ /** If rectangles a and b intersect, return true and set this rectangle to
+ * that intersection, otherwise return false and do not change this
+ * rectangle. If either rectangle is empty, do nothing and return false.
+ */
+ bool intersect(const SkRect& a, const SkRect& b);
+
+ /**
+ * Return true if rectangles a and b are not empty and intersect.
+ */
+ static bool Intersects(const SkRect& a, const SkRect& b) {
+ return !a.isEmpty() && !b.isEmpty() &&
+ a.fLeft < b.fRight && b.fLeft < a.fRight &&
+ a.fTop < b.fBottom && b.fTop < a.fBottom;
+ }
+
+ /**
+ * Update this rectangle to enclose itself and the specified rectangle.
+ * If this rectangle is empty, just set it to the specified rectangle.
+ * If the specified rectangle is empty, do nothing.
+ */
+ void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
+
+ /** Update this rectangle to enclose itself and the specified rectangle.
+ If this rectangle is empty, just set it to the specified rectangle. If the specified
+ rectangle is empty, do nothing.
+ */
+ void join(const SkRect& r) {
+ this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ }
+ // alias for join()
+ void growToInclude(const SkRect& r) { this->join(r); }
+
+ /**
+ * Grow the rect to include the specified (x,y). After this call, the
+ * following will be true: fLeft <= x <= fRight && fTop <= y <= fBottom.
+ *
+ * This is close, but not quite the same contract as contains(), since
+ * contains() treats the left and top different from the right and bottom.
+ * contains(x,y) -> fLeft <= x < fRight && fTop <= y < fBottom. Also note
+ * that contains(x,y) always returns false if the rect is empty.
+ */
+ void growToInclude(SkScalar x, SkScalar y) {
+ fLeft = SkMinScalar(x, fLeft);
+ fRight = SkMaxScalar(x, fRight);
+ fTop = SkMinScalar(y, fTop);
+ fBottom = SkMaxScalar(y, fBottom);
+ }
+
+ /** Bulk version of growToInclude */
+ void growToInclude(const SkPoint pts[], int count) {
+ this->growToInclude(pts, sizeof(SkPoint), count);
+ }
+
+ /** Bulk version of growToInclude with stride. */
+ void growToInclude(const SkPoint pts[], size_t stride, int count) {
+ SkASSERT(count >= 0);
+ SkASSERT(stride >= sizeof(SkPoint));
+ const SkPoint* end = (const SkPoint*)((intptr_t)pts + count * stride);
+ for (; pts < end; pts = (const SkPoint*)((intptr_t)pts + stride)) {
+ this->growToInclude(pts->fX, pts->fY);
+ }
+ }
+
+ /**
+ * Return true if this rectangle contains r, and if both rectangles are
+ * not empty.
+ */
+ bool contains(const SkRect& r) const {
+ // todo: can we eliminate the this->isEmpty check?
+ return !r.isEmpty() && !this->isEmpty() &&
+ fLeft <= r.fLeft && fTop <= r.fTop &&
+ fRight >= r.fRight && fBottom >= r.fBottom;
+ }
+
+ /**
+ * Set the dst rectangle by rounding this rectangle's coordinates to their
+ * nearest integer values using SkScalarRoundToInt.
+ */
+ void round(SkIRect* dst) const {
+ SkASSERT(dst);
+ dst->set(SkScalarRoundToInt(fLeft), SkScalarRoundToInt(fTop),
+ SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom));
+ }
+
+ /**
+ * Variant of round() that explicitly performs the rounding step (i.e. floor(x + 0.5)) using
+ * double instead of SkScalar (float). It does this by calling SkDScalarRoundToInt(), which
+ * may be slower than calling SkScalarRountToInt(), but gives slightly more accurate results.
+ *
+ * e.g.
+ * SkScalar x = 0.49999997f;
+ * int ix = SkScalarRoundToInt(x);
+ * SkASSERT(0 == ix); // <--- fails
+ * ix = SkDScalarRoundToInt(x);
+ * SkASSERT(0 == ix); // <--- succeeds
+ */
+ void dround(SkIRect* dst) const {
+ SkASSERT(dst);
+ dst->set(SkDScalarRoundToInt(fLeft), SkDScalarRoundToInt(fTop),
+ SkDScalarRoundToInt(fRight), SkDScalarRoundToInt(fBottom));
+ }
+
+ /**
+ * Set the dst rectangle by rounding "out" this rectangle, choosing the
+ * SkScalarFloor of top and left, and the SkScalarCeil of right and bottom.
+ */
+ void roundOut(SkIRect* dst) const {
+ SkASSERT(dst);
+ dst->set(SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop),
+ SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom));
+ }
+
+ /**
+ * Expand this rectangle by rounding its coordinates "out", choosing the
+ * floor of top and left, and the ceil of right and bottom. If this rect
+ * is already on integer coordinates, then it will be unchanged.
+ */
+ void roundOut() {
+ this->set(SkScalarFloorToScalar(fLeft),
+ SkScalarFloorToScalar(fTop),
+ SkScalarCeilToScalar(fRight),
+ SkScalarCeilToScalar(fBottom));
+ }
+
+ /**
+ * Set the dst rectangle by rounding "in" this rectangle, choosing the
+ * ceil of top and left, and the floor of right and bottom. This does *not*
+ * call sort(), so it is possible that the resulting rect is inverted...
+ * e.g. left >= right or top >= bottom. Call isEmpty() to detect that.
+ */
+ void roundIn(SkIRect* dst) const {
+ SkASSERT(dst);
+ dst->set(SkScalarCeilToInt(fLeft), SkScalarCeilToInt(fTop),
+ SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom));
+ }
+
+ /**
+ * Return a new SkIRect which is contains the rounded coordinates of this
+ * rect using SkScalarRoundToInt.
+ */
+ SkIRect round() const {
+ SkIRect ir;
+ this->round(&ir);
+ return ir;
+ }
+
+ /**
+ * Swap top/bottom or left/right if there are flipped (i.e. if width()
+ * or height() would have returned a negative value.) This should be called
+ * if the edges are computed separately, and may have crossed over each
+ * other. When this returns, left <= right && top <= bottom
+ */
+ void sort();
+
+ /**
+ * cast-safe way to treat the rect as an array of (4) SkScalars.
+ */
+ const SkScalar* asScalars() const { return &fLeft; }
+
+#ifdef SK_DEVELOPER
+ /**
+ * Dumps the rect using SkDebugf. This is intended for Skia development debugging. Don't
+ * rely on the existence of this function or the formatting of its output.
+ */
+ void dump() const {
+ SkDebugf("{ l: %f, t: %f, r: %f, b: %f }", fLeft, fTop, fRight, fBottom);
+ }
+#endif
+
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkRefCnt.h b/src/third_party/skia/include/core/SkRefCnt.h
new file mode 100644
index 0000000..459ad25
--- /dev/null
+++ b/src/third_party/skia/include/core/SkRefCnt.h
@@ -0,0 +1,250 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkRefCnt_DEFINED
+#define SkRefCnt_DEFINED
+
+#include "SkDynamicAnnotations.h"
+#include "SkThread.h"
+#include "SkInstCnt.h"
+#include "SkTemplates.h"
+
+/** \class SkRefCntBase
+
+ SkRefCntBase is the base class for objects that may be shared by multiple
+ objects. When an existing owner wants to share a reference, it calls ref().
+ When an owner wants to release its reference, it calls unref(). When the
+ shared object's reference count goes to zero as the result of an unref()
+ call, its (virtual) destructor is called. It is an error for the
+ destructor to be called explicitly (or via the object going out of scope on
+ the stack or calling delete) if getRefCnt() > 1.
+*/
+class SK_API SkRefCntBase : SkNoncopyable {
+public:
+ SK_DECLARE_INST_COUNT_ROOT(SkRefCntBase)
+
+ /** Default construct, initializing the reference count to 1.
+ */
+ SkRefCntBase() : fRefCnt(1) {}
+
+ /** Destruct, asserting that the reference count is 1.
+ */
+ virtual ~SkRefCntBase() {
+#ifdef SK_DEBUG
+ SkASSERTF(fRefCnt == 1, "fRefCnt was %d", fRefCnt);
+ fRefCnt = 0; // illegal value, to catch us if we reuse after delete
+#endif
+ }
+
+ /** Return the reference count. Use only for debugging. */
+ int32_t getRefCnt() const { return fRefCnt; }
+
+ /** May return true if the caller is the only owner.
+ * Ensures that all previous owner's actions are complete.
+ */
+ bool unique() const {
+ // We believe we're reading fRefCnt in a safe way here, so we stifle the TSAN warning about
+ // an unproctected read. Generally, don't read fRefCnt, and don't stifle this warning.
+ bool const unique = (1 == SK_ANNOTATE_UNPROTECTED_READ(fRefCnt));
+ if (unique) {
+ // Acquire barrier (L/SL), if not provided by load of fRefCnt.
+ // Prevents user's 'unique' code from happening before decrements.
+ //TODO: issue the barrier.
+ }
+ return unique;
+ }
+
+ /** Increment the reference count. Must be balanced by a call to unref().
+ */
+ void ref() const {
+ SkASSERT(fRefCnt > 0);
+ sk_atomic_inc(&fRefCnt); // No barrier required.
+ }
+
+ /** Decrement the reference count. If the reference count is 1 before the
+ decrement, then delete 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);
+ // Release barrier (SL/S), if not provided below.
+ if (sk_atomic_dec(&fRefCnt) == 1) {
+ // Acquire barrier (L/SL), if not provided above.
+ // Prevents code in dispose from happening before the decrement.
+ sk_membar_acquire__after_atomic_dec();
+ internal_dispose();
+ }
+ }
+
+#ifdef SK_DEBUG
+ void validate() const {
+ SkASSERT(fRefCnt > 0);
+ }
+#endif
+
+protected:
+ /**
+ * Allow subclasses to call this if they've overridden internal_dispose
+ * so they can reset fRefCnt before the destructor is called. Should only
+ * be called right before calling through to inherited internal_dispose()
+ * or before calling the destructor.
+ */
+ void internal_dispose_restore_refcnt_to_1() const {
+#ifdef SK_DEBUG
+ SkASSERT(0 == fRefCnt);
+ fRefCnt = 1;
+#endif
+ }
+
+private:
+ /**
+ * Called when the ref count goes to 0.
+ */
+ virtual void internal_dispose() const {
+ this->internal_dispose_restore_refcnt_to_1();
+ SkDELETE(this);
+ }
+
+ // The following friends are those which override internal_dispose()
+ // and conditionally call SkRefCnt::internal_dispose().
+ friend class SkWeakRefCnt;
+
+ mutable int32_t fRefCnt;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+#ifdef SK_REF_CNT_MIXIN_INCLUDE
+// It is the responsibility of the following include to define the type SkRefCnt.
+// This SkRefCnt should normally derive from SkRefCntBase.
+#include SK_REF_CNT_MIXIN_INCLUDE
+#else
+class SK_API SkRefCnt : public SkRefCntBase { };
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for
+ null in on each side of the assignment, and ensuring that ref() is called
+ before unref(), in case the two pointers point to the same object.
+ */
+#define SkRefCnt_SafeAssign(dst, src) \
+ do { \
+ if (src) src->ref(); \
+ if (dst) dst->unref(); \
+ dst = src; \
+ } while (0)
+
+
+/** Call obj->ref() and return obj. The obj must not be NULL.
+ */
+template <typename T> static inline T* SkRef(T* obj) {
+ SkASSERT(obj);
+ obj->ref();
+ return obj;
+}
+
+/** Check if the argument is non-null, and if so, call obj->ref() and return obj.
+ */
+template <typename T> static inline T* SkSafeRef(T* obj) {
+ if (obj) {
+ obj->ref();
+ }
+ return obj;
+}
+
+/** Check if the argument is non-null, and if so, call obj->unref()
+ */
+template <typename T> static inline void SkSafeUnref(T* obj) {
+ if (obj) {
+ obj->unref();
+ }
+}
+
+template<typename T> static inline void SkSafeSetNull(T*& obj) {
+ if (obj) {
+ obj->unref();
+ obj = NULL;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Utility class that simply unref's its argument in the destructor.
+ */
+template <typename T> class SkAutoTUnref : SkNoncopyable {
+public:
+ explicit SkAutoTUnref(T* obj = NULL) : fObj(obj) {}
+ ~SkAutoTUnref() { SkSafeUnref(fObj); }
+
+ T* get() const { return fObj; }
+
+ T* reset(T* obj) {
+ SkSafeUnref(fObj);
+ fObj = obj;
+ return obj;
+ }
+
+ void swap(SkAutoTUnref* other) {
+ T* tmp = fObj;
+ fObj = other->fObj;
+ other->fObj = tmp;
+ }
+
+ /**
+ * Return the hosted object (which may be null), transferring ownership.
+ * The reference count is not modified, and the internal ptr is set to NULL
+ * so unref() will not be called in our destructor. A subsequent call to
+ * detach() will do nothing and return null.
+ */
+ T* detach() {
+ T* obj = fObj;
+ fObj = NULL;
+ return obj;
+ }
+
+ /**
+ * BlockRef<B> is a type which inherits from B, cannot be created,
+ * cannot be deleted, and makes ref and unref private.
+ */
+ template<typename B> class BlockRef : public B {
+ private:
+ BlockRef();
+ ~BlockRef();
+ void ref() const;
+ void unref() const;
+ };
+
+ /** If T is const, the type returned from operator-> will also be const. */
+ typedef typename SkTConstType<BlockRef<T>, SkTIsConst<T>::value>::type BlockRefType;
+
+ /**
+ * SkAutoTUnref assumes ownership of the ref. As a result, it is an error
+ * for the user to ref or unref through SkAutoTUnref. Therefore
+ * SkAutoTUnref::operator-> returns BlockRef<T>*. This prevents use of
+ * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref().
+ */
+ BlockRefType *operator->() const {
+ return static_cast<BlockRefType*>(fObj);
+ }
+ operator T*() const { return fObj; }
+
+private:
+ T* fObj;
+};
+// Can't use the #define trick below to guard a bare SkAutoTUnref(...) because it's templated. :(
+
+class SkAutoUnref : public SkAutoTUnref<SkRefCnt> {
+public:
+ SkAutoUnref(SkRefCnt* obj) : SkAutoTUnref<SkRefCnt>(obj) {}
+};
+#define SkAutoUnref(...) SK_REQUIRE_LOCAL_VAR(SkAutoUnref)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkRegion.h b/src/third_party/skia/include/core/SkRegion.h
new file mode 100644
index 0000000..20366bc
--- /dev/null
+++ b/src/third_party/skia/include/core/SkRegion.h
@@ -0,0 +1,453 @@
+
+/*
+ * Copyright 2005 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkRegion_DEFINED
+#define SkRegion_DEFINED
+
+#include "SkRect.h"
+
+class SkPath;
+class SkRgnBuilder;
+
+namespace android {
+ class Region;
+}
+
+#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1)
+#define SkRegion_gRectRunHeadPtr 0
+
+/** \class SkRegion
+
+ The SkRegion class encapsulates the geometric region used to specify
+ clipping areas for drawing.
+*/
+class SK_API SkRegion {
+public:
+ typedef int32_t RunType;
+ enum {
+ kRunTypeSentinel = 0x7FFFFFFF
+ };
+
+ SkRegion();
+ SkRegion(const SkRegion&);
+ explicit SkRegion(const SkIRect&);
+ ~SkRegion();
+
+ SkRegion& operator=(const SkRegion&);
+
+ /**
+ * Return true if the two regions are equal. i.e. The enclose exactly
+ * the same area.
+ */
+ bool operator==(const SkRegion& other) const;
+
+ /**
+ * Return true if the two regions are not equal.
+ */
+ bool operator!=(const SkRegion& other) const {
+ return !(*this == other);
+ }
+
+ /**
+ * Replace this region with the specified region, and return true if the
+ * resulting region is non-empty.
+ */
+ bool set(const SkRegion& src) {
+ SkASSERT(&src);
+ *this = src;
+ return !this->isEmpty();
+ }
+
+ /**
+ * Swap the contents of this and the specified region. This operation
+ * is gauarenteed to never fail.
+ */
+ void swap(SkRegion&);
+
+ /** Return true if this region is empty */
+ bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
+
+ /** Return true if this region is a single, non-empty rectangle */
+ bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
+
+ /** Return true if this region consists of more than 1 rectangular area */
+ bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
+
+ /**
+ * Return the bounds of this region. If the region is empty, returns an
+ * empty rectangle.
+ */
+ const SkIRect& getBounds() const { return fBounds; }
+
+ /**
+ * Returns a value that grows approximately linearly with the number of
+ * intervals comprised in the region. Empty region will return 0, Rect
+ * will return 1, Complex will return a value > 1.
+ *
+ * Use this to compare two regions, where the larger count likely
+ * indicates a more complex region.
+ */
+ int computeRegionComplexity() const;
+
+ /**
+ * Returns true if the region is non-empty, and if so, appends the
+ * boundary(s) of the region to the specified path.
+ * If the region is empty, returns false, and path is left unmodified.
+ */
+ bool getBoundaryPath(SkPath* path) const;
+
+ /**
+ * Set the region to be empty, and return false, since the resulting
+ * region is empty
+ */
+ bool setEmpty();
+
+ /**
+ * If rect is non-empty, set this region to that rectangle and return true,
+ * otherwise set this region to empty and return false.
+ */
+ bool setRect(const SkIRect&);
+
+ /**
+ * If left < right and top < bottom, set this region to that rectangle and
+ * return true, otherwise set this region to empty and return false.
+ */
+ bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom);
+
+ /**
+ * Set this region to the union of an array of rects. This is generally
+ * faster than calling region.op(rect, kUnion_Op) in a loop. If count is
+ * 0, then this region is set to the empty region.
+ * @return true if the resulting region is non-empty
+ */
+ bool setRects(const SkIRect rects[], int count);
+
+ /**
+ * Set this region to the specified region, and return true if it is
+ * non-empty.
+ */
+ bool setRegion(const SkRegion&);
+
+ /**
+ * Set this region to the area described by the path, clipped.
+ * Return true if the resulting region is non-empty.
+ * This produces a region that is identical to the pixels that would be
+ * drawn by the path (with no antialiasing) with the specified clip.
+ */
+ bool setPath(const SkPath&, const SkRegion& clip);
+
+ /**
+ * Returns true if the specified rectangle has a non-empty intersection
+ * with this region.
+ */
+ bool intersects(const SkIRect&) const;
+
+ /**
+ * Returns true if the specified region has a non-empty intersection
+ * with this region.
+ */
+ bool intersects(const SkRegion&) const;
+
+ /**
+ * Return true if the specified x,y coordinate is inside the region.
+ */
+ bool contains(int32_t x, int32_t y) const;
+
+ /**
+ * Return true if the specified rectangle is completely inside the region.
+ * This works for simple (rectangular) and complex regions, and always
+ * returns the correct result. Note: if either this region or the rectangle
+ * is empty, contains() returns false.
+ */
+ bool contains(const SkIRect&) const;
+
+ /**
+ * Return true if the specified region is completely inside the region.
+ * This works for simple (rectangular) and complex regions, and always
+ * returns the correct result. Note: if either region is empty, contains()
+ * returns false.
+ */
+ bool contains(const SkRegion&) const;
+
+ /**
+ * Return true if this region is a single rectangle (not complex) and the
+ * specified rectangle is contained by this region. Returning false is not
+ * a guarantee that the rectangle is not contained by this region, but
+ * return true is a guarantee that the rectangle is contained by this region.
+ */
+ bool quickContains(const SkIRect& r) const {
+ return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ }
+
+ /**
+ * Return true if this region is a single rectangle (not complex) and the
+ * specified rectangle is contained by this region. Returning false is not
+ * a guarantee that the rectangle is not contained by this region, but
+ * return true is a guarantee that the rectangle is contained by this
+ * region.
+ */
+ bool quickContains(int32_t left, int32_t top, int32_t right,
+ int32_t bottom) const {
+ SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
+
+ return left < right && top < bottom &&
+ fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect()
+ /* fBounds.contains(left, top, right, bottom); */
+ fBounds.fLeft <= left && fBounds.fTop <= top &&
+ fBounds.fRight >= right && fBounds.fBottom >= bottom;
+ }
+
+ /**
+ * Return true if this region is empty, or if the specified rectangle does
+ * not intersect the region. Returning false is not a guarantee that they
+ * intersect, but returning true is a guarantee that they do not.
+ */
+ bool quickReject(const SkIRect& rect) const {
+ return this->isEmpty() || rect.isEmpty() ||
+ !SkIRect::Intersects(fBounds, rect);
+ }
+
+ /**
+ * Return true if this region, or rgn, is empty, or if their bounds do not
+ * intersect. Returning false is not a guarantee that they intersect, but
+ * returning true is a guarantee that they do not.
+ */
+ bool quickReject(const SkRegion& rgn) const {
+ return this->isEmpty() || rgn.isEmpty() ||
+ !SkIRect::Intersects(fBounds, rgn.fBounds);
+ }
+
+ /** Translate the region by the specified (dx, dy) amount. */
+ void translate(int dx, int dy) { this->translate(dx, dy, this); }
+
+ /**
+ * Translate the region by the specified (dx, dy) amount, writing the
+ * resulting region into dst. Note: it is legal to pass this region as the
+ * dst parameter, effectively translating the region in place. If dst is
+ * null, nothing happens.
+ */
+ void translate(int dx, int dy, SkRegion* dst) const;
+
+ /**
+ * The logical operations that can be performed when combining two regions.
+ */
+ enum Op {
+ kDifference_Op, //!< subtract the op region from the first region
+ kIntersect_Op, //!< intersect the two regions
+ kUnion_Op, //!< union (inclusive-or) the two regions
+ kXOR_Op, //!< exclusive-or the two regions
+ /** subtract the first region from the op region */
+ kReverseDifference_Op,
+ kReplace_Op, //!< replace the dst region with the op region
+
+ kLastOp = kReplace_Op
+ };
+
+ static const int kOpCnt = kLastOp + 1;
+
+ /**
+ * Set this region to the result of applying the Op to this region and the
+ * specified rectangle: this = (this op rect).
+ * Return true if the resulting region is non-empty.
+ */
+ bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
+
+ /**
+ * Set this region to the result of applying the Op to this region and the
+ * specified rectangle: this = (this op rect).
+ * Return true if the resulting region is non-empty.
+ */
+ bool op(int left, int top, int right, int bottom, Op op) {
+ SkIRect rect;
+ rect.set(left, top, right, bottom);
+ return this->op(*this, rect, op);
+ }
+
+ /**
+ * Set this region to the result of applying the Op to this region and the
+ * specified region: this = (this op rgn).
+ * Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
+
+ /**
+ * Set this region to the result of applying the Op to the specified
+ * rectangle and region: this = (rect op rgn).
+ * Return true if the resulting region is non-empty.
+ */
+ bool op(const SkIRect& rect, const SkRegion& rgn, Op);
+
+ /**
+ * Set this region to the result of applying the Op to the specified
+ * region and rectangle: this = (rgn op rect).
+ * Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRegion& rgn, const SkIRect& rect, Op);
+
+ /**
+ * Set this region to the result of applying the Op to the specified
+ * regions: this = (rgna op rgnb).
+ * Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
+
+#ifdef SK_BUILD_FOR_ANDROID
+ /** Returns a new char* containing the list of rectangles in this region
+ */
+ char* toString();
+#endif
+
+ /**
+ * Returns the sequence of rectangles, sorted in Y and X, that make up
+ * this region.
+ */
+ class SK_API Iterator {
+ public:
+ Iterator() : fRgn(NULL), fDone(true) {}
+ Iterator(const SkRegion&);
+ // if we have a region, reset to it and return true, else return false
+ bool rewind();
+ // reset the iterator, using the new region
+ void reset(const SkRegion&);
+ bool done() const { 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;
+ SkIRect fRect;
+ bool fDone;
+ };
+
+ /**
+ * Returns the sequence of rectangles, sorted in Y and X, that make up
+ * this region intersected with the specified clip rectangle.
+ */
+ class SK_API Cliperator {
+ public:
+ Cliperator(const SkRegion&, const SkIRect& clip);
+ bool done() { return fDone; }
+ void next();
+ const SkIRect& rect() const { return fRect; }
+
+ private:
+ Iterator fIter;
+ SkIRect fClip;
+ SkIRect fRect;
+ bool fDone;
+ };
+
+ /**
+ * Returns the sequence of runs that make up this region for the specified
+ * Y scanline, clipped to the specified left and right X values.
+ */
+ class Spanerator {
+ public:
+ Spanerator(const SkRegion&, int y, int left, int right);
+ bool next(int* left, int* right);
+
+ private:
+ const SkRegion::RunType* fRuns;
+ int fLeft, fRight;
+ bool fDone;
+ };
+
+ /**
+ * Write the region to the buffer, and return the number of bytes written.
+ * If buffer is NULL, it still returns the number of bytes.
+ */
+ size_t writeToMemory(void* buffer) const;
+ /**
+ * Initializes the region from the buffer
+ *
+ * @param buffer Memory to read from
+ * @param length Amount of memory available in the buffer
+ * @return number of bytes read (must be a multiple of 4) or
+ * 0 if there was not enough memory available
+ */
+ size_t readFromMemory(const void* buffer, size_t length);
+
+ /**
+ * Returns a reference to a global empty region. Just a convenience for
+ * callers that need a const empty region.
+ */
+ static const SkRegion& GetEmptyRegion();
+
+ SkDEBUGCODE(void dump() const;)
+ SkDEBUGCODE(void validate() const;)
+ SkDEBUGCODE(static void UnitTest();)
+
+ // expose this to allow for regression test on complex regions
+ SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
+
+private:
+ enum {
+ kOpCount = kReplace_Op + 1
+ };
+
+ enum {
+ // T
+ // [B N L R S]
+ // S
+ kRectRegionRuns = 7
+ };
+
+ friend class android::Region; // needed for marshalling efficiently
+
+ struct RunHead;
+
+ // allocate space for count runs
+ void allocateRuns(int count);
+ void allocateRuns(int count, int ySpanCount, int intervalCount);
+ void allocateRuns(const RunHead& src);
+
+ SkIRect fBounds;
+ RunHead* fRunHead;
+
+ void freeRuns();
+
+ /**
+ * Return the runs from this region, consing up fake runs if the region
+ * is empty or a rect. In those 2 cases, we use tmpStorage to hold the
+ * run data.
+ */
+ const RunType* getRuns(RunType tmpStorage[], int* intervals) const;
+
+ // This is called with runs[] that do not yet have their interval-count
+ // field set on each scanline. That is computed as part of this call
+ // (inside ComputeRunBounds).
+ bool setRuns(RunType runs[], int count);
+
+ int count_runtype_values(int* itop, int* ibot) const;
+
+ static void BuildRectRuns(const SkIRect& bounds,
+ RunType runs[kRectRegionRuns]);
+
+ // If the runs define a simple rect, return true and set bounds to that
+ // rect. If not, return false and ignore bounds.
+ static bool RunsAreARect(const SkRegion::RunType runs[], int count,
+ SkIRect* bounds);
+
+ /**
+ * If the last arg is null, just return if the result is non-empty,
+ * else store the result in the last arg.
+ */
+ static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*);
+
+ friend struct RunHead;
+ friend class Iterator;
+ friend class Spanerator;
+ friend class SkRgnBuilder;
+ friend class SkFlatRegion;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkScalar.h b/src/third_party/skia/include/core/SkScalar.h
new file mode 100644
index 0000000..b37cf5c
--- /dev/null
+++ b/src/third_party/skia/include/core/SkScalar.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkScalar_DEFINED
+#define SkScalar_DEFINED
+
+#include "SkFixed.h"
+#include "SkFloatingPoint.h"
+
+//#define SK_SUPPORT_DEPRECATED_SCALARROUND
+
+typedef float SkScalar;
+
+/** SK_Scalar1 is defined to be 1.0 represented as an SkScalar
+*/
+#define SK_Scalar1 (1.0f)
+/** SK_Scalar1 is defined to be 1/2 represented as an SkScalar
+*/
+#define SK_ScalarHalf (0.5f)
+/** SK_ScalarInfinity is defined to be infinity as an SkScalar
+*/
+#define SK_ScalarInfinity SK_FloatInfinity
+/** SK_ScalarNegativeInfinity is defined to be negative infinity as an SkScalar
+*/
+#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity
+/** SK_ScalarMax is defined to be the largest value representable as an SkScalar
+*/
+#define SK_ScalarMax (3.402823466e+38f)
+/** SK_ScalarMin is defined to be the smallest value representable as an SkScalar
+*/
+#define SK_ScalarMin (-SK_ScalarMax)
+/** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar
+*/
+#define SK_ScalarNaN SK_FloatNaN
+/** 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) {
+ // We rely on the following behavior of infinities and nans
+ // 0 * finite --> 0
+ // 0 * infinity --> NaN
+ // 0 * NaN --> NaN
+ float prod = x * 0;
+ // At this point, prod will either be NaN or 0
+ // Therefore we can return (prod == prod) or (0 == prod).
+ return prod == prod;
+}
+
+/** SkIntToScalar(n) returns its integer argument as an SkScalar
+*/
+#define SkIntToScalar(n) ((float)(n))
+/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar
+*/
+#define SkFixedToScalar(x) SkFixedToFloat(x)
+/** SkScalarToFixed(n) returns its SkScalar argument as an SkFixed
+*/
+#define SkScalarToFixed(x) SkFloatToFixed(x)
+
+#define SkScalarToFloat(n) (n)
+#ifndef SK_SCALAR_TO_FLOAT_EXCLUDED
+#define SkFloatToScalar(n) (n)
+#endif
+
+#define SkScalarToDouble(n) (double)(n)
+#define SkDoubleToScalar(n) (float)(n)
+
+/** SkScalarFraction(x) returns the signed fractional part of the argument
+*/
+#define SkScalarFraction(x) sk_float_mod(x, 1.0f)
+
+#define SkScalarFloorToScalar(x) sk_float_floor(x)
+#define SkScalarCeilToScalar(x) sk_float_ceil(x)
+#define SkScalarRoundToScalar(x) sk_float_floor((x) + 0.5f)
+
+#define SkScalarFloorToInt(x) sk_float_floor2int(x)
+#define SkScalarCeilToInt(x) sk_float_ceil2int(x)
+#define SkScalarRoundToInt(x) sk_float_round2int(x)
+#define SkScalarTruncToInt(x) static_cast<int>(x)
+
+/**
+ * Variant of SkScalarRoundToInt, that performs the rounding step (adding 0.5) explicitly using
+ * double, to avoid possibly losing the low bit(s) of the answer before calling floor().
+ *
+ * This routine will likely be slower than SkScalarRoundToInt(), and should only be used when the
+ * extra precision is known to be valuable.
+ *
+ * In particular, this catches the following case:
+ * SkScalar x = 0.49999997;
+ * int ix = SkScalarRoundToInt(x);
+ * SkASSERT(0 == ix); // <--- fails
+ * ix = SkDScalarRoundToInt(x);
+ * SkASSERT(0 == ix); // <--- succeeds
+ */
+static inline int SkDScalarRoundToInt(SkScalar x) {
+ double xx = x;
+ xx += 0.5;
+ return (int)floor(xx);
+}
+
+/** Returns the absolute value of the specified SkScalar
+*/
+#define SkScalarAbs(x) sk_float_abs(x)
+/** Return x with the sign of y
+ */
+#define SkScalarCopySign(x, y) sk_float_copysign(x, y)
+/** Returns the value pinned between 0 and max inclusive
+*/
+inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) {
+ return x < 0 ? 0 : x > max ? max : x;
+}
+/** Returns the value pinned between min and max inclusive
+*/
+inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) {
+ return x < min ? min : x > max ? max : x;
+}
+/** Returns the specified SkScalar squared (x*x)
+*/
+inline SkScalar SkScalarSquare(SkScalar x) { return x * x; }
+/** Returns the product of two SkScalars
+*/
+#define SkScalarMul(a, b) ((float)(a) * (b))
+/** Returns the product of two SkScalars plus a third SkScalar
+*/
+#define SkScalarMulAdd(a, b, c) ((float)(a) * (b) + (c))
+/** Returns the quotient of two SkScalars (a/b)
+*/
+#define SkScalarDiv(a, b) ((float)(a) / (b))
+/** Returns the mod of two SkScalars (a mod b)
+*/
+#define SkScalarMod(x,y) sk_float_mod(x,y)
+/** Returns the product of the first two arguments, divided by the third argument
+*/
+#define SkScalarMulDiv(a, b, c) ((float)(a) * (b) / (c))
+/** Returns the multiplicative inverse of the SkScalar (1/x)
+*/
+#define SkScalarInvert(x) (SK_Scalar1 / (x))
+#define SkScalarFastInvert(x) (SK_Scalar1 / (x))
+/** Returns the square root of the SkScalar
+*/
+#define SkScalarSqrt(x) sk_float_sqrt(x)
+/** Returns b to the e
+*/
+#define SkScalarPow(b, e) sk_float_pow(b, e)
+/** Returns the average of two SkScalars (a+b)/2
+*/
+#define SkScalarAve(a, b) (((a) + (b)) * 0.5f)
+/** Returns one half of the specified SkScalar
+*/
+#define SkScalarHalf(a) ((a) * 0.5f)
+
+#define SK_ScalarSqrt2 1.41421356f
+#define SK_ScalarPI 3.14159265f
+#define SK_ScalarTanPIOver8 0.414213562f
+#define SK_ScalarRoot2Over2 0.707106781f
+
+#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
+#define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI))
+float SkScalarSinCos(SkScalar radians, SkScalar* cosValue);
+#define SkScalarSin(radians) (float)sk_float_sin(radians)
+#define SkScalarCos(radians) (float)sk_float_cos(radians)
+#define SkScalarTan(radians) (float)sk_float_tan(radians)
+#define SkScalarASin(val) (float)sk_float_asin(val)
+#define SkScalarACos(val) (float)sk_float_acos(val)
+#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x)
+#define SkScalarExp(x) (float)sk_float_exp(x)
+#define SkScalarLog(x) (float)sk_float_log(x)
+
+inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; }
+inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; }
+
+static inline bool SkScalarIsInt(SkScalar x) {
+ return x == (float)(int)x;
+}
+
+// DEPRECATED : use ToInt or ToScalar variant
+#ifdef SK_SUPPORT_DEPRECATED_SCALARROUND
+# define SkScalarFloor(x) SkScalarFloorToInt(x)
+# define SkScalarCeil(x) SkScalarCeilToInt(x)
+# define SkScalarRound(x) SkScalarRoundToInt(x)
+#endif
+
+/**
+ * Returns -1 || 0 || 1 depending on the sign of value:
+ * -1 if x < 0
+ * 0 if x == 0
+ * 1 if x > 0
+ */
+static inline int SkScalarSignAsInt(SkScalar x) {
+ return x < 0 ? -1 : (x > 0);
+}
+
+// Scalar result version of above
+static inline SkScalar SkScalarSignAsScalar(SkScalar x) {
+ return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0);
+}
+
+#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
+
+static inline bool SkScalarNearlyZero(SkScalar x,
+ SkScalar tolerance = SK_ScalarNearlyZero) {
+ SkASSERT(tolerance >= 0);
+ return SkScalarAbs(x) <= tolerance;
+}
+
+static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y,
+ SkScalar tolerance = SK_ScalarNearlyZero) {
+ SkASSERT(tolerance >= 0);
+ return SkScalarAbs(x-y) <= tolerance;
+}
+
+/** Linearly interpolate between A and B, based on t.
+ If t is 0, return A
+ If t is 1, return B
+ else interpolate.
+ t must be [0..SK_Scalar1]
+*/
+static inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) {
+ SkASSERT(t >= 0 && t <= SK_Scalar1);
+ return A + (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);
+
+/*
+ * Helper to compare an array of scalars.
+ */
+static inline bool SkScalarsEqual(const SkScalar a[], const SkScalar b[], int n) {
+ SkASSERT(n >= 0);
+ for (int i = 0; i < n; ++i) {
+ if (a[i] != b[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+#endif
diff --git a/src/third_party/skia/include/core/SkShader.h b/src/third_party/skia/include/core/SkShader.h
new file mode 100644
index 0000000..0fbc1b8
--- /dev/null
+++ b/src/third_party/skia/include/core/SkShader.h
@@ -0,0 +1,509 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkShader_DEFINED
+#define SkShader_DEFINED
+
+#include "SkBitmap.h"
+#include "SkFlattenable.h"
+#include "SkMask.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "../gpu/GrColor.h"
+
+class SkPath;
+class SkPicture;
+class SkXfermode;
+class GrContext;
+class GrFragmentProcessor;
+
+/** \class SkShader
+ *
+ * Shaders specify the source color(s) for what is being drawn. If a paint
+ * has no shader, then the paint's color is used. If the paint has a
+ * shader, then the shader's color(s) are use instead, but they are
+ * modulated by the paint's alpha. This makes it easy to create a shader
+ * once (e.g. bitmap tiling or gradient) and then change its transparency
+ * w/o having to modify the original shader... only the paint's alpha needs
+ * to be modified.
+ */
+class SK_API SkShader : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkShader)
+
+ SkShader(const SkMatrix* localMatrix = NULL);
+ virtual ~SkShader();
+
+ /**
+ * Returns the local matrix.
+ *
+ * FIXME: This can be incorrect for a Shader with its own local matrix
+ * that is also wrapped via CreateLocalMatrixShader.
+ */
+ const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
+
+ /**
+ * Returns true if the local matrix is not an identity matrix.
+ *
+ * FIXME: This can be incorrect for a Shader with its own local matrix
+ * that is also wrapped via CreateLocalMatrixShader.
+ */
+ bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
+
+ enum TileMode {
+ /** replicate the edge color if the shader draws outside of its
+ * original bounds
+ */
+ kClamp_TileMode,
+
+ /** repeat the shader's image horizontally and vertically */
+ kRepeat_TileMode,
+
+ /** repeat the shader's image horizontally and vertically, alternating
+ * mirror images so that adjacent images always seam
+ */
+ kMirror_TileMode,
+
+#if 0
+ /** only draw within the original domain, return 0 everywhere else */
+ kDecal_TileMode,
+#endif
+
+ kTileModeCount
+ };
+
+ // override these in your subclass
+
+ enum Flags {
+ //!< set if all of the colors will be opaque
+ kOpaqueAlpha_Flag = 0x01,
+
+ //! set if this shader's shadeSpan16() method can be called
+ kHasSpan16_Flag = 0x02,
+
+ /** Set this bit if the shader's native data type is instrinsically 16
+ bit, meaning that calling the 32bit shadeSpan() entry point will
+ mean the the impl has to up-sample 16bit data into 32bit. Used as a
+ a means of clearing a dither request if the it will have no effect
+ */
+ kIntrinsicly16_Flag = 0x04,
+
+ /** set if the spans only vary in X (const in Y).
+ e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
+ that varies from left-to-right. This flag specifies this for
+ shadeSpan().
+ */
+ kConstInY32_Flag = 0x08,
+
+ /** same as kConstInY32_Flag, but is set if this is true for shadeSpan16
+ which may not always be the case, since shadeSpan16 may be
+ predithered, which would mean it was not const in Y, even though
+ the 32bit shadeSpan() would be const.
+ */
+ kConstInY16_Flag = 0x10
+ };
+
+ /**
+ * Returns true if the shader is guaranteed to produce only opaque
+ * colors, subject to the SkPaint using the shader to apply an opaque
+ * alpha value. Subclasses should override this to allow some
+ * optimizations.
+ */
+ virtual bool isOpaque() const { return false; }
+
+ /**
+ * ContextRec acts as a parameter bundle for creating Contexts.
+ */
+ struct ContextRec {
+ ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL), fLocalMatrix(NULL) {}
+ ContextRec(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
+ : fDevice(&device)
+ , fPaint(&paint)
+ , fMatrix(&matrix)
+ , fLocalMatrix(NULL) {}
+
+ const SkBitmap* fDevice; // the bitmap we are drawing into
+ const SkPaint* fPaint; // the current paint associated with the draw
+ const SkMatrix* fMatrix; // the current matrix in the canvas
+ const SkMatrix* fLocalMatrix; // optional local matrix
+ };
+
+ class Context : public ::SkNoncopyable {
+ public:
+ Context(const SkShader& shader, const ContextRec&);
+
+ virtual ~Context();
+
+ /**
+ * Called sometimes before drawing with this shader. Return the type of
+ * alpha your shader will return. The default implementation returns 0.
+ * Your subclass should override if it can (even sometimes) report a
+ * non-zero value, since that will enable various blitters to perform
+ * faster.
+ */
+ virtual uint32_t getFlags() const { return 0; }
+
+ /**
+ * Return the alpha associated with the data returned by shadeSpan16(). If
+ * kHasSpan16_Flag is not set, this value is meaningless.
+ */
+ virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
+
+ /**
+ * Called for each span of the object being drawn. Your subclass should
+ * set the appropriate colors (with premultiplied alpha) that correspond
+ * to the specified device coordinates.
+ */
+ virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
+
+ typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
+ virtual ShadeProc asAShadeProc(void** ctx);
+
+ /**
+ * Called only for 16bit devices when getFlags() returns
+ * kOpaqueAlphaFlag | kHasSpan16_Flag
+ */
+ virtual void shadeSpan16(int x, int y, uint16_t[], int count);
+
+ /**
+ * Similar to shadeSpan, but only returns the alpha-channel for a span.
+ * The default implementation calls shadeSpan() and then extracts the alpha
+ * values from the returned colors.
+ */
+ virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
+
+ /**
+ * Helper function that returns true if this shader's shadeSpan16() method
+ * can be called.
+ */
+ bool canCallShadeSpan16() {
+ return SkShader::CanCallShadeSpan16(this->getFlags());
+ }
+
+ // Notification from blitter::blitMask in case we need to see the non-alpha channels
+ virtual void set3DMask(const SkMask*) {}
+
+ protected:
+ // Reference to shader, so we don't have to dupe information.
+ const SkShader& fShader;
+
+ enum MatrixClass {
+ kLinear_MatrixClass, // no perspective
+ kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each
+ // scanline
+ kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
+ };
+ static MatrixClass ComputeMatrixClass(const SkMatrix&);
+
+ uint8_t getPaintAlpha() const { return fPaintAlpha; }
+ const SkMatrix& getTotalInverse() const { return fTotalInverse; }
+ MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
+ const SkMatrix& getCTM() const { return fCTM; }
+ private:
+ SkMatrix fCTM;
+ SkMatrix fTotalInverse;
+ uint8_t fPaintAlpha;
+ uint8_t fTotalInverseClass;
+
+ typedef SkNoncopyable INHERITED;
+ };
+
+ /**
+ * Create the actual object that does the shading.
+ * Size of storage must be >= contextSize.
+ */
+ Context* createContext(const ContextRec&, void* storage) const;
+
+ /**
+ * Return the size of a Context returned by createContext.
+ *
+ * Override this if your subclass overrides createContext, to return the correct size of
+ * your subclass' context.
+ */
+ virtual size_t contextSize() const;
+
+ /**
+ * Helper to check the flags to know if it is legal to call shadeSpan16()
+ */
+ static bool CanCallShadeSpan16(uint32_t flags) {
+ return (flags & kHasSpan16_Flag) != 0;
+ }
+
+ /**
+ 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.
+ kTwoPointConical_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.
+ // Three extra parameters are returned:
+ // 0: x-offset of second circle center
+ // to first.
+ // 1: radius of first circle
+ // 2: the second radius minus the first radius
+ kLinear_BitmapType, //<! Access bitmap using local coords transformed
+ // by matrix. No extras
+
+ kLast_BitmapType = kLinear_BitmapType
+ };
+ /** Optional methods for shaders that can pretend to be a bitmap/texture
+ 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 BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
+ TileMode xy[2]) const;
+
+ /**
+ * If the shader subclass can be represented as a gradient, asAGradient
+ * returns the matching GradientType enum (or kNone_GradientType if it
+ * cannot). Also, if info is not null, asAGradient populates info with
+ * the relevant (see below) parameters for the gradient. fColorCount
+ * is both an input and output parameter. On input, it indicates how
+ * many entries in fColors and fColorOffsets can be used, if they are
+ * non-NULL. After asAGradient has run, fColorCount indicates how
+ * many color-offset pairs there are in the gradient. If there is
+ * insufficient space to store all of the color-offset pairs, fColors
+ * and fColorOffsets will not be altered. fColorOffsets specifies
+ * where on the range of 0 to 1 to transition to the given color.
+ * The meaning of fPoint and fRadius is dependant on the type of gradient.
+ *
+ * None:
+ * info is ignored.
+ * Color:
+ * fColorOffsets[0] is meaningless.
+ * Linear:
+ * fPoint[0] and fPoint[1] are the end-points of the gradient
+ * Radial:
+ * fPoint[0] and fRadius[0] are the center and radius
+ * Radial2:
+ * fPoint[0] and fRadius[0] are the center and radius of the 1st circle
+ * fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
+ * Sweep:
+ * fPoint[0] is the center of the sweep.
+ */
+
+ enum GradientType {
+ kNone_GradientType,
+ kColor_GradientType,
+ kLinear_GradientType,
+ kRadial_GradientType,
+ kRadial2_GradientType,
+ kSweep_GradientType,
+ kConical_GradientType,
+ kLast_GradientType = kConical_GradientType
+ };
+
+ struct GradientInfo {
+ int fColorCount; //!< In-out parameter, specifies passed size
+ // of fColors/fColorOffsets on input, and
+ // actual number of colors/offsets on
+ // output.
+ SkColor* fColors; //!< The colors in the gradient.
+ SkScalar* fColorOffsets; //!< The unit offset for color transitions.
+ SkPoint fPoint[2]; //!< Type specific, see above.
+ SkScalar fRadius[2]; //!< Type specific, see above.
+ TileMode fTileMode; //!< The tile mode used.
+ uint32_t fGradientFlags; //!< see SkGradientShader::Flags
+ };
+
+ virtual GradientType asAGradient(GradientInfo* info) const;
+
+ /**
+ * If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
+ * fill it out with info about the shader.
+ *
+ * These are bare pointers; the ownership and reference count are unchanged.
+ */
+
+ struct ComposeRec {
+ const SkShader* fShaderA;
+ const SkShader* fShaderB;
+ const SkXfermode* fMode;
+ };
+
+ virtual bool asACompose(ComposeRec* rec) const { return false; }
+
+
+ /**
+ * Returns true if the shader subclass succeeds in creating an effect or if none is required.
+ * False is returned if it fails or if there is not an implementation of this method in the
+ * shader subclass.
+ *
+ * On success an implementation of this method must inspect the SkPaint and set paintColor to
+ * the color the effect expects as its input color. If the SkShader wishes to emit a solid
+ * color then it should set paintColor to that color and not create an effect. Note that
+ * GrColor is always premul. The common patterns are to convert paint's SkColor to GrColor or
+ * to extract paint's alpha and replicate it to all channels in paintColor. Upon failure
+ * paintColor should not be modified. It is not recommended to specialize the effect to
+ * the paint's color as then many GPU shaders may be generated.
+ *
+ * The GrContext may be used by the effect to create textures. The GPU device does not
+ * call createContext. Instead we pass the SkPaint here in case the shader needs paint info.
+ */
+ virtual bool asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix*, GrColor*,
+ GrFragmentProcessor**) const;
+
+ /**
+ * If the shader can represent its "average" luminance in a single color, return true and
+ * if color is not NULL, return that color. If it cannot, return false and ignore the color
+ * parameter.
+ *
+ * Note: if this returns true, the returned color will always be opaque, as only the RGB
+ * components are used to compute luminance.
+ */
+ bool asLuminanceColor(SkColor*) const;
+
+#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
+ /**
+ * If the shader is a custom shader which has data the caller might want, call this function
+ * to get that data.
+ */
+ virtual bool asACustomShader(void** customData) const { return false; }
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Factory methods for stock shaders
+
+ /**
+ * Call this to create a new "empty" shader, that will not draw anything.
+ */
+ static SkShader* CreateEmptyShader();
+
+ /**
+ * Call this to create a new shader that just draws the specified color. This should always
+ * draw the same as a paint with this color (and no shader).
+ */
+ static SkShader* CreateColorShader(SkColor);
+
+ /** Call this to create a new shader that will draw with the specified bitmap.
+ *
+ * If the bitmap cannot be used (e.g. has no pixels, or its dimensions
+ * exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
+ * may be returned.
+ *
+ * If the src is kA8_Config then that mask will be colorized using the color on
+ * the paint.
+ *
+ * @param src The bitmap to use inside the shader
+ * @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
+ * @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
+ * @return Returns a new shader object. Note: this function never returns null.
+ */
+ static SkShader* CreateBitmapShader(const SkBitmap& src,
+ TileMode tmx, TileMode tmy,
+ const SkMatrix* localMatrix = NULL);
+
+ /** Call this to create a new shader that will draw with the specified picture.
+ *
+ * @param src The picture to use inside the shader (if not NULL, its ref count
+ * is incremented). The SkPicture must not be changed after
+ * successfully creating a picture shader.
+ * FIXME: src cannot be const due to SkCanvas::drawPicture
+ * @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
+ * @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
+ * @param tile The tile rectangle in picture coordinates: this represents the subset
+ * (or superset) of the picture used when building a tile. It is not
+ * affected by localMatrix and does not imply scaling (only translation
+ * and cropping). If null, the tile rect is considered equal to the picture
+ * bounds.
+ * @return Returns a new shader object. Note: this function never returns null.
+ */
+ static SkShader* CreatePictureShader(SkPicture* src,
+ TileMode tmx, TileMode tmy,
+ const SkMatrix* localMatrix,
+ const SkRect* tile);
+
+ /**
+ * Return a shader that will apply the specified localMatrix to the proxy shader.
+ * The specified matrix will be applied before any matrix associated with the proxy.
+ *
+ * Note: ownership of the proxy is not transferred (though a ref is taken).
+ */
+ static SkShader* CreateLocalMatrixShader(SkShader* proxy, const SkMatrix& localMatrix);
+
+ /**
+ * If this shader can be represented by another shader + a localMatrix, return that shader
+ * and, if not NULL, the localMatrix. If not, return NULL and ignore the localMatrix parameter.
+ *
+ * Note: the returned shader (if not NULL) will have been ref'd, and it is the responsibility
+ * of the caller to balance that with unref() when they are done.
+ */
+ virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const;
+
+ SK_TO_STRING_VIRT()
+ SK_DEFINE_FLATTENABLE_TYPE(SkShader)
+
+protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkShader(SkReadBuffer& );
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
+
+ /**
+ * Your subclass must also override contextSize() if it overrides onCreateContext().
+ * Base class impl returns NULL.
+ */
+ virtual Context* onCreateContext(const ContextRec&, void* storage) const;
+
+ virtual bool onAsLuminanceColor(SkColor*) const {
+ return false;
+ }
+private:
+ // This is essentially const, but not officially so it can be modified in
+ // constructors.
+ SkMatrix fLocalMatrix;
+
+ // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
+ friend class SkLocalMatrixShader;
+
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkSize.h b/src/third_party/skia/include/core/SkSize.h
new file mode 100644
index 0000000..7bc8c71
--- /dev/null
+++ b/src/third_party/skia/include/core/SkSize.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSize_DEFINED
+#define SkSize_DEFINED
+
+#include "SkScalar.h"
+
+template <typename T> struct SkTSize {
+ T fWidth;
+ T fHeight;
+
+ static SkTSize Make(T w, T h) {
+ SkTSize s;
+ s.fWidth = w;
+ s.fHeight = h;
+ return s;
+ }
+
+ void set(T w, T h) {
+ fWidth = w;
+ fHeight = h;
+ }
+
+ /** Returns true iff fWidth == 0 && fHeight == 0
+ */
+ bool isZero() const {
+ return 0 == fWidth && 0 == fHeight;
+ }
+
+ /** Returns true if either widht or height are <= 0 */
+ bool isEmpty() const {
+ return fWidth <= 0 || fHeight <= 0;
+ }
+
+ /** Set the width and height to 0 */
+ void setEmpty() {
+ fWidth = fHeight = 0;
+ }
+
+ T width() const { return fWidth; }
+ T height() const { return fHeight; }
+
+ /** If width or height is < 0, it is set to 0 */
+ void clampNegToZero() {
+ if (fWidth < 0) {
+ fWidth = 0;
+ }
+ if (fHeight < 0) {
+ fHeight = 0;
+ }
+ }
+
+ bool equals(T w, T h) const {
+ return fWidth == w && fHeight == h;
+ }
+};
+
+template <typename T>
+static inline bool operator==(const SkTSize<T>& a, const SkTSize<T>& b) {
+ return a.fWidth == b.fWidth && a.fHeight == b.fHeight;
+}
+
+template <typename T>
+static inline bool operator!=(const SkTSize<T>& a, const SkTSize<T>& b) {
+ return !(a == b);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef SkTSize<int32_t> SkISize;
+
+struct SkSize : public SkTSize<SkScalar> {
+ static SkSize Make(SkScalar w, SkScalar h) {
+ SkSize s;
+ s.fWidth = w;
+ s.fHeight = h;
+ return s;
+ }
+
+
+ SkSize& operator=(const SkISize& src) {
+ this->set(SkIntToScalar(src.fWidth), SkIntToScalar(src.fHeight));
+ return *this;
+ }
+
+ SkISize toRound() const {
+ SkISize s;
+ s.set(SkScalarRoundToInt(fWidth), SkScalarRoundToInt(fHeight));
+ return s;
+ }
+
+ SkISize toCeil() const {
+ SkISize s;
+ s.set(SkScalarCeilToInt(fWidth), SkScalarCeilToInt(fHeight));
+ return s;
+ }
+
+ SkISize toFloor() const {
+ SkISize s;
+ s.set(SkScalarFloorToInt(fWidth), SkScalarFloorToInt(fHeight));
+ return s;
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkStream.h b/src/third_party/skia/include/core/SkStream.h
new file mode 100644
index 0000000..10dbe40
--- /dev/null
+++ b/src/third_party/skia/include/core/SkStream.h
@@ -0,0 +1,452 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkStream_DEFINED
+#define SkStream_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+
+class SkData;
+
+class SkStream;
+class SkStreamRewindable;
+class SkStreamSeekable;
+class SkStreamAsset;
+class SkStreamMemory;
+
+/**
+ * SkStream -- abstraction for a source of bytes. Subclasses can be backed by
+ * memory, or a file, or something else.
+ *
+ * NOTE:
+ *
+ * Classic "streams" APIs are sort of async, in that on a request for N
+ * bytes, they may return fewer than N bytes on a given call, in which case
+ * the caller can "try again" to get more bytes, eventually (modulo an error)
+ * receiving their total N bytes.
+ *
+ * Skia streams behave differently. They are effectively synchronous, and will
+ * always return all N bytes of the request if possible. If they return fewer
+ * (the read() call returns the number of bytes read) then that means there is
+ * no more data (at EOF or hit an error). The caller should *not* call again
+ * in hopes of fulfilling more of the request.
+ */
+class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt
+public:
+ /**
+ * Attempts to open the specified file, and return a stream to it (using
+ * mmap if available). On success, the caller must call unref() on the
+ * returned object. On failure, returns NULL.
+ */
+ static SkStreamAsset* NewFromFile(const char path[]);
+
+ SK_DECLARE_INST_COUNT(SkStream)
+
+ /** Reads or skips size number of bytes.
+ * If buffer == NULL, skip size bytes, return how many were skipped.
+ * If buffer != NULL, copy size bytes into buffer, return how many were copied.
+ * @param buffer when NULL skip size bytes, otherwise copy size bytes into buffer
+ * @param size the number of bytes to skip or copy
+ * @return the number of bytes actually read.
+ */
+ virtual size_t read(void* buffer, size_t size) = 0;
+
+ /** Skip size number of bytes.
+ * @return the actual number bytes that could be skipped.
+ */
+ size_t skip(size_t size) {
+ return this->read(NULL, size);
+ }
+
+ /** Returns true when all the bytes in the stream have been read.
+ * This may return true early (when there are no more bytes to be read)
+ * or late (after the first unsuccessful read).
+ */
+ virtual bool isAtEnd() const = 0;
+
+ int8_t readS8();
+ int16_t readS16();
+ int32_t readS32();
+
+ uint8_t readU8() { return (uint8_t)this->readS8(); }
+ uint16_t readU16() { return (uint16_t)this->readS16(); }
+ uint32_t readU32() { return (uint32_t)this->readS32(); }
+
+ bool readBool() { return this->readU8() != 0; }
+ SkScalar readScalar();
+ size_t readPackedUInt();
+
+//SkStreamRewindable
+ /** Rewinds to the beginning of the stream. Returns true if the stream is known
+ * to be at the beginning after this call returns.
+ */
+ virtual bool rewind() { return false; }
+
+ /** Duplicates this stream. If this cannot be done, returns NULL.
+ * The returned stream will be positioned at the beginning of its data.
+ */
+ virtual SkStreamRewindable* duplicate() const { return NULL; }
+
+//SkStreamSeekable
+ /** Returns true if this stream can report it's current position. */
+ virtual bool hasPosition() const { return false; }
+ /** Returns the current position in the stream. If this cannot be done, returns 0. */
+ virtual size_t getPosition() const { return 0; }
+
+ /** Seeks to an absolute position in the stream. If this cannot be done, returns false.
+ * If an attempt is made to seek past the end of the stream, the position will be set
+ * to the end of the stream.
+ */
+ virtual bool seek(size_t position) { return false; }
+
+ /** Seeks to an relative offset in the stream. If this cannot be done, returns false.
+ * If an attempt is made to move to a position outside the stream, the position will be set
+ * to the closest point within the stream (beginning or end).
+ */
+ virtual bool move(long offset) { return false; }
+
+ /** Duplicates this stream. If this cannot be done, returns NULL.
+ * The returned stream will be positioned the same as this stream.
+ */
+ virtual SkStreamSeekable* fork() const { return NULL; }
+
+//SkStreamAsset
+ /** Returns true if this stream can report it's total length. */
+ virtual bool hasLength() const { return false; }
+ /** Returns the total length of the stream. If this cannot be done, returns 0. */
+ virtual size_t getLength() const { return 0; }
+
+//SkStreamMemory
+ /** Returns the starting address for the data. If this cannot be done, returns NULL. */
+ //TODO: replace with virtual const SkData* getData()
+ virtual const void* getMemoryBase() { return NULL; }
+
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+/** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */
+class SK_API SkStreamRewindable : public SkStream {
+public:
+ virtual bool rewind() SK_OVERRIDE = 0;
+ virtual SkStreamRewindable* duplicate() const SK_OVERRIDE = 0;
+};
+
+/** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */
+class SK_API SkStreamSeekable : public SkStreamRewindable {
+public:
+ virtual SkStreamSeekable* duplicate() const SK_OVERRIDE = 0;
+
+ virtual bool hasPosition() const SK_OVERRIDE { return true; }
+ virtual size_t getPosition() const SK_OVERRIDE = 0;
+ virtual bool seek(size_t position) SK_OVERRIDE = 0;
+ virtual bool move(long offset) SK_OVERRIDE = 0;
+ virtual SkStreamSeekable* fork() const SK_OVERRIDE = 0;
+};
+
+/** SkStreamAsset is a SkStreamSeekable for which getLength is required. */
+class SK_API SkStreamAsset : public SkStreamSeekable {
+public:
+ virtual SkStreamAsset* duplicate() const SK_OVERRIDE = 0;
+ virtual SkStreamAsset* fork() const SK_OVERRIDE = 0;
+
+ virtual bool hasLength() const SK_OVERRIDE { return true; }
+ virtual size_t getLength() const SK_OVERRIDE = 0;
+};
+
+/** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */
+class SK_API SkStreamMemory : public SkStreamAsset {
+public:
+ virtual SkStreamMemory* duplicate() const SK_OVERRIDE = 0;
+ virtual SkStreamMemory* fork() const SK_OVERRIDE = 0;
+
+ virtual const void* getMemoryBase() SK_OVERRIDE = 0;
+};
+
+class SK_API SkWStream : SkNoncopyable {
+public:
+ SK_DECLARE_INST_COUNT_ROOT(SkWStream)
+
+ virtual ~SkWStream();
+
+ /** Called to write bytes to a SkWStream. Returns true on success
+ @param buffer the address of at least size bytes to be written to the stream
+ @param size The number of bytes in buffer to write to the stream
+ @return true on success
+ */
+ virtual bool write(const void* buffer, size_t size) = 0;
+ virtual void newline();
+ virtual void flush();
+
+ virtual size_t bytesWritten() const = 0;
+
+ // helpers
+
+ bool write8(U8CPU);
+ bool write16(U16CPU);
+ bool write32(uint32_t);
+
+ 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);
+
+ bool writeBool(bool v) { return this->write8(v); }
+ bool writeScalar(SkScalar);
+ bool writePackedUInt(size_t);
+
+ bool writeStream(SkStream* input, size_t length);
+
+ /**
+ * This returns the number of bytes in the stream required to store
+ * 'value'.
+ */
+ static int SizeOfPackedUInt(size_t value);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkString.h"
+
+#if !defined(SK_BUILD_FOR_STARBOARD)
+#include <stdio.h>
+#endif
+
+struct SkFILE;
+
+/** A stream that wraps a C FILE* file stream. */
+class SK_API SkFILEStream : public SkStreamAsset {
+public:
+ SK_DECLARE_INST_COUNT(SkFILEStream)
+
+ /** Initialize the stream by calling sk_fopen on the specified path.
+ * This internal stream will be closed in the destructor.
+ */
+ explicit SkFILEStream(const char path[] = NULL);
+
+ enum Ownership {
+ kCallerPasses_Ownership,
+ kCallerRetains_Ownership
+ };
+ /** Initialize the stream with an existing C file stream.
+ * While this stream exists, it assumes exclusive access to the C file stream.
+ * The C file stream will be closed in the destructor unless the caller specifies
+ * kCallerRetains_Ownership.
+ */
+ explicit SkFILEStream(void* file, Ownership ownership = kCallerPasses_Ownership);
+
+ virtual ~SkFILEStream();
+
+ /** Returns true if the current path could be opened. */
+ bool isValid() const { return fFILE != NULL; }
+
+ /** Close the current file, and open a new file with the specified path.
+ * If path is NULL, just close the current file.
+ */
+ void setPath(const char path[]);
+
+ virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
+ virtual bool isAtEnd() const SK_OVERRIDE;
+
+ virtual bool rewind() SK_OVERRIDE;
+ virtual SkStreamAsset* duplicate() const SK_OVERRIDE;
+
+ virtual size_t getPosition() const SK_OVERRIDE;
+ virtual bool seek(size_t position) SK_OVERRIDE;
+ virtual bool move(long offset) SK_OVERRIDE;
+ virtual SkStreamAsset* fork() const SK_OVERRIDE;
+
+ virtual size_t getLength() const SK_OVERRIDE;
+
+ virtual const void* getMemoryBase() SK_OVERRIDE;
+
+private:
+ SkFILE* fFILE;
+ SkString fName;
+ Ownership fOwnership;
+ // fData is lazilly initialized when needed.
+ mutable SkAutoTUnref<SkData> fData;
+
+ typedef SkStreamAsset INHERITED;
+};
+
+class SK_API SkMemoryStream : public SkStreamMemory {
+public:
+ SK_DECLARE_INST_COUNT(SkMemoryStream)
+
+ SkMemoryStream();
+
+ /** We allocate (and free) the memory. Write to it via getMemoryBase() */
+ SkMemoryStream(size_t length);
+
+ /** If copyData is true, the stream makes a private copy of the data. */
+ SkMemoryStream(const void* data, size_t length, bool copyData = false);
+
+ /** Use the specified data as the memory for this stream.
+ * The stream will call ref() on the data (assuming it is not NULL).
+ */
+ SkMemoryStream(SkData*);
+
+ virtual ~SkMemoryStream();
+
+ /** Resets the stream to the specified data and length,
+ just like the constructor.
+ if copyData is true, the stream makes a private copy of the data
+ */
+ virtual void setMemory(const void* data, size_t length,
+ bool copyData = false);
+ /** 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);
+
+ /** Return the stream's data in a SkData.
+ * The caller must call unref() when it is finished using the data.
+ */
+ SkData* copyToData() const;
+
+ /**
+ * Use the specified data as the memory for this stream.
+ * The stream will call ref() on the data (assuming it is not NULL).
+ * The function returns the data parameter as a convenience.
+ */
+ SkData* setData(SkData*);
+
+ void skipToAlign4();
+ const void* getAtPos();
+ size_t peek() const { return fOffset; }
+
+ virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
+ virtual bool isAtEnd() const SK_OVERRIDE;
+
+ virtual bool rewind() SK_OVERRIDE;
+ virtual SkMemoryStream* duplicate() const SK_OVERRIDE;
+
+ virtual size_t getPosition() const SK_OVERRIDE;
+ virtual bool seek(size_t position) SK_OVERRIDE;
+ virtual bool move(long offset) SK_OVERRIDE;
+ virtual SkMemoryStream* fork() const SK_OVERRIDE;
+
+ virtual size_t getLength() const SK_OVERRIDE;
+
+ virtual const void* getMemoryBase() SK_OVERRIDE;
+
+private:
+ SkData* fData;
+ size_t fOffset;
+
+ typedef SkStreamMemory INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+class SK_API SkFILEWStream : public SkWStream {
+public:
+ SK_DECLARE_INST_COUNT(SkFILEWStream)
+
+ SkFILEWStream(const char path[]);
+ virtual ~SkFILEWStream();
+
+ /** Returns true if the current path could be opened.
+ */
+ bool isValid() const { return fFILE != NULL; }
+
+ virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
+ virtual void flush() SK_OVERRIDE;
+ virtual size_t bytesWritten() const SK_OVERRIDE;
+
+private:
+ SkFILE* fFILE;
+
+ typedef SkWStream INHERITED;
+};
+
+class SkMemoryWStream : public SkWStream {
+public:
+ SK_DECLARE_INST_COUNT(SkMemoryWStream)
+
+ SkMemoryWStream(void* buffer, size_t size);
+ virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
+ virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; }
+
+private:
+ char* fBuffer;
+ size_t fMaxLength;
+ size_t fBytesWritten;
+
+ typedef SkWStream INHERITED;
+};
+
+class SK_API SkDynamicMemoryWStream : public SkWStream {
+public:
+ SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream)
+
+ SkDynamicMemoryWStream();
+ virtual ~SkDynamicMemoryWStream();
+
+ virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
+ virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; }
+ // random access write
+ // 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() const { return fBytesWritten; }
+
+ // copy what has been written to the stream into dst
+ void copyTo(void* dst) const;
+
+ /**
+ * Return a copy of the data written so far. This call is responsible for
+ * calling unref() when they are finished with the data.
+ */
+ SkData* copyToData() const;
+
+ /** Reset, returning a reader stream with the current content. */
+ SkStreamAsset* detachAsStream();
+
+ /** Reset the stream to its original, empty, state. */
+ void reset();
+ void padToAlign4();
+private:
+ struct Block;
+ Block* fHead;
+ Block* fTail;
+ size_t fBytesWritten;
+ mutable SkData* fCopy; // is invalidated if we write after it is created
+
+ void invalidateCopy();
+
+ // For access to the Block type.
+ friend class SkBlockMemoryStream;
+ friend class SkBlockMemoryRefCnt;
+
+ typedef SkWStream INHERITED;
+};
+
+
+class SK_API SkDebugWStream : public SkWStream {
+public:
+ SkDebugWStream() : fBytesWritten(0) {}
+ SK_DECLARE_INST_COUNT(SkDebugWStream)
+
+ // overrides
+ virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
+ virtual void newline() SK_OVERRIDE;
+ virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; }
+
+private:
+ size_t fBytesWritten;
+ typedef SkWStream INHERITED;
+};
+
+// for now
+typedef SkFILEStream SkURLStream;
+
+#endif
diff --git a/src/third_party/skia/include/core/SkString.h b/src/third_party/skia/include/core/SkString.h
new file mode 100644
index 0000000..8a962ae
--- /dev/null
+++ b/src/third_party/skia/include/core/SkString.h
@@ -0,0 +1,248 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkString_DEFINED
+#define SkString_DEFINED
+
+#include "SkScalar.h"
+#include "SkTArray.h"
+
+#include <stdarg.h>
+
+/* Some helper functions for C strings
+*/
+
+static bool SkStrStartsWith(const char string[], const char prefixStr[]) {
+ SkASSERT(string);
+ SkASSERT(prefixStr);
+ return !strncmp(string, prefixStr, strlen(prefixStr));
+}
+static bool SkStrStartsWith(const char string[], const char prefixChar) {
+ SkASSERT(string);
+ return (prefixChar == *string);
+}
+
+bool SkStrEndsWith(const char string[], const char suffixStr[]);
+bool SkStrEndsWith(const char string[], const char suffixChar);
+
+int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
+
+static int SkStrFind(const char string[], const char substring[]) {
+ const char *first = strstr(string, substring);
+ if (NULL == first) return -1;
+ return SkToS32(first - &string[0]);
+}
+
+static bool SkStrContains(const char string[], const char substring[]) {
+ SkASSERT(string);
+ SkASSERT(substring);
+ return (-1 != SkStrFind(string, substring));
+}
+static bool SkStrContains(const char string[], const char subchar) {
+ SkASSERT(string);
+ char tmp[2];
+ tmp[0] = subchar;
+ tmp[1] = '\0';
+ return (-1 != SkStrFind(string, tmp));
+}
+
+static inline char *SkStrDup(const char string[]) {
+ char *ret = (char *) sk_malloc_throw(strlen(string)+1);
+ memcpy(ret,string,strlen(string)+1);
+ return ret;
+}
+
+
+
+#define SkStrAppendU32_MaxSize 10
+char* SkStrAppendU32(char buffer[], uint32_t);
+#define SkStrAppendU64_MaxSize 20
+char* SkStrAppendU64(char buffer[], uint64_t, int minDigits);
+
+#define SkStrAppendS32_MaxSize (SkStrAppendU32_MaxSize + 1)
+char* SkStrAppendS32(char buffer[], int32_t);
+#define SkStrAppendS64_MaxSize (SkStrAppendU64_MaxSize + 1)
+char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
+
+/**
+ * Floats have at most 8 significant digits, so we limit our %g to that.
+ * However, the total string could be 15 characters: -1.2345678e-005
+ *
+ * In theory we should only expect up to 2 digits for the exponent, but on
+ * some platforms we have seen 3 (as in the example above).
+ */
+#define SkStrAppendScalar_MaxSize 15
+
+/**
+ * Write the scaler in decimal format into buffer, and return a pointer to
+ * the next char after the last one written. Note: a terminating 0 is not
+ * written into buffer, which must be at least SkStrAppendScalar_MaxSize.
+ * Thus if the caller wants to add a 0 at the end, buffer must be at least
+ * SkStrAppendScalar_MaxSize + 1 bytes large.
+ */
+#define SkStrAppendScalar SkStrAppendFloat
+
+char* SkStrAppendFloat(char buffer[], float);
+char* SkStrAppendFixed(char buffer[], SkFixed);
+
+/** \class SkString
+
+ Light weight class for managing strings. Uses reference
+ counting to make string assignments and copies very fast
+ with no extra RAM cost. Assumes UTF8 encoding.
+*/
+class SK_API SkString {
+public:
+ SkString();
+ explicit SkString(size_t len);
+ explicit SkString(const char text[]);
+ SkString(const char text[], size_t len);
+ SkString(const SkString&);
+ ~SkString();
+
+ bool isEmpty() const { return 0 == fRec->fLength; }
+ size_t size() const { return (size_t) fRec->fLength; }
+ const char* c_str() const { return fRec->data(); }
+ char operator[](size_t n) const { return this->c_str()[n]; }
+
+ bool equals(const SkString&) const;
+ bool equals(const char text[]) const;
+ bool equals(const char text[], size_t len) const;
+
+ bool startsWith(const char prefixStr[]) const {
+ return SkStrStartsWith(fRec->data(), prefixStr);
+ }
+ bool startsWith(const char prefixChar) const {
+ return SkStrStartsWith(fRec->data(), prefixChar);
+ }
+ bool endsWith(const char suffixStr[]) const {
+ return SkStrEndsWith(fRec->data(), suffixStr);
+ }
+ bool endsWith(const char suffixChar) const {
+ return SkStrEndsWith(fRec->data(), suffixChar);
+ }
+ bool contains(const char substring[]) const {
+ return SkStrContains(fRec->data(), substring);
+ }
+ bool contains(const char subchar) const {
+ return SkStrContains(fRec->data(), subchar);
+ }
+ int find(const char substring[]) const {
+ return SkStrFind(fRec->data(), substring);
+ }
+
+ friend bool operator==(const SkString& a, const SkString& b) {
+ return a.equals(b);
+ }
+ friend bool operator!=(const SkString& a, const SkString& b) {
+ return !a.equals(b);
+ }
+
+ // these methods edit the string
+
+ SkString& operator=(const SkString&);
+ SkString& operator=(const char text[]);
+
+ char* writable_str();
+ char& operator[](size_t n) { return this->writable_str()[n]; }
+
+ void reset();
+ void resize(size_t len) { this->set(NULL, len); }
+ void set(const SkString& src) { *this = src; }
+ void set(const char text[]);
+ void set(const char text[], size_t len);
+ void setUTF16(const uint16_t[]);
+ void setUTF16(const uint16_t[], size_t len);
+
+ void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
+ void insert(size_t offset, const char text[]);
+ void insert(size_t offset, const char text[], size_t len);
+ void insertUnichar(size_t offset, SkUnichar);
+ void insertS32(size_t offset, int32_t value);
+ void insertS64(size_t offset, int64_t value, int minDigits = 0);
+ void insertU32(size_t offset, uint32_t value);
+ void insertU64(size_t offset, uint64_t value, int minDigits = 0);
+ void insertHex(size_t offset, uint32_t value, int minDigits = 0);
+ void insertScalar(size_t offset, SkScalar);
+
+ void append(const SkString& str) { this->insert((size_t)-1, str); }
+ void append(const char text[]) { this->insert((size_t)-1, text); }
+ void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
+ void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
+ void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
+ void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
+ void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
+ void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
+ void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
+ void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
+
+ void prepend(const SkString& str) { this->insert(0, str); }
+ void prepend(const char text[]) { this->insert(0, text); }
+ void prepend(const char text[], size_t len) { this->insert(0, text, len); }
+ void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
+ void prependS32(int32_t value) { this->insertS32(0, value); }
+ void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
+ void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
+ void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
+
+ void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
+ void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
+ void appendVAList(const char format[], va_list);
+ void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
+ void prependVAList(const char format[], va_list);
+
+ void remove(size_t offset, size_t length);
+
+ SkString& operator+=(const SkString& s) { this->append(s); return *this; }
+ SkString& operator+=(const char text[]) { this->append(text); return *this; }
+ SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
+
+ /**
+ * Swap contents between this and other. This function is guaranteed
+ * to never fail or throw.
+ */
+ void swap(SkString& other);
+
+private:
+ struct Rec {
+ public:
+ uint32_t fLength; // logically size_t, but we want it to stay 32bits
+ int32_t fRefCnt;
+ char fBeginningOfData;
+
+ char* data() { return &fBeginningOfData; }
+ const char* data() const { return &fBeginningOfData; }
+ };
+ Rec* fRec;
+
+#ifdef SK_DEBUG
+ const char* fStr;
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+
+ static const Rec gEmptyRec;
+ static Rec* AllocRec(const char text[], size_t len);
+ static Rec* RefRec(Rec*);
+};
+
+/// Creates a new string and writes into it using a printf()-style format.
+SkString SkStringPrintf(const char* format, ...);
+
+// Specialized to take advantage of SkString's fast swap path. The unspecialized function is
+// declared in SkTypes.h and called by SkTSort.
+template <> inline void SkTSwap(SkString& a, SkString& b) {
+ a.swap(b);
+}
+
+// Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
+void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out);
+
+#endif
diff --git a/src/third_party/skia/include/core/SkStrokeRec.h b/src/third_party/skia/include/core/SkStrokeRec.h
new file mode 100644
index 0000000..0c5892f
--- /dev/null
+++ b/src/third_party/skia/include/core/SkStrokeRec.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkStrokeRec_DEFINED
+#define SkStrokeRec_DEFINED
+
+#include "SkPaint.h"
+
+class SkPath;
+
+class SkStrokeRec {
+public:
+ enum InitStyle {
+ kHairline_InitStyle,
+ kFill_InitStyle
+ };
+ SkStrokeRec(InitStyle style);
+
+ SkStrokeRec(const SkStrokeRec&);
+ SkStrokeRec(const SkPaint&, SkPaint::Style);
+ explicit SkStrokeRec(const SkPaint&);
+
+ enum Style {
+ kHairline_Style,
+ kFill_Style,
+ kStroke_Style,
+ kStrokeAndFill_Style
+ };
+ enum {
+ kStyleCount = kStrokeAndFill_Style + 1
+ };
+
+ Style getStyle() const;
+ SkScalar getWidth() const { return fWidth; }
+ SkScalar getMiter() const { return fMiterLimit; }
+ SkPaint::Cap getCap() const { return fCap; }
+ SkPaint::Join getJoin() const { return fJoin; }
+
+ bool isHairlineStyle() const {
+ return kHairline_Style == this->getStyle();
+ }
+
+ bool isFillStyle() const {
+ return kFill_Style == this->getStyle();
+ }
+
+ void setFillStyle();
+ void setHairlineStyle();
+ /**
+ * Specify the strokewidth, and optionally if you want stroke + fill.
+ * Note, if width==0, then this request is taken to mean:
+ * strokeAndFill==true -> new style will be Fill
+ * strokeAndFill==false -> new style will be Hairline
+ */
+ void setStrokeStyle(SkScalar width, bool strokeAndFill = false);
+
+ void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
+ fCap = cap;
+ fJoin = join;
+ fMiterLimit = miterLimit;
+ }
+
+ /**
+ * Returns true if this specifes any thick stroking, i.e. applyToPath()
+ * will return true.
+ */
+ bool needToApply() const {
+ Style style = this->getStyle();
+ return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
+ }
+
+ /**
+ * Apply these stroke parameters to the src path, returning the result
+ * in dst.
+ *
+ * If there was no change (i.e. style == hairline or fill) this returns
+ * false and dst is unchanged. Otherwise returns true and the result is
+ * stored in dst.
+ *
+ * src and dst may be the same path.
+ */
+ bool applyToPath(SkPath* dst, const SkPath& src) const;
+
+ bool operator==(const SkStrokeRec& other) const {
+ return fWidth == other.fWidth &&
+ fMiterLimit == other.fMiterLimit &&
+ fCap == other.fCap &&
+ fJoin == other.fJoin &&
+ fStrokeAndFill == other.fStrokeAndFill;
+ }
+
+private:
+ void init(const SkPaint& paint, SkPaint::Style style);
+
+
+ SkScalar fWidth;
+ SkScalar fMiterLimit;
+ SkPaint::Cap fCap;
+ SkPaint::Join fJoin;
+ bool fStrokeAndFill;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkSurface.h b/src/third_party/skia/include/core/SkSurface.h
new file mode 100644
index 0000000..0e238f8
--- /dev/null
+++ b/src/third_party/skia/include/core/SkSurface.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSurface_DEFINED
+#define SkSurface_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkImage.h"
+#include "SkSurfaceProps.h"
+
+class SkCanvas;
+class SkPaint;
+class GrContext;
+class GrRenderTarget;
+
+/**
+ * SkSurface represents the backend/results of drawing to a canvas. For raster
+ * drawing, the surface will be pixels, but (for example) when drawing into
+ * a PDF or Picture canvas, the surface stores the recorded commands.
+ *
+ * To draw into a canvas, first create the appropriate type of Surface, and
+ * then request the canvas from the surface.
+ */
+class SK_API SkSurface : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkSurface)
+
+ /**
+ * Create a new surface, using the specified pixels/rowbytes as its
+ * backend.
+ *
+ * If the requested surface cannot be created, or the request is not a
+ * supported configuration, NULL will be returned.
+ */
+ static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes,
+ const SkSurfaceProps* = NULL);
+
+ /**
+ * The same as NewRasterDirect, but also accepts a call-back routine, which is invoked
+ * when the surface is deleted, and is passed the pixel memory and the specified context.
+ */
+ static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes,
+ void (*releaseProc)(void* pixels, void* context),
+ void* context, const SkSurfaceProps* = NULL);
+
+ /**
+ * Return a new surface, with the memory for the pixels automatically
+ * allocated.
+ *
+ * If the requested surface cannot be created, or the request is not a
+ * supported configuration, NULL will be returned.
+ */
+ static SkSurface* NewRaster(const SkImageInfo&, const SkSurfaceProps* = NULL);
+
+ /**
+ * Helper version of NewRaster. It creates a SkImageInfo with the
+ * specified width and height, and populates the rest of info to match
+ * pixels in SkPMColor format.
+ */
+ static SkSurface* NewRasterPMColor(int width, int height, const SkSurfaceProps* props = NULL) {
+ return NewRaster(SkImageInfo::MakeN32Premul(width, height), props);
+ }
+
+ /**
+ * Return a new surface using the specified render target.
+ */
+ static SkSurface* NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*);
+
+ static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) {
+ return NewRenderTargetDirect(target, NULL);
+ }
+
+ /**
+ * Return a new surface whose contents will be drawn to an offscreen
+ * render target, allocated by the surface.
+ */
+ static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ const SkSurfaceProps* = NULL);
+
+ static SkSurface* NewRenderTarget(GrContext* gr, const SkImageInfo& info) {
+ return NewRenderTarget(gr, info, 0, NULL);
+ }
+
+ /**
+ * Return a new surface whose contents will be drawn to an offscreen
+ * render target, allocated by the surface from the scratch texture pool
+ * managed by the GrContext. The scratch texture pool serves the purpose
+ * of retaining textures after they are no longer in use in order to
+ * re-use them later without having to re-allocate. Scratch textures
+ * should be used in cases where high turnover is expected. This allows,
+ * for example, the copy on write to recycle a texture from a recently
+ * released SkImage snapshot of the surface.
+ * Note: Scratch textures count against the GrContext's cached resource
+ * budget.
+ */
+ static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ const SkSurfaceProps* = NULL);
+
+ static SkSurface* NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info) {
+ return NewScratchRenderTarget(gr, info, 0, NULL);
+ }
+
+#ifdef SK_SUPPORT_LEGACY_TEXTRENDERMODE
+ /**
+ * Text rendering modes that can be passed to NewRenderTarget*
+ */
+ enum TextRenderMode {
+ /**
+ * This will use the standard text rendering method
+ */
+ kStandard_TextRenderMode,
+ /**
+ * This will use signed distance fields for text rendering when possible
+ */
+ kDistanceField_TextRenderMode,
+ };
+ static SkSurface* NewRenderTargetDirect(GrRenderTarget*, TextRenderMode);
+ static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ TextRenderMode);
+ static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+ TextRenderMode);
+#endif
+
+ int width() const { return fWidth; }
+ int height() const { return fHeight; }
+
+ /**
+ * Returns a unique non-zero, unique value identifying the content of this
+ * surface. Each time the content is changed changed, either by drawing
+ * into this surface, or explicitly calling notifyContentChanged()) this
+ * method will return a new value.
+ *
+ * If this surface is empty (i.e. has a zero-dimention), this will return
+ * 0.
+ */
+ uint32_t generationID();
+
+ /**
+ * Modes that can be passed to notifyContentWillChange
+ */
+ enum ContentChangeMode {
+ /**
+ * Use this mode if it is known that the upcoming content changes will
+ * clear or overwrite prior contents, thus making them discardable.
+ */
+ kDiscard_ContentChangeMode,
+ /**
+ * Use this mode if prior surface contents need to be preserved or
+ * if in doubt.
+ */
+ kRetain_ContentChangeMode,
+ };
+
+ /**
+ * Call this if the contents are about to change. This will (lazily) force a new
+ * value to be returned from generationID() when it is called next.
+ */
+ void notifyContentWillChange(ContentChangeMode mode);
+
+ /**
+ * Return a canvas that will draw into this surface. This will always
+ * return the same canvas for a given surface, and is manged/owned by the
+ * surface. It should not be used when its parent surface has gone out of
+ * scope.
+ */
+ SkCanvas* getCanvas();
+
+ /**
+ * Return a new surface that is "compatible" with this one, in that it will
+ * efficiently be able to be drawn into this surface. Typical calling
+ * pattern:
+ *
+ * SkSurface* A = SkSurface::New...();
+ * SkCanvas* canvasA = surfaceA->newCanvas();
+ * ...
+ * SkSurface* surfaceB = surfaceA->newSurface(...);
+ * SkCanvas* canvasB = surfaceB->newCanvas();
+ * ... // draw using canvasB
+ * canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
+ */
+ SkSurface* newSurface(const SkImageInfo&);
+
+ /**
+ * Returns an image of the current state of the surface pixels up to this
+ * point. Subsequent changes to the surface (by drawing into its canvas)
+ * will not be reflected in this image.
+ */
+ SkImage* newImageSnapshot();
+
+ /**
+ * Thought the caller could get a snapshot image explicitly, and draw that,
+ * it seems that directly drawing a surface into another canvas might be
+ * a common pattern, and that we could possibly be more efficient, since
+ * we'd know that the "snapshot" need only live until we've handed it off
+ * to the canvas.
+ */
+ void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
+
+ /**
+ * If the surface has direct access to its pixels (i.e. they are in local
+ * RAM) return the const-address of those pixels, and if not null, return
+ * the ImageInfo and rowBytes. The returned address is only valid while
+ * the surface object is in scope, and no API call is made on the surface
+ * or its canvas.
+ *
+ * On failure, returns NULL and the info and rowBytes parameters are
+ * ignored.
+ */
+ const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
+
+ const SkSurfaceProps& props() const { return fProps; }
+
+protected:
+ SkSurface(int width, int height, const SkSurfaceProps*);
+ SkSurface(const SkImageInfo&, const SkSurfaceProps*);
+
+ // called by subclass if their contents have changed
+ void dirtyGenerationID() {
+ fGenerationID = 0;
+ }
+
+private:
+ const SkSurfaceProps fProps;
+ const int fWidth;
+ const int fHeight;
+ uint32_t fGenerationID;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkSurfaceProps.h b/src/third_party/skia/include/core/SkSurfaceProps.h
new file mode 100644
index 0000000..0154473
--- /dev/null
+++ b/src/third_party/skia/include/core/SkSurfaceProps.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSurfaceProps_DEFINED
+#define SkSurfaceProps_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ * Description of how the LCD strips are arranged for each pixel. If this is unknown, or the
+ * pixels are meant to be "portable" and/or transformed before showing (e.g. rotated, scaled)
+ * then use kUnknown_SkPixelGeometry.
+ */
+enum SkPixelGeometry {
+ kUnknown_SkPixelGeometry,
+ kRGB_H_SkPixelGeometry,
+ kBGR_H_SkPixelGeometry,
+ kRGB_V_SkPixelGeometry,
+ kBGR_V_SkPixelGeometry,
+};
+
+// Returns true iff geo is a known geometry and is RGB.
+static inline bool SkPixelGeometryIsRGB(SkPixelGeometry geo) {
+ return kRGB_H_SkPixelGeometry == geo || kRGB_V_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is BGR.
+static inline bool SkPixelGeometryIsBGR(SkPixelGeometry geo) {
+ return kBGR_H_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is horizontal.
+static inline bool SkPixelGeometryIsH(SkPixelGeometry geo) {
+ return kRGB_H_SkPixelGeometry == geo || kBGR_H_SkPixelGeometry == geo;
+}
+
+// Returns true iff geo is a known geometry and is vertical.
+static inline bool SkPixelGeometryIsV(SkPixelGeometry geo) {
+ return kRGB_V_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo;
+}
+
+/**
+ * Describes properties and constraints of a given SkSurface. The rendering engine can parse these
+ * during drawing, and can sometimes optimize its performance (e.g. disabling an expensive
+ * feature).
+ */
+class SkSurfaceProps {
+public:
+ enum Flags {
+ kDisallowAntiAlias_Flag = 1 << 0,
+ kDisallowDither_Flag = 1 << 1,
+ kUseDistanceFieldFonts_Flag = 1 << 2,
+ };
+ SkSurfaceProps(uint32_t flags, SkPixelGeometry);
+
+ enum InitType {
+ kLegacyFontHost_InitType
+ };
+ SkSurfaceProps(InitType);
+ SkSurfaceProps(uint32_t flags, InitType);
+
+ uint32_t flags() const { return fFlags; }
+ SkPixelGeometry pixelGeometry() const { return fPixelGeometry; }
+
+ bool isDisallowAA() const { return SkToBool(fFlags & kDisallowAntiAlias_Flag); }
+ bool isDisallowDither() const { return SkToBool(fFlags & kDisallowDither_Flag); }
+ bool isUseDistanceFieldFonts() const { return SkToBool(fFlags & kUseDistanceFieldFonts_Flag); }
+
+private:
+ SkSurfaceProps();
+
+ uint32_t fFlags;
+ SkPixelGeometry fPixelGeometry;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTArray.h b/src/third_party/skia/include/core/SkTArray.h
new file mode 100644
index 0000000..06a85bc
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTArray.h
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTArray_DEFINED
+#define SkTArray_DEFINED
+
+#include <new>
+#include "SkTypes.h"
+#include "SkTemplates.h"
+
+template <typename T, bool MEM_COPY = false> class SkTArray;
+
+namespace SkTArrayExt {
+
+template<typename T>
+inline void copy(SkTArray<T, true>* self, int dst, int src) {
+ memcpy(&self->fItemArray[dst], &self->fItemArray[src], sizeof(T));
+}
+template<typename T>
+inline void copy(SkTArray<T, true>* self, const T* array) {
+ memcpy(self->fMemArray, array, self->fCount * sizeof(T));
+}
+template<typename T>
+inline void copyAndDelete(SkTArray<T, true>* self, char* newMemArray) {
+ memcpy(newMemArray, self->fMemArray, self->fCount * sizeof(T));
+}
+
+template<typename T>
+inline void copy(SkTArray<T, false>* self, int dst, int src) {
+ SkNEW_PLACEMENT_ARGS(&self->fItemArray[dst], T, (self->fItemArray[src]));
+}
+template<typename T>
+inline void copy(SkTArray<T, false>* self, const T* array) {
+ for (int i = 0; i < self->fCount; ++i) {
+ SkNEW_PLACEMENT_ARGS(self->fItemArray + i, T, (array[i]));
+ }
+}
+template<typename T>
+inline void copyAndDelete(SkTArray<T, false>* self, char* newMemArray) {
+ for (int i = 0; i < self->fCount; ++i) {
+ SkNEW_PLACEMENT_ARGS(newMemArray + sizeof(T) * i, T, (self->fItemArray[i]));
+ self->fItemArray[i].~T();
+ }
+}
+
+}
+
+template <typename T, bool MEM_COPY> void* operator new(size_t, SkTArray<T, MEM_COPY>*, int);
+
+/** When MEM_COPY is true T will be bit copied when moved.
+ When MEM_COPY is false, T will be copy constructed / destructed.
+ In all cases T will be default-initialized on allocation,
+ and its destructor will be called from this object's destructor.
+*/
+template <typename T, bool MEM_COPY> class SkTArray {
+public:
+ /**
+ * Creates an empty array with no initial storage
+ */
+ SkTArray() {
+ fCount = 0;
+ fReserveCount = gMIN_ALLOC_COUNT;
+ fAllocCount = 0;
+ fMemArray = NULL;
+ fPreAllocMemArray = NULL;
+ }
+
+ /**
+ * Creates an empty array that will preallocate space for reserveCount
+ * elements.
+ */
+ explicit SkTArray(int reserveCount) {
+ this->init(NULL, 0, NULL, reserveCount);
+ }
+
+ /**
+ * Copies one array to another. The new array will be heap allocated.
+ */
+ explicit SkTArray(const SkTArray& array) {
+ this->init(array.fItemArray, array.fCount, NULL, 0);
+ }
+
+ /**
+ * Creates a SkTArray by copying contents of a standard C array. The new
+ * array will be heap allocated. Be careful not to use this constructor
+ * when you really want the (void*, int) version.
+ */
+ SkTArray(const T* array, int count) {
+ this->init(array, count, NULL, 0);
+ }
+
+ /**
+ * assign copy of array to this
+ */
+ SkTArray& operator =(const SkTArray& array) {
+ for (int i = 0; i < fCount; ++i) {
+ fItemArray[i].~T();
+ }
+ fCount = 0;
+ this->checkRealloc((int)array.count());
+ fCount = array.count();
+ SkTArrayExt::copy(this, static_cast<const T*>(array.fMemArray));
+ return *this;
+ }
+
+ virtual ~SkTArray() {
+ for (int i = 0; i < fCount; ++i) {
+ fItemArray[i].~T();
+ }
+ if (fMemArray != fPreAllocMemArray) {
+ sk_free(fMemArray);
+ }
+ }
+
+ /**
+ * Resets to count() == 0
+ */
+ void reset() { this->pop_back_n(fCount); }
+
+ /**
+ * Resets to count() = n newly constructed T objects.
+ */
+ void reset(int n) {
+ SkASSERT(n >= 0);
+ for (int i = 0; i < fCount; ++i) {
+ fItemArray[i].~T();
+ }
+ // set fCount to 0 before calling checkRealloc so that no copy cons. are called.
+ fCount = 0;
+ this->checkRealloc(n);
+ fCount = n;
+ for (int i = 0; i < fCount; ++i) {
+ SkNEW_PLACEMENT(fItemArray + i, T);
+ }
+ }
+
+ /**
+ * Resets to a copy of a C array.
+ */
+ void reset(const T* array, int count) {
+ for (int i = 0; i < fCount; ++i) {
+ fItemArray[i].~T();
+ }
+ int delta = count - fCount;
+ this->checkRealloc(delta);
+ fCount = count;
+ SkTArrayExt::copy(this, array);
+ }
+
+ void removeShuffle(int n) {
+ SkASSERT(n < fCount);
+ int newCount = fCount - 1;
+ fCount = newCount;
+ fItemArray[n].~T();
+ if (n != newCount) {
+ SkTArrayExt::copy(this, n, newCount);
+ fItemArray[newCount].~T();
+ }
+ }
+
+ /**
+ * Number of elements in the array.
+ */
+ int count() const { return fCount; }
+
+ /**
+ * Is the array empty.
+ */
+ bool empty() const { return !fCount; }
+
+ /**
+ * Adds 1 new default-initialized T value and returns it by reference. Note
+ * the reference only remains valid until the next call that adds or removes
+ * elements.
+ */
+ T& push_back() {
+ T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
+ SkNEW_PLACEMENT(newT, T);
+ return *newT;
+ }
+
+ /**
+ * Version of above that uses a copy constructor to initialize the new item
+ */
+ T& push_back(const T& t) {
+ T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
+ SkNEW_PLACEMENT_ARGS(newT, T, (t));
+ return *newT;
+ }
+
+ /**
+ * Allocates n more default-initialized T values, and returns the address of
+ * the start of that new range. Note: this address is only valid until the
+ * next API call made on the array that might add or remove elements.
+ */
+ T* push_back_n(int n) {
+ SkASSERT(n >= 0);
+ T* newTs = reinterpret_cast<T*>(this->push_back_raw(n));
+ for (int i = 0; i < n; ++i) {
+ SkNEW_PLACEMENT(newTs + i, T);
+ }
+ return newTs;
+ }
+
+ /**
+ * Version of above that uses a copy constructor to initialize all n items
+ * to the same T.
+ */
+ T* push_back_n(int n, const T& t) {
+ SkASSERT(n >= 0);
+ T* newTs = reinterpret_cast<T*>(this->push_back_raw(n));
+ for (int i = 0; i < n; ++i) {
+ SkNEW_PLACEMENT_ARGS(newTs[i], T, (t));
+ }
+ return newTs;
+ }
+
+ /**
+ * Version of above that uses a copy constructor to initialize the n items
+ * to separate T values.
+ */
+ T* push_back_n(int n, const T t[]) {
+ SkASSERT(n >= 0);
+ this->checkRealloc(n);
+ for (int i = 0; i < n; ++i) {
+ SkNEW_PLACEMENT_ARGS(fItemArray + fCount + i, T, (t[i]));
+ }
+ fCount += n;
+ return fItemArray + fCount - n;
+ }
+
+ /**
+ * Removes the last element. Not safe to call when count() == 0.
+ */
+ void pop_back() {
+ SkASSERT(fCount > 0);
+ --fCount;
+ fItemArray[fCount].~T();
+ this->checkRealloc(0);
+ }
+
+ /**
+ * Removes the last n elements. Not safe to call when count() < n.
+ */
+ void pop_back_n(int n) {
+ SkASSERT(n >= 0);
+ SkASSERT(fCount >= n);
+ fCount -= n;
+ for (int i = 0; i < n; ++i) {
+ fItemArray[fCount + i].~T();
+ }
+ this->checkRealloc(0);
+ }
+
+ /**
+ * Pushes or pops from the back to resize. Pushes will be default
+ * initialized.
+ */
+ void resize_back(int newCount) {
+ SkASSERT(newCount >= 0);
+
+ if (newCount > fCount) {
+ this->push_back_n(newCount - fCount);
+ } else if (newCount < fCount) {
+ this->pop_back_n(fCount - newCount);
+ }
+ }
+
+ T* begin() {
+ return fItemArray;
+ }
+ const T* begin() const {
+ return fItemArray;
+ }
+ T* end() {
+ return fItemArray ? fItemArray + fCount : NULL;
+ }
+ const T* end() const {
+ return fItemArray ? fItemArray + fCount : NULL;;
+ }
+
+ /**
+ * Get the i^th element.
+ */
+ T& operator[] (int i) {
+ SkASSERT(i < fCount);
+ SkASSERT(i >= 0);
+ return fItemArray[i];
+ }
+
+ const T& operator[] (int i) const {
+ SkASSERT(i < fCount);
+ SkASSERT(i >= 0);
+ return fItemArray[i];
+ }
+
+ /**
+ * equivalent to operator[](0)
+ */
+ T& front() { SkASSERT(fCount > 0); return fItemArray[0];}
+
+ const T& front() const { SkASSERT(fCount > 0); return fItemArray[0];}
+
+ /**
+ * equivalent to operator[](count() - 1)
+ */
+ T& back() { SkASSERT(fCount); return fItemArray[fCount - 1];}
+
+ const T& back() const { SkASSERT(fCount > 0); return fItemArray[fCount - 1];}
+
+ /**
+ * equivalent to operator[](count()-1-i)
+ */
+ T& fromBack(int i) {
+ SkASSERT(i >= 0);
+ SkASSERT(i < fCount);
+ return fItemArray[fCount - i - 1];
+ }
+
+ const T& fromBack(int i) const {
+ SkASSERT(i >= 0);
+ SkASSERT(i < fCount);
+ return fItemArray[fCount - i - 1];
+ }
+
+ bool operator==(const SkTArray<T, MEM_COPY>& right) const {
+ int leftCount = this->count();
+ if (leftCount != right.count()) {
+ return false;
+ }
+ for (int index = 0; index < leftCount; ++index) {
+ if (fItemArray[index] != right.fItemArray[index]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool operator!=(const SkTArray<T, MEM_COPY>& right) const {
+ return !(*this == right);
+ }
+
+protected:
+ /**
+ * Creates an empty array that will use the passed storage block until it
+ * is insufficiently large to hold the entire array.
+ */
+ template <int N>
+ SkTArray(SkAlignedSTStorage<N,T>* storage) {
+ this->init(NULL, 0, storage->get(), N);
+ }
+
+ /**
+ * Copy another array, using preallocated storage if preAllocCount >=
+ * array.count(). Otherwise storage will only be used when array shrinks
+ * to fit.
+ */
+ template <int N>
+ SkTArray(const SkTArray& array, SkAlignedSTStorage<N,T>* storage) {
+ this->init(array.fItemArray, array.fCount, storage->get(), N);
+ }
+
+ /**
+ * Copy a C array, using preallocated storage if preAllocCount >=
+ * count. Otherwise storage will only be used when array shrinks
+ * to fit.
+ */
+ template <int N>
+ SkTArray(const T* array, int count, SkAlignedSTStorage<N,T>* storage) {
+ this->init(array, count, storage->get(), N);
+ }
+
+ void init(const T* array, int count,
+ void* preAllocStorage, int preAllocOrReserveCount) {
+ SkASSERT(count >= 0);
+ SkASSERT(preAllocOrReserveCount >= 0);
+ fCount = count;
+ fReserveCount = (preAllocOrReserveCount > 0) ?
+ preAllocOrReserveCount :
+ gMIN_ALLOC_COUNT;
+ fPreAllocMemArray = preAllocStorage;
+ if (fReserveCount >= fCount &&
+ preAllocStorage) {
+ fAllocCount = fReserveCount;
+ fMemArray = preAllocStorage;
+ } else {
+ fAllocCount = SkMax32(fCount, fReserveCount);
+ fMemArray = sk_malloc_throw(fAllocCount * sizeof(T));
+ }
+
+ SkTArrayExt::copy(this, array);
+ }
+
+private:
+
+ static const int gMIN_ALLOC_COUNT = 8;
+
+ // Helper function that makes space for n objects, adjusts the count, but does not initialize
+ // the new objects.
+ void* push_back_raw(int n) {
+ this->checkRealloc(n);
+ void* ptr = fItemArray + fCount;
+ fCount += n;
+ return ptr;
+ }
+
+ inline void checkRealloc(int delta) {
+ SkASSERT(fCount >= 0);
+ SkASSERT(fAllocCount >= 0);
+
+ SkASSERT(-delta <= fCount);
+
+ int newCount = fCount + delta;
+ int newAllocCount = fAllocCount;
+
+ if (newCount > fAllocCount || newCount < (fAllocCount / 3)) {
+ // whether we're growing or shrinking, we leave at least 50% extra space for future
+ // growth (clamped to the reserve count).
+ newAllocCount = SkMax32(newCount + ((newCount + 1) >> 1), fReserveCount);
+ }
+ if (newAllocCount != fAllocCount) {
+
+ fAllocCount = newAllocCount;
+ char* newMemArray;
+
+ if (fAllocCount == fReserveCount && fPreAllocMemArray) {
+ newMemArray = (char*) fPreAllocMemArray;
+ } else {
+ newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T));
+ }
+
+ SkTArrayExt::copyAndDelete<T>(this, newMemArray);
+
+ if (fMemArray != fPreAllocMemArray) {
+ sk_free(fMemArray);
+ }
+ fMemArray = newMemArray;
+ }
+ }
+
+ friend void* operator new<T>(size_t, SkTArray*, int);
+
+ template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, int dst, int src);
+ template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*);
+ template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true>* that, char*);
+
+ template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, int dst, int src);
+ template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*);
+ template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, false>* that, char*);
+
+ int fReserveCount;
+ int fCount;
+ int fAllocCount;
+ void* fPreAllocMemArray;
+ union {
+ T* fItemArray;
+ void* fMemArray;
+ };
+};
+
+// Use the below macro (SkNEW_APPEND_TO_TARRAY) rather than calling this directly
+template <typename T, bool MEM_COPY>
+void* operator new(size_t, SkTArray<T, MEM_COPY>* array, int atIndex) {
+ // Currently, we only support adding to the end of the array. When the array class itself
+ // supports random insertion then this should be updated.
+ // SkASSERT(atIndex >= 0 && atIndex <= array->count());
+ SkASSERT(atIndex == array->count());
+ return array->push_back_raw(1);
+}
+
+// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
+// to match the op new silences warnings about missing op delete when a constructor throws an
+// exception.
+template <typename T, bool MEM_COPY>
+void operator delete(void*, SkTArray<T, MEM_COPY>* array, int atIndex) {
+ SK_CRASH();
+}
+
+// Constructs a new object as the last element of an SkTArray.
+#define SkNEW_APPEND_TO_TARRAY(array_ptr, type_name, args) \
+ (new ((array_ptr), (array_ptr)->count()) type_name args)
+
+
+/**
+ * Subclass of SkTArray that contains a preallocated memory block for the array.
+ */
+template <int N, typename T, bool MEM_COPY = false>
+class SkSTArray : public SkTArray<T, MEM_COPY> {
+private:
+ typedef SkTArray<T, MEM_COPY> INHERITED;
+
+public:
+ SkSTArray() : INHERITED(&fStorage) {
+ }
+
+ SkSTArray(const SkSTArray& array)
+ : INHERITED(array, &fStorage) {
+ }
+
+ explicit SkSTArray(const INHERITED& array)
+ : INHERITED(array, &fStorage) {
+ }
+
+ explicit SkSTArray(int reserveCount)
+ : INHERITED(reserveCount) {
+ }
+
+ SkSTArray(const T* array, int count)
+ : INHERITED(array, count, &fStorage) {
+ }
+
+ SkSTArray& operator= (const SkSTArray& array) {
+ return *this = *(const INHERITED*)&array;
+ }
+
+ SkSTArray& operator= (const INHERITED& array) {
+ INHERITED::operator=(array);
+ return *this;
+ }
+
+private:
+ SkAlignedSTStorage<N,T> fStorage;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTDArray.h b/src/third_party/skia/include/core/SkTDArray.h
new file mode 100644
index 0000000..92f297c
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTDArray.h
@@ -0,0 +1,389 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTDArray_DEFINED
+#define SkTDArray_DEFINED
+
+#include "SkTypes.h"
+
+template <typename T> class SkTDArray {
+public:
+ SkTDArray() {
+ fReserve = fCount = 0;
+ fArray = NULL;
+#ifdef SK_DEBUG
+ fData = NULL;
+#endif
+ }
+ SkTDArray(const T src[], int count) {
+ SkASSERT(src || count == 0);
+
+ fReserve = fCount = 0;
+ fArray = NULL;
+#ifdef SK_DEBUG
+ fData = NULL;
+#endif
+ if (count) {
+ fArray = (T*)sk_malloc_throw(count * sizeof(T));
+#ifdef SK_DEBUG
+ fData = (ArrayT*)fArray;
+#endif
+ memcpy(fArray, src, sizeof(T) * count);
+ fReserve = fCount = count;
+ }
+ }
+ SkTDArray(const SkTDArray<T>& src) {
+ fReserve = fCount = 0;
+ fArray = NULL;
+#ifdef SK_DEBUG
+ fData = NULL;
+#endif
+ SkTDArray<T> tmp(src.fArray, src.fCount);
+ this->swap(tmp);
+ }
+ ~SkTDArray() {
+ sk_free(fArray);
+ }
+
+ SkTDArray<T>& operator=(const SkTDArray<T>& src) {
+ if (this != &src) {
+ if (src.fCount > fReserve) {
+ SkTDArray<T> tmp(src.fArray, src.fCount);
+ this->swap(tmp);
+ } else {
+ memcpy(fArray, src.fArray, sizeof(T) * src.fCount);
+ fCount = src.fCount;
+ }
+ }
+ return *this;
+ }
+
+ friend bool operator==(const SkTDArray<T>& a, const SkTDArray<T>& b) {
+ return a.fCount == b.fCount &&
+ (a.fCount == 0 ||
+ !memcmp(a.fArray, b.fArray, a.fCount * sizeof(T)));
+ }
+ friend bool operator!=(const SkTDArray<T>& a, const SkTDArray<T>& b) {
+ return !(a == b);
+ }
+
+ void swap(SkTDArray<T>& other) {
+ SkTSwap(fArray, other.fArray);
+#ifdef SK_DEBUG
+ SkTSwap(fData, other.fData);
+#endif
+ SkTSwap(fReserve, other.fReserve);
+ SkTSwap(fCount, other.fCount);
+ }
+
+ /** Return a ptr to the array of data, to be freed with sk_free. This also
+ resets the SkTDArray to be empty.
+ */
+ T* detach() {
+ T* array = fArray;
+ fArray = NULL;
+ fReserve = fCount = 0;
+ SkDEBUGCODE(fData = NULL;)
+ return array;
+ }
+
+ bool isEmpty() const { return fCount == 0; }
+
+ /**
+ * Return the number of elements in the array
+ */
+ int count() const { return fCount; }
+
+ /**
+ * Return the total number of elements allocated.
+ * reserved() - count() gives you the number of elements you can add
+ * without causing an allocation.
+ */
+ int reserved() const { return fReserve; }
+
+ /**
+ * return the number of bytes in the array: count * sizeof(T)
+ */
+ size_t bytes() const { return fCount * sizeof(T); }
+
+ T* begin() { return fArray; }
+ const T* begin() const { return fArray; }
+ T* end() { return fArray ? fArray + fCount : NULL; }
+ const T* end() const { return fArray ? fArray + fCount : NULL; }
+
+ T& operator[](int index) {
+ SkASSERT(index < fCount);
+ return fArray[index];
+ }
+ const T& operator[](int index) const {
+ SkASSERT(index < fCount);
+ return fArray[index];
+ }
+
+ T& getAt(int index) {
+ return (*this)[index];
+ }
+ const T& getAt(int index) const {
+ return (*this)[index];
+ }
+
+ void reset() {
+ if (fArray) {
+ sk_free(fArray);
+ fArray = NULL;
+#ifdef SK_DEBUG
+ fData = NULL;
+#endif
+ fReserve = fCount = 0;
+ } else {
+ SkASSERT(fReserve == 0 && fCount == 0);
+ }
+ }
+
+ void rewind() {
+ // same as setCount(0)
+ fCount = 0;
+ }
+
+ /**
+ * Sets the number of elements in the array.
+ * If the array does not have space for count elements, it will increase
+ * the storage allocated to some amount greater than that required.
+ * It will never shrink the shrink the storage.
+ */
+ void setCount(int count) {
+ SkASSERT(count >= 0);
+ if (count > fReserve) {
+ this->resizeStorageToAtLeast(count);
+ }
+ fCount = count;
+ }
+
+ void setReserve(int reserve) {
+ if (reserve > fReserve) {
+ this->resizeStorageToAtLeast(reserve);
+ }
+ }
+
+ T* prepend() {
+ this->adjustCount(1);
+ memmove(fArray + 1, fArray, (fCount - 1) * sizeof(T));
+ return fArray;
+ }
+
+ T* append() {
+ return this->append(1, NULL);
+ }
+ T* append(int count, const T* src = NULL) {
+ int oldCount = fCount;
+ if (count) {
+ SkASSERT(src == NULL || fArray == NULL ||
+ src + count <= fArray || fArray + oldCount <= src);
+
+ this->adjustCount(count);
+ if (src) {
+ memcpy(fArray + oldCount, src, sizeof(T) * count);
+ }
+ }
+ return fArray + oldCount;
+ }
+
+ T* appendClear() {
+ T* result = this->append();
+ *result = 0;
+ return result;
+ }
+
+ T* insert(int index) {
+ return this->insert(index, 1, NULL);
+ }
+ T* insert(int index, int count, const T* src = NULL) {
+ SkASSERT(count);
+ SkASSERT(index <= fCount);
+ size_t oldCount = fCount;
+ this->adjustCount(count);
+ T* dst = fArray + index;
+ memmove(dst + count, dst, sizeof(T) * (oldCount - index));
+ if (src) {
+ memcpy(dst, src, sizeof(T) * count);
+ }
+ return dst;
+ }
+
+ void remove(int index, int count = 1) {
+ SkASSERT(index + count <= fCount);
+ fCount = fCount - count;
+ memmove(fArray + index, fArray + index + count, sizeof(T) * (fCount - index));
+ }
+
+ void removeShuffle(int index) {
+ SkASSERT(index < fCount);
+ int newCount = fCount - 1;
+ fCount = newCount;
+ if (index != newCount) {
+ memcpy(fArray + index, fArray + newCount, sizeof(T));
+ }
+ }
+
+ int find(const T& elem) const {
+ const T* iter = fArray;
+ const T* stop = fArray + fCount;
+
+ for (; iter < stop; iter++) {
+ if (*iter == elem) {
+ return (int) (iter - fArray);
+ }
+ }
+ return -1;
+ }
+
+ int rfind(const T& elem) const {
+ const T* iter = fArray + fCount;
+ const T* stop = fArray;
+
+ while (iter > stop) {
+ if (*--iter == elem) {
+ return SkToInt(iter - stop);
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns true iff the array contains this element.
+ */
+ bool contains(const T& elem) const {
+ return (this->find(elem) >= 0);
+ }
+
+ /**
+ * Copies up to max elements into dst. The number of items copied is
+ * capped by count - index. The actual number copied is returned.
+ */
+ int copyRange(T* dst, int index, int max) const {
+ SkASSERT(max >= 0);
+ SkASSERT(!max || dst);
+ if (index >= fCount) {
+ return 0;
+ }
+ int count = SkMin32(max, fCount - index);
+ memcpy(dst, fArray + index, sizeof(T) * count);
+ return count;
+ }
+
+ void copy(T* dst) const {
+ this->copyRange(dst, 0, fCount);
+ }
+
+ // routines to treat the array like a stack
+ T* push() { return this->append(); }
+ void push(const T& elem) { *this->append() = elem; }
+ const T& top() const { return (*this)[fCount - 1]; }
+ T& top() { return (*this)[fCount - 1]; }
+ void pop(T* elem) { SkASSERT(fCount > 0); if (elem) *elem = (*this)[fCount - 1]; --fCount; }
+ void pop() { SkASSERT(fCount > 0); --fCount; }
+
+ void deleteAll() {
+ T* iter = fArray;
+ T* stop = fArray + fCount;
+ while (iter < stop) {
+ SkDELETE (*iter);
+ iter += 1;
+ }
+ this->reset();
+ }
+
+ void freeAll() {
+ T* iter = fArray;
+ T* stop = fArray + fCount;
+ while (iter < stop) {
+ sk_free(*iter);
+ iter += 1;
+ }
+ this->reset();
+ }
+
+ void unrefAll() {
+ T* iter = fArray;
+ T* stop = fArray + fCount;
+ while (iter < stop) {
+ (*iter)->unref();
+ iter += 1;
+ }
+ this->reset();
+ }
+
+ void safeUnrefAll() {
+ T* iter = fArray;
+ T* stop = fArray + fCount;
+ while (iter < stop) {
+ SkSafeUnref(*iter);
+ iter += 1;
+ }
+ this->reset();
+ }
+
+ void visitAll(void visitor(T&)) {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ if (*curr) {
+ visitor(*curr);
+ }
+ }
+ }
+
+#ifdef SK_DEBUG
+ void validate() const {
+ SkASSERT((fReserve == 0 && fArray == NULL) ||
+ (fReserve > 0 && fArray != NULL));
+ SkASSERT(fCount <= fReserve);
+ SkASSERT(fData == (ArrayT*)fArray);
+ }
+#endif
+
+private:
+#ifdef SK_DEBUG
+ enum {
+ kDebugArraySize = 16
+ };
+ typedef T ArrayT[kDebugArraySize];
+ ArrayT* fData;
+#endif
+ T* fArray;
+ int fReserve;
+ int fCount;
+
+ /**
+ * Adjusts the number of elements in the array.
+ * This is the same as calling setCount(count() + delta).
+ */
+ void adjustCount(int delta) {
+ this->setCount(fCount + delta);
+ }
+
+ /**
+ * Increase the storage allocation such that it can hold (fCount + extra)
+ * elements.
+ * It never shrinks the allocation, and it may increase the allocation by
+ * more than is strictly required, based on a private growth heuristic.
+ *
+ * note: does NOT modify fCount
+ */
+ void resizeStorageToAtLeast(int count) {
+ SkASSERT(count > fReserve);
+ fReserve = count + 4;
+ fReserve += fReserve / 4;
+ fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T));
+#ifdef SK_DEBUG
+ fData = (ArrayT*)fArray;
+#endif
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTDStack.h b/src/third_party/skia/include/core/SkTDStack.h
new file mode 100644
index 0000000..e286e4a
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTDStack.h
@@ -0,0 +1,110 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTDStack_DEFINED
+#define SkTDStack_DEFINED
+
+#include "SkTypes.h"
+
+template <typename T> class SkTDStack : SkNoncopyable {
+public:
+ SkTDStack() : fCount(0), fTotalCount(0) {
+ fInitialRec.fNext = NULL;
+ fRec = &fInitialRec;
+
+ // fCount = kSlotCount;
+ }
+
+ ~SkTDStack() {
+ Rec* rec = fRec;
+ while (rec != &fInitialRec) {
+ Rec* next = rec->fNext;
+ sk_free(rec);
+ rec = next;
+ }
+ }
+
+ int count() const { return fTotalCount; }
+ int depth() const { return fTotalCount; }
+ bool empty() const { return fTotalCount == 0; }
+
+ T* push() {
+ SkASSERT(fCount <= kSlotCount);
+ if (fCount == kSlotCount) {
+ Rec* rec = (Rec*)sk_malloc_throw(sizeof(Rec));
+ rec->fNext = fRec;
+ fRec = rec;
+ fCount = 0;
+ }
+ ++fTotalCount;
+ return &fRec->fSlots[fCount++];
+ }
+
+ void push(const T& elem) { *this->push() = elem; }
+
+ const T& index(int idx) const {
+ SkASSERT(fRec && fCount > idx);
+ return fRec->fSlots[fCount - idx - 1];
+ }
+
+ T& index(int idx) {
+ SkASSERT(fRec && fCount > idx);
+ return fRec->fSlots[fCount - idx - 1];
+ }
+
+ const T& top() const {
+ SkASSERT(fRec && fCount > 0);
+ return fRec->fSlots[fCount - 1];
+ }
+
+ T& top() {
+ SkASSERT(fRec && fCount > 0);
+ return fRec->fSlots[fCount - 1];
+ }
+
+ void pop(T* elem) {
+ if (elem) {
+ *elem = fRec->fSlots[fCount - 1];
+ }
+ this->pop();
+ }
+
+ void pop() {
+ SkASSERT(fCount > 0 && fRec);
+ --fTotalCount;
+ if (--fCount == 0) {
+ if (fRec != &fInitialRec) {
+ Rec* rec = fRec->fNext;
+ sk_free(fRec);
+ fCount = kSlotCount;
+ fRec = rec;
+ } else {
+ SkASSERT(fTotalCount == 0);
+ }
+ }
+ }
+
+private:
+ enum {
+ kSlotCount = 8
+ };
+
+ struct Rec;
+ friend struct Rec;
+
+ struct Rec {
+ Rec* fNext;
+ T fSlots[kSlotCount];
+ };
+ Rec fInitialRec;
+ Rec* fRec;
+ int fCount, fTotalCount;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTDict.h b/src/third_party/skia/include/core/SkTDict.h
new file mode 100644
index 0000000..106cace
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTDict.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTDict_DEFINED
+#define SkTDict_DEFINED
+
+#include "SkChunkAlloc.h"
+#include "SkTSearch.h"
+#include "SkTDArray.h"
+
+template <typename T> class SkTDict : SkNoncopyable {
+public:
+ SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {}
+
+ void reset() {
+ fArray.reset();
+ fStrings.reset();
+ }
+
+ int count() const { return fArray.count(); }
+
+ bool set(const char name[], const T& value) {
+ return set(name, strlen(name), value);
+ }
+
+ bool set(const char name[], size_t len, const T& value) {
+ SkASSERT(name);
+
+ int index = this->find_index(name, len);
+
+ if (index >= 0) {
+ fArray[index].fValue = value;
+ return false;
+ } else {
+ Pair* pair = fArray.insert(~index);
+ char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
+ memcpy(copy, name, len);
+ copy[len] = '\0';
+ pair->fName = copy;
+ pair->fValue = value;
+ return true;
+ }
+ }
+
+ bool find(const char name[]) const {
+ return this->find_index(name) >= 0;
+ }
+
+ bool find(const char name[], size_t len) const {
+ return this->find_index(name, len) >= 0;
+ }
+
+ bool find(const char name[], T* value) const {
+ return find(name, strlen(name), value);
+ }
+
+ bool find(const char name[], size_t len, T* value) const {
+ int index = this->find_index(name, len);
+
+ if (index >= 0) {
+ if (value) {
+ *value = fArray[index].fValue;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool findKey(T& value, const char** name) const {
+ const Pair* end = fArray.end();
+ for (const Pair* pair = fArray.begin(); pair < end; pair++) {
+ if (pair->fValue != value) {
+ continue;
+ }
+ *name = pair->fName;
+ return true;
+ }
+ return false;
+ }
+
+public:
+ struct Pair {
+ const char* fName;
+ T fValue;
+
+ friend int operator<(const Pair& a, const Pair& b) {
+ return strcmp(a.fName, b.fName);
+ }
+
+ friend int operator!=(const Pair& a, const Pair& b) {
+ return strcmp(a.fName, b.fName);
+ }
+ };
+ friend class Iter;
+
+public:
+ class Iter {
+ public:
+ Iter(const SkTDict<T>& dict) {
+ fIter = dict.fArray.begin();
+ fStop = dict.fArray.end();
+ }
+
+ const char* next(T* value) {
+ const char* name = NULL;
+ if (fIter < fStop) {
+ name = fIter->fName;
+ if (value) {
+ *value = fIter->fValue;
+ }
+ fIter += 1;
+ }
+ return name;
+ }
+ private:
+ const Pair* fIter;
+ const Pair* fStop;
+ };
+
+private:
+ SkTDArray<Pair> fArray;
+ SkChunkAlloc fStrings;
+
+ int find_index(const char name[]) const {
+ return find_index(name, strlen(name));
+ }
+
+ int find_index(const char name[], size_t len) const {
+ SkASSERT(name);
+
+ int count = fArray.count();
+ int index = ~0;
+
+ if (count) {
+ index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair));
+ }
+ return index;
+ }
+ friend class Iter;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTInternalLList.h b/src/third_party/skia/include/core/SkTInternalLList.h
new file mode 100644
index 0000000..1aa1a12
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTInternalLList.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTInternalLList_DEFINED
+#define SkTInternalLList_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ * Helper class to automatically initialize the doubly linked list created pointers.
+ */
+template <typename T> class SkPtrWrapper {
+ public:
+ SkPtrWrapper() : fPtr(NULL) {}
+ SkPtrWrapper& operator =(T* ptr) { fPtr = ptr; return *this; }
+ operator T*() const { return fPtr; }
+ T* operator->() { return fPtr; }
+ private:
+ T* fPtr;
+};
+
+
+/**
+ * This macro creates the member variables required by the SkTInternalLList class. It should be
+ * placed in the private section of any class that will be stored in a double linked list.
+ */
+#define SK_DECLARE_INTERNAL_LLIST_INTERFACE(ClassName) \
+ friend class SkTInternalLList<ClassName>; \
+ /* back pointer to the owning list - for debugging */ \
+ SkDEBUGCODE(SkPtrWrapper<SkTInternalLList<ClassName> > fList;) \
+ SkPtrWrapper<ClassName> fPrev; \
+ SkPtrWrapper<ClassName> fNext
+
+/**
+ * This class implements a templated internal doubly linked list data structure.
+ */
+template <class T> class SkTInternalLList : SkNoncopyable {
+public:
+ SkTInternalLList()
+ : fHead(NULL)
+ , fTail(NULL) {
+ }
+
+ void remove(T* entry) {
+ SkASSERT(fHead && fTail);
+ SkASSERT(this->isInList(entry));
+
+ T* prev = entry->fPrev;
+ T* next = entry->fNext;
+
+ if (prev) {
+ prev->fNext = next;
+ } else {
+ fHead = next;
+ }
+ if (next) {
+ next->fPrev = prev;
+ } else {
+ fTail = prev;
+ }
+
+ entry->fPrev = NULL;
+ entry->fNext = NULL;
+
+#ifdef SK_DEBUG
+ entry->fList = NULL;
+#endif
+ }
+
+ void addToHead(T* entry) {
+ SkASSERT(NULL == entry->fPrev && NULL == entry->fNext);
+ SkASSERT(NULL == entry->fList);
+
+ entry->fPrev = NULL;
+ entry->fNext = fHead;
+ if (fHead) {
+ fHead->fPrev = entry;
+ }
+ fHead = entry;
+ if (NULL == fTail) {
+ fTail = entry;
+ }
+
+#ifdef SK_DEBUG
+ entry->fList = this;
+#endif
+ }
+
+ void addToTail(T* entry) {
+ SkASSERT(NULL == entry->fPrev && NULL == entry->fNext);
+ SkASSERT(NULL == entry->fList);
+
+ entry->fPrev = fTail;
+ entry->fNext = NULL;
+ if (fTail) {
+ fTail->fNext = entry;
+ }
+ fTail = entry;
+ if (NULL == fHead) {
+ fHead = entry;
+ }
+
+#ifdef SK_DEBUG
+ entry->fList = this;
+#endif
+ }
+
+ /**
+ * Inserts a new list entry before an existing list entry. The new entry must not already be
+ * a member of this or any other list. If existingEntry is NULL then the new entry is added
+ * at the tail.
+ */
+ void addBefore(T* newEntry, T* existingEntry) {
+ SkASSERT(newEntry);
+
+ if (NULL == existingEntry) {
+ this->addToTail(newEntry);
+ return;
+ }
+
+ SkASSERT(this->isInList(existingEntry));
+ newEntry->fNext = existingEntry;
+ T* prev = existingEntry->fPrev;
+ existingEntry->fPrev = newEntry;
+ newEntry->fPrev = prev;
+ if (NULL == prev) {
+ SkASSERT(fHead == existingEntry);
+ fHead = newEntry;
+ } else {
+ prev->fNext = newEntry;
+ }
+#ifdef SK_DEBUG
+ newEntry->fList = this;
+#endif
+ }
+
+ /**
+ * Inserts a new list entry after an existing list entry. The new entry must not already be
+ * a member of this or any other list. If existingEntry is NULL then the new entry is added
+ * at the head.
+ */
+ void addAfter(T* newEntry, T* existingEntry) {
+ SkASSERT(newEntry);
+
+ if (NULL == existingEntry) {
+ this->addToHead(newEntry);
+ return;
+ }
+
+ SkASSERT(this->isInList(existingEntry));
+ newEntry->fPrev = existingEntry;
+ T* next = existingEntry->fNext;
+ existingEntry->fNext = newEntry;
+ newEntry->fNext = next;
+ if (NULL == next) {
+ SkASSERT(fTail == existingEntry);
+ fTail = newEntry;
+ } else {
+ next->fPrev = newEntry;
+ }
+#ifdef SK_DEBUG
+ newEntry->fList = this;
+#endif
+ }
+
+ bool isEmpty() const {
+ return NULL == fHead && NULL == fTail;
+ }
+
+ T* head() { return fHead; }
+ T* tail() { return fTail; }
+
+ class Iter {
+ public:
+ enum IterStart {
+ kHead_IterStart,
+ kTail_IterStart
+ };
+
+ Iter() : fCurr(NULL) {}
+ Iter(const Iter& iter) : fCurr(iter.fCurr) {}
+ Iter& operator= (const Iter& iter) { fCurr = iter.fCurr; return *this; }
+
+ T* init(const SkTInternalLList& list, IterStart startLoc) {
+ if (kHead_IterStart == startLoc) {
+ fCurr = list.fHead;
+ } else {
+ SkASSERT(kTail_IterStart == startLoc);
+ fCurr = list.fTail;
+ }
+
+ return fCurr;
+ }
+
+ T* get() { return fCurr; }
+
+ /**
+ * Return the next/previous element in the list or NULL if at the end.
+ */
+ T* next() {
+ if (NULL == fCurr) {
+ return NULL;
+ }
+
+ fCurr = fCurr->fNext;
+ return fCurr;
+ }
+
+ T* prev() {
+ if (NULL == fCurr) {
+ return NULL;
+ }
+
+ fCurr = fCurr->fPrev;
+ return fCurr;
+ }
+
+ private:
+ T* fCurr;
+ };
+
+#ifdef SK_DEBUG
+ void validate() const {
+ SkASSERT(!fHead == !fTail);
+ Iter iter;
+ for (T* item = iter.init(*this, Iter::kHead_IterStart); item; item = iter.next()) {
+ SkASSERT(this->isInList(item));
+ if (NULL == item->fPrev) {
+ SkASSERT(fHead == item);
+ } else {
+ SkASSERT(item->fPrev->fNext == item);
+ }
+ if (NULL == item->fNext) {
+ SkASSERT(fTail == item);
+ } else {
+ SkASSERT(item->fNext->fPrev == item);
+ }
+ }
+ }
+
+ /**
+ * Debugging-only method that uses the list back pointer to check if 'entry' is indeed in 'this'
+ * list.
+ */
+ bool isInList(const T* entry) const {
+ return entry->fList == this;
+ }
+
+ /**
+ * Debugging-only method that laboriously counts the list entries.
+ */
+ int countEntries() const {
+ int count = 0;
+ for (T* entry = fHead; entry; entry = entry->fNext) {
+ ++count;
+ }
+ return count;
+ }
+#endif // SK_DEBUG
+
+private:
+ T* fHead;
+ T* fTail;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTLazy.h b/src/third_party/skia/include/core/SkTLazy.h
new file mode 100644
index 0000000..a1dc001
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTLazy.h
@@ -0,0 +1,192 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef SkTLazy_DEFINED
+#define SkTLazy_DEFINED
+
+#include "SkTypes.h"
+#include <new>
+
+template <typename T> class SkTLazy;
+template <typename T> void* operator new(size_t, SkTLazy<T>* lazy);
+
+/**
+ * Efficient way to defer allocating/initializing a class until it is needed
+ * (if ever).
+ */
+template <typename T> class SkTLazy {
+public:
+ SkTLazy() : fPtr(NULL) {}
+
+ explicit SkTLazy(const T* src) : fPtr(NULL) {
+ if (src) {
+ fPtr = new (fStorage) T(*src);
+ }
+ }
+
+ SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) {
+ if (src.isValid()) {
+ fPtr = new (fStorage) T(*src->get());
+ } else {
+ fPtr = NULL;
+ }
+ }
+
+ ~SkTLazy() {
+ if (this->isValid()) {
+ fPtr->~T();
+ }
+ }
+
+ /**
+ * Return a pointer to a default-initialized instance of the class. If a
+ * previous instance had been initialized (either from init() or set()) it
+ * will first be destroyed, so that a freshly initialized instance is
+ * always returned.
+ */
+ T* init() {
+ if (this->isValid()) {
+ fPtr->~T();
+ }
+ fPtr = new (SkTCast<T*>(fStorage)) T;
+ return fPtr;
+ }
+
+ /**
+ * Copy src into this, and return a pointer to a copy of it. Note this
+ * will always return the same pointer, so if it is called on a lazy that
+ * has already been initialized, then this will copy over the previous
+ * contents.
+ */
+ T* set(const T& src) {
+ if (this->isValid()) {
+ *fPtr = src;
+ } else {
+ fPtr = new (SkTCast<T*>(fStorage)) T(src);
+ }
+ return fPtr;
+ }
+
+ /**
+ * Destroy the lazy object (if it was created via init() or set())
+ */
+ void reset() {
+ if (this->isValid()) {
+ fPtr->~T();
+ fPtr = NULL;
+ }
+ }
+
+ /**
+ * Returns true if a valid object has been initialized in the SkTLazy,
+ * false otherwise.
+ */
+ bool isValid() const { return SkToBool(fPtr); }
+
+ /**
+ * Returns the object. This version should only be called when the caller
+ * knows that the object has been initialized.
+ */
+ T* get() const { SkASSERT(this->isValid()); return fPtr; }
+
+ /**
+ * Like above but doesn't assert if object isn't initialized (in which case
+ * NULL is returned).
+ */
+ T* getMaybeNull() const { return fPtr; }
+
+private:
+ friend void* operator new<T>(size_t, SkTLazy* lazy);
+
+ T* fPtr; // NULL or fStorage
+ char fStorage[sizeof(T)];
+};
+
+// Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly
+template <typename T> void* operator new(size_t, SkTLazy<T>* lazy) {
+ SkASSERT(!lazy->isValid());
+ lazy->fPtr = reinterpret_cast<T*>(lazy->fStorage);
+ return lazy->fPtr;
+}
+
+// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
+// to match the op new silences warnings about missing op delete when a constructor throws an
+// exception.
+template <typename T> void operator delete(void*, SkTLazy<T>*) { SK_CRASH(); }
+
+// Use this to construct a T inside an SkTLazy using a non-default constructor.
+#define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name args)
+
+/**
+ * A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized
+ * with a const pointer but provides a non-const pointer accessor. The first time the
+ * accessor is called (if ever) the object is cloned.
+ *
+ * In the following example at most one copy of constThing is made:
+ *
+ * SkTCopyOnFirstWrite<Thing> thing(&constThing);
+ * ...
+ * function_that_takes_a_const_thing_ptr(thing); // constThing is passed
+ * ...
+ * if (need_to_modify_thing()) {
+ * thing.writable()->modifyMe(); // makes a copy of constThing
+ * }
+ * ...
+ * x = thing->readSomething();
+ * ...
+ * if (need_to_modify_thing_now()) {
+ * thing.writable()->changeMe(); // makes a copy of constThing if we didn't call modifyMe()
+ * }
+ *
+ * consume_a_thing(thing); // could be constThing or a modified copy.
+ */
+template <typename T>
+class SkTCopyOnFirstWrite {
+public:
+ SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
+
+ // Constructor for delayed initialization.
+ SkTCopyOnFirstWrite() : fObj(NULL) {}
+
+ // Should only be called once, and only if the default constructor was used.
+ void init(const T& initial) {
+ SkASSERT(NULL == fObj);
+ SkASSERT(!fLazy.isValid());
+ fObj = &initial;
+ }
+
+ /**
+ * Returns a writable T*. The first time this is called the initial object is cloned.
+ */
+ T* writable() {
+ SkASSERT(fObj);
+ if (!fLazy.isValid()) {
+ fLazy.set(*fObj);
+ fObj = fLazy.get();
+ }
+ return const_cast<T*>(fObj);
+ }
+
+ /**
+ * Operators for treating this as though it were a const pointer.
+ */
+
+ const T *operator->() const { return fObj; }
+
+ operator const T*() const { return fObj; }
+
+ const T& operator *() const { return *fObj; }
+
+private:
+ const T* fObj;
+ SkTLazy<T> fLazy;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTRegistry.h b/src/third_party/skia/include/core/SkTRegistry.h
new file mode 100644
index 0000000..0994c99
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTRegistry.h
@@ -0,0 +1,55 @@
+
+/*
+ * Copyright 2009 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTRegistry_DEFINED
+#define SkTRegistry_DEFINED
+
+#include "SkTypes.h"
+
+/** Template class that registers itself (in the constructor) into a linked-list
+ and provides a function-pointer. This can be used to auto-register a set of
+ services, e.g. a set of image codecs.
+ */
+template <typename T> class SkTRegistry : SkNoncopyable {
+public:
+ typedef T Factory;
+
+ explicit SkTRegistry(T fact) : fFact(fact) {
+#ifdef SK_BUILD_FOR_ANDROID
+ // work-around for double-initialization bug
+ {
+ SkTRegistry* reg = gHead;
+ while (reg) {
+ if (reg == this) {
+ return;
+ }
+ reg = reg->fChain;
+ }
+ }
+#endif
+ fChain = gHead;
+ gHead = this;
+ }
+
+ static const SkTRegistry* Head() { return gHead; }
+
+ const SkTRegistry* next() const { return fChain; }
+ const Factory& factory() const { return fFact; }
+
+private:
+ Factory fFact;
+ SkTRegistry* fChain;
+
+ static SkTRegistry* gHead;
+};
+
+// The caller still needs to declare an instance of this somewhere
+template <typename T> SkTRegistry<T>* SkTRegistry<T>::gHead;
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTSearch.h b/src/third_party/skia/include/core/SkTSearch.h
new file mode 100644
index 0000000..a4e4994
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTSearch.h
@@ -0,0 +1,146 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTSearch_DEFINED
+#define SkTSearch_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ * All of the SkTSearch variants want to return the index (0...N-1) of the
+ * found element, or the bit-not of where to insert the element.
+ *
+ * At a simple level, if the return value is negative, it was not found.
+ *
+ * For clients that want to insert the new element if it was not found, use
+ * the following logic:
+ *
+ * int index = SkTSearch(...);
+ * if (index >= 0) {
+ * // found at index
+ * } else {
+ * index = ~index; // now we are positive
+ * // insert at index
+ * }
+ */
+
+
+// The most general form of SkTSearch takes an array of T and a key of type K. A functor, less, is
+// used to perform comparisons. It has two function operators:
+// bool operator() (const T& t, const K& k)
+// bool operator() (const K& t, const T& k)
+template <typename T, typename K, typename LESS>
+int SkTSearch(const T base[], int count, const K& key, size_t elemSize, LESS& less)
+{
+ SkASSERT(count >= 0);
+ if (count <= 0) {
+ return ~0;
+ }
+
+ SkASSERT(base != NULL); // base may be NULL if count is zero
+
+ int lo = 0;
+ int hi = count - 1;
+
+ while (lo < hi) {
+ int mid = (hi + lo) >> 1;
+ const T* elem = (const T*)((const char*)base + mid * elemSize);
+
+ if (less(*elem, key))
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ const T* elem = (const T*)((const char*)base + hi * elemSize);
+ if (less(*elem, key)) {
+ hi += 1;
+ hi = ~hi;
+ } else if (less(key, *elem)) {
+ hi = ~hi;
+ }
+ return hi;
+}
+
+// Adapts a less-than function to a functor.
+template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToFunctorAdaptor {
+ bool operator()(const T& a, const T& b) { return LESS(a, b); }
+};
+
+// Specialization for case when T==K and the caller wants to use a function rather than functor.
+template <typename T, bool (LESS)(const T&, const T&)>
+int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
+ static SkTLessFunctionToFunctorAdaptor<T, LESS> functor;
+ return SkTSearch(base, count, target, elemSize, functor);
+}
+
+// Adapts operator < to a functor.
+template <typename T> struct SkTLessFunctor {
+ bool operator()(const T& a, const T& b) { return a < b; }
+};
+
+// Specialization for T==K, compare using op <.
+template <typename T>
+int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
+ static SkTLessFunctor<T> functor;
+ return SkTSearch(base, count, target, elemSize, functor);
+}
+
+// Similar to SkLessFunctionToFunctorAdaptor but makes the functor interface take T* rather than T.
+template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToPtrFunctorAdaptor {
+ bool operator() (const T* t, const T* k) { return LESS(*t, *k); }
+};
+
+// Specialization for case where domain is an array of T* and the key value is a T*, and you want
+// to compare the T objects, not the pointers.
+template <typename T, bool (LESS)(const T&, const T&)>
+int SkTSearch(T* base[], int count, T* target, size_t elemSize) {
+ static SkTLessFunctionToPtrFunctorAdaptor<T, LESS> functor;
+ return SkTSearch(base, count, target, elemSize, functor);
+}
+
+int SkStrSearch(const char*const* base, int count, const char target[],
+ size_t target_len, size_t elemSize);
+int SkStrSearch(const char*const* base, int count, const char target[],
+ size_t elemSize);
+
+/** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
+ base points to a table of lower-case strings.
+*/
+int SkStrLCSearch(const char*const* base, int count, const char target[],
+ size_t target_len, size_t elemSize);
+int SkStrLCSearch(const char*const* base, int count, const char target[],
+ size_t elemSize);
+
+/** Helper class to convert a string to lower-case, but only modifying the ascii
+ characters. This makes the routine very fast and never changes the string
+ length, but it is not suitable for linguistic purposes. Normally this is
+ used for buiding and searching string tables.
+*/
+class SkAutoAsciiToLC {
+public:
+ SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
+ ~SkAutoAsciiToLC();
+
+ const char* lc() const { return fLC; }
+ size_t length() const { return fLength; }
+
+private:
+ char* fLC; // points to either the heap or fStorage
+ size_t fLength;
+ enum {
+ STORAGE = 64
+ };
+ char fStorage[STORAGE+1];
+};
+
+// Helper when calling qsort with a compare proc that has typed its arguments
+#define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void*)>(compare)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTemplates.h b/src/third_party/skia/include/core/SkTemplates.h
new file mode 100644
index 0000000..5ef28ea
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTemplates.h
@@ -0,0 +1,492 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTemplates_DEFINED
+#define SkTemplates_DEFINED
+
+#include "SkTypes.h"
+#include <limits.h>
+#include <new>
+
+/** \file SkTemplates.h
+
+ This file contains light-weight template classes for type-safe and exception-safe
+ resource management.
+*/
+
+/**
+ * Marks a local variable as known to be unused (to avoid warnings).
+ * Note that this does *not* prevent the local variable from being optimized away.
+ */
+template<typename T> inline void sk_ignore_unused_variable(const T&) { }
+
+/**
+ * SkTIsConst<T>::value is true if the type T is const.
+ * The type T is constrained not to be an array or reference type.
+ */
+template <typename T> struct SkTIsConst {
+ static T* t;
+ static uint16_t test(const volatile void*);
+ static uint32_t test(volatile void *);
+ static const bool value = (sizeof(uint16_t) == sizeof(test(t)));
+};
+
+///@{
+/** SkTConstType<T, CONST>::type will be 'const T' if CONST is true, 'T' otherwise. */
+template <typename T, bool CONST> struct SkTConstType {
+ typedef T type;
+};
+template <typename T> struct SkTConstType<T, true> {
+ typedef const T type;
+};
+///@}
+
+/**
+ * Returns a pointer to a D which comes immediately after S[count].
+ */
+template <typename D, typename S> static D* SkTAfter(S* ptr, size_t count = 1) {
+ return reinterpret_cast<D*>(ptr + count);
+}
+
+/**
+ * Returns a pointer to a D which comes byteOffset bytes after S.
+ */
+template <typename D, typename S> static D* SkTAddOffset(S* ptr, size_t byteOffset) {
+ // The intermediate char* has the same const-ness as D as this produces better error messages.
+ // This relies on the fact that reinterpret_cast can add constness, but cannot remove it.
+ return reinterpret_cast<D*>(
+ reinterpret_cast<typename SkTConstType<char, SkTIsConst<D>::value>::type*>(ptr) + byteOffset
+ );
+}
+
+/** \class SkAutoTCallVProc
+
+ Call a function when this goes out of scope. The template uses two
+ parameters, the object, and a function that is to be called in the destructor.
+ If detach() is called, the object reference is set to null. If the object
+ reference is null when the destructor is called, we do not call the
+ function.
+*/
+template <typename T, void (*P)(T*)> class SkAutoTCallVProc : SkNoncopyable {
+public:
+ SkAutoTCallVProc(T* obj): fObj(obj) {}
+ ~SkAutoTCallVProc() { if (fObj) P(fObj); }
+
+ operator T*() const { return fObj; }
+ T* operator->() const { SkASSERT(fObj); return fObj; }
+
+ T* detach() { T* obj = fObj; fObj = NULL; return obj; }
+ void reset(T* obj = NULL) {
+ if (fObj != obj) {
+ if (fObj) {
+ P(fObj);
+ }
+ fObj = obj;
+ }
+ }
+private:
+ T* fObj;
+};
+
+/** \class SkAutoTCallIProc
+
+Call a function when this goes out of scope. The template uses two
+parameters, the object, and a function that is to be called in the destructor.
+If detach() is called, the object reference is set to null. If the object
+reference is null when the destructor is called, we do not call the
+function.
+*/
+template <typename T, int (*P)(T*)> class SkAutoTCallIProc : SkNoncopyable {
+public:
+ SkAutoTCallIProc(T* obj): fObj(obj) {}
+ ~SkAutoTCallIProc() { if (fObj) P(fObj); }
+ T* detach() { T* obj = fObj; fObj = NULL; return obj; }
+private:
+ T* fObj;
+};
+
+/** \class SkAutoTDelete
+ An SkAutoTDelete<T> is like a T*, except that the destructor of SkAutoTDelete<T>
+ automatically deletes the pointer it holds (if any). That is, SkAutoTDelete<T>
+ owns the T object that it points to. Like a T*, an SkAutoTDelete<T> may hold
+ either NULL or a pointer to a T object. Also like T*, SkAutoTDelete<T> is
+ thread-compatible, and once you dereference it, you get the threadsafety
+ guarantees of T.
+
+ The size of a SkAutoTDelete is small: sizeof(SkAutoTDelete<T>) == sizeof(T*)
+*/
+template <typename T> class SkAutoTDelete : SkNoncopyable {
+public:
+ SkAutoTDelete(T* obj = NULL) : fObj(obj) {}
+ ~SkAutoTDelete() { SkDELETE(fObj); }
+
+ T* get() const { return fObj; }
+ operator T*() { return fObj; }
+ T& operator*() const { SkASSERT(fObj); return *fObj; }
+ T* operator->() const { SkASSERT(fObj); return fObj; }
+
+ void reset(T* obj) {
+ if (fObj != obj) {
+ SkDELETE(fObj);
+ fObj = obj;
+ }
+ }
+
+ /**
+ * Delete the owned object, setting the internal pointer to NULL.
+ */
+ void free() {
+ SkDELETE(fObj);
+ fObj = NULL;
+ }
+
+ /**
+ * Transfer ownership of the object to the caller, setting the internal
+ * pointer to NULL. Note that this differs from get(), which also returns
+ * the pointer, but it does not transfer ownership.
+ */
+ T* detach() {
+ T* obj = fObj;
+ fObj = NULL;
+ return obj;
+ }
+
+ void swap(SkAutoTDelete* that) {
+ SkTSwap(fObj, that->fObj);
+ }
+
+private:
+ T* fObj;
+};
+
+// Calls ~T() in the destructor.
+template <typename T> class SkAutoTDestroy : SkNoncopyable {
+public:
+ SkAutoTDestroy(T* obj = NULL) : fObj(obj) {}
+ ~SkAutoTDestroy() {
+ if (fObj) {
+ fObj->~T();
+ }
+ }
+
+ T* get() const { return fObj; }
+ T& operator*() const { SkASSERT(fObj); return *fObj; }
+ T* operator->() const { SkASSERT(fObj); return fObj; }
+
+private:
+ T* fObj;
+};
+
+template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
+public:
+ SkAutoTDeleteArray(T array[]) : fArray(array) {}
+ ~SkAutoTDeleteArray() { SkDELETE_ARRAY(fArray); }
+
+ T* get() const { return fArray; }
+ void free() { SkDELETE_ARRAY(fArray); fArray = NULL; }
+ T* detach() { T* array = fArray; fArray = NULL; return array; }
+
+ void reset(T array[]) {
+ if (fArray != array) {
+ SkDELETE_ARRAY(fArray);
+ fArray = array;
+ }
+ }
+
+private:
+ T* fArray;
+};
+
+/** Allocate an array of T elements, and free the array in the destructor
+ */
+template <typename T> class SkAutoTArray : SkNoncopyable {
+public:
+ SkAutoTArray() {
+ fArray = NULL;
+ SkDEBUGCODE(fCount = 0;)
+ }
+ /** Allocate count number of T elements
+ */
+ explicit SkAutoTArray(int count) {
+ SkASSERT(count >= 0);
+ fArray = NULL;
+ if (count) {
+ fArray = SkNEW_ARRAY(T, count);
+ }
+ SkDEBUGCODE(fCount = count;)
+ }
+
+ /** Reallocates given a new count. Reallocation occurs even if new count equals old count.
+ */
+ void reset(int count) {
+ SkDELETE_ARRAY(fArray);
+ SkASSERT(count >= 0);
+ fArray = NULL;
+ if (count) {
+ fArray = SkNEW_ARRAY(T, count);
+ }
+ SkDEBUGCODE(fCount = count;)
+ }
+
+ ~SkAutoTArray() {
+ SkDELETE_ARRAY(fArray);
+ }
+
+ /** Return the array of T elements. Will be NULL if count == 0
+ */
+ T* get() const { return fArray; }
+
+ /** Return the nth element in the array
+ */
+ T& operator[](int index) const {
+ SkASSERT((unsigned)index < (unsigned)fCount);
+ return fArray[index];
+ }
+
+private:
+ T* fArray;
+ SkDEBUGCODE(int fCount;)
+};
+
+/** Wraps SkAutoTArray, with room for up to N elements preallocated
+ */
+template <int N, typename T> class SkAutoSTArray : SkNoncopyable {
+public:
+ /** Initialize with no objects */
+ SkAutoSTArray() {
+ fArray = NULL;
+ fCount = 0;
+ }
+
+ /** Allocate count number of T elements
+ */
+ SkAutoSTArray(int count) {
+ fArray = NULL;
+ fCount = 0;
+ this->reset(count);
+ }
+
+ ~SkAutoSTArray() {
+ this->reset(0);
+ }
+
+ /** Destroys previous objects in the array and default constructs count number of objects */
+ void reset(int count) {
+ T* start = fArray;
+ T* iter = start + fCount;
+ while (iter > start) {
+ (--iter)->~T();
+ }
+
+ if (fCount != count) {
+ if (fCount > N) {
+ // 'fArray' was allocated last time so free it now
+ SkASSERT((T*) fStorage != fArray);
+ sk_free(fArray);
+ }
+
+ if (count > N) {
+ fArray = (T*) sk_malloc_throw(count * sizeof(T));
+ } else if (count > 0) {
+ fArray = (T*) fStorage;
+ } else {
+ fArray = NULL;
+ }
+
+ fCount = count;
+ }
+
+ iter = fArray;
+ T* stop = fArray + count;
+ while (iter < stop) {
+ SkNEW_PLACEMENT(iter++, T);
+ }
+ }
+
+ /** Return the number of T elements in the array
+ */
+ int count() const { return fCount; }
+
+ /** Return the array of T elements. Will be NULL if count == 0
+ */
+ T* get() const { return fArray; }
+
+ /** Return the nth element in the array
+ */
+ T& operator[](int index) const {
+ SkASSERT(index < fCount);
+ return fArray[index];
+ }
+
+private:
+ int fCount;
+ T* fArray;
+ // since we come right after fArray, fStorage should be properly aligned
+ char fStorage[N * sizeof(T)];
+};
+
+/** Manages an array of T elements, freeing the array in the destructor.
+ * Does NOT call any constructors/destructors on T (T must be POD).
+ */
+template <typename T> class SkAutoTMalloc : SkNoncopyable {
+public:
+ /** Takes ownership of the ptr. The ptr must be a value which can be passed to sk_free. */
+ explicit SkAutoTMalloc(T* ptr = NULL) {
+ fPtr = ptr;
+ }
+
+ /** Allocates space for 'count' Ts. */
+ explicit SkAutoTMalloc(size_t count) {
+ fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW);
+ }
+
+ ~SkAutoTMalloc() {
+ sk_free(fPtr);
+ }
+
+ /** Resize the memory area pointed to by the current ptr preserving contents. */
+ void realloc(size_t count) {
+ fPtr = reinterpret_cast<T*>(sk_realloc_throw(fPtr, count * sizeof(T)));
+ }
+
+ /** Resize the memory area pointed to by the current ptr without preserving contents. */
+ void reset(size_t count) {
+ sk_free(fPtr);
+ fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW);
+ }
+
+ T* get() const { return fPtr; }
+
+ operator T*() {
+ return fPtr;
+ }
+
+ operator const T*() const {
+ return fPtr;
+ }
+
+ T& operator[](int index) {
+ return fPtr[index];
+ }
+
+ const T& operator[](int index) const {
+ return fPtr[index];
+ }
+
+ /**
+ * Transfer ownership of the ptr to the caller, setting the internal
+ * pointer to NULL. Note that this differs from get(), which also returns
+ * the pointer, but it does not transfer ownership.
+ */
+ T* detach() {
+ T* ptr = fPtr;
+ fPtr = NULL;
+ return ptr;
+ }
+
+private:
+ T* fPtr;
+};
+
+template <size_t N, typename T> class SkAutoSTMalloc : SkNoncopyable {
+public:
+ SkAutoSTMalloc() {
+ fPtr = NULL;
+ }
+
+ SkAutoSTMalloc(size_t count) {
+ if (count > N) {
+ fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
+ } else if (count) {
+ fPtr = fTStorage;
+ } else {
+ fPtr = NULL;
+ }
+ }
+
+ ~SkAutoSTMalloc() {
+ if (fPtr != fTStorage) {
+ sk_free(fPtr);
+ }
+ }
+
+ // doesn't preserve contents
+ T* reset(size_t count) {
+ if (fPtr != fTStorage) {
+ sk_free(fPtr);
+ }
+ if (count > N) {
+ fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
+ } else if (count) {
+ fPtr = fTStorage;
+ } else {
+ fPtr = NULL;
+ }
+ return fPtr;
+ }
+
+ T* get() const { return fPtr; }
+
+ operator T*() {
+ return fPtr;
+ }
+
+ operator const T*() const {
+ return fPtr;
+ }
+
+ T& operator[](int index) {
+ return fPtr[index];
+ }
+
+ const T& operator[](int index) const {
+ return fPtr[index];
+ }
+
+private:
+ T* fPtr;
+ union {
+ uint32_t fStorage32[(N*sizeof(T) + 3) >> 2];
+ T fTStorage[1]; // do NOT want to invoke T::T()
+ };
+};
+
+/**
+ * Reserves memory that is aligned on double and pointer boundaries.
+ * Hopefully this is sufficient for all practical purposes.
+ */
+template <size_t N> class SkAlignedSStorage : SkNoncopyable {
+public:
+ void* get() { return fData; }
+private:
+ union {
+ void* fPtr;
+ double fDouble;
+ char fData[N];
+ };
+};
+
+/**
+ * Reserves memory that is aligned on double and pointer boundaries.
+ * Hopefully this is sufficient for all practical purposes. Otherwise,
+ * we have to do some arcane trickery to determine alignment of non-POD
+ * types. Lifetime of the memory is the lifetime of the object.
+ */
+template <int N, typename T> class SkAlignedSTStorage : SkNoncopyable {
+public:
+ /**
+ * Returns void* because this object does not initialize the
+ * memory. Use placement new for types that require a cons.
+ */
+ void* get() { return fStorage.get(); }
+private:
+ SkAlignedSStorage<sizeof(T)*N> fStorage;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTextBlob.h b/src/third_party/skia/include/core/SkTextBlob.h
new file mode 100644
index 0000000..8ee1d19
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTextBlob.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTextBlob_DEFINED
+#define SkTextBlob_DEFINED
+
+#include "SkPaint.h"
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+#include "SkTDArray.h"
+
+class SkReadBuffer;
+class SkWriteBuffer;
+
+/** \class SkTextBlob
+
+ SkTextBlob combines multiple text runs into an immutable, ref-counted structure.
+*/
+class SK_API SkTextBlob : public SkRefCnt {
+public:
+ /**
+ * Returns the blob bounding box.
+ */
+ const SkRect& bounds() const { return fBounds; }
+
+ /**
+ * Return a non-zero, unique value representing the text blob.
+ */
+ uint32_t uniqueID() const;
+
+ /**
+ * Serialize to a buffer.
+ */
+ void flatten(SkWriteBuffer&) const;
+
+ /**
+ * Recreate an SkTextBlob that was serialized into a buffer.
+ *
+ * @param SkReadBuffer Serialized blob data.
+ * @return A new SkTextBlob representing the serialized data, or NULL if the buffer is
+ * invalid.
+ */
+ static const SkTextBlob* CreateFromBuffer(SkReadBuffer&);
+
+private:
+ enum GlyphPositioning {
+ kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph.
+ kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph.
+ kFull_Positioning = 2 // Point positioning -- two scalars per glyph.
+ };
+
+ class RunRecord;
+
+ class RunIterator {
+ public:
+ RunIterator(const SkTextBlob* blob);
+
+ bool done() const;
+ void next();
+
+ uint32_t glyphCount() const;
+ const uint16_t* glyphs() const;
+ const SkScalar* pos() const;
+ const SkPoint& offset() const;
+ void applyFontToPaint(SkPaint*) const;
+ GlyphPositioning positioning() const;
+
+ private:
+ const RunRecord* fCurrentRun;
+ int fRemainingRuns;
+
+ SkDEBUGCODE(uint8_t* fStorageTop;)
+ };
+
+ SkTextBlob(int runCount, const SkRect& bounds);
+
+ virtual ~SkTextBlob();
+ virtual void internal_dispose() const SK_OVERRIDE;
+
+ static unsigned ScalarsPerGlyph(GlyphPositioning pos);
+
+ friend class SkBaseDevice;
+ friend class SkTextBlobBuilder;
+ friend class TextBlobTester;
+
+ const int fRunCount;
+ const SkRect fBounds;
+ mutable uint32_t fUniqueID;
+
+ SkDEBUGCODE(size_t fStorageSize;)
+
+ // The actual payload resides in externally-managed storage, following the object.
+ // (see the .cpp for more details)
+
+ typedef SkRefCnt INHERITED;
+};
+
+/** \class SkTextBlobBuilder
+
+ Helper class for constructing SkTextBlobs.
+ */
+class SK_API SkTextBlobBuilder {
+public:
+ SkTextBlobBuilder();
+
+ ~SkTextBlobBuilder();
+
+ /**
+ * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and
+ * can be reused.
+ */
+ const SkTextBlob* build();
+
+ /**
+ * Glyph and position buffers associated with a run.
+ *
+ * A run is a sequence of glyphs sharing the same font metrics and positioning mode.
+ */
+ struct RunBuffer {
+ uint16_t* glyphs;
+ SkScalar* pos;
+ };
+
+ /**
+ * Allocates a new default-positioned run and returns its writable glyph buffer
+ * for direct manipulation.
+ *
+ * @param font The font to be used for this run.
+ * @param count Number of glyphs.
+ * @param x,y Position within the blob.
+ * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
+ * be used when computing the blob bounds, to avoid re-measuring.
+ *
+ * @return A writable glyph buffer, valid until the next allocRun() or
+ * build() call. The buffer is guaranteed to hold @count@ glyphs.
+ */
+ const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
+ const SkRect* bounds = NULL);
+
+ /**
+ * Allocates a new horizontally-positioned run and returns its writable glyph and position
+ * buffers for direct manipulation.
+ *
+ * @param font The font to be used for this run.
+ * @param count Number of glyphs.
+ * @param y Vertical offset within the blob.
+ * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
+ * be used when computing the blob bounds, to avoid re-measuring.
+ *
+ * @return Writable glyph and position buffers, valid until the next allocRun()
+ * or build() call. The buffers are guaranteed to hold @count@ elements.
+ */
+ const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
+ const SkRect* bounds = NULL);
+
+ /**
+ * Allocates a new fully-positioned run and returns its writable glyph and position
+ * buffers for direct manipulation.
+ *
+ * @param font The font to be used for this run.
+ * @param count Number of glyphs.
+ * @param bounds Optional run bounding box. If known in advance (!= NULL), it will
+ * be used when computing the blob bounds, to avoid re-measuring.
+ *
+ * @return Writable glyph and position buffers, valid until the next allocRun()
+ * or build() call. The glyph buffer and position buffer are
+ * guaranteed to hold @count@ and 2 * @count@ elements, respectively.
+ */
+ const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL);
+
+private:
+ void reserve(size_t size);
+ void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
+ int count, SkPoint offset, const SkRect* bounds);
+ bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
+ int count, SkPoint offset);
+ void updateDeferredBounds();
+
+ SkAutoTMalloc<uint8_t> fStorage;
+ size_t fStorageSize;
+ size_t fStorageUsed;
+
+ SkRect fBounds;
+ int fRunCount;
+ bool fDeferredBounds;
+ size_t fLastRun; // index into fStorage
+
+ RunBuffer fCurrentRunBuffer;
+};
+
+#endif // SkTextBlob_DEFINED
diff --git a/src/third_party/skia/include/core/SkThread.h b/src/third_party/skia/include/core/SkThread.h
new file mode 100644
index 0000000..bcbc437
--- /dev/null
+++ b/src/third_party/skia/include/core/SkThread.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkThread_DEFINED
+#define SkThread_DEFINED
+
+#include "SkTypes.h"
+
+// SK_ATOMICS_PLATFORM_H must provide inline implementations for the following declarations.
+
+/** Atomically adds one to the int referenced by addr and returns the previous value.
+ * No additional memory barrier is required; this must act as a compiler barrier.
+ */
+static int32_t sk_atomic_inc(int32_t* addr);
+static int64_t sk_atomic_inc(int64_t* addr);
+
+/** Atomically adds inc to the int referenced by addr and returns the previous value.
+ * No additional memory barrier is required; this must act as a compiler barrier.
+ */
+static int32_t sk_atomic_add(int32_t* addr, int32_t inc);
+
+/** Atomically subtracts one from the int referenced by addr and returns the previous value.
+ * This must act as a release (SL/S) memory barrier and as a compiler barrier.
+ */
+static int32_t sk_atomic_dec(int32_t* addr);
+
+/** Atomic compare and set.
+ * If *addr == before, set *addr to after and return true, otherwise return false.
+ * This must act as a release (SL/S) memory barrier and as a compiler barrier.
+ */
+static bool sk_atomic_cas(int32_t* addr, int32_t before, int32_t after);
+
+/** If sk_atomic_dec does not act as an acquire (L/SL) barrier,
+ * this must act as an acquire (L/SL) memory barrier and as a compiler barrier.
+ */
+static void sk_membar_acquire__after_atomic_dec();
+
+/** If sk_atomic_conditional_inc does not act as an acquire (L/SL) barrier,
+ * this must act as an acquire (L/SL) memory barrier and as a compiler barrier.
+ */
+static void sk_membar_acquire__after_atomic_conditional_inc();
+
+#include SK_ATOMICS_PLATFORM_H
+
+/** Atomically adds one to the int referenced by addr iff the referenced int was not 0
+ * and returns the previous value.
+ * No additional memory barrier is required; this must act as a compiler barrier.
+ */
+template<typename INT_TYPE> static inline INT_TYPE sk_atomic_conditional_inc(INT_TYPE* addr) {
+ INT_TYPE prev;
+ do {
+ prev = *addr;
+ if (0 == prev) {
+ break;
+ }
+ } while (!sk_atomic_cas(addr, prev, prev+1));
+ return prev;
+}
+
+// SK_BARRIERS_PLATFORM_H must provide implementations for the following declarations:
+
+/** Prevent the compiler from reordering across this barrier. */
+static void sk_compiler_barrier();
+
+/** Read T*, with at least an acquire barrier.
+ *
+ * Only needs to be implemented for T which can be atomically read.
+ */
+template <typename T> T sk_acquire_load(T*);
+
+/** Write T*, with at least a release barrier.
+ *
+ * Only needs to be implemented for T which can be atomically written.
+ */
+template <typename T> void sk_release_store(T*, T);
+
+#include SK_BARRIERS_PLATFORM_H
+
+/** SK_MUTEX_PLATFORM_H must provide the following (or equivalent) declarations.
+
+class SkBaseMutex {
+public:
+ void acquire(); // Block until this thread owns the mutex.
+ void release(); // Assuming this thread owns the mutex, release it.
+ void assertHeld(); // If SK_DEBUG, assert this thread owns the mutex.
+};
+
+class SkMutex : SkBaseMutex {
+public:
+ SkMutex();
+ ~SkMutex();
+};
+
+#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ...
+*/
+
+#include SK_MUTEX_PLATFORM_H
+
+
+class SkAutoMutexAcquire : SkNoncopyable {
+public:
+ explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex) {
+ SkASSERT(fMutex != NULL);
+ mutex.acquire();
+ }
+
+ explicit SkAutoMutexAcquire(SkBaseMutex* mutex) : fMutex(mutex) {
+ if (mutex) {
+ mutex->acquire();
+ }
+ }
+
+ /** If the mutex has not been released, release it now. */
+ ~SkAutoMutexAcquire() {
+ if (fMutex) {
+ fMutex->release();
+ }
+ }
+
+ /** If the mutex has not been released, release it now. */
+ void release() {
+ if (fMutex) {
+ fMutex->release();
+ fMutex = NULL;
+ }
+ }
+
+ /** Assert that we're holding the mutex. */
+ void assertHeld() {
+ SkASSERT(fMutex);
+ fMutex->assertHeld();
+ }
+
+private:
+ SkBaseMutex* fMutex;
+};
+#define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTime.h b/src/third_party/skia/include/core/SkTime.h
new file mode 100644
index 0000000..51616d4
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTime.h
@@ -0,0 +1,65 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTime_DEFINED
+#define SkTime_DEFINED
+
+#include "SkTypes.h"
+
+/** \class SkTime
+ Platform-implemented utilities to return time of day, and millisecond counter.
+*/
+class SkTime {
+public:
+ struct DateTime {
+ uint16_t fYear; //!< e.g. 2005
+ uint8_t fMonth; //!< 1..12
+ uint8_t fDayOfWeek; //!< 0..6, 0==Sunday
+ uint8_t fDay; //!< 1..31
+ uint8_t fHour; //!< 0..23
+ uint8_t fMinute; //!< 0..59
+ uint8_t fSecond; //!< 0..59
+ };
+ static void GetDateTime(DateTime*);
+
+ static SkMSec GetMSecs();
+};
+
+#if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN32)
+ extern SkMSec gForceTickCount;
+#endif
+
+#define SK_TIME_FACTOR 1
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkAutoTime {
+public:
+ // The label is not deep-copied, so its address must remain valid for the
+ // lifetime of this object
+ SkAutoTime(const char* label = NULL, SkMSec minToDump = 0) : fLabel(label)
+ {
+ fNow = SkTime::GetMSecs();
+ fMinToDump = minToDump;
+ }
+ ~SkAutoTime()
+ {
+ SkMSec dur = SkTime::GetMSecs() - fNow;
+ if (dur >= fMinToDump) {
+ SkDebugf("%s %d\n", fLabel ? fLabel : "", dur);
+ }
+ }
+private:
+ const char* fLabel;
+ SkMSec fNow;
+ SkMSec fMinToDump;
+};
+#define SkAutoTime(...) SK_REQUIRE_LOCAL_VAR(SkAutoTime)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTypeface.h b/src/third_party/skia/include/core/SkTypeface.h
new file mode 100644
index 0000000..a080d84
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTypeface.h
@@ -0,0 +1,365 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTypeface_DEFINED
+#define SkTypeface_DEFINED
+
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkWeakRefCnt.h"
+
+class SkDescriptor;
+class SkFontDescriptor;
+class SkScalerContext;
+struct SkScalerContextRec;
+class SkStream;
+class SkAdvancedTypefaceMetrics;
+class SkWStream;
+
+typedef uint32_t SkFontID;
+/** Machine endian. */
+typedef uint32_t SkFontTableTag;
+
+/** \class SkTypeface
+
+ The SkTypeface class specifies the typeface and intrinsic style of a font.
+ This is used in the paint, along with optionally algorithmic settings like
+ textSize, textSkewX, textScaleX, kFakeBoldText_Mask, to specify
+ how text appears when drawn (and measured).
+
+ Typeface objects are immutable, and so they can be shared between threads.
+*/
+class SK_API SkTypeface : public SkWeakRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkTypeface)
+
+ /** Style specifies the intrinsic style attributes of a given typeface
+ */
+ enum Style {
+ kNormal = 0,
+ kBold = 0x01,
+ kItalic = 0x02,
+
+ // helpers
+ kBoldItalic = 0x03
+ };
+
+ /** Returns the typeface's intrinsic style attributes
+ */
+ Style style() const { return fStyle; }
+
+ /** Returns true if getStyle() has the kBold bit set.
+ */
+ bool isBold() const { return (fStyle & kBold) != 0; }
+
+ /** Returns true if getStyle() has the kItalic bit set.
+ */
+ bool isItalic() const { return (fStyle & kItalic) != 0; }
+
+ /** Returns true if the typeface claims to be fixed-pitch.
+ * This is a style bit, advance widths may vary even if this returns true.
+ */
+ bool isFixedPitch() const { return fIsFixedPitch; }
+
+ /** Return a 32bit value for this typeface, unique for the underlying font
+ data. Will never return 0.
+ */
+ SkFontID uniqueID() const { return fUniqueID; }
+
+ /** Return the uniqueID for the specified typeface. If the face is null,
+ resolve it to the default font and return its uniqueID. Will never
+ return 0.
+ */
+ static SkFontID UniqueID(const SkTypeface* face);
+
+ /** Returns true if the two typefaces reference the same underlying font,
+ handling either being null (treating null as the default font)
+ */
+ static bool Equal(const SkTypeface* facea, const SkTypeface* faceb);
+
+ /**
+ * Returns a ref() to the default typeface. The caller must call unref()
+ * when they are done referencing the object. Never returns NULL.
+ */
+ static SkTypeface* RefDefault(Style style = SkTypeface::kNormal);
+
+ /** Return a new reference to the typeface that most closely matches the
+ requested familyName and style. Pass null as the familyName to return
+ the default font for the requested style. Will never return null
+
+ @param familyName May be NULL. The name of the font family.
+ @param style The style (normal, bold, italic) of the typeface.
+ @return reference to the closest-matching typeface. Call must call
+ unref() when they are done.
+ */
+ static SkTypeface* CreateFromName(const char familyName[], Style style);
+
+ /** 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.
+ If family is NULL, this selects from the default font's family.
+
+ @param family May be NULL. The name of the existing type face.
+ @param s The style (normal, bold, italic) of the type face.
+ @return reference to the closest-matching typeface. Call must call
+ unref() when they are done.
+ */
+ static SkTypeface* CreateFromTypeface(const SkTypeface* family, Style s);
+
+ /** Return a new typeface given a file. If the file does not exist, or is
+ not a valid font file, returns null.
+ */
+ static SkTypeface* CreateFromFile(const char path[], int index = 0);
+
+ /** Return a new typeface given a stream. If the stream is
+ not a valid font file, returns null. Ownership of the stream is
+ transferred, so the caller must not reference it again.
+ */
+ static SkTypeface* CreateFromStream(SkStream* stream, int index = 0);
+
+ /** Write a unique signature to a stream, sufficient to reconstruct a
+ typeface referencing the same font when Deserialize is called.
+ */
+ void serialize(SkWStream*) const;
+
+ /** Given the data previously written by serialize(), return a new instance
+ to a typeface referring to the same font. If that font is not available,
+ return null. If an instance is returned, the caller is responsible for
+ calling unref() when they are done with it.
+ */
+ static SkTypeface* Deserialize(SkStream*);
+
+ enum Encoding {
+ kUTF8_Encoding,
+ kUTF16_Encoding,
+ kUTF32_Encoding
+ };
+
+ /**
+ * Given an array of character codes, of the specified encoding,
+ * optionally return their corresponding glyph IDs (if glyphs is not NULL).
+ *
+ * @param chars pointer to the array of character codes
+ * @param encoding how the characters are encoded
+ * @param glyphs (optional) returns the corresponding glyph IDs for each
+ * character code, up to glyphCount values. If a character code is
+ * not found in the typeface, the corresponding glyph ID will be 0.
+ * @param glyphCount number of code points in 'chars' to process. If glyphs
+ * is not NULL, then it must point sufficient memory to write
+ * glyphCount values into it.
+ * @return the number of number of continuous non-zero glyph IDs computed
+ * from the beginning of chars. This value is valid, even if the
+ * glyphs parameter is NULL.
+ */
+ int charsToGlyphs(const void* chars, Encoding encoding, uint16_t glyphs[],
+ int glyphCount) const;
+
+ /**
+ * Return the number of glyphs in the typeface.
+ */
+ int countGlyphs() const;
+
+ // Table getters -- may fail if the underlying font format is not organized
+ // as 4-byte tables.
+
+ /** Return the number of tables in the font. */
+ int countTables() const;
+
+ /** Copy into tags[] (allocated by the caller) the list of table tags in
+ * the font, and return the number. This will be the same as CountTables()
+ * or 0 if an error occured. If tags == NULL, this only returns the count
+ * (the same as calling countTables()).
+ */
+ int getTableTags(SkFontTableTag tags[]) const;
+
+ /** Given a table tag, return the size of its contents, or 0 if not present
+ */
+ size_t getTableSize(SkFontTableTag) const;
+
+ /** Copy the contents of a table into data (allocated by the caller). Note
+ * that the contents of the table will be in their native endian order
+ * (which for most truetype tables is big endian). If the table tag is
+ * not found, or there is an error copying the data, then 0 is returned.
+ * If this happens, it is possible that some or all of the memory pointed
+ * to by data may have been written to, even though an error has occured.
+ *
+ * @param fontID the font to copy the table from
+ * @param tag The table tag whose contents are to be copied
+ * @param offset The offset in bytes into the table's contents where the
+ * copy should start from.
+ * @param length The number of bytes, starting at offset, of table data
+ * to copy.
+ * @param data storage address where the table contents are copied to
+ * @return the number of bytes actually copied into data. If offset+length
+ * exceeds the table's size, then only the bytes up to the table's
+ * size are actually copied, and this is the value returned. If
+ * offset > the table's size, or tag is not a valid table,
+ * then 0 is returned.
+ */
+ size_t getTableData(SkFontTableTag tag, size_t offset, size_t length,
+ void* data) const;
+
+ /**
+ * Return the units-per-em value for this typeface, or zero if there is an
+ * error.
+ */
+ int getUnitsPerEm() const;
+
+ /**
+ * Given a run of glyphs, return the associated horizontal adjustments.
+ * Adjustments are in "design units", which are integers relative to the
+ * typeface's units per em (see getUnitsPerEm).
+ *
+ * Some typefaces are known to never support kerning. Calling this method
+ * with all zeros (e.g. getKerningPairAdustments(NULL, 0, NULL)) returns
+ * a boolean indicating if the typeface might support kerning. If it
+ * returns false, then it will always return false (no kerning) for all
+ * possible glyph runs. If it returns true, then it *may* return true for
+ * somne glyph runs.
+ *
+ * If count is non-zero, then the glyphs parameter must point to at least
+ * [count] valid glyph IDs, and the adjustments parameter must be
+ * sized to at least [count - 1] entries. If the method returns true, then
+ * [count-1] entries in the adjustments array will be set. If the method
+ * returns false, then no kerning should be applied, and the adjustments
+ * array will be in an undefined state (possibly some values may have been
+ * written, but none of them should be interpreted as valid values).
+ */
+ bool getKerningPairAdjustments(const uint16_t glyphs[], int count,
+ int32_t adjustments[]) const;
+
+ struct LocalizedString {
+ SkString fString;
+ SkString fLanguage;
+ };
+ class LocalizedStrings : ::SkNoncopyable {
+ public:
+ virtual ~LocalizedStrings() { }
+ virtual bool next(LocalizedString* localizedString) = 0;
+ void unref() { SkDELETE(this); }
+ };
+ /**
+ * Returns an iterator which will attempt to enumerate all of the
+ * family names specified by the font.
+ * It is the caller's responsibility to unref() the returned pointer.
+ */
+ LocalizedStrings* createFamilyNameIterator() const;
+
+ /**
+ * Return the family name for this typeface. It will always be returned
+ * encoded as UTF8, but the language of the name is whatever the host
+ * platform chooses.
+ */
+ void getFamilyName(SkString* name) const;
+
+ /**
+ * Return a stream for the contents of the font data, or NULL on failure.
+ * If ttcIndex is not null, it is set to the TrueTypeCollection index
+ * of this typeface within the stream, or 0 if the stream is not a
+ * collection.
+ */
+ SkStream* openStream(int* ttcIndex) const;
+
+ /**
+ * Return a scalercontext for the given descriptor. If this fails, then
+ * if allowFailure is true, this returns NULL, else it returns a
+ * dummy scalercontext that will not crash, but will draw nothing.
+ */
+ SkScalerContext* createScalerContext(const SkDescriptor*,
+ bool allowFailure = false) const;
+
+ // PRIVATE / EXPERIMENTAL -- do not call
+ void filterRec(SkScalerContextRec* rec) const {
+ this->onFilterRec(rec);
+ }
+ // PRIVATE / EXPERIMENTAL -- do not call
+ void getFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
+ this->onGetFontDescriptor(desc, isLocal);
+ }
+
+protected:
+ /** uniqueID must be unique and non-zero
+ */
+ SkTypeface(Style style, SkFontID uniqueID, bool isFixedPitch = false);
+ virtual ~SkTypeface();
+
+ /** Sets the fixedPitch bit. If used, must be called in the constructor. */
+ void setIsFixedPitch(bool isFixedPitch) { fIsFixedPitch = isFixedPitch; }
+
+ friend class SkScalerContext;
+ static SkTypeface* GetDefaultTypeface(Style style = SkTypeface::kNormal);
+
+ virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const = 0;
+ virtual void onFilterRec(SkScalerContextRec*) const = 0;
+ virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+ const uint32_t* glyphIDs,
+ uint32_t glyphIDsCount) const = 0;
+
+ virtual SkStream* onOpenStream(int* ttcIndex) const = 0;
+ virtual void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const = 0;
+
+ virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
+ int glyphCount) const = 0;
+ virtual int onCountGlyphs() const = 0;
+
+ virtual int onGetUPEM() const = 0;
+ virtual bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
+ int32_t adjustments[]) const;
+
+ /** Returns the family name of the typeface as known by its font manager.
+ * This name may or may not be produced by the family name iterator.
+ */
+ virtual void onGetFamilyName(SkString* familyName) const = 0;
+
+ /** Returns an iterator over the family names in the font. */
+ virtual LocalizedStrings* onCreateFamilyNameIterator() const = 0;
+
+ virtual int onGetTableTags(SkFontTableTag tags[]) const = 0;
+ virtual size_t onGetTableData(SkFontTableTag, size_t offset,
+ size_t length, void* data) const = 0;
+
+private:
+ friend class SkGTypeface;
+ friend class SkPDFFont;
+ friend class SkPDFCIDFont;
+ friend class GrPathRendering;
+ friend class GrGLPathRendering;
+
+ /** Retrieve detailed typeface metrics. Used by the PDF backend.
+ @param perGlyphInfo Indicate what glyph specific information (advances,
+ names, etc.) should be populated.
+ @param glyphIDs For per-glyph info, specify subset of the font by
+ giving glyph ids. Each integer represents a glyph
+ id. Passing NULL means all glyphs in the font.
+ @param glyphIDsCount Number of elements in subsetGlyphIds. Ignored if
+ glyphIDs is NULL.
+ @return The returned object has already been referenced.
+ */
+ SkAdvancedTypefaceMetrics* getAdvancedTypefaceMetrics(
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+ const uint32_t* glyphIDs = NULL,
+ uint32_t glyphIDsCount = 0) const;
+
+private:
+ static SkTypeface* CreateDefault(int style); // SkLazyPtr requires an int, not a Style.
+ static void DeleteDefault(SkTypeface*);
+
+ SkFontID fUniqueID;
+ Style fStyle;
+ bool fIsFixedPitch;
+
+ friend class SkPaint;
+ friend class SkGlyphCache; // GetDefaultTypeface
+ // just so deprecated fonthost can call protected methods
+ friend class SkFontHost;
+
+ typedef SkWeakRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkTypes.h b/src/third_party/skia/include/core/SkTypes.h
new file mode 100644
index 0000000..0e9e230
--- /dev/null
+++ b/src/third_party/skia/include/core/SkTypes.h
@@ -0,0 +1,677 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTypes_DEFINED
+#define SkTypes_DEFINED
+
+#include "SkPreConfig.h"
+#include "SkUserConfig.h"
+#include "SkPostConfig.h"
+#include <stdint.h>
+
+/** \file SkTypes.h
+*/
+
+/** See SkGraphics::GetVersion() to retrieve these at runtime
+ */
+#define SKIA_VERSION_MAJOR 1
+#define SKIA_VERSION_MINOR 0
+#define SKIA_VERSION_PATCH 0
+
+/*
+ memory wrappers to be implemented by the porting layer (platform)
+*/
+
+/** Called internally if we run out of memory. The platform implementation must
+ not return, but should either throw an exception or otherwise exit.
+*/
+SK_API extern void sk_out_of_memory(void);
+/** Called internally if we hit an unrecoverable error.
+ The platform implementation must not return, but should either throw
+ an exception or otherwise exit.
+*/
+SK_API extern void sk_throw(void);
+
+enum {
+ SK_MALLOC_TEMP = 0x01, //!< hint to sk_malloc that the requested memory will be freed in the scope of the stack frame
+ SK_MALLOC_THROW = 0x02 //!< instructs sk_malloc to call sk_throw if the memory cannot be allocated.
+};
+/** Return a block of memory (at least 4-byte aligned) of at least the
+ specified size. If the requested memory cannot be returned, either
+ return null (if SK_MALLOC_TEMP bit is clear) or throw an exception
+ (if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free().
+*/
+SK_API extern void* sk_malloc_flags(size_t size, unsigned flags);
+/** Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag
+*/
+SK_API extern void* sk_malloc_throw(size_t size);
+/** Same as standard realloc(), but this one never returns null on failure. It will throw
+ an exception if it fails.
+*/
+SK_API extern void* sk_realloc_throw(void* buffer, size_t size);
+/** Free memory returned by sk_malloc(). It is safe to pass null.
+*/
+SK_API extern void sk_free(void*);
+
+/** Much like calloc: returns a pointer to at least size zero bytes, or NULL on failure.
+ */
+SK_API extern void* sk_calloc(size_t size);
+
+/** Same as sk_calloc, but throws an exception instead of returning NULL on failure.
+ */
+SK_API extern void* sk_calloc_throw(size_t size);
+
+// bzero is safer than memset, but we can't rely on it, so... sk_bzero()
+static inline void sk_bzero(void* buffer, size_t size) {
+ memset(buffer, 0, size);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_OVERRIDE_GLOBAL_NEW
+#include <new>
+
+inline void* operator new(size_t size) {
+ return sk_malloc_throw(size);
+}
+
+inline void operator delete(void* p) {
+ sk_free(p);
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define SK_INIT_TO_AVOID_WARNING = 0
+
+#ifndef SkDebugf
+ SK_API void SkDebugf(const char format[], ...);
+#endif
+
+#ifdef SK_DEBUG
+ #define SkASSERT(cond) SK_ALWAYSBREAK(cond)
+ #define SkDEBUGFAIL(message) SkASSERT(false && message)
+ #define SkDEBUGCODE(code) code
+ #define SkDECLAREPARAM(type, var) , type var
+ #define SkPARAM(var) , var
+// #define SkDEBUGF(args ) SkDebugf##args
+ #define SkDEBUGF(args ) SkDebugf args
+ #define SkAssertResult(cond) SkASSERT(cond)
+#else
+ #define SkASSERT(cond)
+ #define SkDEBUGFAIL(message)
+ #define SkDEBUGCODE(code)
+ #define SkDEBUGF(args)
+ #define SkDECLAREPARAM(type, var)
+ #define SkPARAM(var)
+
+ // unlike SkASSERT, this guy executes its condition in the non-debug build
+ #define SkAssertResult(cond) cond
+#endif
+
+#define SkFAIL(message) SK_ALWAYSBREAK(false && message)
+
+// We want to evaluate cond only once, and inside the SkASSERT somewhere so we see its string form.
+// So we use the comma operator to make an SkDebugf that always returns false: we'll evaluate cond,
+// and if it's true the assert passes; if it's false, we'll print the message and the assert fails.
+#define SkASSERTF(cond, fmt, ...) SkASSERT((cond) || (SkDebugf(fmt"\n", __VA_ARGS__), false))
+
+#ifdef SK_DEVELOPER
+ #define SkDEVCODE(code) code
+#else
+ #define SkDEVCODE(code)
+#endif
+
+#ifdef SK_IGNORE_TO_STRING
+ #define SK_TO_STRING_NONVIRT()
+ #define SK_TO_STRING_VIRT()
+ #define SK_TO_STRING_PUREVIRT()
+ #define SK_TO_STRING_OVERRIDE()
+#else
+ // the 'toString' helper functions convert Sk* objects to human-readable
+ // form in developer mode
+ #define SK_TO_STRING_NONVIRT() void toString(SkString* str) const;
+ #define SK_TO_STRING_VIRT() virtual void toString(SkString* str) const;
+ #define SK_TO_STRING_PUREVIRT() virtual void toString(SkString* str) const = 0;
+ #define SK_TO_STRING_OVERRIDE() virtual void toString(SkString* str) const SK_OVERRIDE;
+#endif
+
+template <bool>
+struct SkCompileAssert {
+};
+
+// Uses static_cast<bool>(expr) instead of bool(expr) due to
+// https://connect.microsoft.com/VisualStudio/feedback/details/832915
+
+// The extra parentheses in SkCompileAssert<(...)> are a work around for
+// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57771
+// which was fixed in gcc 4.8.2.
+#define SK_COMPILE_ASSERT(expr, msg) \
+ typedef SkCompileAssert<(static_cast<bool>(expr))> \
+ msg[static_cast<bool>(expr) ? 1 : -1] SK_UNUSED
+
+/*
+ * Usage: SK_MACRO_CONCAT(a, b) to construct the symbol ab
+ *
+ * SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
+ *
+ */
+#define SK_MACRO_CONCAT(X, Y) SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
+#define SK_MACRO_CONCAT_IMPL_PRIV(X, Y) X ## Y
+
+/*
+ * Usage: SK_MACRO_APPEND_LINE(foo) to make foo123, where 123 is the current
+ * line number. Easy way to construct
+ * unique names for local functions or
+ * variables.
+ */
+#define SK_MACRO_APPEND_LINE(name) SK_MACRO_CONCAT(name, __LINE__)
+
+/**
+ * For some classes, it's almost always an error to instantiate one without a name, e.g.
+ * {
+ * SkAutoMutexAcquire(&mutex);
+ * <some code>
+ * }
+ * In this case, the writer meant to hold mutex while the rest of the code in the block runs,
+ * but instead the mutex is acquired and then immediately released. The correct usage is
+ * {
+ * SkAutoMutexAcquire lock(&mutex);
+ * <some code>
+ * }
+ *
+ * To prevent callers from instantiating your class without a name, use SK_REQUIRE_LOCAL_VAR
+ * like this:
+ * class classname {
+ * <your class>
+ * };
+ * #define classname(...) SK_REQUIRE_LOCAL_VAR(classname)
+ *
+ * This won't work with templates, and you must inline the class' constructors and destructors.
+ * Take a look at SkAutoFree and SkAutoMalloc in this file for examples.
+ */
+#define SK_REQUIRE_LOCAL_VAR(classname) \
+ SK_COMPILE_ASSERT(false, missing_name_for_##classname)
+
+///////////////////////////////////////////////////////////////////////
+
+/**
+ * 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 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
+ SK_API int8_t SkToS8(intmax_t);
+ SK_API uint8_t SkToU8(uintmax_t);
+ SK_API int16_t SkToS16(intmax_t);
+ SK_API uint16_t SkToU16(uintmax_t);
+ SK_API int32_t SkToS32(intmax_t);
+ SK_API uint32_t SkToU32(uintmax_t);
+ SK_API int SkToInt(intmax_t);
+ SK_API unsigned SkToUInt(uintmax_t);
+ SK_API size_t SkToSizeT(uintmax_t);
+#else
+ #define SkToS8(x) ((int8_t)(x))
+ #define SkToU8(x) ((uint8_t)(x))
+ #define SkToS16(x) ((int16_t)(x))
+ #define SkToU16(x) ((uint16_t)(x))
+ #define SkToS32(x) ((int32_t)(x))
+ #define SkToU32(x) ((uint32_t)(x))
+ #define SkToInt(x) ((int)(x))
+ #define SkToUInt(x) ((unsigned)(x))
+ #define SkToSizeT(x) ((size_t)(x))
+#endif
+
+/** Returns 0 or 1 based on the condition
+*/
+#define SkToBool(cond) ((cond) != 0)
+
+#define SK_MaxS16 32767
+#define SK_MinS16 -32767
+#define SK_MaxU16 0xFFFF
+#define SK_MinU16 0
+#define SK_MaxS32 0x7FFFFFFF
+#define SK_MinS32 -SK_MaxS32
+#define SK_MaxU32 0xFFFFFFFF
+#define SK_MinU32 0
+#define SK_NaN32 (1 << 31)
+
+/** Returns true if the value can be represented with signed 16bits
+ */
+static inline bool SkIsS16(long x) {
+ return (int16_t)x == x;
+}
+
+/** Returns true if the value can be represented with unsigned 16bits
+ */
+static inline bool SkIsU16(long x) {
+ return (uint16_t)x == x;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+#ifndef SK_OFFSETOF
+ #define SK_OFFSETOF(type, field) (size_t)((char*)&(((type*)1)->field) - (char*)1)
+#endif
+
+/** Returns the number of entries in an array (not a pointer)
+*/
+#define SK_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+
+#define SkAlign2(x) (((x) + 1) >> 1 << 1)
+#define SkIsAlign2(x) (0 == ((x) & 1))
+
+#define SkAlign4(x) (((x) + 3) >> 2 << 2)
+#define SkIsAlign4(x) (0 == ((x) & 3))
+
+#define SkAlign8(x) (((x) + 7) >> 3 << 3)
+#define SkIsAlign8(x) (0 == ((x) & 7))
+
+#define SkAlignPtr(x) (sizeof(void*) == 8 ? SkAlign8(x) : SkAlign4(x))
+#define SkIsAlignPtr(x) (sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x))
+
+typedef uint32_t SkFourByteTag;
+#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+
+/** 32 bit integer to hold a unicode value
+*/
+typedef int32_t SkUnichar;
+/** 32 bit value to hold a millisecond count
+*/
+typedef uint32_t SkMSec;
+/** 1 second measured in milliseconds
+*/
+#define SK_MSec1 1000
+/** maximum representable milliseconds
+*/
+#define SK_MSecMax 0x7FFFFFFF
+/** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
+*/
+#define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0)
+/** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
+*/
+#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
+
+/** The generation IDs in Skia reserve 0 has an invalid marker.
+ */
+#define SK_InvalidGenID 0
+/** The unique IDs in Skia reserve 0 has an invalid marker.
+ */
+#define SK_InvalidUniqueID 0
+
+/****************************************************************************
+ The rest of these only build with C++
+*/
+#ifdef __cplusplus
+
+/** Faster than SkToBool for integral conditions. Returns 0 or 1
+*/
+static inline int Sk32ToBool(uint32_t n) {
+ return (n | (0-n)) >> 31;
+}
+
+/** Generic swap function. Classes with efficient swaps should specialize this function to take
+ their fast path. This function is used by SkTSort. */
+template <typename T> inline void SkTSwap(T& a, T& b) {
+ T c(a);
+ a = b;
+ b = c;
+}
+
+static inline int32_t SkAbs32(int32_t value) {
+ if (value < 0) {
+ value = -value;
+ }
+ return value;
+}
+
+template <typename T> inline T SkTAbs(T value) {
+ if (value < 0) {
+ value = -value;
+ }
+ return value;
+}
+
+static inline int32_t SkMax32(int32_t a, int32_t b) {
+ if (a < b)
+ a = b;
+ return a;
+}
+
+static inline int32_t SkMin32(int32_t a, int32_t b) {
+ if (a > b)
+ a = b;
+ return a;
+}
+
+template <typename T> const T& SkTMin(const T& a, const T& b) {
+ return (a < b) ? a : b;
+}
+
+template <typename T> const T& SkTMax(const T& a, const T& b) {
+ return (b < a) ? a : b;
+}
+
+static inline int32_t SkSign32(int32_t a) {
+ return (a >> 31) | ((unsigned) -a >> 31);
+}
+
+static inline int32_t SkFastMin32(int32_t value, int32_t max) {
+ if (value > max) {
+ value = max;
+ }
+ return value;
+}
+
+/** Returns signed 32 bit value pinned between min and max, inclusively
+*/
+static inline int32_t SkPin32(int32_t value, int32_t min, int32_t max) {
+ if (value < min) {
+ value = min;
+ }
+ if (value > max) {
+ value = max;
+ }
+ return value;
+}
+
+static inline uint32_t SkSetClearShift(uint32_t bits, bool cond,
+ unsigned shift) {
+ SkASSERT((int)cond == 0 || (int)cond == 1);
+ return (bits & ~(1 << shift)) | ((int)cond << shift);
+}
+
+static inline uint32_t SkSetClearMask(uint32_t bits, bool cond,
+ uint32_t mask) {
+ return cond ? bits | mask : bits & ~mask;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** Use to combine multiple bits in a bitmask in a type safe way.
+ */
+template <typename T>
+T SkTBitOr(T a, T b) {
+ return (T)(a | b);
+}
+
+/**
+ * Use to cast a pointer to a different type, and maintaining strict-aliasing
+ */
+template <typename Dst> Dst SkTCast(const void* ptr) {
+ union {
+ const void* src;
+ Dst dst;
+ } data;
+ data.src = ptr;
+ return data.dst;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/** \class SkNoncopyable
+
+SkNoncopyable is the base class for objects that may do not want to
+be copied. It hides its copy-constructor and its assignment-operator.
+*/
+class SK_API SkNoncopyable {
+public:
+ SkNoncopyable() {}
+
+private:
+ SkNoncopyable(const SkNoncopyable&);
+ SkNoncopyable& operator=(const SkNoncopyable&);
+};
+
+class SkAutoFree : SkNoncopyable {
+public:
+ SkAutoFree() : fPtr(NULL) {}
+ explicit SkAutoFree(void* ptr) : fPtr(ptr) {}
+ ~SkAutoFree() { sk_free(fPtr); }
+
+ /** Return the currently allocate buffer, or null
+ */
+ void* get() const { return fPtr; }
+
+ /** Assign a new ptr allocated with sk_malloc (or null), and return the
+ previous ptr. Note it is the caller's responsibility to sk_free the
+ returned ptr.
+ */
+ void* set(void* ptr) {
+ void* prev = fPtr;
+ fPtr = ptr;
+ return prev;
+ }
+
+ /** Transfer ownership of the current ptr to the caller, setting the
+ internal reference to null. Note the caller is reponsible for calling
+ sk_free on the returned address.
+ */
+ void* detach() { return this->set(NULL); }
+
+ /** Free the current buffer, and set the internal reference to NULL. Same
+ as calling sk_free(detach())
+ */
+ void free() {
+ sk_free(fPtr);
+ fPtr = NULL;
+ }
+
+private:
+ void* fPtr;
+ // illegal
+ SkAutoFree(const SkAutoFree&);
+ SkAutoFree& operator=(const SkAutoFree&);
+};
+#define SkAutoFree(...) SK_REQUIRE_LOCAL_VAR(SkAutoFree)
+
+/**
+ * Manage an allocated block of heap memory. This object is the sole manager of
+ * the lifetime of the block, so the caller must not call sk_free() or delete
+ * on the block, unless detach() was called.
+ */
+class SkAutoMalloc : SkNoncopyable {
+public:
+ explicit SkAutoMalloc(size_t size = 0) {
+ fPtr = size ? sk_malloc_throw(size) : NULL;
+ fSize = size;
+ }
+
+ ~SkAutoMalloc() {
+ sk_free(fPtr);
+ }
+
+ /**
+ * Passed to reset to specify what happens if the requested size is smaller
+ * than the current size (and the current block was dynamically allocated).
+ */
+ enum OnShrink {
+ /**
+ * If the requested size is smaller than the current size, and the
+ * current block is dynamically allocated, free the old block and
+ * malloc a new block of the smaller size.
+ */
+ kAlloc_OnShrink,
+
+ /**
+ * If the requested size is smaller than the current size, and the
+ * current block is dynamically allocated, just return the old
+ * block.
+ */
+ kReuse_OnShrink
+ };
+
+ /**
+ * Reallocates the block to a new size. The ptr may or may not change.
+ */
+ void* reset(size_t size, OnShrink shrink = kAlloc_OnShrink, bool* didChangeAlloc = NULL) {
+ if (size == fSize || (kReuse_OnShrink == shrink && size < fSize)) {
+ if (didChangeAlloc) {
+ *didChangeAlloc = false;
+ }
+ return fPtr;
+ }
+
+ sk_free(fPtr);
+ fPtr = size ? sk_malloc_throw(size) : NULL;
+ fSize = size;
+ if (didChangeAlloc) {
+ *didChangeAlloc = true;
+ }
+
+ return fPtr;
+ }
+
+ /**
+ * Releases the block back to the heap
+ */
+ void free() {
+ this->reset(0);
+ }
+
+ /**
+ * Return the allocated block.
+ */
+ void* get() { return fPtr; }
+ const void* get() const { return fPtr; }
+
+ /** Transfer ownership of the current ptr to the caller, setting the
+ internal reference to null. Note the caller is reponsible for calling
+ sk_free on the returned address.
+ */
+ void* detach() {
+ void* ptr = fPtr;
+ fPtr = NULL;
+ fSize = 0;
+ return ptr;
+ }
+
+private:
+ void* fPtr;
+ size_t fSize; // can be larger than the requested size (see kReuse)
+};
+#define SkAutoMalloc(...) SK_REQUIRE_LOCAL_VAR(SkAutoMalloc)
+
+/**
+ * Manage an allocated block of memory. If the requested size is <= kSize, then
+ * the allocation will come from the stack rather than the heap. This object
+ * is the sole manager of the lifetime of the block, so the caller must not
+ * call sk_free() or delete on the block.
+ */
+template <size_t kSize> class SkAutoSMalloc : SkNoncopyable {
+public:
+ /**
+ * Creates initially empty storage. get() returns a ptr, but it is to
+ * a zero-byte allocation. Must call reset(size) to return an allocated
+ * block.
+ */
+ SkAutoSMalloc() {
+ fPtr = fStorage;
+ fSize = kSize;
+ }
+
+ /**
+ * Allocate a block of the specified size. If size <= kSize, then the
+ * allocation will come from the stack, otherwise it will be dynamically
+ * allocated.
+ */
+ explicit SkAutoSMalloc(size_t size) {
+ fPtr = fStorage;
+ fSize = kSize;
+ this->reset(size);
+ }
+
+ /**
+ * Free the allocated block (if any). If the block was small enought to
+ * have been allocated on the stack (size <= kSize) then this does nothing.
+ */
+ ~SkAutoSMalloc() {
+ if (fPtr != (void*)fStorage) {
+ sk_free(fPtr);
+ }
+ }
+
+ /**
+ * Return the allocated block. May return non-null even if the block is
+ * of zero size. Since this may be on the stack or dynamically allocated,
+ * the caller must not call sk_free() on it, but must rely on SkAutoSMalloc
+ * to manage it.
+ */
+ void* get() const { return fPtr; }
+
+ /**
+ * Return a new block of the requested size, freeing (as necessary) any
+ * previously allocated block. As with the constructor, if size <= kSize
+ * then the return block may be allocated locally, rather than from the
+ * heap.
+ */
+ void* reset(size_t size,
+ SkAutoMalloc::OnShrink shrink = SkAutoMalloc::kAlloc_OnShrink,
+ bool* didChangeAlloc = NULL) {
+ size = (size < kSize) ? kSize : size;
+ bool alloc = size != fSize && (SkAutoMalloc::kAlloc_OnShrink == shrink || size > fSize);
+ if (didChangeAlloc) {
+ *didChangeAlloc = alloc;
+ }
+ if (alloc) {
+ if (fPtr != (void*)fStorage) {
+ sk_free(fPtr);
+ }
+
+ if (size == kSize) {
+ SkASSERT(fPtr != fStorage); // otherwise we lied when setting didChangeAlloc.
+ fPtr = fStorage;
+ } else {
+ fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
+ }
+
+ fSize = size;
+ }
+ SkASSERT(fSize >= size && fSize >= kSize);
+ SkASSERT((fPtr == fStorage) || fSize > kSize);
+ return fPtr;
+ }
+
+private:
+ void* fPtr;
+ size_t fSize; // can be larger than the requested size (see kReuse)
+ uint32_t fStorage[(kSize + 3) >> 2];
+};
+// Can't guard the constructor because it's a template class.
+
+#endif /* C++ */
+
+#endif
diff --git a/src/third_party/skia/include/core/SkUnPreMultiply.h b/src/third_party/skia/include/core/SkUnPreMultiply.h
new file mode 100644
index 0000000..16181ce
--- /dev/null
+++ b/src/third_party/skia/include/core/SkUnPreMultiply.h
@@ -0,0 +1,58 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+
+
+#ifndef SkUnPreMultiply_DEFINED
+#define SkUnPreMultiply_DEFINED
+
+#include "SkColor.h"
+
+class SK_API SkUnPreMultiply {
+public:
+ typedef uint32_t Scale;
+
+ // index this table with alpha [0..255]
+ static const Scale* GetScaleTable() {
+ return gTable;
+ }
+
+ static Scale GetScale(U8CPU alpha) {
+ SkASSERT(alpha <= 255);
+ return gTable[alpha];
+ }
+
+ /** Usage:
+
+ const Scale* table = SkUnPreMultiply::GetScaleTable();
+
+ for (...) {
+ unsigned a = ...
+ SkUnPreMultiply::Scale scale = table[a];
+
+ red = SkUnPreMultiply::ApplyScale(scale, red);
+ ...
+ // now red is unpremultiplied
+ }
+ */
+ static U8CPU ApplyScale(Scale scale, U8CPU component) {
+ SkASSERT(component <= 255);
+ return (scale * component + (1 << 23)) >> 24;
+ }
+
+ static SkColor PMColorToColor(SkPMColor c);
+
+ static uint32_t UnPreMultiplyPreservingByteOrder(SkPMColor c);
+
+private:
+ static const uint32_t gTable[256];
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkUtils.h b/src/third_party/skia/include/core/SkUtils.h
new file mode 100644
index 0000000..d522ae0
--- /dev/null
+++ b/src/third_party/skia/include/core/SkUtils.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkUtils_DEFINED
+#define SkUtils_DEFINED
+
+#include "SkTypes.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** Similar to memset(), but it assigns a 16bit value into the buffer.
+ @param buffer The memory to have value copied into it
+ @param value The 16bit value to be copied into buffer
+ @param count The number of times value should be copied into the buffer.
+*/
+void sk_memset16(uint16_t dst[], uint16_t value, int count);
+typedef void (*SkMemset16Proc)(uint16_t dst[], uint16_t value, int count);
+SkMemset16Proc SkMemset16GetPlatformProc();
+
+/** Similar to memset(), but it assigns a 32bit value into the buffer.
+ @param buffer The memory to have value copied into it
+ @param value The 32bit value to be copied into buffer
+ @param count The number of times value should be copied into the buffer.
+*/
+void sk_memset32(uint32_t dst[], uint32_t value, int count);
+typedef void (*SkMemset32Proc)(uint32_t dst[], uint32_t value, int count);
+SkMemset32Proc SkMemset32GetPlatformProc();
+
+/** Similar to memcpy(), but it copies count 32bit values from src to dst.
+ @param dst The memory to have value copied into it
+ @param src The memory to have value copied from it
+ @param count The number of values should be copied.
+*/
+void sk_memcpy32(uint32_t dst[], const uint32_t src[], int count);
+typedef void (*SkMemcpy32Proc)(uint32_t dst[], const uint32_t src[], int count);
+SkMemcpy32Proc SkMemcpy32GetPlatformProc();
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define kMaxBytesInUTF8Sequence 4
+
+#ifdef SK_DEBUG
+ int SkUTF8_LeadByteToCount(unsigned c);
+#else
+ #define SkUTF8_LeadByteToCount(c) ((((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1)
+#endif
+
+inline int SkUTF8_CountUTF8Bytes(const char utf8[]) {
+ SkASSERT(utf8);
+ return SkUTF8_LeadByteToCount(*(const uint8_t*)utf8);
+}
+
+int SkUTF8_CountUnichars(const char utf8[]);
+int SkUTF8_CountUnichars(const char utf8[], size_t byteLength);
+SkUnichar SkUTF8_ToUnichar(const char utf8[]);
+SkUnichar SkUTF8_NextUnichar(const char**);
+SkUnichar SkUTF8_PrevUnichar(const char**);
+
+/** Return the number of bytes need to convert a unichar
+ into a utf8 sequence. Will be 1..kMaxBytesInUTF8Sequence,
+ or 0 if uni is illegal.
+*/
+size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[] = NULL);
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define SkUTF16_IsHighSurrogate(c) (((c) & 0xFC00) == 0xD800)
+#define SkUTF16_IsLowSurrogate(c) (((c) & 0xFC00) == 0xDC00)
+
+int SkUTF16_CountUnichars(const uint16_t utf16[]);
+int SkUTF16_CountUnichars(const uint16_t utf16[], int numberOf16BitValues);
+// returns the current unichar and then moves past it (*p++)
+SkUnichar SkUTF16_NextUnichar(const uint16_t**);
+// this guy backs up to the previus unichar value, and returns it (*--p)
+SkUnichar SkUTF16_PrevUnichar(const uint16_t**);
+size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t utf16[] = NULL);
+
+size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues,
+ char utf8[] = NULL);
+
+inline bool SkUnichar_IsVariationSelector(SkUnichar uni) {
+/* The 'true' ranges are:
+ * 0x180B <= uni <= 0x180D
+ * 0xFE00 <= uni <= 0xFE0F
+ * 0xE0100 <= uni <= 0xE01EF
+ */
+ if (uni < 0x180B || uni > 0xE01EF) {
+ return false;
+ }
+ if ((uni > 0x180D && uni < 0xFE00) || (uni > 0xFE0F && uni < 0xE0100)) {
+ return false;
+ }
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkAutoTrace {
+public:
+ /** NOTE: label contents are not copied, just the ptr is
+ retained, so DON'T DELETE IT.
+ */
+ SkAutoTrace(const char label[]) : fLabel(label) {
+ SkDebugf("--- trace: %s Enter\n", fLabel);
+ }
+ ~SkAutoTrace() {
+ SkDebugf("--- trace: %s Leave\n", fLabel);
+ }
+private:
+ const char* fLabel;
+};
+#define SkAutoTrace(...) SK_REQUIRE_LOCAL_VAR(SkAutoTrace)
+
+#endif
diff --git a/src/third_party/skia/include/core/SkWeakRefCnt.h b/src/third_party/skia/include/core/SkWeakRefCnt.h
new file mode 100644
index 0000000..210dcc9
--- /dev/null
+++ b/src/third_party/skia/include/core/SkWeakRefCnt.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkWeakRefCnt_DEFINED
+#define SkWeakRefCnt_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkThread.h"
+
+/** \class SkWeakRefCnt
+
+ SkWeakRefCnt is the base class for objects that may be shared by multiple
+ objects. When an existing strong owner wants to share a reference, it calls
+ ref(). When a strong owner wants to release its reference, it calls
+ unref(). When the shared object's strong reference count goes to zero as
+ the result of an unref() call, its (virtual) weak_dispose method is called.
+ It is an error for the destructor to be called explicitly (or via the
+ object going out of scope on the stack or calling delete) if
+ getRefCnt() > 1.
+
+ In addition to strong ownership, an owner may instead obtain a weak
+ reference by calling weak_ref(). A call to weak_ref() must be balanced by a
+ call to weak_unref(). To obtain a strong reference from a weak reference,
+ call try_ref(). If try_ref() returns true, the owner's pointer is now also
+ a strong reference on which unref() must be called. Note that this does not
+ affect the original weak reference, weak_unref() must still be called. When
+ the weak reference count goes to zero, the object is deleted. While the
+ weak reference count is positive and the strong reference count is zero the
+ object still exists, but will be in the disposed state. It is up to the
+ object to define what this means.
+
+ Note that a strong reference implicitly implies a weak reference. As a
+ result, it is allowable for the owner of a strong ref to call try_ref().
+ This will have the same effect as calling ref(), but may be more expensive.
+
+ Example:
+
+ SkWeakRefCnt myRef = strongRef.weak_ref();
+ ... // strongRef.unref() may or may not be called
+ if (myRef.try_ref()) {
+ ... // use myRef
+ myRef.unref();
+ } else {
+ // myRef is in the disposed state
+ }
+ myRef.weak_unref();
+*/
+class SK_API SkWeakRefCnt : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkWeakRefCnt)
+
+ /** Default construct, initializing the reference counts to 1.
+ The strong references collectively hold one weak reference. When the
+ strong reference count goes to zero, the collectively held weak
+ reference is released.
+ */
+ SkWeakRefCnt() : SkRefCnt(), fWeakCnt(1) {}
+
+ /** Destruct, asserting that the weak reference count is 1.
+ */
+ virtual ~SkWeakRefCnt() {
+#ifdef SK_DEBUG
+ SkASSERT(fWeakCnt == 1);
+ fWeakCnt = 0;
+#endif
+ }
+
+ /** Return the weak reference count.
+ */
+ int32_t getWeakCnt() const { return fWeakCnt; }
+
+#ifdef SK_DEBUG
+ void validate() const {
+ this->INHERITED::validate();
+ SkASSERT(fWeakCnt > 0);
+ }
+#endif
+
+ /** Creates a strong reference from a weak reference, if possible. The
+ caller must already be an owner. If try_ref() returns true the owner
+ is in posession of an additional strong reference. Both the original
+ reference and new reference must be properly unreferenced. If try_ref()
+ returns false, no strong reference could be created and the owner's
+ reference is in the same state as before the call.
+ */
+ bool SK_WARN_UNUSED_RESULT try_ref() const {
+ if (sk_atomic_conditional_inc(&fRefCnt) != 0) {
+ // Acquire barrier (L/SL), if not provided above.
+ // Prevents subsequent code from happening before the increment.
+ sk_membar_acquire__after_atomic_conditional_inc();
+ return true;
+ }
+ return false;
+ }
+
+ /** Increment the weak reference count. Must be balanced by a call to
+ weak_unref().
+ */
+ void weak_ref() const {
+ SkASSERT(fRefCnt > 0);
+ SkASSERT(fWeakCnt > 0);
+ sk_atomic_inc(&fWeakCnt); // No barrier required.
+ }
+
+ /** Decrement the weak reference count. If the weak 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 weak_unref() const {
+ SkASSERT(fWeakCnt > 0);
+ // Release barrier (SL/S), if not provided below.
+ if (sk_atomic_dec(&fWeakCnt) == 1) {
+ // Acquire barrier (L/SL), if not provided above.
+ // Prevents code in destructor from happening before the decrement.
+ sk_membar_acquire__after_atomic_dec();
+#ifdef SK_DEBUG
+ // so our destructor won't complain
+ fWeakCnt = 1;
+#endif
+ this->INHERITED::internal_dispose();
+ }
+ }
+
+ /** Returns true if there are no strong references to the object. When this
+ is the case all future calls to try_ref() will return false.
+ */
+ bool weak_expired() const {
+ return fRefCnt == 0;
+ }
+
+protected:
+ /** Called when the strong reference count goes to zero. This allows the
+ object to free any resources it may be holding. Weak references may
+ still exist and their level of allowed access to the object is defined
+ by the object's class.
+ */
+ virtual void weak_dispose() const {
+ }
+
+private:
+ /** Called when the strong reference count goes to zero. Calls weak_dispose
+ on the object and releases the implicit weak reference held
+ collectively by the strong references.
+ */
+ virtual void internal_dispose() const SK_OVERRIDE {
+ weak_dispose();
+ weak_unref();
+ }
+
+ /* Invariant: fWeakCnt = #weak + (fRefCnt > 0 ? 1 : 0) */
+ mutable int32_t fWeakCnt;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkWriteBuffer.h b/src/third_party/skia/include/core/SkWriteBuffer.h
new file mode 100644
index 0000000..04acbf1
--- /dev/null
+++ b/src/third_party/skia/include/core/SkWriteBuffer.h
@@ -0,0 +1,120 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkWriteBuffer_DEFINED
+#define SkWriteBuffer_DEFINED
+
+#include "SkBitmapHeap.h"
+#include "SkData.h"
+#include "SkPath.h"
+#include "SkPicture.h"
+#include "SkRefCnt.h"
+#include "SkWriter32.h"
+
+class SkBitmap;
+class SkFactorySet;
+class SkFlattenable;
+class SkNamedFactorySet;
+class SkRefCntSet;
+
+class SkWriteBuffer {
+public:
+ enum Flags {
+ kCrossProcess_Flag = 1 << 0,
+ kValidation_Flag = 1 << 1,
+ };
+
+ SkWriteBuffer(uint32_t flags = 0);
+ SkWriteBuffer(void* initialStorage, size_t storageSize, uint32_t flags = 0);
+ ~SkWriteBuffer();
+
+ bool isCrossProcess() const {
+ return this->isValidating() || SkToBool(fFlags & kCrossProcess_Flag);
+ }
+
+ SkWriter32* getWriter32() { return &fWriter; }
+ void reset(void* storage = NULL, size_t storageSize = 0) {
+ fWriter.reset(storage, storageSize);
+ }
+
+ uint32_t* reserve(size_t size) { return fWriter.reserve(size); }
+
+ size_t bytesWritten() const { return fWriter.bytesWritten(); }
+
+ void writeByteArray(const void* data, size_t size);
+ void writeDataAsByteArray(SkData* data) { this->writeByteArray(data->data(), data->size()); }
+ void writeBool(bool value);
+ void writeFixed(SkFixed value);
+ void writeScalar(SkScalar value);
+ void writeScalarArray(const SkScalar* value, uint32_t count);
+ void writeInt(int32_t value);
+ void writeIntArray(const int32_t* value, uint32_t count);
+ void writeUInt(uint32_t value);
+ void write32(int32_t value);
+ void writeString(const char* value);
+ void writeEncodedString(const void* value, size_t byteLength, SkPaint::TextEncoding encoding);
+ void writeFunctionPtr(void* ptr) { fWriter.writePtr(ptr); }
+
+ void writeFlattenable(const SkFlattenable* flattenable);
+ void writeColor(const SkColor& color);
+ void writeColorArray(const SkColor* color, uint32_t count);
+ void writePoint(const SkPoint& point);
+ void writePointArray(const SkPoint* point, uint32_t count);
+ void writeMatrix(const SkMatrix& matrix);
+ void writeIRect(const SkIRect& rect);
+ void writeRect(const SkRect& rect);
+ void writeRegion(const SkRegion& region);
+ void writePath(const SkPath& path);
+ size_t writeStream(SkStream* stream, size_t length);
+ void writeBitmap(const SkBitmap& bitmap);
+ void writeTypeface(SkTypeface* typeface);
+ void writePaint(const SkPaint& paint) { paint.flatten(*this); }
+
+ bool writeToStream(SkWStream*);
+ void writeToMemory(void* dst) { fWriter.flatten(dst); }
+
+ SkFactorySet* setFactoryRecorder(SkFactorySet*);
+ SkNamedFactorySet* setNamedFactoryRecorder(SkNamedFactorySet*);
+
+ SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
+ SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
+
+ /**
+ * Set an SkBitmapHeap to store bitmaps rather than flattening.
+ *
+ * Incompatible with an EncodeBitmap function. If an EncodeBitmap function is set, setting an
+ * SkBitmapHeap will set the function to NULL in release mode and crash in debug.
+ */
+ void setBitmapHeap(SkBitmapHeap*);
+
+ /**
+ * Provide a function to encode an SkBitmap to an SkData. writeBitmap will attempt to use
+ * bitmapEncoder to store the SkBitmap. If the reader does not provide a function to decode, it
+ * will not be able to restore SkBitmaps, but will still be able to read the rest of the stream.
+ * bitmapEncoder will never be called with a NULL pixelRefOffset.
+ *
+ * Incompatible with the SkBitmapHeap. If an encoder is set fBitmapHeap will be set to NULL in
+ * release and crash in debug.
+ */
+ void setBitmapEncoder(SkPicture::EncodeBitmap bitmapEncoder);
+
+private:
+ bool isValidating() const { return SkToBool(fFlags & kValidation_Flag); }
+
+ const uint32_t fFlags;
+ SkFactorySet* fFactorySet;
+ SkNamedFactorySet* fNamedFactorySet;
+ SkWriter32 fWriter;
+
+ SkBitmapHeap* fBitmapHeap;
+ SkRefCntSet* fTFSet;
+
+ SkPicture::EncodeBitmap fBitmapEncoder;
+};
+
+#endif // SkWriteBuffer_DEFINED
diff --git a/src/third_party/skia/include/core/SkWriter32.h b/src/third_party/skia/include/core/SkWriter32.h
new file mode 100644
index 0000000..fd24ba9
--- /dev/null
+++ b/src/third_party/skia/include/core/SkWriter32.h
@@ -0,0 +1,281 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkWriter32_DEFINED
+#define SkWriter32_DEFINED
+
+#include "SkData.h"
+#include "SkMatrix.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRRect.h"
+#include "SkRect.h"
+#include "SkRegion.h"
+#include "SkScalar.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+#include "SkTypes.h"
+
+class SK_API SkWriter32 : SkNoncopyable {
+public:
+ /**
+ * The caller can specify an initial block of storage, which the caller manages.
+ *
+ * SkWriter32 will try to back reserve and write calls with this external storage until the
+ * first time an allocation doesn't fit. From then it will use dynamically allocated storage.
+ * This used to be optional behavior, but pipe now relies on it.
+ */
+ SkWriter32(void* external = NULL, size_t externalBytes = 0) {
+ this->reset(external, externalBytes);
+ }
+
+ // return the current offset (will always be a multiple of 4)
+ size_t bytesWritten() const { return fUsed; }
+
+ SK_ATTR_DEPRECATED("use bytesWritten")
+ size_t size() const { return this->bytesWritten(); }
+
+ void reset(void* external = NULL, size_t externalBytes = 0) {
+ SkASSERT(SkIsAlign4((uintptr_t)external));
+ SkASSERT(SkIsAlign4(externalBytes));
+
+ fSnapshot.reset(NULL);
+ fData = (uint8_t*)external;
+ fCapacity = externalBytes;
+ fUsed = 0;
+ fExternal = external;
+ }
+
+ // Returns the current buffer.
+ // The pointer may be invalidated by any future write calls.
+ const uint32_t* contiguousArray() const {
+ return (uint32_t*)fData;
+ }
+
+ // size MUST be multiple of 4
+ uint32_t* reserve(size_t size) {
+ SkASSERT(SkAlign4(size) == size);
+ size_t offset = fUsed;
+ size_t totalRequired = fUsed + size;
+ if (totalRequired > fCapacity) {
+ this->growToAtLeast(totalRequired);
+ }
+ fUsed = totalRequired;
+ return (uint32_t*)(fData + offset);
+ }
+
+ /**
+ * Read a T record at offset, which must be a multiple of 4. Only legal if the record
+ * was written atomically using the write methods below.
+ */
+ template<typename T>
+ const T& readTAt(size_t offset) const {
+ SkASSERT(SkAlign4(offset) == offset);
+ SkASSERT(offset < fUsed);
+ return *(T*)(fData + offset);
+ }
+
+ /**
+ * Overwrite a T record at offset, which must be a multiple of 4. Only legal if the record
+ * was written atomically using the write methods below.
+ */
+ template<typename T>
+ void overwriteTAt(size_t offset, const T& value) {
+ SkASSERT(SkAlign4(offset) == offset);
+ SkASSERT(offset < fUsed);
+ SkASSERT(fSnapshot.get() == NULL);
+ *(T*)(fData + offset) = value;
+ }
+
+ bool writeBool(bool value) {
+ this->write32(value);
+ return value;
+ }
+
+ void writeInt(int32_t value) {
+ this->write32(value);
+ }
+
+ void write8(int32_t value) {
+ *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
+ }
+
+ void write16(int32_t value) {
+ *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
+ }
+
+ void write32(int32_t value) {
+ *(int32_t*)this->reserve(sizeof(value)) = value;
+ }
+
+ void writePtr(void* value) {
+ *(void**)this->reserve(sizeof(value)) = value;
+ }
+
+ void writeScalar(SkScalar value) {
+ *(SkScalar*)this->reserve(sizeof(value)) = value;
+ }
+
+ void writePoint(const SkPoint& pt) {
+ *(SkPoint*)this->reserve(sizeof(pt)) = pt;
+ }
+
+ void writeRect(const SkRect& rect) {
+ *(SkRect*)this->reserve(sizeof(rect)) = rect;
+ }
+
+ void writeIRect(const SkIRect& rect) {
+ *(SkIRect*)this->reserve(sizeof(rect)) = rect;
+ }
+
+ void writeRRect(const SkRRect& rrect) {
+ rrect.writeToMemory(this->reserve(SkRRect::kSizeInMemory));
+ }
+
+ void writePath(const SkPath& path) {
+ size_t size = path.writeToMemory(NULL);
+ SkASSERT(SkAlign4(size) == size);
+ path.writeToMemory(this->reserve(size));
+ }
+
+ void writeMatrix(const SkMatrix& matrix) {
+ size_t size = matrix.writeToMemory(NULL);
+ SkASSERT(SkAlign4(size) == size);
+ matrix.writeToMemory(this->reserve(size));
+ }
+
+ void writeRegion(const SkRegion& rgn) {
+ size_t size = rgn.writeToMemory(NULL);
+ SkASSERT(SkAlign4(size) == size);
+ rgn.writeToMemory(this->reserve(size));
+ }
+
+ // write count bytes (must be a multiple of 4)
+ void writeMul4(const void* values, size_t size) {
+ this->write(values, size);
+ }
+
+ /**
+ * Write size bytes from values. size must be a multiple of 4, though
+ * values need not be 4-byte aligned.
+ */
+ void write(const void* values, size_t size) {
+ SkASSERT(SkAlign4(size) == size);
+ memcpy(this->reserve(size), values, size);
+ }
+
+ /**
+ * Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be
+ * filled in with zeroes.
+ */
+ uint32_t* reservePad(size_t size) {
+ size_t alignedSize = SkAlign4(size);
+ uint32_t* p = this->reserve(alignedSize);
+ if (alignedSize != size) {
+ SkASSERT(alignedSize >= 4);
+ p[alignedSize / 4 - 1] = 0;
+ }
+ return p;
+ }
+
+ /**
+ * Write size bytes from src, and pad to 4 byte alignment with zeroes.
+ */
+ void writePad(const void* src, size_t size) {
+ memcpy(this->reservePad(size), src, size);
+ }
+
+ /**
+ * Writes a string to the writer, which can be retrieved with
+ * SkReader32::readString().
+ * The length can be specified, or if -1 is passed, it will be computed by
+ * calling strlen(). The length must be < max size_t.
+ *
+ * If you write NULL, it will be read as "".
+ */
+ void writeString(const char* str, size_t len = (size_t)-1);
+
+ /**
+ * Computes the size (aligned to multiple of 4) need to write the string
+ * in a call to writeString(). If the length is not specified, it will be
+ * computed by calling strlen().
+ */
+ static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
+
+ /**
+ * Move the cursor back to offset bytes from the beginning.
+ * offset must be a multiple of 4 no greater than size().
+ */
+ void rewindToOffset(size_t offset) {
+ SkASSERT(SkAlign4(offset) == offset);
+ SkASSERT(offset <= bytesWritten());
+ fUsed = offset;
+ }
+
+ // copy into a single buffer (allocated by caller). Must be at least size()
+ void flatten(void* dst) const {
+ memcpy(dst, fData, fUsed);
+ }
+
+ bool writeToStream(SkWStream* stream) const {
+ return stream->write(fData, fUsed);
+ }
+
+ // read from the stream, and write up to length bytes. Return the actual
+ // number of bytes written.
+ size_t readFromStream(SkStream* stream, size_t length) {
+ return stream->read(this->reservePad(length), length);
+ }
+
+ /**
+ * Captures a snapshot of the data as it is right now, and return it.
+ * Multiple calls without intervening writes may return the same SkData,
+ * but this is not guaranteed.
+ * Future appends will not affect the returned buffer.
+ * It is illegal to call overwriteTAt after this without an intervening
+ * append. It may cause the snapshot buffer to be corrupted.
+ * Callers must unref the returned SkData.
+ * This is not thread safe, it should only be called on the writing thread,
+ * the result however can be shared across threads.
+ */
+ SkData* snapshotAsData() const;
+private:
+ void growToAtLeast(size_t size);
+
+ uint8_t* fData; // Points to either fInternal or fExternal.
+ size_t fCapacity; // Number of bytes we can write to fData.
+ size_t fUsed; // Number of bytes written.
+ void* fExternal; // Unmanaged memory block.
+ SkAutoTMalloc<uint8_t> fInternal; // Managed memory block.
+ SkAutoTUnref<SkData> fSnapshot; // Holds the result of last asData.
+};
+
+/**
+ * Helper class to allocated SIZE bytes as part of the writer, and to provide
+ * that storage to the constructor as its initial storage buffer.
+ *
+ * This wrapper ensures proper alignment rules are met for the storage.
+ */
+template <size_t SIZE> class SkSWriter32 : public SkWriter32 {
+public:
+ SkSWriter32() { this->reset(); }
+
+ void reset() {this->INHERITED::reset(fData.fStorage, SIZE); }
+
+private:
+ union {
+ void* fPtrAlignment;
+ double fDoubleAlignment;
+ char fStorage[SIZE];
+ } fData;
+
+ typedef SkWriter32 INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/core/SkXfermode.h b/src/third_party/skia/include/core/SkXfermode.h
new file mode 100644
index 0000000..bedcc24
--- /dev/null
+++ b/src/third_party/skia/include/core/SkXfermode.h
@@ -0,0 +1,240 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkXfermode_DEFINED
+#define SkXfermode_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkColor.h"
+
+class GrFragmentProcessor;
+class GrTexture;
+class SkString;
+
+/** \class SkXfermode
+ *
+ * SkXfermode is the base class for objects that are called to implement custom
+ * "transfer-modes" in the drawing pipeline. The static function Create(Modes)
+ * can be called to return an instance of any of the predefined subclasses as
+ * specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
+ * then objects drawn with that paint have the xfermode applied.
+ *
+ * All subclasses are required to be reentrant-safe : it must be legal to share
+ * the same instance between several threads.
+ */
+class SK_API SkXfermode : public SkFlattenable {
+public:
+ SK_DECLARE_INST_COUNT(SkXfermode)
+
+ virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const;
+ virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const;
+ virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const;
+
+ /** Enum of possible coefficients to describe some xfermodes
+ */
+ enum Coeff {
+ kZero_Coeff, /** 0 */
+ kOne_Coeff, /** 1 */
+ kSC_Coeff, /** src color */
+ kISC_Coeff, /** inverse src color (i.e. 1 - sc) */
+ kDC_Coeff, /** dst color */
+ kIDC_Coeff, /** inverse dst color (i.e. 1 - dc) */
+ kSA_Coeff, /** src alpha */
+ kISA_Coeff, /** inverse src alpha (i.e. 1 - sa) */
+ kDA_Coeff, /** dst alpha */
+ kIDA_Coeff, /** inverse dst alpha (i.e. 1 - da) */
+
+ kCoeffCount
+ };
+
+ /** If the xfermode can be expressed as an equation using the coefficients
+ in Coeff, then asCoeff() returns true, and sets (if not null) src and
+ dst accordingly.
+
+ result = src_coeff * src_color + dst_coeff * dst_color;
+
+ As examples, here are some of the porterduff coefficients
+
+ MODE SRC_COEFF DST_COEFF
+ clear zero zero
+ src one zero
+ dst zero one
+ srcover one isa
+ dstover ida one
+ */
+ virtual bool asCoeff(Coeff* src, Coeff* dst) const;
+
+ /**
+ * The same as calling xfermode->asCoeff(..), except that this also checks
+ * if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
+ */
+ static bool AsCoeff(const SkXfermode*, Coeff* src, Coeff* dst);
+
+ /** List of predefined xfermodes.
+ The algebra for the modes uses the following symbols:
+ Sa, Sc - source alpha and color
+ Da, Dc - destination alpha and color (before compositing)
+ [a, c] - Resulting (alpha, color) values
+ For these equations, the colors are in premultiplied state.
+ If no xfermode is specified, kSrcOver is assumed.
+ The modes are ordered by those that can be expressed as a pair of Coeffs, followed by those
+ that aren't Coeffs but have separable r,g,b computations, and finally
+ those that are not separable.
+ */
+ enum Mode {
+ kClear_Mode, //!< [0, 0]
+ kSrc_Mode, //!< [Sa, Sc]
+ kDst_Mode, //!< [Da, Dc]
+ kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Sc + (1 - Sa)*Dc]
+ kDstOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Dc + (1 - Da)*Sc]
+ kSrcIn_Mode, //!< [Sa * Da, Sc * Da]
+ kDstIn_Mode, //!< [Sa * Da, Sa * Dc]
+ kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)]
+ kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
+ kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
+ kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
+ kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
+ kPlus_Mode, //!< [Sa + Da, Sc + Dc]
+ kModulate_Mode, // multiplies all components (= alpha and color)
+
+ // Following blend modes are defined in the CSS Compositing standard:
+ // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
+ kScreen_Mode,
+ kLastCoeffMode = kScreen_Mode,
+
+ kOverlay_Mode,
+ kDarken_Mode,
+ kLighten_Mode,
+ kColorDodge_Mode,
+ kColorBurn_Mode,
+ kHardLight_Mode,
+ kSoftLight_Mode,
+ kDifference_Mode,
+ kExclusion_Mode,
+ kMultiply_Mode,
+ kLastSeparableMode = kMultiply_Mode,
+
+ kHue_Mode,
+ kSaturation_Mode,
+ kColor_Mode,
+ kLuminosity_Mode,
+ kLastMode = kLuminosity_Mode
+ };
+
+ /**
+ * Gets the name of the Mode as a string.
+ */
+ static const char* ModeName(Mode);
+
+ /**
+ * If the xfermode is one of the modes in the Mode enum, then asMode()
+ * returns true and sets (if not null) mode accordingly. Otherwise it
+ * returns false and ignores the mode parameter.
+ */
+ virtual bool asMode(Mode* mode) const;
+
+ /**
+ * The same as calling xfermode->asMode(mode), except that this also checks
+ * if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
+ */
+ static bool AsMode(const SkXfermode*, Mode* mode);
+
+ /**
+ * Returns true if the xfermode claims to be the specified Mode. This works
+ * correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
+ * you can say this without checking for a null...
+ *
+ * If (SkXfermode::IsMode(paint.getXfermode(),
+ * SkXfermode::kDstOver_Mode)) {
+ * ...
+ * }
+ */
+ static bool IsMode(const SkXfermode* xfer, Mode mode);
+
+ /** Return an SkXfermode object for the specified mode.
+ */
+ static SkXfermode* Create(Mode mode);
+
+ /** Return a function pointer to a routine that applies the specified
+ porter-duff transfer mode.
+ */
+ static SkXfermodeProc GetProc(Mode mode);
+
+ /** Return a function pointer to a routine that applies the specified
+ porter-duff transfer mode and srcColor to a 16bit device color. Note,
+ if the mode+srcColor might return a non-opaque color, then there is not
+ 16bit proc, and this will return NULL.
+ */
+ static SkXfermodeProc16 GetProc16(Mode mode, SkColor srcColor);
+
+ /**
+ * If the specified mode can be represented by a pair of Coeff, then return
+ * true and set (if not NULL) the corresponding coeffs. If the mode is
+ * not representable as a pair of Coeffs, return false and ignore the
+ * src and dst parameters.
+ */
+ static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
+
+ SK_ATTR_DEPRECATED("use AsMode(...)")
+ static bool IsMode(const SkXfermode* xfer, Mode* mode) {
+ return AsMode(xfer, mode);
+ }
+
+ /** A subclass may implement this factory function to work with the GPU backend. It is legal
+ to call this with all params NULL to simply test the return value. If effect is non-NULL
+ then the xfermode may optionally allocate an effect to return and the caller as *effect.
+ The caller will install it and own a ref to it. Since the xfermode may or may not assign
+ *effect, the caller should set *effect to NULL beforehand. background specifies the
+ texture to use as the background for compositing, and should be accessed in the effect's
+ fragment shader. If NULL, the effect should request access to destination color
+ (setWillReadDstColor()), and use that in the fragment shader (builder->dstColor()).
+ */
+ virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture* background = NULL) const;
+
+ /** Returns true if the xfermode can be expressed as coeffs (src, dst), or as an effect
+ (effect). This helper calls the asCoeff() and asFragmentProcessor() virtuals. If the
+ xfermode is NULL, it is treated as kSrcOver_Mode. It is legal to call this with all params
+ NULL to simply test the return value. effect, src, and dst must all be NULL or all
+ non-NULL.
+ */
+ static bool asFragmentProcessorOrCoeff(SkXfermode*, GrFragmentProcessor**, Coeff* src,
+ Coeff* dst, GrTexture* background = NULL);
+
+ SK_TO_STRING_PUREVIRT()
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+ SK_DEFINE_FLATTENABLE_TYPE(SkXfermode)
+
+protected:
+ SkXfermode() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkXfermode(SkReadBuffer& rb) : SkFlattenable(rb) {}
+#endif
+
+ /** The default implementation of xfer32/xfer16/xferA8 in turn call this
+ method, 1 color at a time (upscaled to a SkPMColor). The default
+ implmentation of this method just returns dst. If performance is
+ important, your subclass should override xfer32/xfer16/xferA8 directly.
+
+ This method will not be called directly by the client, so it need not
+ be implemented if your subclass has overridden xfer32/xfer16/xferA8
+ */
+ virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
+
+private:
+ enum {
+ kModeCount = kLastMode + 1
+ };
+
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/device/xps/SkConstexprMath.h b/src/third_party/skia/include/device/xps/SkConstexprMath.h
new file mode 100644
index 0000000..9625d51
--- /dev/null
+++ b/src/third_party/skia/include/device/xps/SkConstexprMath.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkConstexprMath_DEFINED
+#define SkConstexprMath_DEFINED
+
+#include "SkTypes.h"
+#include <limits.h>
+
+template <uintmax_t N, uintmax_t B>
+struct SK_LOG {
+ //! Compile-time constant ceiling(logB(N)).
+ static const uintmax_t value = 1 + SK_LOG<N/B, B>::value;
+};
+template <uintmax_t B>
+struct SK_LOG<1, B> {
+ static const uintmax_t value = 0;
+};
+template <uintmax_t B>
+struct SK_LOG<0, B> {
+ static const uintmax_t value = 0;
+};
+
+template<uintmax_t N>
+struct SK_2N1 {
+ //! Compile-time constant (2^N)-1.
+ static const uintmax_t value = (SK_2N1<N-1>::value << 1) + 1;
+};
+template<>
+struct SK_2N1<1> {
+ static const uintmax_t value = 1;
+};
+
+/** Compile-time constant number of base n digits in type t
+ if the bits of type t are considered as unsigned base two.
+*/
+#define SK_BASE_N_DIGITS_IN(n, t) (\
+ SK_LOG<SK_2N1<(sizeof(t) * CHAR_BIT)>::value, n>::value\
+)
+/** Compile-time constant number of base 10 digits in type t
+ if the bits of type t are considered as unsigned base two.
+*/
+#define SK_DIGITS_IN(t) SK_BASE_N_DIGITS_IN(10, (t))
+
+// Compile-time constant maximum value of two unsigned values.
+template <uintmax_t a, uintmax_t b> struct SkTUMax {
+ static const uintmax_t value = (b < a) ? a : b;
+};
+
+#endif
diff --git a/src/third_party/skia/include/device/xps/SkXPSDevice.h b/src/third_party/skia/include/device/xps/SkXPSDevice.h
new file mode 100644
index 0000000..2aa7ba8
--- /dev/null
+++ b/src/third_party/skia/include/device/xps/SkXPSDevice.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkXPSDevice_DEFINED
+#define SkXPSDevice_DEFINED
+
+#include "SkTypes.h"
+#include <ObjBase.h>
+#include <XpsObjectModel.h>
+
+#include "SkAutoCoInitialize.h"
+#include "SkBitmapDevice.h"
+#include "SkBitSet.h"
+#include "SkCanvas.h"
+#include "SkColor.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkShader.h"
+#include "SkSize.h"
+#include "SkTArray.h"
+#include "SkTScopedComPtr.h"
+#include "SkTypeface.h"
+
+//#define SK_XPS_USE_DETERMINISTIC_IDS
+
+/** \class SkXPSDevice
+
+ The drawing context for the XPS backend.
+*/
+class SkXPSDevice : public SkBitmapDevice {
+public:
+ SK_API SkXPSDevice();
+ SK_API virtual ~SkXPSDevice();
+
+ virtual bool beginPortfolio(SkWStream* outputStream);
+ /**
+ @param unitsPerMeter converts geometry units into physical units.
+ @param pixelsPerMeter resolution to use when geometry must be rasterized.
+ @param trimSize final page size in physical units.
+ The top left of the trim is the origin of physical space.
+ @param mediaBox The size of the physical media in physical units.
+ The top and left must be less than zero.
+ The bottom and right must be greater than the trimSize.
+ The default is to coincide with the trimSize.
+ @param bleedBox The size of the bleed box in physical units.
+ Must be contained within the mediaBox.
+ The default is to coincide with the mediaBox.
+ @param artBox The size of the content box in physical units.
+ Must be contained within the trimSize.
+ The default is to coincide with the trimSize.
+ @param cropBox The size of the recommended view port in physical units.
+ Must be contained within the mediaBox.
+ The default is to coincide with the mediaBox.
+ */
+ virtual bool beginSheet(
+ const SkVector& unitsPerMeter,
+ const SkVector& pixelsPerMeter,
+ const SkSize& trimSize,
+ const SkRect* mediaBox = NULL,
+ const SkRect* bleedBox = NULL,
+ const SkRect* artBox = NULL,
+ const SkRect* cropBox = NULL);
+
+ virtual bool endSheet();
+ virtual bool endPortfolio();
+
+protected:
+ virtual void clear(SkColor color) SK_OVERRIDE;
+
+ virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawPoints(
+ const SkDraw&,
+ SkCanvas::PointMode mode,
+ size_t count, const SkPoint[],
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawRect(
+ const SkDraw&,
+ const SkRect& r,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawRRect(
+ const SkDraw&,
+ const SkRRect&,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawPath(
+ const SkDraw&,
+ const SkPath& platonicPath,
+ const SkPaint& paint,
+ const SkMatrix* prePathMatrix,
+ bool pathIsMutable) SK_OVERRIDE;
+
+ virtual void drawBitmap(
+ const SkDraw&,
+ const SkBitmap& bitmap,
+ const SkMatrix& matrix,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawSprite(
+ const SkDraw&,
+ const SkBitmap& bitmap,
+ int x, int y,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawText(
+ const SkDraw&,
+ const void* text, size_t len,
+ SkScalar x, SkScalar y,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawPosText(
+ const SkDraw&,
+ const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY, int scalarsPerPos,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawTextOnPath(
+ const SkDraw&,
+ const void* text, size_t len,
+ const SkPath& path,
+ const SkMatrix* matrix,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawVertices(
+ const SkDraw&,
+ SkCanvas::VertexMode,
+ int vertexCount, const SkPoint verts[],
+ const SkPoint texs[], const SkColor colors[],
+ SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void drawDevice(
+ const SkDraw&,
+ SkBaseDevice* device,
+ int x, int y,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE;
+
+private:
+ class TypefaceUse : ::SkNoncopyable {
+ public:
+ SkFontID typefaceId;
+ int ttcIndex;
+ SkStream* fontData;
+ IXpsOMFontResource* xpsFont;
+ SkBitSet* glyphsUsed;
+
+ explicit TypefaceUse();
+ ~TypefaceUse();
+ };
+ friend static HRESULT subset_typeface(TypefaceUse* current);
+
+ SkXPSDevice(IXpsOMObjectFactory* xpsFactory);
+
+ SkAutoCoInitialize fAutoCo;
+ SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
+ SkTScopedComPtr<IStream> fOutputStream;
+ SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
+
+ unsigned int fCurrentPage;
+ SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
+ SkSize fCurrentCanvasSize;
+ SkVector fCurrentUnitsPerMeter;
+ SkVector fCurrentPixelsPerMeter;
+
+ SkTArray<TypefaceUse, true> fTypefaces;
+
+ /** Creates a GUID based id and places it into buffer.
+ buffer should have space for at least GUID_ID_LEN wide characters.
+ The string will always be wchar null terminated.
+ XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0
+ The string may begin with a digit,
+ and so may not be suitable as a bare resource key.
+ */
+ HRESULT createId(wchar_t* buffer, size_t bufferSize, wchar_t sep = '-');
+#ifdef SK_XPS_USE_DETERMINISTIC_IDS
+ decltype(GUID::Data1) fNextId = 0;
+#endif
+
+ HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
+
+ HRESULT createXpsPage(
+ const XPS_SIZE& pageSize,
+ IXpsOMPage** page);
+
+ HRESULT createXpsThumbnail(
+ IXpsOMPage* page, const unsigned int pageNumber,
+ IXpsOMImageResource** image);
+
+ void internalDrawRect(
+ const SkDraw&,
+ const SkRect& r,
+ bool transformRect,
+ const SkPaint& paint);
+
+ HRESULT createXpsBrush(
+ const SkPaint& skPaint,
+ IXpsOMBrush** xpsBrush,
+ const SkMatrix* parentTransform = NULL);
+
+ HRESULT createXpsSolidColorBrush(
+ const SkColor skColor, const SkAlpha alpha,
+ IXpsOMBrush** xpsBrush);
+
+ HRESULT createXpsImageBrush(
+ const SkBitmap& bitmap,
+ const SkMatrix& localMatrix,
+ const SkShader::TileMode (&xy)[2],
+ const SkAlpha alpha,
+ IXpsOMTileBrush** xpsBrush);
+
+ HRESULT createXpsLinearGradient(
+ SkShader::GradientInfo info,
+ const SkAlpha alpha,
+ const SkMatrix& localMatrix,
+ IXpsOMMatrixTransform* xpsMatrixToUse,
+ IXpsOMBrush** xpsBrush);
+
+ HRESULT createXpsRadialGradient(
+ SkShader::GradientInfo info,
+ const SkAlpha alpha,
+ const SkMatrix& localMatrix,
+ IXpsOMMatrixTransform* xpsMatrixToUse,
+ IXpsOMBrush** xpsBrush);
+
+ HRESULT createXpsGradientStop(
+ const SkColor skColor,
+ const SkScalar offset,
+ IXpsOMGradientStop** xpsGradStop);
+
+ HRESULT createXpsTransform(
+ const SkMatrix& matrix,
+ IXpsOMMatrixTransform ** xpsTransform);
+
+ HRESULT createXpsRect(
+ const SkRect& rect,
+ BOOL stroke, BOOL fill,
+ IXpsOMGeometryFigure** xpsRect);
+
+ HRESULT createXpsQuad(
+ const SkPoint (&points)[4],
+ BOOL stroke, BOOL fill,
+ IXpsOMGeometryFigure** xpsQuad);
+
+ HRESULT CreateTypefaceUse(
+ const SkPaint& paint,
+ TypefaceUse** fontResource);
+
+ HRESULT AddGlyphs(
+ const SkDraw& d,
+ IXpsOMObjectFactory* xpsFactory,
+ IXpsOMCanvas* canvas,
+ TypefaceUse* font,
+ LPCWSTR text,
+ XPS_GLYPH_INDEX* xpsGlyphs,
+ UINT32 xpsGlyphsLen,
+ XPS_POINT *origin,
+ FLOAT fontSize,
+ XPS_STYLE_SIMULATION sims,
+ const SkMatrix& transform,
+ const SkPaint& paint);
+
+ HRESULT addXpsPathGeometry(
+ IXpsOMGeometryFigureCollection* figures,
+ BOOL stroke, BOOL fill, const SkPath& path);
+
+ HRESULT createPath(
+ IXpsOMGeometryFigure* figure,
+ IXpsOMVisualCollection* visuals,
+ IXpsOMPath** path);
+
+ HRESULT sideOfClamp(
+ const SkRect& leftPoints, const XPS_RECT& left,
+ IXpsOMImageResource* imageResource,
+ IXpsOMVisualCollection* visuals);
+
+ HRESULT cornerOfClamp(
+ const SkRect& tlPoints,
+ const SkColor color,
+ IXpsOMVisualCollection* visuals);
+
+ HRESULT clip(
+ IXpsOMVisual* xpsVisual,
+ const SkDraw& d);
+ HRESULT clipToPath(
+ IXpsOMVisual* xpsVisual,
+ const SkPath& clipPath,
+ XPS_FILL_RULE fillRule);
+
+ HRESULT drawInverseWindingPath(
+ const SkDraw& d,
+ const SkPath& devicePath,
+ IXpsOMPath* xpsPath);
+
+ HRESULT shadePath(
+ IXpsOMPath* shadedPath,
+ const SkPaint& shaderPaint,
+ const SkMatrix& matrix,
+ BOOL* fill, BOOL* stroke);
+
+ void convertToPpm(
+ const SkMaskFilter* filter,
+ SkMatrix* matrix,
+ SkVector* ppuScale,
+ const SkIRect& clip, SkIRect* clipIRect);
+
+ HRESULT applyMask(
+ const SkDraw& d,
+ const SkMask& mask,
+ const SkVector& ppuScale,
+ IXpsOMPath* shadedPath);
+
+ virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
+
+ // Disable the default copy and assign implementation.
+ SkXPSDevice(const SkXPSDevice&);
+ void operator=(const SkXPSDevice&);
+
+ typedef SkBitmapDevice INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/Sk1DPathEffect.h b/src/third_party/skia/include/effects/Sk1DPathEffect.h
new file mode 100644
index 0000000..87047e4
--- /dev/null
+++ b/src/third_party/skia/include/effects/Sk1DPathEffect.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef Sk1DPathEffect_DEFINED
+#define Sk1DPathEffect_DEFINED
+
+#include "SkPathEffect.h"
+#include "SkPath.h"
+
+class SkPathMeasure;
+
+// This class is not exported to java.
+class SK_API Sk1DPathEffect : public SkPathEffect {
+public:
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+protected:
+ /** Called at the start of each contour, returns the initial offset
+ into that contour.
+ */
+ virtual SkScalar begin(SkScalar contourLength) const = 0;
+ /** Called with the current distance along the path, with the current matrix
+ for the point/tangent at the specified distance.
+ Return the distance to travel for the next call. If return <= 0, then that
+ contour is done.
+ */
+ virtual SkScalar next(SkPath* dst, SkScalar dist, SkPathMeasure&) const = 0;
+
+private:
+ typedef SkPathEffect INHERITED;
+};
+
+class SK_API SkPath1DPathEffect : public Sk1DPathEffect {
+public:
+ enum Style {
+ kTranslate_Style, // translate the shape to each position
+ kRotate_Style, // rotate the shape about its center
+ kMorph_Style, // transform each point, and turn lines into curves
+
+ kStyleCount
+ };
+
+ /** Dash by replicating the specified path.
+ @param path The path to replicate (dash)
+ @param advance The space between instances of path
+ @param phase distance (mod advance) along path for its initial position
+ @param style how to transform path at each point (based on the current
+ position and tangent)
+ */
+ static SkPath1DPathEffect* Create(const SkPath& path, SkScalar advance, SkScalar phase,
+ Style style) {
+ return SkNEW_ARGS(SkPath1DPathEffect, (path, advance, phase, style));
+ }
+
+ virtual bool filterPath(SkPath*, const SkPath&,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath1DPathEffect)
+
+protected:
+ SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkPath1DPathEffect(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ // overrides from Sk1DPathEffect
+ virtual SkScalar begin(SkScalar contourLength) const SK_OVERRIDE;
+ virtual SkScalar next(SkPath*, SkScalar, SkPathMeasure&) const SK_OVERRIDE;
+
+private:
+ SkPath fPath; // copied from constructor
+ SkScalar fAdvance; // copied from constructor
+ SkScalar fInitialOffset; // computed from phase
+ Style fStyle; // copied from constructor
+
+ typedef Sk1DPathEffect INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/Sk2DPathEffect.h b/src/third_party/skia/include/effects/Sk2DPathEffect.h
new file mode 100644
index 0000000..80a27a3
--- /dev/null
+++ b/src/third_party/skia/include/effects/Sk2DPathEffect.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef Sk2DPathEffect_DEFINED
+#define Sk2DPathEffect_DEFINED
+
+#include "SkPath.h"
+#include "SkPathEffect.h"
+#include "SkMatrix.h"
+
+class SK_API Sk2DPathEffect : public SkPathEffect {
+public:
+ virtual bool filterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_UNFLATTENABLE_OBJECT()
+
+protected:
+ /** New virtual, to be overridden by subclasses.
+ This is called once from filterPath, and provides the
+ uv parameter bounds for the path. Subsequent calls to
+ next() will receive u and v values within these bounds,
+ and then a call to end() will signal the end of processing.
+ */
+ virtual void begin(const SkIRect& uvBounds, SkPath* dst) const;
+ virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) const;
+ virtual void end(SkPath* dst) const;
+
+ /** Low-level virtual called per span of locations in the u-direction.
+ The default implementation calls next() repeatedly with each
+ location.
+ */
+ virtual void nextSpan(int u, int v, int ucount, SkPath* dst) const;
+
+ const SkMatrix& getMatrix() const { return fMatrix; }
+
+ // protected so that subclasses can call this during unflattening
+ explicit Sk2DPathEffect(const SkMatrix& mat);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit Sk2DPathEffect(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkMatrix fMatrix, fInverse;
+ bool fMatrixIsInvertible;
+
+ // illegal
+ Sk2DPathEffect(const Sk2DPathEffect&);
+ Sk2DPathEffect& operator=(const Sk2DPathEffect&);
+
+ friend class Sk2DPathEffectBlitter;
+ typedef SkPathEffect INHERITED;
+};
+
+class SK_API SkLine2DPathEffect : public Sk2DPathEffect {
+public:
+ static SkLine2DPathEffect* Create(SkScalar width, const SkMatrix& matrix) {
+ return SkNEW_ARGS(SkLine2DPathEffect, (width, matrix));
+ }
+
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLine2DPathEffect)
+
+protected:
+ SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix)
+ : Sk2DPathEffect(matrix), fWidth(width) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkLine2DPathEffect(SkReadBuffer&);
+#endif
+
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual void nextSpan(int u, int v, int ucount, SkPath*) const SK_OVERRIDE;
+
+private:
+ SkScalar fWidth;
+
+ typedef Sk2DPathEffect INHERITED;
+};
+
+class SK_API SkPath2DPathEffect : public Sk2DPathEffect {
+public:
+ /**
+ * Stamp the specified path to fill the shape, using the matrix to define
+ * the latice.
+ */
+ static SkPath2DPathEffect* Create(const SkMatrix& matrix, const SkPath& path) {
+ return SkNEW_ARGS(SkPath2DPathEffect, (matrix, path));
+ }
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath2DPathEffect)
+
+protected:
+ SkPath2DPathEffect(const SkMatrix&, const SkPath&);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkPath2DPathEffect(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual void next(const SkPoint&, int u, int v, SkPath*) const SK_OVERRIDE;
+
+private:
+ SkPath fPath;
+
+ typedef Sk2DPathEffect INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkAlphaThresholdFilter.h b/src/third_party/skia/include/effects/SkAlphaThresholdFilter.h
new file mode 100644
index 0000000..f409ee0
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkAlphaThresholdFilter.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkAlphaThresholdFilter_DEFINED
+#define SkAlphaThresholdFilter_DEFINED
+
+#include "SkRegion.h"
+#include "SkImageFilter.h"
+
+class SK_API SkAlphaThresholdFilter {
+public:
+ /**
+ * Creates an image filter that samples a region. If the sample is inside the
+ * region the alpha of the image is boosted up to a threshold value. If it is
+ * outside the region then the alpha is decreased to the threshold value.
+ * The 0,0 point of the region corresponds to the upper left corner of the
+ * source image.
+ */
+ static SkImageFilter* Create(const SkRegion& region, SkScalar innerThreshold,
+ SkScalar outerThreshold, SkImageFilter* input = NULL);
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkArithmeticMode.h b/src/third_party/skia/include/effects/SkArithmeticMode.h
new file mode 100644
index 0000000..3b9585d
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkArithmeticMode.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkArithmeticMode_DEFINED
+#define SkArithmeticMode_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkScalar.h"
+
+class SkXfermode;
+
+class SK_API SkArithmeticMode {
+public:
+ /**
+ * result = clamp[k1 * src * dst + k2 * src + k3 * dst + k4]
+ *
+ * src and dst are treated as being [0.0 .. 1.0]. The polynomial is
+ * evaluated on their unpremultiplied components.
+ *
+ * k1=k2=k3=0, k4=1.0 results in returning opaque white
+ * k1=k3=k4=0, k2=1.0 results in returning the src
+ * k1=k2=k4=0, k3=1.0 results in returning the dst
+ */
+ static SkXfermode* Create(SkScalar k1, SkScalar k2,
+ SkScalar k3, SkScalar k4,
+ bool enforcePMColor = true);
+
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP();
+
+private:
+ SkArithmeticMode(); // can't be instantiated
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkAvoidXfermode.h b/src/third_party/skia/include/effects/SkAvoidXfermode.h
new file mode 100644
index 0000000..53ce708
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkAvoidXfermode.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkAvoidXfermode_DEFINED
+#define SkAvoidXfermode_DEFINED
+
+#include "SkXfermode.h"
+
+/** \class SkAvoidXfermode
+
+ This xfermode will draw the src everywhere except on top of the specified
+ color.
+*/
+class SK_API SkAvoidXfermode : public SkXfermode {
+public:
+ enum Mode {
+ kAvoidColor_Mode, //!< draw everywhere except on the opColor
+ kTargetColor_Mode //!< draw only on top of the opColor
+ };
+
+ /** This xfermode draws, or doesn't draw, based on the destination's
+ distance from an op-color.
+
+ There are two modes, and each mode interprets a tolerance value.
+
+ Avoid: In this mode, drawing is allowed only on destination pixels that
+ are different from the op-color.
+ Tolerance near 0: avoid any colors even remotely similar to the op-color
+ Tolerance near 255: avoid only colors nearly identical to the op-color
+
+ Target: In this mode, drawing only occurs on destination pixels that
+ are similar to the op-color
+ Tolerance near 0: draw only on colors that are nearly identical to the op-color
+ Tolerance near 255: draw on any colors even remotely similar to the op-color
+ */
+ static SkAvoidXfermode* Create(SkColor opColor, U8CPU tolerance, Mode mode) {
+ return SkNEW_ARGS(SkAvoidXfermode, (opColor, tolerance, mode));
+ }
+
+ // overrides from SkXfermode
+ virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+ virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+ virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAvoidXfermode)
+
+protected:
+ SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkAvoidXfermode(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkColor fOpColor;
+ uint32_t fDistMul; // x.14 cached from fTolerance
+ uint8_t fTolerance;
+ Mode fMode;
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkBitmapSource.h b/src/third_party/skia/include/effects/SkBitmapSource.h
new file mode 100644
index 0000000..9004a46
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkBitmapSource.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBitmapSource_DEFINED
+#define SkBitmapSource_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkBitmap.h"
+
+class SK_API SkBitmapSource : public SkImageFilter {
+public:
+ static SkBitmapSource* Create(const SkBitmap& bitmap) {
+ return SkNEW_ARGS(SkBitmapSource, (bitmap));
+ }
+ static SkBitmapSource* Create(const SkBitmap& bitmap, const SkRect& srcRect,
+ const SkRect& dstRect) {
+ return SkNEW_ARGS(SkBitmapSource, (bitmap, srcRect, dstRect));
+ }
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapSource)
+
+protected:
+ explicit SkBitmapSource(const SkBitmap& bitmap);
+ SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkBitmapSource(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const SK_OVERRIDE;
+
+private:
+ SkBitmap fBitmap;
+ SkRect fSrcRect, fDstRect;
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkBlurDrawLooper.h b/src/third_party/skia/include/effects/SkBlurDrawLooper.h
new file mode 100644
index 0000000..9db9f0d
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkBlurDrawLooper.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkBlurDrawLooper_DEFINED
+#define SkBlurDrawLooper_DEFINED
+
+#include "SkDrawLooper.h"
+#include "SkColor.h"
+
+class SkMaskFilter;
+class SkColorFilter;
+
+/** \class SkBlurDrawLooper
+ This class draws a shadow of the object (possibly offset), and then draws
+ the original object in its original position.
+ should there be an option to just draw the shadow/blur layer? webkit?
+*/
+class SK_API SkBlurDrawLooper : public SkDrawLooper {
+public:
+ enum BlurFlags {
+ kNone_BlurFlag = 0x00,
+ /**
+ The blur layer's dx/dy/radius aren't affected by the canvas
+ transform.
+ */
+ kIgnoreTransform_BlurFlag = 0x01,
+ kOverrideColor_BlurFlag = 0x02,
+ kHighQuality_BlurFlag = 0x04,
+ /** mask for all blur flags */
+ kAll_BlurFlag = 0x07
+ };
+
+ static SkBlurDrawLooper* Create(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
+ uint32_t flags = kNone_BlurFlag) {
+ return SkNEW_ARGS(SkBlurDrawLooper, (color, sigma, dx, dy, flags));
+ }
+
+ virtual ~SkBlurDrawLooper();
+
+ virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE;
+
+ virtual size_t contextSize() const SK_OVERRIDE { return sizeof(BlurDrawLooperContext); }
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurDrawLooper)
+
+protected:
+ SkBlurDrawLooper(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
+ uint32_t flags);
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkBlurDrawLooper(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool asABlurShadow(BlurShadowRec*) const SK_OVERRIDE;
+
+private:
+ SkMaskFilter* fBlur;
+ SkColorFilter* fColorFilter;
+ SkScalar fDx, fDy, fSigma;
+ SkColor fBlurColor;
+ uint32_t fBlurFlags;
+
+ enum State {
+ kBeforeEdge,
+ kAfterEdge,
+ kDone
+ };
+
+ class BlurDrawLooperContext : public SkDrawLooper::Context {
+ public:
+ explicit BlurDrawLooperContext(const SkBlurDrawLooper* looper);
+
+ virtual bool next(SkCanvas* canvas, SkPaint* paint) SK_OVERRIDE;
+
+ private:
+ const SkBlurDrawLooper* fLooper;
+ State fState;
+ };
+
+ void init(SkScalar sigma, SkScalar dx, SkScalar dy, SkColor color, uint32_t flags);
+ void initEffects();
+
+ typedef SkDrawLooper INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkBlurImageFilter.h b/src/third_party/skia/include/effects/SkBlurImageFilter.h
new file mode 100644
index 0000000..cfa895a
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkBlurImageFilter.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBlurImageFilter_DEFINED
+#define SkBlurImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkSize.h"
+
+class SK_API SkBlurImageFilter : public SkImageFilter {
+public:
+ static SkBlurImageFilter* Create(SkScalar sigmaX,
+ SkScalar sigmaY,
+ SkImageFilter* input = NULL,
+ const CropRect* cropRect = NULL, uint32_t uniqueID = 0) {
+ return SkNEW_ARGS(SkBlurImageFilter, (sigmaX, sigmaY, input, cropRect, uniqueID));
+ }
+
+ virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
+
+protected:
+ SkBlurImageFilter(SkScalar sigmaX,
+ SkScalar sigmaY,
+ SkImageFilter* input,
+ const CropRect* cropRect,
+ uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkBlurImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
+ SkIRect* dst) const SK_OVERRIDE;
+
+ bool canFilterImageGPU() const SK_OVERRIDE { return true; }
+ virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+
+private:
+ SkSize fSigma;
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkBlurMaskFilter.h b/src/third_party/skia/include/effects/SkBlurMaskFilter.h
new file mode 100644
index 0000000..356475e
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkBlurMaskFilter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBlurMaskFilter_DEFINED
+#define SkBlurMaskFilter_DEFINED
+
+// we include this since our callers will need to at least be able to ref/unref
+#include "SkMaskFilter.h"
+#include "SkScalar.h"
+#include "SkBlurTypes.h"
+
+class SK_API SkBlurMaskFilter {
+public:
+ /**
+ * If radius > 0, return the corresponding sigma, else return 0. Use this to convert from the
+ * (legacy) idea of specify the blur "radius" to the standard notion of specifying its sigma.
+ */
+ static SkScalar ConvertRadiusToSigma(SkScalar radius);
+
+ enum BlurFlags {
+ kNone_BlurFlag = 0x00,
+ /** The blur layer's radius is not affected by transforms */
+ kIgnoreTransform_BlurFlag = 0x01,
+ /** Use a smother, higher qulity blur algorithm */
+ kHighQuality_BlurFlag = 0x02,
+ /** mask for all blur flags */
+ kAll_BlurFlag = 0x03
+ };
+
+ /** Create a blur maskfilter.
+ * @param style The SkBlurStyle to use
+ * @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
+ * @param flags Flags to use - defaults to none
+ * @return The new blur maskfilter
+ */
+ static SkMaskFilter* Create(SkBlurStyle style, SkScalar sigma, uint32_t flags = kNone_BlurFlag);
+
+ /** Create an emboss maskfilter
+ @param blurSigma standard deviation of the Gaussian blur to apply
+ before applying lighting (e.g. 3)
+ @param direction array of 3 scalars [x, y, z] specifying the direction of the light source
+ @param ambient 0...1 amount of ambient light
+ @param specular coefficient for specular highlights (e.g. 8)
+ @return the emboss maskfilter
+ */
+ static SkMaskFilter* CreateEmboss(SkScalar blurSigma, const SkScalar direction[3],
+ SkScalar ambient, SkScalar specular);
+
+ SK_ATTR_DEPRECATED("use sigma version")
+ static SkMaskFilter* CreateEmboss(const SkScalar direction[3],
+ SkScalar ambient, SkScalar specular,
+ SkScalar blurRadius);
+
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+
+private:
+ SkBlurMaskFilter(); // can't be instantiated
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkColorFilterImageFilter.h b/src/third_party/skia/include/effects/SkColorFilterImageFilter.h
new file mode 100644
index 0000000..46f2d2a
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkColorFilterImageFilter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkColorFilterImageFilter_DEFINED
+#define SkColorFilterImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SkColorFilter;
+
+class SK_API SkColorFilterImageFilter : public SkImageFilter {
+public:
+ static SkColorFilterImageFilter* Create(SkColorFilter* cf,
+ SkImageFilter* input = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0);
+ virtual ~SkColorFilterImageFilter();
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterImageFilter)
+
+protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkColorFilterImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+
+ virtual bool asColorFilter(SkColorFilter**) const SK_OVERRIDE;
+
+private:
+ SkColorFilterImageFilter(SkColorFilter* cf,
+ SkImageFilter* input,
+ const CropRect* cropRect,
+ uint32_t uniqueID);
+ SkColorFilter* fColorFilter;
+
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkColorMatrix.h b/src/third_party/skia/include/effects/SkColorMatrix.h
new file mode 100644
index 0000000..c598a12
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkColorMatrix.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkColorMatrix_DEFINED
+#define SkColorMatrix_DEFINED
+
+#include "SkScalar.h"
+
+class SK_API SkColorMatrix {
+public:
+ SkScalar fMat[20];
+
+ enum Elem {
+ kR_Scale = 0,
+ kG_Scale = 6,
+ kB_Scale = 12,
+ kA_Scale = 18,
+
+ kR_Trans = 4,
+ kG_Trans = 9,
+ kB_Trans = 14,
+ kA_Trans = 19,
+ };
+
+ void setIdentity();
+ void setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
+ SkScalar aScale = SK_Scalar1);
+ void preScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
+ SkScalar aScale = SK_Scalar1);
+ void postScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
+ SkScalar aScale = SK_Scalar1);
+ void postTranslate(SkScalar rTrans, SkScalar gTrans, SkScalar bTrans,
+ SkScalar aTrans = 0);
+
+ enum Axis {
+ kR_Axis = 0,
+ kG_Axis = 1,
+ kB_Axis = 2
+ };
+ void setRotate(Axis, SkScalar degrees);
+ void setSinCos(Axis, SkScalar sine, SkScalar cosine);
+ void preRotate(Axis, SkScalar degrees);
+ void postRotate(Axis, SkScalar degrees);
+
+ void setConcat(const SkColorMatrix& a, const SkColorMatrix& b);
+ void preConcat(const SkColorMatrix& mat) { this->setConcat(*this, mat); }
+ void postConcat(const SkColorMatrix& mat) { this->setConcat(mat, *this); }
+
+ void setSaturation(SkScalar sat);
+ void setRGB2YUV();
+ void setYUV2RGB();
+
+ bool operator==(const SkColorMatrix& other) const {
+ return 0 == memcmp(fMat, other.fMat, sizeof(fMat));
+ }
+
+ bool operator!=(const SkColorMatrix& other) const { return !((*this) == other); }
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkColorMatrixFilter.h b/src/third_party/skia/include/effects/SkColorMatrixFilter.h
new file mode 100644
index 0000000..dad4062
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkColorMatrixFilter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkColorMatrixFilter_DEFINED
+#define SkColorMatrixFilter_DEFINED
+
+#include "SkColorFilter.h"
+#include "SkColorMatrix.h"
+
+class SK_API SkColorMatrixFilter : public SkColorFilter {
+public:
+ static SkColorMatrixFilter* Create(const SkColorMatrix& cm) {
+ return SkNEW_ARGS(SkColorMatrixFilter, (cm));
+ }
+ static SkColorMatrixFilter* Create(const SkScalar array[20]) {
+ return SkNEW_ARGS(SkColorMatrixFilter, (array));
+ }
+
+ // overrides from SkColorFilter
+ virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const SK_OVERRIDE;
+ virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]) const SK_OVERRIDE;
+ virtual uint32_t getFlags() const SK_OVERRIDE;
+ virtual bool asColorMatrix(SkScalar matrix[20]) const SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+ virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+#endif
+
+ struct State {
+ int32_t fArray[20];
+ int fShift;
+ };
+
+ SK_TO_STRING_OVERRIDE()
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorMatrixFilter)
+
+protected:
+ explicit SkColorMatrixFilter(const SkColorMatrix&);
+ explicit SkColorMatrixFilter(const SkScalar array[20]);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkColorMatrixFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkColorMatrix fMatrix;
+
+ typedef void (*Proc)(const State&, unsigned r, unsigned g, unsigned b,
+ unsigned a, int32_t result[4]);
+
+ Proc fProc;
+ State fState;
+ uint32_t fFlags;
+
+ void initState(const SkScalar array[20]);
+
+ typedef SkColorFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkComposeImageFilter.h b/src/third_party/skia/include/effects/SkComposeImageFilter.h
new file mode 100644
index 0000000..26eed37
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkComposeImageFilter.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkComposeImageFilter_DEFINED
+#define SkComposeImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SK_API SkComposeImageFilter : public SkImageFilter {
+public:
+ virtual ~SkComposeImageFilter();
+
+ static SkImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) {
+ if (NULL == outer) {
+ return SkSafeRef(inner);
+ }
+ if (NULL == inner) {
+ return SkRef(outer);
+ }
+ SkImageFilter* inputs[2] = { outer, inner };
+ return SkNEW_ARGS(SkComposeImageFilter, (inputs));
+ }
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter)
+
+protected:
+ explicit SkComposeImageFilter(SkImageFilter* inputs[2]) : INHERITED(2, inputs) {
+ SkASSERT(inputs[0]);
+ SkASSERT(inputs[1]);
+ }
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkComposeImageFilter(SkReadBuffer& buffer);
+#endif
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE;
+
+private:
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkCornerPathEffect.h b/src/third_party/skia/include/effects/SkCornerPathEffect.h
new file mode 100644
index 0000000..e61d494
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkCornerPathEffect.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkCornerPathEffect_DEFINED
+#define SkCornerPathEffect_DEFINED
+
+#include "SkPathEffect.h"
+
+/** \class SkCornerPathEffect
+
+ SkCornerPathEffect is a subclass of SkPathEffect that can turn sharp corners
+ into various treatments (e.g. rounded corners)
+*/
+class SK_API SkCornerPathEffect : public SkPathEffect {
+public:
+ /** radius must be > 0 to have an effect. It specifies the distance from each corner
+ that should be "rounded".
+ */
+ static SkCornerPathEffect* Create(SkScalar radius) {
+ return SkNEW_ARGS(SkCornerPathEffect, (radius));
+ }
+ virtual ~SkCornerPathEffect();
+
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkCornerPathEffect)
+
+protected:
+ explicit SkCornerPathEffect(SkScalar radius);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkCornerPathEffect(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkScalar fRadius;
+
+ typedef SkPathEffect INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkDashPathEffect.h b/src/third_party/skia/include/effects/SkDashPathEffect.h
new file mode 100644
index 0000000..3946224
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkDashPathEffect.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDashPathEffect_DEFINED
+#define SkDashPathEffect_DEFINED
+
+#include "SkPathEffect.h"
+
+/** \class SkDashPathEffect
+
+ SkDashPathEffect is a subclass of SkPathEffect that implements dashing
+*/
+class SK_API SkDashPathEffect : public SkPathEffect {
+public:
+ /** intervals: array containing an even number of entries (>=2), with
+ the even indices specifying the length of "on" intervals, and the odd
+ indices specifying the length of "off" intervals.
+ count: number of elements in the intervals array
+ phase: offset into the intervals array (mod the sum of all of the
+ intervals).
+
+ For example: if intervals[] = {10, 20}, count = 2, and phase = 25,
+ this will set up a dashed path like so:
+ 5 pixels off
+ 10 pixels on
+ 20 pixels off
+ 10 pixels on
+ 20 pixels off
+ ...
+ A phase of -5, 25, 55, 85, etc. would all result in the same path,
+ because the sum of all the intervals is 30.
+
+ Note: only affects stroked paths.
+ */
+ static SkDashPathEffect* Create(const SkScalar intervals[], int count,
+ SkScalar phase) {
+ return SkNEW_ARGS(SkDashPathEffect, (intervals, count, phase));
+ }
+ virtual ~SkDashPathEffect();
+
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ virtual bool asPoints(PointData* results, const SkPath& src,
+ const SkStrokeRec&, const SkMatrix&,
+ const SkRect*) const SK_OVERRIDE;
+
+ virtual DashType asADash(DashInfo* info) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDashPathEffect)
+
+protected:
+ SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkDashPathEffect(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkScalar* fIntervals;
+ int32_t fCount;
+ SkScalar fPhase;
+ // computed from phase
+ SkScalar fInitialDashLength;
+ int32_t fInitialDashIndex;
+ SkScalar fIntervalLength;
+
+ typedef SkPathEffect INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkDiscretePathEffect.h b/src/third_party/skia/include/effects/SkDiscretePathEffect.h
new file mode 100644
index 0000000..8f1082c
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkDiscretePathEffect.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDiscretePathEffect_DEFINED
+#define SkDiscretePathEffect_DEFINED
+
+#include "SkPathEffect.h"
+
+/** \class SkDiscretePathEffect
+
+ This path effect chops a path into discrete segments, and randomly displaces them.
+*/
+class SK_API SkDiscretePathEffect : public SkPathEffect {
+public:
+ /** Break the path into segments of segLength length, and randomly move the endpoints
+ away from the original path by a maximum of deviation.
+ Note: works on filled or framed paths
+
+ @param seedAssist This is a caller-supplied seedAssist that modifies
+ the seed value that is used to randomize the path
+ segments' endpoints. If not supplied it defaults to 0,
+ in which case filtering a path multiple times will
+ result in the same set of segments (this is useful for
+ testing). If a caller does not want this behaviour
+ they can pass in a different seedAssist to get a
+ different set of path segments.
+ */
+ static SkDiscretePathEffect* Create(SkScalar segLength,
+ SkScalar deviation,
+ uint32_t seedAssist=0) {
+ return SkNEW_ARGS(SkDiscretePathEffect,
+ (segLength, deviation, seedAssist));
+ }
+
+ virtual bool filterPath(SkPath* dst, const SkPath& src,
+ SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiscretePathEffect)
+
+protected:
+ SkDiscretePathEffect(SkScalar segLength,
+ SkScalar deviation,
+ uint32_t seedAssist);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkDiscretePathEffect(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkScalar fSegLength, fPerterb;
+
+ /* Caller-supplied 32 bit seed assist */
+ uint32_t fSeedAssist;
+
+ typedef SkPathEffect INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkDisplacementMapEffect.h b/src/third_party/skia/include/effects/SkDisplacementMapEffect.h
new file mode 100644
index 0000000..0a658ac
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkDisplacementMapEffect.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDisplacementMapEffect_DEFINED
+#define SkDisplacementMapEffect_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkBitmap.h"
+
+class SK_API SkDisplacementMapEffect : public SkImageFilter {
+public:
+ enum ChannelSelectorType {
+ kUnknown_ChannelSelectorType,
+ kR_ChannelSelectorType,
+ kG_ChannelSelectorType,
+ kB_ChannelSelectorType,
+ kA_ChannelSelectorType
+ };
+
+ ~SkDisplacementMapEffect();
+
+ static SkDisplacementMapEffect* Create(ChannelSelectorType xChannelSelector,
+ ChannelSelectorType yChannelSelector,
+ SkScalar scale, SkImageFilter* displacement,
+ SkImageFilter* color = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0);
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
+
+ virtual bool onFilterImage(Proxy* proxy,
+ const SkBitmap& src,
+ const Context& ctx,
+ SkBitmap* dst,
+ SkIPoint* offset) const SK_OVERRIDE;
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
+
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
+ SkIRect* dst) const SK_OVERRIDE;
+
+#if SK_SUPPORT_GPU
+ virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
+ virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+#endif
+
+protected:
+ SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
+ ChannelSelectorType yChannelSelector,
+ SkScalar scale, SkImageFilter* inputs[2],
+ const CropRect* cropRect,
+ uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkDisplacementMapEffect(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ ChannelSelectorType fXChannelSelector;
+ ChannelSelectorType fYChannelSelector;
+ SkScalar fScale;
+ typedef SkImageFilter INHERITED;
+ const SkImageFilter* getDisplacementInput() const { return getInput(0); }
+ const SkImageFilter* getColorInput() const { return getInput(1); }
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkDrawExtraPathEffect.h b/src/third_party/skia/include/effects/SkDrawExtraPathEffect.h
new file mode 100644
index 0000000..392a46b
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkDrawExtraPathEffect.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SK_DRAW_EXTRA_PATH_EFFECT_H
+#define SK_DRAW_EXTRA_PATH_EFFECT_H
+
+class SkAnimator;
+
+void InitializeSkExtraPathEffects(SkAnimator* animator);
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkDropShadowImageFilter.h b/src/third_party/skia/include/effects/SkDropShadowImageFilter.h
new file mode 100644
index 0000000..0d6c24e
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkDropShadowImageFilter.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkColor.h"
+#include "SkImageFilter.h"
+#include "SkScalar.h"
+
+class SK_API SkDropShadowImageFilter : public SkImageFilter {
+public:
+ static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
+ SkScalar sigmaX, SkScalar sigmaY, SkColor color,
+ SkImageFilter* input = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0) {
+ return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY,
+ color, input, cropRect, uniqueID));
+ }
+ virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
+
+protected:
+ SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
+ SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkDropShadowImageFilter(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+ virtual bool onFilterImage(Proxy*, const SkBitmap& source, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
+ SkIRect* dst) const SK_OVERRIDE;
+
+private:
+ SkScalar fDx, fDy, fSigmaX, fSigmaY;
+ SkColor fColor;
+ typedef SkImageFilter INHERITED;
+};
diff --git a/src/third_party/skia/include/effects/SkEmbossMaskFilter.h b/src/third_party/skia/include/effects/SkEmbossMaskFilter.h
new file mode 100644
index 0000000..74895fb
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkEmbossMaskFilter.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkEmbossMaskFilter_DEFINED
+#define SkEmbossMaskFilter_DEFINED
+
+#include "SkMaskFilter.h"
+
+/** \class SkEmbossMaskFilter
+
+ This mask filter creates a 3D emboss look, by specifying a light and blur amount.
+*/
+class SK_API SkEmbossMaskFilter : public SkMaskFilter {
+public:
+ struct Light {
+ SkScalar fDirection[3]; // x,y,z
+ uint16_t fPad;
+ uint8_t fAmbient;
+ uint8_t fSpecular; // exponent, 4.4 right now
+ };
+
+ static SkEmbossMaskFilter* Create(SkScalar blurSigma, const Light& light);
+
+ // overrides from SkMaskFilter
+ // This method is not exported to java.
+ virtual SkMask::Format getFormat() const SK_OVERRIDE;
+ // This method is not exported to java.
+ virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
+ SkIPoint* margin) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmbossMaskFilter)
+
+protected:
+ SkEmbossMaskFilter(SkScalar blurSigma, const Light& light);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkEmbossMaskFilter(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ Light fLight;
+ SkScalar fBlurSigma;
+
+ typedef SkMaskFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkGradientShader.h b/src/third_party/skia/include/effects/SkGradientShader.h
new file mode 100644
index 0000000..8d1a931
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkGradientShader.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkGradientShader_DEFINED
+#define SkGradientShader_DEFINED
+
+#include "SkShader.h"
+
+#define SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
+
+/** \class SkGradientShader
+
+ SkGradientShader hosts factories for creating subclasses of SkShader that
+ render linear and radial gradients.
+*/
+class SK_API SkGradientShader {
+public:
+ enum Flags {
+ /** By default gradients will interpolate their colors in unpremul space
+ * and then premultiply each of the results. By setting this flag, the
+ * gradients will premultiply their colors first, and then interpolate
+ * between them.
+ */
+ kInterpolateColorsInPremul_Flag = 1 << 0,
+ };
+
+ /** Returns a shader that generates a linear gradient between the two
+ specified points.
+ <p />
+ CreateLinear returns a shader with a reference count of 1.
+ The caller should decrement the shader's reference count when done with the shader.
+ It is an error for count to be < 2.
+ @param pts The start and end points for the gradient.
+ @param colors The array[count] of colors, to be distributed between the two points
+ @param pos May be NULL. array[count] of SkScalars, or NULL, of the relative position of
+ each corresponding color in the colors array. If this is NULL,
+ the the colors are distributed evenly between the start and end point.
+ If this is not null, the values must begin with 0, end with 1.0, and
+ intermediate values must be strictly increasing.
+ @param count Must be >=2. The number of colors (and pos if not NULL) entries.
+ @param mode The tiling mode
+ */
+ static SkShader* CreateLinear(const SkPoint pts[2],
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode,
+ uint32_t flags, const SkMatrix* localMatrix);
+
+ static SkShader* CreateLinear(const SkPoint pts[2],
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode) {
+ return CreateLinear(pts, colors, pos, count, mode, 0, NULL);
+ }
+
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
+ static SkShader* CreateLinear(const SkPoint pts[2],
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode, void* ignored,
+ uint32_t flags, const SkMatrix* localMatrix) {
+ return CreateLinear(pts, colors, pos, count, mode, flags, localMatrix);
+ }
+#endif
+
+ /** Returns a shader that generates a radial gradient given the center and radius.
+ <p />
+ CreateRadial returns a shader with a reference count of 1.
+ The caller should decrement the shader's reference count when done with the shader.
+ It is an error for colorCount to be < 2, or for radius to be <= 0.
+ @param center The center of the circle for this gradient
+ @param radius Must be positive. The radius of the circle for this gradient
+ @param colors The array[count] of colors, to be distributed between the center and edge of the circle
+ @param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
+ each corresponding color in the colors array. If this is NULL,
+ the the colors are distributed evenly between the center and edge of the circle.
+ If this is not null, the values must begin with 0, end with 1.0, and
+ intermediate values must be strictly increasing.
+ @param count Must be >= 2. The number of colors (and pos if not NULL) entries
+ @param mode The tiling mode
+ */
+ static SkShader* CreateRadial(const SkPoint& center, SkScalar radius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode,
+ uint32_t flags, const SkMatrix* localMatrix);
+
+ static SkShader* CreateRadial(const SkPoint& center, SkScalar radius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode) {
+ return CreateRadial(center, radius, colors, pos, count, mode, 0, NULL);
+ }
+
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
+ static SkShader* CreateRadial(const SkPoint& center, SkScalar radius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode, void* ignored,
+ uint32_t flags, const SkMatrix* localMatrix) {
+ return CreateRadial(center, radius, colors, pos, count, mode, flags, localMatrix);
+ }
+#endif
+
+ /** Returns a shader that generates a radial gradient given the start position, start radius, end position and end radius.
+ <p />
+ CreateTwoPointRadial returns a shader with a reference count of 1.
+ The caller should decrement the shader's reference count when done with the shader.
+ It is an error for colorCount to be < 2, for startRadius or endRadius to be < 0, or for
+ startRadius to be equal to endRadius.
+ @param start The center of the start circle for this gradient
+ @param startRadius Must be positive. The radius of the start circle for this gradient.
+ @param end The center of the end circle for this gradient
+ @param endRadius Must be positive. The radius of the end circle for this gradient.
+ @param colors The array[count] of colors, to be distributed between the center and edge of the circle
+ @param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
+ each corresponding color in the colors array. If this is NULL,
+ the the colors are distributed evenly between the center and edge of the circle.
+ If this is not null, the values must begin with 0, end with 1.0, and
+ intermediate values must be strictly increasing.
+ @param count Must be >= 2. The number of colors (and pos if not NULL) entries
+ @param mode The tiling mode
+ */
+ static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
+ const SkPoint& end, SkScalar endRadius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode,
+ uint32_t flags, const SkMatrix* localMatrix);
+
+ static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
+ const SkPoint& end, SkScalar endRadius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode) {
+ return CreateTwoPointRadial(start, startRadius, end, endRadius, colors, pos, count, mode,
+ 0, NULL);
+ }
+
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
+ static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
+ const SkPoint& end, SkScalar endRadius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode, void* ignored,
+ uint32_t flags, const SkMatrix* localMatrix) {
+ return CreateTwoPointRadial(start, startRadius, end, endRadius, colors, pos, count, mode,
+ flags, localMatrix);
+ }
+#endif
+
+ /**
+ * Returns a shader that generates a conical gradient given two circles, or
+ * returns NULL if the inputs are invalid. The gradient interprets the
+ * two circles according to the following HTML spec.
+ * http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient
+ */
+ static SkShader* CreateTwoPointConical(const SkPoint& start, SkScalar startRadius,
+ const SkPoint& end, SkScalar endRadius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode,
+ uint32_t flags, const SkMatrix* localMatrix);
+
+ static SkShader* CreateTwoPointConical(const SkPoint& start, SkScalar startRadius,
+ const SkPoint& end, SkScalar endRadius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode) {
+ return CreateTwoPointConical(start, startRadius, end, endRadius, colors, pos, count, mode,
+ 0, NULL);
+ }
+
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
+ static SkShader* CreateTwoPointConical(const SkPoint& start, SkScalar startRadius,
+ const SkPoint& end, SkScalar endRadius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode, void* ignored,
+ uint32_t flags, const SkMatrix* localMatrix) {
+ return CreateTwoPointConical(start, startRadius, end, endRadius, colors, pos, count, mode,
+ flags, localMatrix);
+ }
+#endif
+
+ /** Returns a shader that generates a sweep gradient given a center.
+ <p />
+ CreateSweep returns a shader with a reference count of 1.
+ The caller should decrement the shader's reference count when done with the shader.
+ It is an error for colorCount to be < 2.
+ @param cx The X coordinate of the center of the sweep
+ @param cx The Y coordinate of the center of the sweep
+ @param colors The array[count] of colors, to be distributed around the center.
+ @param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
+ each corresponding color in the colors array. If this is NULL,
+ the the colors are distributed evenly between the center and edge of the circle.
+ If this is not null, the values must begin with 0, end with 1.0, and
+ intermediate values must be strictly increasing.
+ @param count Must be >= 2. The number of colors (and pos if not NULL) entries
+ */
+ static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
+ const SkColor colors[], const SkScalar pos[], int count,
+ uint32_t flags, const SkMatrix* localMatrix);
+
+ static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
+ const SkColor colors[], const SkScalar pos[], int count) {
+ return CreateSweep(cx, cy, colors, pos, count, 0, NULL);
+ }
+
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
+ static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
+ const SkColor colors[], const SkScalar pos[], int count,
+ void* ignored,
+ uint32_t flags, const SkMatrix* localMatrix) {
+ return CreateSweep(cx, cy, colors, pos, count, flags, localMatrix);
+ }
+#endif
+
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkLayerDrawLooper.h b/src/third_party/skia/include/effects/SkLayerDrawLooper.h
new file mode 100644
index 0000000..5bb8b66
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkLayerDrawLooper.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLayerDrawLooper_DEFINED
+#define SkLayerDrawLooper_DEFINED
+
+#include "SkDrawLooper.h"
+#include "SkPaint.h"
+#include "SkPoint.h"
+#include "SkXfermode.h"
+
+class SK_API SkLayerDrawLooper : public SkDrawLooper {
+public:
+ SK_DECLARE_INST_COUNT(SkLayerDrawLooper)
+
+ virtual ~SkLayerDrawLooper();
+
+ /**
+ * Bits specifies which aspects of the layer's paint should replace the
+ * corresponding aspects on the draw's paint.
+ * kEntirePaint_Bits means use the layer's paint completely.
+ * 0 means ignore the layer's paint... except for fColorMode, which is
+ * always applied.
+ */
+ enum Bits {
+ kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings
+ kTextSkewX_Bit = 1 << 1, //!< use this layer's textskewx
+ kPathEffect_Bit = 1 << 2, //!< use this layer's patheffect
+ kMaskFilter_Bit = 1 << 3, //!< use this layer's maskfilter
+ kShader_Bit = 1 << 4, //!< use this layer's shader
+ kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter
+ kXfermode_Bit = 1 << 6, //!< use this layer's xfermode
+
+ /**
+ * Use the layer's paint entirely, with these exceptions:
+ * - We never override the draw's paint's text_encoding, since that is
+ * used to interpret the text/len parameters in draw[Pos]Text.
+ * - Color is always computed using the LayerInfo's fColorMode.
+ */
+ kEntirePaint_Bits = -1
+
+ };
+ typedef int32_t BitFlags;
+
+ /**
+ * Info for how to apply the layer's paint and offset.
+ *
+ * fColorMode controls how we compute the final color for the layer:
+ * The layer's paint's color is treated as the SRC
+ * The draw's paint's color is treated as the DST
+ * final-color = Mode(layers-color, draws-color);
+ * Any SkXfermode::Mode will work. Two common choices are:
+ * kSrc_Mode: to use the layer's color, ignoring the draw's
+ * kDst_Mode: to just keep the draw's color, ignoring the layer's
+ */
+ struct SK_API LayerInfo {
+ BitFlags fPaintBits;
+ SkXfermode::Mode fColorMode;
+ SkVector fOffset;
+ bool fPostTranslate; //!< applies to fOffset
+
+ /**
+ * Initial the LayerInfo. Defaults to settings that will draw the
+ * layer with no changes: e.g.
+ * fPaintBits == 0
+ * fColorMode == kDst_Mode
+ * fOffset == (0, 0)
+ */
+ LayerInfo();
+ };
+
+ virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE;
+
+ virtual size_t contextSize() const SK_OVERRIDE { return sizeof(LayerDrawLooperContext); }
+
+ virtual bool asABlurShadow(BlurShadowRec* rec) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) {
+ return CreateProc(buffer);
+ }
+ virtual Factory getFactory() const SK_OVERRIDE { return DeepCreateProc; }
+#else
+ virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; }
+#endif
+ static SkFlattenable* CreateProc(SkReadBuffer& buffer);
+
+protected:
+ SkLayerDrawLooper();
+
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ struct Rec {
+ Rec* fNext;
+ SkPaint fPaint;
+ LayerInfo fInfo;
+ };
+ Rec* fRecs;
+ Rec* fTopRec;
+ int fCount;
+
+ // state-machine during the init/next cycle
+ class LayerDrawLooperContext : public SkDrawLooper::Context {
+ public:
+ explicit LayerDrawLooperContext(const SkLayerDrawLooper* looper);
+
+ protected:
+ virtual bool next(SkCanvas*, SkPaint* paint) SK_OVERRIDE;
+
+ private:
+ Rec* fCurrRec;
+
+ static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
+ };
+
+ class MyRegistrar : public SkFlattenable::Registrar {
+ public:
+ MyRegistrar();
+ };
+
+ typedef SkDrawLooper INHERITED;
+
+public:
+ class SK_API Builder {
+ public:
+ Builder();
+ ~Builder();
+
+ /**
+ * Call for each layer you want to add (from top to bottom).
+ * This returns a paint you can modify, but that ptr is only valid until
+ * the next call made to addLayer().
+ */
+ SkPaint* addLayer(const LayerInfo&);
+
+ /**
+ * This layer will draw with the original paint, at the specified offset
+ */
+ void addLayer(SkScalar dx, SkScalar dy);
+
+ /**
+ * This layer will with the original paint and no offset.
+ */
+ void addLayer() { this->addLayer(0, 0); }
+
+ /// Similar to addLayer, but adds a layer to the top.
+ SkPaint* addLayerOnTop(const LayerInfo&);
+
+ /**
+ * Pass list of layers on to newly built looper and return it. This will
+ * also reset the builder, so it can be used to build another looper.
+ */
+ SkLayerDrawLooper* detachLooper();
+
+ private:
+ Rec* fRecs;
+ Rec* fTopRec;
+ int fCount;
+ };
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkLayerRasterizer.h b/src/third_party/skia/include/effects/SkLayerRasterizer.h
new file mode 100644
index 0000000..60b3f20
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkLayerRasterizer.h
@@ -0,0 +1,92 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkLayerRasterizer_DEFINED
+#define SkLayerRasterizer_DEFINED
+
+#include "SkRasterizer.h"
+#include "SkDeque.h"
+#include "SkScalar.h"
+
+class SkPaint;
+
+class SK_API SkLayerRasterizer : public SkRasterizer {
+public:
+ virtual ~SkLayerRasterizer();
+
+ class SK_API Builder {
+ public:
+ Builder();
+ ~Builder();
+
+ void addLayer(const SkPaint& paint) {
+ this->addLayer(paint, 0, 0);
+ }
+
+ /**
+ * Add a new layer (above any previous layers) to the rasterizer.
+ * The layer will extract those fields that affect the mask from
+ * the specified paint, but will not retain a reference to the paint
+ * object itself, so it may be reused without danger of side-effects.
+ */
+ void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy);
+
+ /**
+ * Pass queue of layers on to newly created layer rasterizer and return it. The builder
+ * *cannot* be used any more after calling this function. If no layers have been added,
+ * returns NULL.
+ *
+ * The caller is responsible for calling unref() on the returned object, if non NULL.
+ */
+ SkLayerRasterizer* detachRasterizer();
+
+ /**
+ * Create and return a new immutable SkLayerRasterizer that contains a shapshot of the
+ * layers that were added to the Builder, without modifying the Builder. The Builder
+ * *may* be used after calling this function. It will continue to hold any layers
+ * previously added, so consecutive calls to this function will return identical objects,
+ * and objects returned by future calls to this function contain all the layers in
+ * previously returned objects. If no layers have been added, returns NULL.
+ *
+ * Future calls to addLayer will not affect rasterizers previously returned by this call.
+ *
+ * The caller is responsible for calling unref() on the returned object, if non NULL.
+ */
+ SkLayerRasterizer* snapshotRasterizer() const;
+
+ private:
+ SkDeque* fLayers;
+ };
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerRasterizer)
+
+protected:
+ SkLayerRasterizer();
+ SkLayerRasterizer(SkDeque* layers);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkLayerRasterizer(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ // override from SkRasterizer
+ virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
+ const SkIRect* clipBounds,
+ SkMask* mask, SkMask::CreateMode mode) const;
+
+private:
+ const SkDeque* const fLayers;
+
+ static SkDeque* ReadLayers(SkReadBuffer& buffer);
+
+ friend class LayerRasterizerTester;
+
+ typedef SkRasterizer INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkLerpXfermode.h b/src/third_party/skia/include/effects/SkLerpXfermode.h
new file mode 100644
index 0000000..d779f16
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkLerpXfermode.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLerpXfermode_DEFINED
+#define SkLerpXfermode_DEFINED
+
+#include "SkXfermode.h"
+
+class SK_API SkLerpXfermode : public SkXfermode {
+public:
+ /**
+ * result = scale * src + (1 - scale) * dst
+ *
+ * When scale == 1, this is the same as kSrc_Mode
+ * When scale == 0, this is the same as kDst_Mode
+ */
+ static SkXfermode* Create(SkScalar scale);
+
+ // overrides from SkXfermode
+ virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+ virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+ virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLerpXfermode)
+
+protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkLerpXfermode(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkLerpXfermode(unsigned scale256);
+
+ unsigned fScale256; // 0..256
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkLightingImageFilter.h b/src/third_party/skia/include/effects/SkLightingImageFilter.h
new file mode 100644
index 0000000..5fb0822
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkLightingImageFilter.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLightingImageFilter_DEFINED
+#define SkLightingImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkColor.h"
+
+class SK_API SkPoint3 {
+public:
+ SkPoint3() {}
+ SkPoint3(SkScalar x, SkScalar y, SkScalar z)
+ : fX(x), fY(y), fZ(z) {}
+ SkScalar dot(const SkPoint3& other) const {
+ return fX * other.fX + fY * other.fY + fZ * other.fZ;
+ }
+ SkScalar maxComponent() const {
+ return fX > fY ? (fX > fZ ? fX : fZ) : (fY > fZ ? fY : fZ);
+ }
+ void normalize() {
+ // Small epsilon is added to prevent division by 0.
+ SkScalar scale = SkScalarInvert(SkScalarSqrt(dot(*this)) + SK_ScalarNearlyZero);
+ fX = fX * scale;
+ fY = fY * scale;
+ fZ = fZ * scale;
+ }
+ SkPoint3 operator*(SkScalar scalar) const {
+ return SkPoint3(fX * scalar, fY * scalar, fZ * scalar);
+ }
+ SkPoint3 operator-(const SkPoint3& other) const {
+ return SkPoint3(fX - other.fX, fY - other.fY, fZ - other.fZ);
+ }
+ bool operator==(const SkPoint3& other) const {
+ return fX == other.fX && fY == other.fY && fZ == other.fZ;
+ }
+ SkScalar fX, fY, fZ;
+};
+
+class SkLight;
+
+class SK_API SkLightingImageFilter : public SkImageFilter {
+public:
+ static SkImageFilter* CreateDistantLitDiffuse(const SkPoint3& direction,
+ SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
+ SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+ static SkImageFilter* CreatePointLitDiffuse(const SkPoint3& location,
+ SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
+ SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+ static SkImageFilter* CreateSpotLitDiffuse(const SkPoint3& location,
+ const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
+ SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
+ SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+ static SkImageFilter* CreateDistantLitSpecular(const SkPoint3& direction,
+ SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
+ SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+ static SkImageFilter* CreatePointLitSpecular(const SkPoint3& location,
+ SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
+ SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+ static SkImageFilter* CreateSpotLitSpecular(const SkPoint3& location,
+ const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
+ SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
+ SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+ ~SkLightingImageFilter();
+
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+
+protected:
+ SkLightingImageFilter(SkLight* light,
+ SkScalar surfaceScale,
+ SkImageFilter* input,
+ const CropRect* cropRect,
+ uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkLightingImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+ const SkLight* light() const { return fLight.get(); }
+ SkScalar surfaceScale() const { return fSurfaceScale; }
+
+private:
+ typedef SkImageFilter INHERITED;
+ SkAutoTUnref<SkLight> fLight;
+ SkScalar fSurfaceScale;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkLumaColorFilter.h b/src/third_party/skia/include/effects/SkLumaColorFilter.h
new file mode 100644
index 0000000..420999f
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkLumaColorFilter.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLumaColorFilter_DEFINED
+#define SkLumaColorFilter_DEFINED
+
+#include "SkColorFilter.h"
+
+/**
+ * Luminance-to-alpha color filter, as defined in
+ * http://www.w3.org/TR/SVG/masking.html#Masking
+ * http://www.w3.org/TR/css-masking/#MaskValues
+ *
+ * The resulting color is black with transparency equal to the
+ * luminance value modulated by alpha:
+ *
+ * C' = [ Lum * a, 0, 0, 0 ]
+ *
+ */
+class SK_API SkLumaColorFilter : public SkColorFilter {
+public:
+ static SkColorFilter* Create();
+
+ virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const SK_OVERRIDE;
+
+#if SK_SUPPORT_GPU
+ virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+#endif
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLumaColorFilter)
+
+protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkLumaColorFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkLumaColorFilter();
+
+ typedef SkColorFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkMagnifierImageFilter.h b/src/third_party/skia/include/effects/SkMagnifierImageFilter.h
new file mode 100644
index 0000000..4dd47ef
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkMagnifierImageFilter.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMagnifierImageFilter_DEFINED
+#define SkMagnifierImageFilter_DEFINED
+
+#include "SkRect.h"
+#include "SkImageFilter.h"
+
+class SK_API SkMagnifierImageFilter : public SkImageFilter {
+public:
+ static SkImageFilter* Create(const SkRect& src, SkScalar inset, SkImageFilter* input = NULL);
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMagnifierImageFilter)
+
+protected:
+ SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset, SkImageFilter* input);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkMagnifierImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+ virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+ const SkIRect& bounds) const SK_OVERRIDE;
+#endif
+
+private:
+ SkRect fSrcRect;
+ SkScalar fInset;
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkMatrixConvolutionImageFilter.h b/src/third_party/skia/include/effects/SkMatrixConvolutionImageFilter.h
new file mode 100644
index 0000000..c04d7d1
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkMatrixConvolutionImageFilter.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMatrixConvolutionImageFilter_DEFINED
+#define SkMatrixConvolutionImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkScalar.h"
+#include "SkSize.h"
+#include "SkPoint.h"
+
+/*! \class SkMatrixConvolutionImageFilter
+ Matrix convolution image filter. This filter applies an NxM image
+ processing kernel to a given input image. This can be used to produce
+ effects such as sharpening, blurring, edge detection, etc.
+ */
+
+class SK_API SkMatrixConvolutionImageFilter : public SkImageFilter {
+public:
+ /*! \enum TileMode */
+ enum TileMode {
+ kClamp_TileMode = 0, /*!< Clamp to the image's edge pixels. */
+ kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */
+ kClampToBlack_TileMode, /*!< Fill with transparent black. */
+ kMax_TileMode = kClampToBlack_TileMode
+ };
+
+ virtual ~SkMatrixConvolutionImageFilter();
+
+ /** Construct a matrix convolution image filter.
+ @param kernelSize The kernel size in pixels, in each dimension (N by M).
+ @param kernel The image processing kernel. Must contain N * M
+ elements, in row order.
+ @param gain A scale factor applied to each pixel after
+ convolution. This can be used to normalize the
+ kernel, if it does not sum to 1.
+ @param bias A bias factor added to each pixel after convolution.
+ @param kernelOffset An offset applied to each pixel coordinate before
+ convolution. This can be used to center the kernel
+ over the image (e.g., a 3x3 kernel should have an
+ offset of {1, 1}).
+ @param tileMode How accesses outside the image are treated. (@see
+ TileMode).
+ @param convolveAlpha If true, all channels are convolved. If false,
+ only the RGB channels are convolved, and
+ alpha is copied from the source image.
+ @param input The input image filter. If NULL, the src bitmap
+ passed to filterImage() is used instead.
+ @param cropRect The rectangle to which the output processing will be limited.
+ */
+ static SkMatrixConvolutionImageFilter* Create(const SkISize& kernelSize,
+ const SkScalar* kernel,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ TileMode tileMode,
+ bool convolveAlpha,
+ SkImageFilter* input = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0);
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter)
+
+protected:
+ SkMatrixConvolutionImageFilter(const SkISize& kernelSize,
+ const SkScalar* kernel,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ TileMode tileMode,
+ bool convolveAlpha,
+ SkImageFilter* input,
+ const CropRect* cropRect,
+ uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkMatrixConvolutionImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE;
+
+
+#if SK_SUPPORT_GPU
+ virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
+ const SkIRect& bounds) const SK_OVERRIDE;
+#endif
+
+private:
+ SkISize fKernelSize;
+ SkScalar* fKernel;
+ SkScalar fGain;
+ SkScalar fBias;
+ SkIPoint fKernelOffset;
+ TileMode fTileMode;
+ bool fConvolveAlpha;
+ typedef SkImageFilter INHERITED;
+
+ template <class PixelFetcher, bool convolveAlpha>
+ void filterPixels(const SkBitmap& src,
+ SkBitmap* result,
+ const SkIRect& rect,
+ const SkIRect& bounds) const;
+ template <class PixelFetcher>
+ void filterPixels(const SkBitmap& src,
+ SkBitmap* result,
+ const SkIRect& rect,
+ const SkIRect& bounds) const;
+ void filterInteriorPixels(const SkBitmap& src,
+ SkBitmap* result,
+ const SkIRect& rect,
+ const SkIRect& bounds) const;
+ void filterBorderPixels(const SkBitmap& src,
+ SkBitmap* result,
+ const SkIRect& rect,
+ const SkIRect& bounds) const;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkMatrixImageFilter.h b/src/third_party/skia/include/effects/SkMatrixImageFilter.h
new file mode 100644
index 0000000..ae6a0b7
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkMatrixImageFilter.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMatrixImageFilter_DEFINED
+#define SkMatrixImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkScalar.h"
+#include "SkSize.h"
+#include "SkPoint.h"
+#include "SkPaint.h"
+
+/*! \class SkMatrixImageFilter
+ Matrix transformation image filter. This filter draws its source
+ input transformed by the given matrix.
+ */
+
+class SK_API SkMatrixImageFilter : public SkImageFilter {
+public:
+ /** Construct a 2D transformation image filter.
+ * @param transform The matrix to apply when drawing the src bitmap
+ * @param filterLevel The quality of filtering to apply when scaling.
+ * @param input The input image filter. If NULL, the src bitmap
+ * passed to filterImage() is used instead.
+ */
+
+ static SkMatrixImageFilter* Create(const SkMatrix& transform,
+ SkPaint::FilterLevel,
+ SkImageFilter* input = NULL,
+ uint32_t uniqueID = 0);
+ virtual ~SkMatrixImageFilter();
+
+ virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixImageFilter)
+
+protected:
+ SkMatrixImageFilter(const SkMatrix& transform,
+ SkPaint::FilterLevel,
+ SkImageFilter* input,
+ uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkMatrixImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
+ SkIRect* dst) const SK_OVERRIDE;
+
+private:
+ SkMatrix fTransform;
+ SkPaint::FilterLevel fFilterLevel;
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkMergeImageFilter.h b/src/third_party/skia/include/effects/SkMergeImageFilter.h
new file mode 100644
index 0000000..5e723aa
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkMergeImageFilter.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMergeImageFilter_DEFINED
+#define SkMergeImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+#include "SkXfermode.h"
+
+class SK_API SkMergeImageFilter : public SkImageFilter {
+public:
+ virtual ~SkMergeImageFilter();
+
+ static SkMergeImageFilter* Create(SkImageFilter* first, SkImageFilter* second,
+ SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0) {
+ SkImageFilter* inputs[2] = { first, second };
+ SkXfermode::Mode modes[2] = { mode, mode };
+ return SkNEW_ARGS(SkMergeImageFilter, (inputs, 2, modes, cropRect, uniqueID));
+ }
+ static SkMergeImageFilter* Create(SkImageFilter* filters[], int count,
+ const SkXfermode::Mode modes[] = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0) {
+ return SkNEW_ARGS(SkMergeImageFilter, (filters, count, modes, cropRect, uniqueID));
+ }
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
+
+protected:
+ SkMergeImageFilter(SkImageFilter* filters[], int count,
+ const SkXfermode::Mode modes[],
+ const CropRect* cropRect,
+ uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkMergeImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+
+private:
+ uint8_t* fModes; // SkXfermode::Mode
+
+ // private storage, to avoid dynamically allocating storage for our copy
+ // of the modes (unless the count is so large we can't fit).
+ intptr_t fStorage[16];
+
+ void initAllocModes();
+ void initModes(const SkXfermode::Mode []);
+
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkMorphologyImageFilter.h b/src/third_party/skia/include/effects/SkMorphologyImageFilter.h
new file mode 100644
index 0000000..3f2be45
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkMorphologyImageFilter.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMorphologyImageFilter_DEFINED
+#define SkMorphologyImageFilter_DEFINED
+
+#include "SkColor.h"
+#include "SkImageFilter.h"
+#include "SkSize.h"
+
+class SK_API SkMorphologyImageFilter : public SkImageFilter {
+public:
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const SK_OVERRIDE;
+
+ /**
+ * All morphology procs have the same signature: src is the source buffer, dst the
+ * destination buffer, radius is the morphology radius, width and height are the bounds
+ * of the destination buffer (in pixels), and srcStride and dstStride are the
+ * number of pixels per row in each buffer. All buffers are 8888.
+ */
+
+ typedef void (*Proc)(const SkPMColor* src, SkPMColor* dst, int radius,
+ int width, int height, int srcStride, int dstStride);
+
+protected:
+ SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input,
+ const CropRect* cropRect, uint32_t uniqueID);
+ bool filterImageGeneric(Proc procX, Proc procY,
+ Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const;
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkMorphologyImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+ virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
+ bool filterImageGPUGeneric(bool dilate, Proxy* proxy, const SkBitmap& src,
+ const Context& ctm, SkBitmap* result,
+ SkIPoint* offset) const;
+#endif
+
+ SkISize radius() const { return fRadius; }
+
+private:
+ SkISize fRadius;
+ typedef SkImageFilter INHERITED;
+};
+
+class SK_API SkDilateImageFilter : public SkMorphologyImageFilter {
+public:
+ static SkDilateImageFilter* Create(int radiusX, int radiusY,
+ SkImageFilter* input = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0) {
+ if (radiusX < 0 || radiusY < 0) {
+ return NULL;
+ }
+ return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect, uniqueID));
+ }
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+ virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+#endif
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter)
+
+protected:
+ SkDilateImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+ : INHERITED(radiusX, radiusY, input, cropRect, uniqueID) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkDilateImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+private:
+ typedef SkMorphologyImageFilter INHERITED;
+};
+
+class SK_API SkErodeImageFilter : public SkMorphologyImageFilter {
+public:
+ static SkErodeImageFilter* Create(int radiusX, int radiusY,
+ SkImageFilter* input = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0) {
+ if (radiusX < 0 || radiusY < 0) {
+ return NULL;
+ }
+ return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect, uniqueID));
+ }
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+ virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+#endif
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter)
+
+protected:
+ SkErodeImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+ : INHERITED(radiusX, radiusY, input, cropRect, uniqueID) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkErodeImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+private:
+ typedef SkMorphologyImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkOffsetImageFilter.h b/src/third_party/skia/include/effects/SkOffsetImageFilter.h
new file mode 100644
index 0000000..a870c0b
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkOffsetImageFilter.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkOffsetImageFilter_DEFINED
+#define SkOffsetImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkPoint.h"
+
+class SK_API SkOffsetImageFilter : public SkImageFilter {
+ typedef SkImageFilter INHERITED;
+
+public:
+ static SkOffsetImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0) {
+ if (!SkScalarIsFinite(dx) || !SkScalarIsFinite(dy)) {
+ return NULL;
+ }
+ return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect, uniqueID));
+ }
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter)
+
+protected:
+ SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkOffsetImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE;
+
+private:
+ SkVector fOffset;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkPaintFlagsDrawFilter.h b/src/third_party/skia/include/effects/SkPaintFlagsDrawFilter.h
new file mode 100644
index 0000000..cb2a8b7
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkPaintFlagsDrawFilter.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPaintFlagsDrawFilter_DEFINED
+#define SkPaintFlagsDrawFilter_DEFINED
+
+#include "SkDrawFilter.h"
+
+class SK_API SkPaintFlagsDrawFilter : public SkDrawFilter {
+public:
+ SkPaintFlagsDrawFilter(uint32_t clearFlags, uint32_t setFlags);
+
+ virtual bool filter(SkPaint*, Type) SK_OVERRIDE;
+
+private:
+ uint16_t fClearFlags; // user specified
+ uint16_t fSetFlags; // user specified
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkPerlinNoiseShader.h b/src/third_party/skia/include/effects/SkPerlinNoiseShader.h
new file mode 100644
index 0000000..2937926
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkPerlinNoiseShader.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPerlinNoiseShader_DEFINED
+#define SkPerlinNoiseShader_DEFINED
+
+#include "SkShader.h"
+
+/** \class SkPerlinNoiseShader
+
+ SkPerlinNoiseShader creates an image using the Perlin turbulence function.
+
+ It can produce tileable noise if asked to stitch tiles and provided a tile size.
+ In order to fill a large area with repeating noise, set the stitchTiles flag to
+ true, and render exactly a single tile of noise. Without this flag, the result
+ will contain visible seams between tiles.
+
+ The algorithm used is described here :
+ http://www.w3.org/TR/SVG/filters.html#feTurbulenceElement
+*/
+class SK_API SkPerlinNoiseShader : public SkShader {
+public:
+ struct StitchData;
+ struct PaintingData;
+
+ /**
+ * About the noise types : the difference between the 2 is just minor tweaks to the algorithm,
+ * they're not 2 entirely different noises. The output looks different, but once the noise is
+ * generated in the [1, -1] range, the output is brought back in the [0, 1] range by doing :
+ * kFractalNoise_Type : noise * 0.5 + 0.5
+ * kTurbulence_Type : abs(noise)
+ * Very little differences between the 2 types, although you can tell the difference visually.
+ */
+ enum Type {
+ kFractalNoise_Type,
+ kTurbulence_Type,
+ kFirstType = kFractalNoise_Type,
+ kLastType = kTurbulence_Type
+ };
+ /**
+ * This will construct Perlin noise of the given type (Fractal Noise or Turbulence).
+ *
+ * Both base frequencies (X and Y) have a usual range of (0..1).
+ *
+ * The number of octaves provided should be fairly small, although no limit is enforced.
+ * Each octave doubles the frequency, so 10 octaves would produce noise from
+ * baseFrequency * 1, * 2, * 4, ..., * 512, which quickly yields insignificantly small
+ * periods and resembles regular unstructured noise rather than Perlin noise.
+ *
+ * If tileSize isn't NULL or an empty size, the tileSize parameter will be used to modify
+ * the frequencies so that the noise will be tileable for the given tile size. If tileSize
+ * is NULL or an empty size, the frequencies will be used as is without modification.
+ */
+ static SkShader* CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
+ int numOctaves, SkScalar seed,
+ const SkISize* tileSize = NULL);
+ static SkShader* CreateTurbulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
+ int numOctaves, SkScalar seed,
+ const SkISize* tileSize = NULL);
+ /**
+ * Create alias for CreateTurbulunce until all Skia users changed
+ * its code to use the new naming
+ */
+ static SkShader* CreateTubulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
+ int numOctaves, SkScalar seed,
+ const SkISize* tileSize = NULL) {
+ return CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed, tileSize);
+ }
+
+
+ virtual size_t contextSize() const SK_OVERRIDE;
+
+ class PerlinNoiseShaderContext : public SkShader::Context {
+ public:
+ PerlinNoiseShaderContext(const SkPerlinNoiseShader& shader, const ContextRec&);
+ virtual ~PerlinNoiseShaderContext();
+
+ virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
+ virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE;
+
+ private:
+ SkPMColor shade(const SkPoint& point, StitchData& stitchData) const;
+ SkScalar calculateTurbulenceValueForPoint(
+ int channel,
+ StitchData& stitchData, const SkPoint& point) const;
+ SkScalar noise2D(int channel,
+ const StitchData& stitchData, const SkPoint& noiseVector) const;
+
+ SkMatrix fMatrix;
+ PaintingData* fPaintingData;
+
+ typedef SkShader::Context INHERITED;
+ };
+
+ virtual bool asFragmentProcessor(GrContext* context, const SkPaint&, const SkMatrix*, GrColor*,
+ GrFragmentProcessor**) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader)
+
+protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkPerlinNoiseShader(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+ virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
+
+private:
+ SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX,
+ SkScalar baseFrequencyY, int numOctaves, SkScalar seed,
+ const SkISize* tileSize);
+ virtual ~SkPerlinNoiseShader();
+
+ // TODO (scroggo): Once all SkShaders are created from a factory, and we have removed the
+ // constructor that creates SkPerlinNoiseShader from an SkReadBuffer, several fields can
+ // be made constant.
+ /*const*/ SkPerlinNoiseShader::Type fType;
+ /*const*/ SkScalar fBaseFrequencyX;
+ /*const*/ SkScalar fBaseFrequencyY;
+ /*const*/ int fNumOctaves;
+ /*const*/ SkScalar fSeed;
+ /*const*/ SkISize fTileSize;
+ /*const*/ bool fStitchTiles;
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkPictureImageFilter.h b/src/third_party/skia/include/effects/SkPictureImageFilter.h
new file mode 100644
index 0000000..fbd04f0
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkPictureImageFilter.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPictureImageFilter_DEFINED
+#define SkPictureImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkPicture.h"
+
+class SK_API SkPictureImageFilter : public SkImageFilter {
+public:
+ /**
+ * Refs the passed-in picture.
+ */
+ static SkPictureImageFilter* Create(const SkPicture* picture, int32_t uniqueID = 0) {
+ return SkNEW_ARGS(SkPictureImageFilter, (picture, uniqueID));
+ }
+
+ /**
+ * Refs the passed-in picture. cropRect can be used to crop or expand the destination rect when
+ * the picture is drawn. (No scaling is implied by the dest rect; only the CTM is applied.)
+ */
+ static SkPictureImageFilter* Create(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID = 0) {
+ return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect, uniqueID));
+ }
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
+
+protected:
+ explicit SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID);
+ SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID);
+ virtual ~SkPictureImageFilter();
+ /* Constructs an SkPictureImageFilter object from an SkReadBuffer.
+ * Note: If the SkPictureImageFilter object construction requires bitmap
+ * decoding, the decoder must be set on the SkReadBuffer parameter by calling
+ * SkReadBuffer::setBitmapDecoder() before calling this constructor.
+ * @param SkReadBuffer Serialized picture data.
+ */
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkPictureImageFilter(SkReadBuffer&);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
+ SkIRect* dst) const SK_OVERRIDE;
+
+private:
+ const SkPicture* fPicture;
+ SkRect fCropRect;
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkPixelXorXfermode.h b/src/third_party/skia/include/effects/SkPixelXorXfermode.h
new file mode 100644
index 0000000..eb485b4
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkPixelXorXfermode.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPixelXorXfermode_DEFINED
+#define SkPixelXorXfermode_DEFINED
+
+#include "SkXfermode.h"
+
+/** SkPixelXorXfermode implements a simple pixel xor (op ^ src ^ dst).
+ This transformation does not follow premultiplied conventions, therefore
+ this proc *always* returns an opaque color (alpha == 255). Thus it is
+ not really usefull for operating on blended colors.
+*/
+class SK_API SkPixelXorXfermode : public SkXfermode {
+public:
+ static SkPixelXorXfermode* Create(SkColor opColor) {
+ return SkNEW_ARGS(SkPixelXorXfermode, (opColor));
+ }
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPixelXorXfermode)
+
+protected:
+ explicit SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkPixelXorXfermode(SkReadBuffer& rb);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ // override from SkXfermode
+ virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
+
+private:
+ SkColor fOpColor;
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkPorterDuff.h b/src/third_party/skia/include/effects/SkPorterDuff.h
new file mode 100644
index 0000000..e984e8e
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkPorterDuff.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPorterDuff_DEFINED
+#define SkPorterDuff_DEFINED
+
+#include "SkColor.h"
+#include "SkXfermode.h"
+
+class SkXfermode;
+
+class SK_API SkPorterDuff {
+public:
+ /** List of predefined xfermodes. In general, the algebra for the modes
+ uses the following symbols:
+ Sa, Sc - source alpha and color
+ Da, Dc - destination alpha and color (before compositing)
+ [a, c] - Resulting (alpha, color) values
+ For these equations, the colors are in premultiplied state.
+ If no xfermode is specified, kSrcOver is assumed.
+ */
+ enum Mode {
+ kClear_Mode, //!< [0, 0]
+ kSrc_Mode, //!< [Sa, Sc]
+ kDst_Mode, //!< [Da, Dc]
+ kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Sc + (1 - Sa)*Dc]
+ kDstOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Dc + (1 - Da)*Sc]
+ kSrcIn_Mode, //!< [Sa * Da, Sc * Da]
+ kDstIn_Mode, //!< [Sa * Da, Sa * Dc]
+ kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)]
+ kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
+ kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
+ kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
+ kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
+ kDarken_Mode, //!< [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]
+ kLighten_Mode, //!< [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]
+ kModulate_Mode, //!< [Sa * Da, Sc * Dc] multiplies all components
+ kScreen_Mode, //!< [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
+ kAdd_Mode, //!< Saturate(S + D)
+#ifdef SK_BUILD_FOR_ANDROID
+ kOverlay_Mode,
+#endif
+
+ kModeCount
+ };
+
+ /** Return an SkXfermode object for the specified mode.
+ */
+ static SkXfermode* CreateXfermode(Mode mode);
+
+ /** Return a function pointer to a routine that applies the specified
+ porter-duff transfer mode.
+ */
+ static SkXfermodeProc GetXfermodeProc(Mode mode);
+
+ /** Return a function pointer to a routine that applies the specified
+ porter-duff transfer mode and srcColor to a 16bit device color. Note,
+ if the mode+srcColor might return a non-opaque color, then there is not
+ 16bit proc, and this will return NULL.
+ */
+ static SkXfermodeProc16 GetXfermodeProc16(Mode mode, SkColor srcColor);
+
+ /** If the specified xfermode advertises itself as one of the porterduff
+ modes (via SkXfermode::Coeff), return true and if not null, set mode
+ to the corresponding porterduff mode. If it is not recognized as a one,
+ return false and ignore the mode parameter.
+ */
+ static bool IsMode(SkXfermode*, Mode* mode);
+
+ /** Return the corersponding SkXfermode::Mode
+ */
+ static SkXfermode::Mode ToXfermodeMode(Mode);
+} SK_ATTR_DEPRECATED("use SkXfermode::Mode");
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkRectShaderImageFilter.h b/src/third_party/skia/include/effects/SkRectShaderImageFilter.h
new file mode 100644
index 0000000..c4311db
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkRectShaderImageFilter.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRectShaderImageFilter_DEFINED
+#define SkRectShaderImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkRect.h"
+
+class SkShader;
+
+class SK_API SkRectShaderImageFilter : public SkImageFilter {
+public:
+ /** Create a new image filter which fills the given rectangle with pixels
+ * produced by the given SkShader. If no rectangle is specified, an output
+ * is produced with the same bounds as the input primitive (even though
+ * the input primitive's pixels are not used for processing).
+ * @param s Shader to call for processing. Cannot be NULL. Will be
+ * ref'ed by the new image filter.
+ * @param rect Rectangle of output pixels in which to apply the shader.
+ * If NULL or a given crop edge is not specified, the source
+ * primitive's bounds are used instead.
+ */
+ SK_ATTR_DEPRECATED("use Create(SkShader*, const CropRect*)")
+ static SkRectShaderImageFilter* Create(SkShader* s, const SkRect& rect);
+
+ static SkRectShaderImageFilter* Create(SkShader* s, const CropRect* rect = NULL, uint32_t uniqueID = 0);
+ virtual ~SkRectShaderImageFilter();
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRectShaderImageFilter)
+
+protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkRectShaderImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+
+private:
+ SkRectShaderImageFilter(SkShader* s, const CropRect* rect, uint32_t uniqueID = 0);
+ SkShader* fShader;
+
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkTableColorFilter.h b/src/third_party/skia/include/effects/SkTableColorFilter.h
new file mode 100644
index 0000000..5714d07
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkTableColorFilter.h
@@ -0,0 +1,36 @@
+
+#ifndef SkTableColorFilter_DEFINED
+#define SkTableColorFilter_DEFINED
+
+#include "SkColorFilter.h"
+
+class SK_API SkTableColorFilter {
+public:
+ /**
+ * Create a table colorfilter, copying the table into the filter, and
+ * applying it to all 4 components.
+ * a' = table[a];
+ * r' = table[r];
+ * g' = table[g];
+ * b' = table[b];
+ * Compoents are operated on in unpremultiplied space. If the incomming
+ * colors are premultiplied, they are temporarily unpremultiplied, then
+ * the table is applied, and then the result is remultiplied.
+ */
+ static SkColorFilter* Create(const uint8_t table[256]);
+
+ /**
+ * Create a table colorfilter, with a different table for each
+ * component [A, R, G, B]. If a given table is NULL, then it is
+ * treated as identity, with the component left unchanged. If a table
+ * is not null, then its contents are copied into the filter.
+ */
+ static SkColorFilter* CreateARGB(const uint8_t tableA[256],
+ const uint8_t tableR[256],
+ const uint8_t tableG[256],
+ const uint8_t tableB[256]);
+
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkTableMaskFilter.h b/src/third_party/skia/include/effects/SkTableMaskFilter.h
new file mode 100644
index 0000000..8b94179
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkTableMaskFilter.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTableMaskFilter_DEFINED
+#define SkTableMaskFilter_DEFINED
+
+#include "SkMaskFilter.h"
+#include "SkScalar.h"
+
+/** \class SkTableMaskFilter
+
+ Applies a table lookup on each of the alpha values in the mask.
+ Helper methods create some common tables (e.g. gamma, clipping)
+ */
+class SK_API SkTableMaskFilter : public SkMaskFilter {
+public:
+ virtual ~SkTableMaskFilter();
+
+ /** Utility that sets the gamma table
+ */
+ static void MakeGammaTable(uint8_t table[256], SkScalar gamma);
+
+ /** Utility that creates a clipping table: clamps values below min to 0
+ and above max to 255, and rescales the remaining into 0..255
+ */
+ static void MakeClipTable(uint8_t table[256], uint8_t min, uint8_t max);
+
+ static SkTableMaskFilter* Create(const uint8_t table[256]) {
+ return SkNEW_ARGS(SkTableMaskFilter, (table));
+ }
+
+ static SkTableMaskFilter* CreateGamma(SkScalar gamma) {
+ uint8_t table[256];
+ MakeGammaTable(table, gamma);
+ return SkNEW_ARGS(SkTableMaskFilter, (table));
+ }
+
+ static SkTableMaskFilter* CreateClip(uint8_t min, uint8_t max) {
+ uint8_t table[256];
+ MakeClipTable(table, min, max);
+ return SkNEW_ARGS(SkTableMaskFilter, (table));
+ }
+
+ virtual SkMask::Format getFormat() const SK_OVERRIDE;
+ virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&,
+ SkIPoint*) const SK_OVERRIDE;
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTableMaskFilter)
+
+protected:
+ SkTableMaskFilter();
+ explicit SkTableMaskFilter(const uint8_t table[256]);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkTableMaskFilter(SkReadBuffer& rb);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ uint8_t fTable[256];
+
+ typedef SkMaskFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkTestImageFilters.h b/src/third_party/skia/include/effects/SkTestImageFilters.h
new file mode 100644
index 0000000..a8186e0
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkTestImageFilters.h
@@ -0,0 +1,40 @@
+#ifndef _SkTestImageFilters_h
+#define _SkTestImageFilters_h
+
+#include "SkImageFilter.h"
+#include "SkPoint.h"
+
+// Fun mode that scales down (only) and then scales back up to look pixelated
+class SK_API SkDownSampleImageFilter : public SkImageFilter {
+public:
+ static SkDownSampleImageFilter* Create(SkScalar scale, SkImageFilter* input = NULL) {
+ if (!SkScalarIsFinite(scale)) {
+ return NULL;
+ }
+ // we don't support scale in this range
+ if (scale > SK_Scalar1 || scale <= 0) {
+ return NULL;
+ }
+ return SkNEW_ARGS(SkDownSampleImageFilter, (scale, input));
+ }
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDownSampleImageFilter)
+
+protected:
+ SkDownSampleImageFilter(SkScalar scale, SkImageFilter* input)
+ : INHERITED(1, &input), fScale(scale) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkDownSampleImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+
+private:
+ SkScalar fScale;
+
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkTileImageFilter.h b/src/third_party/skia/include/effects/SkTileImageFilter.h
new file mode 100644
index 0000000..440337a
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkTileImageFilter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTileImageFilter_DEFINED
+#define SkTileImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SK_API SkTileImageFilter : public SkImageFilter {
+ typedef SkImageFilter INHERITED;
+
+public:
+ /** Create a tile image filter
+ @param srcRect Defines the pixels to tile
+ @param dstRect Defines the pixels where tiles are drawn
+ @param input Input from which the subregion defined by srcRect will be tiled
+ */
+ static SkTileImageFilter* Create(const SkRect& srcRect, const SkRect& dstRect,
+ SkImageFilter* input, uint32_t uniqueID = 0);
+
+ virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
+ SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE;
+ virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
+ SkIRect* dst) const SK_OVERRIDE;
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTileImageFilter)
+
+protected:
+ SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input, uint32_t uniqueID)
+ : INHERITED(1, &input, NULL, uniqueID), fSrcRect(srcRect), fDstRect(dstRect) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkTileImageFilter(SkReadBuffer& buffer);
+#endif
+
+ virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
+
+private:
+ SkRect fSrcRect;
+ SkRect fDstRect;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkTransparentShader.h b/src/third_party/skia/include/effects/SkTransparentShader.h
new file mode 100644
index 0000000..e23687c
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkTransparentShader.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTransparentShader_DEFINED
+#define SkTransparentShader_DEFINED
+
+#include "SkShader.h"
+
+class SK_API SkTransparentShader : public SkShader {
+public:
+ SkTransparentShader() {}
+
+ virtual size_t contextSize() const SK_OVERRIDE;
+
+ class TransparentShaderContext : public SkShader::Context {
+ public:
+ TransparentShaderContext(const SkTransparentShader& shader, const ContextRec&);
+ virtual ~TransparentShaderContext();
+
+ virtual uint32_t getFlags() const SK_OVERRIDE;
+ virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
+ virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
+
+ private:
+ const SkBitmap* fDevice;
+
+ typedef SkShader::Context INHERITED;
+ };
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTransparentShader)
+
+protected:
+ virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
+
+ // we don't need to flatten anything at all
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE {}
+
+private:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ SkTransparentShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/effects/SkXfermodeImageFilter.h b/src/third_party/skia/include/effects/SkXfermodeImageFilter.h
new file mode 100644
index 0000000..6736889
--- /dev/null
+++ b/src/third_party/skia/include/effects/SkXfermodeImageFilter.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkXfermodeImageFilter_DEFINED
+#define SkXfermodeImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SkBitmap;
+class SkXfermode;
+
+class SK_API SkXfermodeImageFilter : public SkImageFilter {
+ /**
+ * This filter takes an xfermode, and uses it to composite the foreground
+ * over the background. If foreground or background is NULL, the input
+ * bitmap (src) is used instead.
+ */
+
+public:
+ virtual ~SkXfermodeImageFilter();
+
+ static SkXfermodeImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
+ SkImageFilter* foreground = NULL,
+ const CropRect* cropRect = NULL,
+ uint32_t uniqueID = 0) {
+ SkImageFilter* inputs[2] = { background, foreground };
+ return SkNEW_ARGS(SkXfermodeImageFilter, (mode, inputs, cropRect, uniqueID));
+ }
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter)
+
+ virtual bool onFilterImage(Proxy* proxy,
+ const SkBitmap& src,
+ const Context& ctx,
+ SkBitmap* dst,
+ SkIPoint* offset) const SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+ virtual bool canFilterImageGPU() const SK_OVERRIDE;
+ virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
+ SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
+#endif
+
+protected:
+ SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* inputs[2],
+ const CropRect* cropRect, uint32_t uniqueID);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit SkXfermodeImageFilter(SkReadBuffer& buffer);
+#endif
+ virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkXfermode* fMode;
+ typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrBackendProcessorFactory.h b/src/third_party/skia/include/gpu/GrBackendProcessorFactory.h
new file mode 100644
index 0000000..b51a474
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrBackendProcessorFactory.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrBackendProcessorFactory_DEFINED
+#define GrBackendProcessorFactory_DEFINED
+
+#include "GrTypes.h"
+#include "SkTemplates.h"
+#include "SkThread.h"
+#include "SkTypes.h"
+#include "SkTArray.h"
+
+class GrGLProcessor;
+class GrGLCaps;
+class GrProcessor;
+
+/**
+ * Used by effects to build their keys. It incorporates each per-processor key into a larger shader
+ * key.
+ */
+class GrProcessorKeyBuilder {
+public:
+ GrProcessorKeyBuilder(SkTArray<unsigned char, true>* data) : fData(data), fCount(0) {
+ SkASSERT(0 == fData->count() % sizeof(uint32_t));
+ }
+
+ void add32(uint32_t v) {
+ ++fCount;
+ fData->push_back_n(4, reinterpret_cast<uint8_t*>(&v));
+ }
+
+ /** Inserts count uint32_ts into the key. The returned pointer is only valid until the next
+ add*() call. */
+ uint32_t* SK_WARN_UNUSED_RESULT add32n(int count) {
+ SkASSERT(count > 0);
+ fCount += count;
+ return reinterpret_cast<uint32_t*>(fData->push_back_n(4 * count));
+ }
+
+ size_t size() const { return sizeof(uint32_t) * fCount; }
+
+private:
+ SkTArray<uint8_t, true>* fData; // unowned ptr to the larger key.
+ int fCount; // number of uint32_ts added to fData by the effect.
+};
+
+/**
+ * This class is used to pass the key that was created for a GrGLProcessor back to it
+ * when it emits code. It may allow the emit step to skip calculations that were
+ * performed when computing the key.
+ */
+class GrProcessorKey {
+public:
+ GrProcessorKey(const uint32_t* key, int count) : fKey(key), fCount(count) {
+ SkASSERT(0 == reinterpret_cast<intptr_t>(key) % sizeof(uint32_t));
+ }
+
+ /** Gets the uint32_t values that the effect inserted into the key. */
+ uint32_t get32(int index) const {
+ SkASSERT(index >=0 && index < fCount);
+ return fKey[index];
+ }
+
+ /** Gets the number of uint32_t values that the effect inserted into the key. */
+ int count32() const { return fCount; }
+
+private:
+ const uint32_t* fKey; // unowned ptr into the larger key.
+ int fCount; // number of uint32_ts inserted by the effect into its key.
+};
+
+/**
+ * Given a GrProcessor of a particular type, creates the corresponding graphics-backend-specific
+ * effect object. It also tracks equivalence of shaders generated via a key. The factory for an
+ * effect is accessed via GrProcessor::getFactory(). Each factory instance is assigned an ID at
+ * construction. The ID of GrProcessor::getFactory() is used as a type identifier. Thus, a
+ * GrProcessor subclass must always return the same object from getFactory() and that factory object
+ * must be unique to the GrProcessor subclass (and unique from any further derived subclasses).
+ *
+ * Rather than subclassing this class themselves, it is recommended that GrProcessor authors use
+ * the templated subclass GrTBackendEffectFactory by writing their getFactory() method as:
+ *
+ * const GrBackendEffectFactory& MyEffect::getFactory() const {
+ * return GrTBackendEffectFactory<MyEffect>::getInstance();
+ * }
+ *
+ * Using GrTBackendEffectFactory places a few constraints on the effect. See that class's comments.
+ */
+class GrBackendProcessorFactory : SkNoncopyable {
+public:
+ /**
+ * Generates an effect's key. The key is based on the aspects of the GrProcessor object's
+ * configuration that affect GLSL code generation. Two GrProcessor instances that would cause
+ * this->createGLInstance()->emitCode() to produce different code must produce different keys.
+ */
+ virtual void getGLProcessorKey(const GrProcessor&, const GrGLCaps&,
+ GrProcessorKeyBuilder*) const = 0;
+
+ /**
+ * Produces a human-reable name for the effect.
+ */
+ virtual const char* name() const = 0;
+
+ /**
+ * A unique value for every instance of this factory. It is automatically incorporated into the
+ * effect's key. This allows keys generated by getGLProcessorKey() to only be unique within a
+ * GrProcessor subclass and not necessarily across subclasses.
+ */
+ uint32_t effectClassID() const { return fEffectClassID; }
+
+protected:
+ GrBackendProcessorFactory() : fEffectClassID(GenID()) {}
+ virtual ~GrBackendProcessorFactory() {}
+
+private:
+ enum {
+ kIllegalEffectClassID = 0,
+ };
+
+ static uint32_t GenID() {
+ // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
+ // atomic inc returns the old value not the incremented value. So we add
+ // 1 to the returned value.
+ uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&fCurrEffectClassID)) + 1;
+ if (!id) {
+ SkFAIL("This should never wrap as it should only be called once for each GrProcessor "
+ "subclass.");
+ }
+ return id;
+ }
+
+ const uint32_t fEffectClassID;
+ static int32_t fCurrEffectClassID;
+};
+
+class GrFragmentProcessor;
+class GrGeometryProcessor;
+class GrGLFragmentProcessor;
+class GrGLGeometryProcessor;
+
+/**
+ * Backend processor factory cannot actually create anything, it is up to subclasses to implement
+ * a create binding which matches Gr to GL in a type safe way
+ */
+
+class GrBackendFragmentProcessorFactory : public GrBackendProcessorFactory {
+public:
+ /**
+ * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a
+ * GLSL program and to manage updating uniforms for the program when it is used.
+ */
+ virtual GrGLFragmentProcessor* createGLInstance(const GrFragmentProcessor&) const = 0;
+};
+
+class GrBackendGeometryProcessorFactory : public GrBackendProcessorFactory {
+public:
+ /**
+ * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a
+ * GLSL program and to manage updating uniforms for the program when it is used.
+ */
+ virtual GrGLGeometryProcessor* createGLInstance(const GrGeometryProcessor&) const = 0;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrBinHashKey.h b/src/third_party/skia/include/gpu/GrBinHashKey.h
new file mode 100644
index 0000000..585a1a1
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrBinHashKey.h
@@ -0,0 +1,102 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrBinHashKey_DEFINED
+#define GrBinHashKey_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ * GrBinHashKey is a hash key class that can take a data chunk of any predetermined
+ * length. The hash function used is the One-at-a-Time Hash
+ * (http://burtleburtle.net/bob/hash/doobs.html).
+ */
+template<size_t KEY_SIZE>
+class GrBinHashKey {
+public:
+ enum { kKeySize = KEY_SIZE };
+
+ GrBinHashKey() {
+ this->reset();
+ }
+
+ void reset() {
+ fHash = 0;
+#ifdef SK_DEBUG
+ fIsValid = false;
+#endif
+ }
+
+ void setKeyData(const uint32_t* SK_RESTRICT data) {
+ SK_COMPILE_ASSERT(KEY_SIZE % 4 == 0, key_size_mismatch);
+ memcpy(&fData, data, KEY_SIZE);
+
+ uint32_t hash = 0;
+ size_t len = KEY_SIZE;
+ while (len >= 4) {
+ hash += *data++;
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ len -= 4;
+ }
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+#ifdef SK_DEBUG
+ fIsValid = true;
+#endif
+ fHash = hash;
+ }
+
+ bool operator==(const GrBinHashKey<KEY_SIZE>& key) const {
+ SkASSERT(fIsValid && key.fIsValid);
+ if (fHash != key.fHash) {
+ return false;
+ }
+ for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) {
+ if (fData[i] != key.fData[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool operator<(const GrBinHashKey<KEY_SIZE>& key) const {
+ SkASSERT(fIsValid && key.fIsValid);
+ for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) {
+ if (fData[i] < key.fData[i]) {
+ return true;
+ } else if (fData[i] > key.fData[i]) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ uint32_t getHash() const {
+ SkASSERT(fIsValid);
+ return fHash;
+ }
+
+ const uint8_t* getData() const {
+ SkASSERT(fIsValid);
+ return reinterpret_cast<const uint8_t*>(fData);
+ }
+
+private:
+ uint32_t fHash;
+ uint32_t fData[KEY_SIZE / sizeof(uint32_t)]; // Buffer for key storage.
+
+#ifdef SK_DEBUG
+public:
+ bool fIsValid;
+#endif
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrClipData.h b/src/third_party/skia/include/gpu/GrClipData.h
new file mode 100644
index 0000000..12a23b3
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrClipData.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrClip_DEFINED
+#define GrClip_DEFINED
+
+#include "SkClipStack.h"
+#include "GrSurface.h"
+
+struct SkIRect;
+
+/**
+ * GrClipData encapsulates the information required to construct the clip
+ * masks. 'fOrigin' is only non-zero when saveLayer has been called
+ * with an offset bounding box. The clips in 'fClipStack' are in
+ * device coordinates (i.e., they have been translated by -fOrigin w.r.t.
+ * the canvas' device coordinates).
+ */
+class GrClipData : SkNoncopyable {
+public:
+ const SkClipStack* fClipStack;
+ SkIPoint fOrigin;
+
+ GrClipData()
+ : fClipStack(NULL) {
+ fOrigin.setZero();
+ }
+
+ bool operator==(const GrClipData& other) const {
+ if (fOrigin != other.fOrigin) {
+ return false;
+ }
+
+ if (fClipStack && other.fClipStack) {
+ return *fClipStack == *other.fClipStack;
+ }
+
+ return fClipStack == other.fClipStack;
+ }
+
+ bool operator!=(const GrClipData& other) const {
+ return !(*this == other);
+ }
+
+ void getConservativeBounds(const GrSurface* surface,
+ SkIRect* devResult,
+ bool* isIntersectionOfRects = NULL) const {
+ this->getConservativeBounds(surface->width(), surface->height(),
+ devResult, isIntersectionOfRects);
+ }
+
+ void getConservativeBounds(int width, int height,
+ SkIRect* devResult,
+ bool* isIntersectionOfRects = NULL) const;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrColor.h b/src/third_party/skia/include/gpu/GrColor.h
new file mode 100644
index 0000000..4ab709b
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrColor.h
@@ -0,0 +1,163 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrColor_DEFINED
+#define GrColor_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ * GrColor is 4 bytes for R, G, B, A, in a specific order defined below. The components are stored
+ * premultiplied.
+ */
+typedef uint32_t GrColor;
+
+// shift amount to assign a component to a GrColor int
+// These shift values are chosen for compatibility with GL attrib arrays
+// ES doesn't allow BGRA vertex attrib order so if they were not in this order
+// we'd have to swizzle in shaders.
+#ifdef SK_CPU_BENDIAN
+ #define GrColor_SHIFT_R 24
+ #define GrColor_SHIFT_G 16
+ #define GrColor_SHIFT_B 8
+ #define GrColor_SHIFT_A 0
+#else
+ #define GrColor_SHIFT_R 0
+ #define GrColor_SHIFT_G 8
+ #define GrColor_SHIFT_B 16
+ #define GrColor_SHIFT_A 24
+#endif
+
+/**
+ * Pack 4 components (RGBA) into a GrColor int
+ */
+static inline GrColor GrColorPackRGBA(unsigned r, unsigned g,
+ unsigned b, unsigned a) {
+ SkASSERT((uint8_t)r == r);
+ SkASSERT((uint8_t)g == g);
+ SkASSERT((uint8_t)b == b);
+ SkASSERT((uint8_t)a == a);
+ return (r << GrColor_SHIFT_R) |
+ (g << GrColor_SHIFT_G) |
+ (b << GrColor_SHIFT_B) |
+ (a << GrColor_SHIFT_A);
+}
+
+// extract a component (byte) from a GrColor int
+
+#define GrColorUnpackR(color) (((color) >> GrColor_SHIFT_R) & 0xFF)
+#define GrColorUnpackG(color) (((color) >> GrColor_SHIFT_G) & 0xFF)
+#define GrColorUnpackB(color) (((color) >> GrColor_SHIFT_B) & 0xFF)
+#define GrColorUnpackA(color) (((color) >> GrColor_SHIFT_A) & 0xFF)
+
+/**
+ * Since premultiplied means that alpha >= color, we construct a color with
+ * each component==255 and alpha == 0 to be "illegal"
+ */
+#define GrColor_ILLEGAL (~(0xFF << GrColor_SHIFT_A))
+
+/**
+ * Assert in debug builds that a GrColor is premultiplied.
+ */
+static inline void GrColorIsPMAssert(GrColor c) {
+#ifdef SK_DEBUG
+ unsigned a = GrColorUnpackA(c);
+ unsigned r = GrColorUnpackR(c);
+ unsigned g = GrColorUnpackG(c);
+ unsigned b = GrColorUnpackB(c);
+
+ SkASSERT(r <= a);
+ SkASSERT(g <= a);
+ SkASSERT(b <= a);
+#endif
+}
+
+/** Converts a GrColor to an rgba array of GrGLfloat */
+static inline void GrColorToRGBAFloat(GrColor color, float rgba[4]) {
+ static const float ONE_OVER_255 = 1.f / 255.f;
+ rgba[0] = GrColorUnpackR(color) * ONE_OVER_255;
+ rgba[1] = GrColorUnpackG(color) * ONE_OVER_255;
+ rgba[2] = GrColorUnpackB(color) * ONE_OVER_255;
+ rgba[3] = GrColorUnpackA(color) * ONE_OVER_255;
+}
+
+/** Determines whether the color is opaque or not. */
+static inline bool GrColorIsOpaque(GrColor color) {
+ return (color & (0xFFU << GrColor_SHIFT_A)) == (0xFFU << GrColor_SHIFT_A);
+}
+
+/**
+ * Flags used for bitfields of color components. They are defined so that the bit order reflects the
+ * GrColor shift order.
+ */
+enum GrColorComponentFlags {
+ kR_GrColorComponentFlag = 1 << (GrColor_SHIFT_R / 8),
+ kG_GrColorComponentFlag = 1 << (GrColor_SHIFT_G / 8),
+ kB_GrColorComponentFlag = 1 << (GrColor_SHIFT_B / 8),
+ kA_GrColorComponentFlag = 1 << (GrColor_SHIFT_A / 8),
+
+ kRGB_GrColorComponentFlags = (kR_GrColorComponentFlag | kG_GrColorComponentFlag |
+ kB_GrColorComponentFlag),
+
+ kRGBA_GrColorComponentFlags = (kR_GrColorComponentFlag | kG_GrColorComponentFlag |
+ kB_GrColorComponentFlag | kA_GrColorComponentFlag)
+};
+
+static inline char GrColorComponentFlagToChar(GrColorComponentFlags component) {
+ SkASSERT(SkIsPow2(component));
+ switch (component) {
+ case kR_GrColorComponentFlag:
+ return 'r';
+ case kG_GrColorComponentFlag:
+ return 'g';
+ case kB_GrColorComponentFlag:
+ return 'b';
+ case kA_GrColorComponentFlag:
+ return 'a';
+ default:
+ SkFAIL("Invalid color component flag.");
+ return '\0';
+ }
+}
+
+static inline uint32_t GrPixelConfigComponentMask(GrPixelConfig config) {
+ SkASSERT(config >= 0 && config < kGrPixelConfigCnt);
+ static const uint32_t kFlags[] = {
+ 0, // kUnknown_GrPixelConfig
+ kA_GrColorComponentFlag, // kAlpha_8_GrPixelConfig
+ kRGBA_GrColorComponentFlags, // kIndex_8_GrPixelConfig
+ kRGB_GrColorComponentFlags, // kRGB_565_GrPixelConfig
+ kRGBA_GrColorComponentFlags, // kRGBA_4444_GrPixelConfig
+ kRGBA_GrColorComponentFlags, // kRGBA_8888_GrPixelConfig
+ kRGBA_GrColorComponentFlags, // kBGRA_8888_GrPixelConfig
+ kRGB_GrColorComponentFlags, // kETC1_GrPixelConfig
+ kA_GrColorComponentFlag, // kLATC_GrPixelConfig
+ kA_GrColorComponentFlag, // kR11_EAC_GrPixelConfig
+ kRGBA_GrColorComponentFlags, // kASTC_12x12_GrPixelConfig
+ kRGBA_GrColorComponentFlags, // kRGBA_float_GrPixelConfig
+ };
+ return kFlags[config];
+
+ GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
+ GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
+ GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
+ GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
+ GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
+ GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
+ GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
+ GR_STATIC_ASSERT(7 == kETC1_GrPixelConfig);
+ GR_STATIC_ASSERT(8 == kLATC_GrPixelConfig);
+ GR_STATIC_ASSERT(9 == kR11_EAC_GrPixelConfig);
+ GR_STATIC_ASSERT(10 == kASTC_12x12_GrPixelConfig);
+ GR_STATIC_ASSERT(11 == kRGBA_float_GrPixelConfig);
+ GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFlags) == kGrPixelConfigCnt);
+}
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrConfig.h b/src/third_party/skia/include/gpu/GrConfig.h
new file mode 100644
index 0000000..86ad63a
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrConfig.h
@@ -0,0 +1,251 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrConfig_DEFINED
+#define GrConfig_DEFINED
+
+#include "SkTypes.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// preconfig section:
+//
+// All the work before including GrUserConfig.h should center around guessing
+// what platform we're on, and defining low-level symbols based on that.
+//
+// A build environment may have already defined symbols, so we first check
+// for that
+//
+
+// hack to ensure we know what sort of Apple platform we're on
+#if defined(__APPLE_CPP__) || defined(__APPLE_CC__)
+ #include <TargetConditionals.h>
+#endif
+
+/**
+ * Gr defines are set to 0 or 1, rather than being undefined or defined
+ */
+
+#if !defined(GR_CACHE_STATS)
+ #define GR_CACHE_STATS 0
+#endif
+
+#if !defined(GR_GPU_STATS)
+#define GR_GPU_STATS 0
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(SK_BUILD_FOR_WIN32)
+// VC8 doesn't support stdint.h, so we define those types here.
+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 __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/*
+ * Include stdint.h with defines that trigger declaration of C99 limit/const
+ * macros here before anyone else has a chance to include stdint.h without
+ * these.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+#include <stdint.h>
+#endif
+
+/*
+ * The "user config" file can be empty, and everything should work. It is
+ * meant to store a given platform/client's overrides of our guess-work.
+ *
+ * A alternate user config file can be specified by defining
+ * GR_USER_CONFIG_FILE. It should be defined relative to GrConfig.h
+ *
+ * e.g. it can change the BUILD target or supply its own defines for anything
+ * else (e.g. GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT)
+ */
+#if !defined(GR_USER_CONFIG_FILE)
+ #include "GrUserConfig.h"
+#else
+ #include GR_USER_CONFIG_FILE
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// postconfig section:
+//
+
+// By now we must have a GR_..._BUILD symbol set to 1, and a decision about
+// debug -vs- release
+//
+
+#define GrPrintf SkDebugf
+
+/**
+ * GR_STRING makes a string of X where X is expanded before conversion to a string
+ * if X itself contains macros.
+ */
+#define GR_STRING(X) GR_STRING_IMPL(X)
+#define GR_STRING_IMPL(X) #X
+
+/**
+ * GR_CONCAT concatenates X and Y where each is expanded before
+ * contanenation if either contains macros.
+ */
+#define GR_CONCAT(X,Y) GR_CONCAT_IMPL(X,Y)
+#define GR_CONCAT_IMPL(X,Y) X##Y
+
+/**
+ * Creates a string of the form "<filename>(<linenumber>) : "
+ */
+#define GR_FILE_AND_LINE_STR __FILE__ "(" GR_STRING(__LINE__) ") : "
+
+/**
+ * Compilers have different ways of issuing warnings. This macro
+ * attempts to abstract them, but may need to be specialized for your
+ * particular compiler.
+ * To insert compiler warnings use "#pragma message GR_WARN(<string>)"
+ */
+#if defined(_MSC_VER) && _MSC_VER
+ #define GR_WARN(MSG) (GR_FILE_AND_LINE_STR "WARNING: " MSG)
+#else//__GNUC__ - may need other defines for different compilers
+ #define GR_WARN(MSG) ("WARNING: " MSG)
+#endif
+
+/**
+ * GR_ALWAYSBREAK is an unconditional break in all builds.
+ */
+#if !defined(GR_ALWAYSBREAK)
+ #if defined(SK_BUILD_FOR_WIN32)
+ #define GR_ALWAYSBREAK SkNO_RETURN_HINT(); __debugbreak()
+ #else
+ // TODO: do other platforms really not have continuable breakpoints?
+ // sign extend for 64bit architectures to be sure this is
+ // in the high address range
+ #define GR_ALWAYSBREAK SkNO_RETURN_HINT(); *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
+ #endif
+#endif
+
+/**
+ * GR_DEBUGBREAK is an unconditional break in debug builds.
+ */
+#if !defined(GR_DEBUGBREAK)
+ #ifdef SK_DEBUG
+ #define GR_DEBUGBREAK GR_ALWAYSBREAK
+ #else
+ #define GR_DEBUGBREAK
+ #endif
+#endif
+
+/**
+ * GR_ALWAYSASSERT is an assertion in all builds.
+ */
+#if !defined(GR_ALWAYSASSERT)
+ #define GR_ALWAYSASSERT(COND) \
+ do { \
+ if (!(COND)) { \
+ GrPrintf("%s %s failed\n", GR_FILE_AND_LINE_STR, #COND); \
+ GR_ALWAYSBREAK; \
+ } \
+ } while (false)
+#endif
+
+/**
+ * GR_DEBUGASSERT is an assertion in debug builds only.
+ */
+#if !defined(GR_DEBUGASSERT)
+ #ifdef SK_DEBUG
+ #define GR_DEBUGASSERT(COND) GR_ALWAYSASSERT(COND)
+ #else
+ #define GR_DEBUGASSERT(COND)
+ #endif
+#endif
+
+/**
+ * Prettier forms of the above macros.
+ */
+#define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND)
+
+/**
+ * GR_STATIC_ASSERT is a compile time assertion. Depending on the platform
+ * it may print the message in the compiler log. Obviously, the condition must
+ * be evaluatable at compile time.
+ */
+// VS 2010 and GCC compiled with c++0x or gnu++0x support the new
+// static_assert.
+#if !defined(GR_STATIC_ASSERT)
+ #if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)
+ #define GR_STATIC_ASSERT(CONDITION) static_assert(CONDITION, "bug")
+ #else
+ template <bool> class GR_STATIC_ASSERT_FAILURE;
+ template <> class GR_STATIC_ASSERT_FAILURE<true> {};
+ #define GR_STATIC_ASSERT(CONDITION) \
+ enum {GR_CONCAT(X,__LINE__) = \
+ sizeof(GR_STATIC_ASSERT_FAILURE<CONDITION>)}
+ #endif
+#endif
+
+/**
+ * GR_GEOM_BUFFER_MAP_THRESHOLD gives a threshold (in bytes) for when Gr should
+ * map a GrGeometryBuffer to update its contents. It will use map() if the
+ * size of the updated region is greater than the threshold. Otherwise it will
+ * use updateData().
+ */
+#if !defined(GR_GEOM_BUFFER_MAP_THRESHOLD)
+ #define GR_GEOM_BUFFER_MAP_THRESHOLD (1 << 15)
+#endif
+
+/**
+ * GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT gives a threshold (in megabytes) for the
+ * maximum size of the texture cache in vram. The value is only a default and
+ * can be overridden at runtime.
+ */
+#if !defined(GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT)
+ #define GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT 96
+#endif
+
+/**
+ * GR_DEFAULT_RESOURCE_CACHE_COUNT_LIMIT specifies the maximum number of
+ * textures the texture cache can hold in vram. The value is only a default and
+ * can be overridden at runtime.
+ */
+#if !defined(GR_DEFAULT_RESOURCE_CACHE_COUNT_LIMIT)
+ #define GR_DEFAULT_RESOURCE_CACHE_COUNT_LIMIT 2048
+#endif
+
+/**
+ * GR_STROKE_PATH_RENDERING controls whether or not the GrStrokePathRenderer can be selected
+ * as a path renderer. GrStrokePathRenderer is currently an experimental path renderer.
+ */
+#if !defined(GR_STROKE_PATH_RENDERING)
+ #define GR_STROKE_PATH_RENDERING 0
+#endif
+
+/**
+ * GR_ALWAYS_ALLOCATE_ON_HEAP determines whether various temporary buffers created
+ * in the GPU backend are always allocated on the heap or are allowed to be
+ * allocated on the stack for smaller memory requests.
+ *
+ * This is only used for memory buffers that are created and then passed through to the
+ * 3D API (e.g. as texture or geometry data)
+ */
+#if !defined(GR_ALWAYS_ALLOCATE_ON_HEAP)
+ #define GR_ALWAYS_ALLOCATE_ON_HEAP 0
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrContext.h b/src/third_party/skia/include/gpu/GrContext.h
new file mode 100644
index 0000000..45cd599
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrContext.h
@@ -0,0 +1,1167 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrContext_DEFINED
+#define GrContext_DEFINED
+
+#include "GrClipData.h"
+#include "GrColor.h"
+#include "GrPaint.h"
+#include "GrPathRendererChain.h"
+#include "GrRenderTarget.h"
+#include "GrTexture.h"
+#include "SkMatrix.h"
+#include "SkPathEffect.h"
+#include "SkTypes.h"
+
+class GrAARectRenderer;
+class GrAutoScratchTexture;
+class GrDrawState;
+class GrDrawTarget;
+class GrFontCache;
+class GrFragmentProcessor;
+class GrGpu;
+class GrGpuTraceMarker;
+class GrIndexBuffer;
+class GrIndexBufferAllocPool;
+class GrInOrderDrawBuffer;
+class GrLayerCache;
+class GrOvalRenderer;
+class GrPath;
+class GrPathRenderer;
+class GrResourceEntry;
+class GrResourceCache;
+class GrResourceCache2;
+class GrStencilBuffer;
+class GrTestTarget;
+class GrTextContext;
+class GrTextureParams;
+class GrVertexBuffer;
+class GrVertexBufferAllocPool;
+class GrStrokeInfo;
+class GrSoftwarePathRenderer;
+class SkStrokeRec;
+
+class SK_API GrContext : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(GrContext)
+
+ struct Options {
+ Options() : fDrawPathToCompressedTexture(false) { }
+
+ // EXPERIMENTAL
+ // May be removed in the future, or may become standard depending
+ // on the outcomes of a variety of internal tests.
+ bool fDrawPathToCompressedTexture;
+ };
+
+ /**
+ * Creates a GrContext for a backend context.
+ */
+ static GrContext* Create(GrBackend, GrBackendContext, const Options* opts = NULL);
+
+ virtual ~GrContext();
+
+ /**
+ * The GrContext normally assumes that no outsider is setting state
+ * within the underlying 3D API's context/device/whatever. This call informs
+ * the context that the state was modified and it should resend. Shouldn't
+ * be called frequently for good performance.
+ * The flag bits, state, is dpendent on which backend is used by the
+ * context, either GL or D3D (possible in future).
+ */
+ void resetContext(uint32_t state = kAll_GrBackendState);
+
+ /**
+ * Callback function to allow classes to cleanup on GrContext destruction.
+ * The 'info' field is filled in with the 'info' passed to addCleanUp.
+ */
+ typedef void (*PFCleanUpFunc)(const GrContext* context, void* info);
+
+ /**
+ * Add a function to be called from within GrContext's destructor.
+ * This gives classes a chance to free resources held on a per context basis.
+ * The 'info' parameter will be stored and passed to the callback function.
+ */
+ void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
+ CleanUpData* entry = fCleanUpData.push();
+
+ entry->fFunc = cleanUp;
+ entry->fInfo = info;
+ }
+
+ /**
+ * Abandons all GPU resources and assumes the underlying backend 3D API
+ * context is not longer usable. Call this if you have lost the associated
+ * GPU context, and thus internal texture, buffer, etc. references/IDs are
+ * now invalid. Should be called even when GrContext is no longer going to
+ * be used for two reasons:
+ * 1) ~GrContext will not try to free the objects in the 3D API.
+ * 2) Any GrGpuResources created by this GrContext that outlive
+ * will be marked as invalid (GrGpuResource::wasDestroyed()) and
+ * when they're destroyed no 3D API calls will be made.
+ * Content drawn since the last GrContext::flush() may be lost. After this
+ * function is called the only valid action on the GrContext or
+ * GrGpuResources it created is to destroy them.
+ */
+ void abandonContext();
+ void contextDestroyed() { this->abandonContext(); } // legacy alias
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Resource Cache
+
+ /**
+ * Return the current GPU resource cache limits.
+ *
+ * @param maxResources If non-null, returns maximum number of resources that
+ * can be held in the cache.
+ * @param maxResourceBytes If non-null, returns maximum number of bytes of
+ * video memory that can be held in the cache.
+ */
+ void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const;
+ SK_ATTR_DEPRECATED("This function has been renamed to getResourceCacheLimits().")
+ void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
+ this->getResourceCacheLimits(maxTextures, maxTextureBytes);
+ }
+
+ /**
+ * Gets the current GPU resource cache usage.
+ *
+ * @param resourceCount If non-null, returns the number of resources that are held in the
+ * cache.
+ * @param maxResourceBytes If non-null, returns the total number of bytes of video memory held
+ * in the cache.
+ */
+ void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const;
+
+ SK_ATTR_DEPRECATED("Use getResourceCacheUsage().")
+ size_t getGpuTextureCacheBytes() const {
+ size_t bytes;
+ this->getResourceCacheUsage(NULL, &bytes);
+ return bytes;
+ }
+
+ SK_ATTR_DEPRECATED("Use getResourceCacheUsage().")
+ int getGpuTextureCacheResourceCount() const {
+ int count;
+ this->getResourceCacheUsage(&count, NULL);
+ return count;
+ }
+
+ /**
+ * Specify the GPU resource cache limits. If the current cache exceeds either
+ * of these, it will be purged (LRU) to keep the cache within these limits.
+ *
+ * @param maxResources The maximum number of resources that can be held in
+ * the cache.
+ * @param maxResourceBytes The maximum number of bytes of video memory
+ * that can be held in the cache.
+ */
+ void setResourceCacheLimits(int maxResources, size_t maxResourceBytes);
+ SK_ATTR_DEPRECATED("This function has been renamed to setResourceCacheLimits().")
+ void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
+ this->setResourceCacheLimits(maxTextures, maxTextureBytes);
+ }
+
+ /**
+ * Frees GPU created by the context. Can be called to reduce GPU memory
+ * pressure.
+ */
+ void freeGpuResources();
+
+ /**
+ * This method should be called whenever a GrResource is unreffed or
+ * switched from exclusive to non-exclusive. This
+ * gives the resource cache a chance to discard unneeded resources.
+ * Note: this entry point will be removed once totally ref-driven
+ * cache maintenance is implemented.
+ */
+ void purgeCache();
+
+ /**
+ * Purge all the unlocked resources from the cache.
+ * This entry point is mainly meant for timing texture uploads
+ * and is not defined in normal builds of Skia.
+ */
+ void purgeAllUnlockedResources();
+
+ /**
+ * Stores a custom resource in the cache, based on the specified key.
+ */
+ void addResourceToCache(const GrResourceKey&, GrGpuResource*);
+
+ /**
+ * Finds a resource in the cache, based on the specified key. This is intended for use in
+ * conjunction with addResourceToCache(). The return value will be NULL if not found. The
+ * caller must balance with a call to unref().
+ */
+ GrGpuResource* findAndRefCachedResource(const GrResourceKey&);
+
+ /**
+ * Creates a new text rendering context that is optimal for the
+ * render target and the context. Caller assumes the ownership
+ * of the returned object. The returned object must be deleted
+ * before the context is destroyed.
+ */
+ GrTextContext* createTextContext(GrRenderTarget*,
+ const SkDeviceProperties&,
+ bool enableDistanceFieldFonts);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Textures
+
+ /**
+ * Creates a new entry, based on the specified key and texture and returns it. The caller owns a
+ * ref on the returned texture which must be balanced by a call to unref.
+ *
+ * @param params The texture params used to draw a texture may help determine
+ * the cache entry used. (e.g. different versions may exist
+ * for different wrap modes on GPUs with limited NPOT
+ * texture support). NULL implies clamp wrap modes.
+ * @param desc Description of the texture properties.
+ * @param cacheID Cache-specific properties (e.g., texture gen ID)
+ * @param srcData Pointer to the pixel values.
+ * @param rowBytes The number of bytes between rows of the texture. Zero
+ * implies tightly packed rows. For compressed pixel configs, this
+ * field is ignored.
+ * @param cacheKey (optional) If non-NULL, we'll write the cache key we used to cacheKey.
+ */
+ GrTexture* createTexture(const GrTextureParams* params,
+ const GrTextureDesc& desc,
+ const GrCacheID& cacheID,
+ const void* srcData,
+ size_t rowBytes,
+ GrResourceKey* cacheKey = NULL);
+ /**
+ * Search for an entry based on key and dimensions. If found, ref it and return it. The return
+ * value will be NULL if not found. The caller must balance with a call to unref.
+ *
+ * @param desc Description of the texture properties.
+ * @param cacheID Cache-specific properties (e.g., texture gen ID)
+ * @param params The texture params used to draw a texture may help determine
+ * the cache entry used. (e.g. different versions may exist
+ * for different wrap modes on GPUs with limited NPOT
+ * texture support). NULL implies clamp wrap modes.
+ */
+ GrTexture* findAndRefTexture(const GrTextureDesc& desc,
+ const GrCacheID& cacheID,
+ const GrTextureParams* params);
+ /**
+ * Determines whether a texture is in the cache. If the texture is found it
+ * will not be locked or returned. This call does not affect the priority of
+ * the texture for deletion.
+ */
+ bool isTextureInCache(const GrTextureDesc& desc,
+ const GrCacheID& cacheID,
+ const GrTextureParams* params) const;
+
+ /**
+ * Enum that determines how closely a returned scratch texture must match
+ * a provided GrTextureDesc.
+ */
+ enum ScratchTexMatch {
+ /**
+ * Finds a texture that exactly matches the descriptor.
+ */
+ kExact_ScratchTexMatch,
+ /**
+ * Finds a texture that approximately matches the descriptor. Will be
+ * at least as large in width and height as desc specifies. If desc
+ * specifies that texture is a render target then result will be a
+ * render target. If desc specifies a render target and doesn't set the
+ * no stencil flag then result will have a stencil. Format and aa level
+ * will always match.
+ */
+ kApprox_ScratchTexMatch
+ };
+
+ /**
+ * Returns a texture matching the desc. It's contents are unknown. Subsequent
+ * requests with the same descriptor are not guaranteed to return the same
+ * texture. The same texture is guaranteed not be returned again until it is
+ * unlocked. Call must be balanced with an unlockTexture() call. The caller
+ * owns a ref on the returned texture and must balance with a call to unref.
+ *
+ * Textures created by createAndLockTexture() hide the complications of
+ * tiling non-power-of-two textures on APIs that don't support this (e.g.
+ * unextended GLES2). Tiling a NPOT texture created by lockScratchTexture on
+ * such an API will create gaps in the tiling pattern. This includes clamp
+ * mode. (This may be addressed in a future update.)
+ */
+ GrTexture* lockAndRefScratchTexture(const GrTextureDesc&, ScratchTexMatch match);
+
+ /**
+ * When done with an entry, call unlockScratchTexture(entry) on it, which returns
+ * it to the cache, where it may be purged. This does not unref the texture.
+ */
+ void unlockScratchTexture(GrTexture* texture);
+
+ /**
+ * Creates a texture that is outside the cache. Does not count against
+ * cache's budget.
+ */
+ GrTexture* createUncachedTexture(const GrTextureDesc& desc,
+ void* srcData,
+ size_t rowBytes);
+
+ /**
+ * Returns true if the specified use of an indexed texture is supported.
+ * Support may depend upon whether the texture params indicate that the
+ * texture will be tiled. Passing NULL for the texture params indicates
+ * clamp mode.
+ */
+ bool supportsIndex8PixelConfig(const GrTextureParams*,
+ int width,
+ int height) const;
+
+ /**
+ * Return the max width or height of a texture supported by the current GPU.
+ */
+ int getMaxTextureSize() const;
+
+ /**
+ * Temporarily override the true max texture size. Note: an override
+ * larger then the true max texture size will have no effect.
+ * This entry point is mainly meant for testing texture size dependent
+ * features and is only available if defined outside of Skia (see
+ * bleed GM.
+ */
+ void setMaxTextureSizeOverride(int maxTextureSizeOverride);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Render targets
+
+ /**
+ * Sets the render target.
+ * @param target the render target to set.
+ */
+ void setRenderTarget(GrRenderTarget* target) {
+ fRenderTarget.reset(SkSafeRef(target));
+ }
+
+ /**
+ * Gets the current render target.
+ * @return the currently bound render target.
+ */
+ const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
+ GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
+
+ /**
+ * Can the provided configuration act as a color render target?
+ */
+ bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const;
+
+ /**
+ * Return the max width or height of a render target supported by the
+ * current GPU.
+ */
+ int getMaxRenderTargetSize() const;
+
+ /**
+ * Returns the max sample count for a render target. It will be 0 if MSAA
+ * is not supported.
+ */
+ int getMaxSampleCount() const;
+
+ /**
+ * Returns the recommended sample count for a render target when using this
+ * context.
+ *
+ * @param config the configuration of the render target.
+ * @param dpi the display density in dots per inch.
+ *
+ * @return sample count that should be perform well and have good enough
+ * rendering quality for the display. Alternatively returns 0 if
+ * MSAA is not supported or recommended to be used by default.
+ */
+ int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Backend Surfaces
+
+ /**
+ * Wraps an existing texture with a GrTexture object.
+ *
+ * OpenGL: if the object is a texture Gr may change its GL texture params
+ * when it is drawn.
+ *
+ * @param desc description of the object to create.
+ *
+ * @return GrTexture object or NULL on failure.
+ */
+ GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc);
+
+ /**
+ * Wraps an existing render target with a GrRenderTarget object. It is
+ * similar to wrapBackendTexture but can be used to draw into surfaces
+ * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
+ * the client will resolve to a texture).
+ *
+ * @param desc description of the object to create.
+ *
+ * @return GrTexture object or NULL on failure.
+ */
+ GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Matrix state
+
+ /**
+ * Gets the current transformation matrix.
+ * @return the current matrix.
+ */
+ const SkMatrix& getMatrix() const { return fViewMatrix; }
+
+ /**
+ * Sets the transformation matrix.
+ * @param m the matrix to set.
+ */
+ void setMatrix(const SkMatrix& m) { fViewMatrix = m; }
+
+ /**
+ * Sets the current transformation matrix to identity.
+ */
+ void setIdentityMatrix() { fViewMatrix.reset(); }
+
+ /**
+ * Concats the current matrix. The passed matrix is applied before the
+ * current matrix.
+ * @param m the matrix to concat.
+ */
+ void concatMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Clip state
+ /**
+ * Gets the current clip.
+ * @return the current clip.
+ */
+ const GrClipData* getClip() const { return fClip; }
+
+ /**
+ * Sets the clip.
+ * @param clipData the clip to set.
+ */
+ void setClip(const GrClipData* clipData) { fClip = clipData; }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Draws
+
+ /**
+ * Clear the entire or rect of the render target, ignoring any clips.
+ * @param rect the rect to clear or the whole thing if rect is NULL.
+ * @param color the color to clear to.
+ * @param canIgnoreRect allows partial clears to be converted to whole
+ * clears on platforms for which that is cheap
+ * @param target if non-NULL, the render target to clear otherwise clear
+ * the current render target
+ */
+ void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
+ GrRenderTarget* target = NULL);
+
+ /**
+ * Draw everywhere (respecting the clip) with the paint.
+ */
+ void drawPaint(const GrPaint& paint);
+
+ /**
+ * Draw the rect using a paint.
+ * @param paint describes how to color pixels.
+ * @param strokeInfo the stroke information (width, join, cap), and.
+ * the dash information (intervals, count, phase).
+ * If strokeInfo == NULL, then the rect is filled.
+ * Otherwise, if stroke width == 0, then the stroke
+ * is always a single pixel thick, else the rect is
+ * mitered/beveled stroked based on stroke width.
+ * The rects coords are used to access the paint (through texture matrix)
+ */
+ void drawRect(const GrPaint& paint,
+ const SkRect&,
+ const GrStrokeInfo* strokeInfo = NULL);
+
+ /**
+ * Maps a rect of local coordinates onto the a rect of destination
+ * coordinates. The localRect is stretched over the dstRect. The dstRect is
+ * transformed by the context's matrix. An additional optional matrix can be
+ * provided to transform the local rect.
+ *
+ * @param paint describes how to color pixels.
+ * @param dstRect the destination rect to draw.
+ * @param localRect rect of local coordinates to be mapped onto dstRect
+ * @param localMatrix Optional matrix to transform localRect.
+ */
+ void drawRectToRect(const GrPaint& paint,
+ const SkRect& dstRect,
+ const SkRect& localRect,
+ const SkMatrix* localMatrix = NULL);
+
+ /**
+ * Draw a roundrect using a paint.
+ *
+ * @param paint describes how to color pixels.
+ * @param rrect the roundrect to draw
+ * @param strokeInfo the stroke information (width, join, cap) and
+ * the dash information (intervals, count, phase).
+ */
+ void drawRRect(const GrPaint& paint, const SkRRect& rrect, const GrStrokeInfo& strokeInfo);
+
+ /**
+ * Shortcut for drawing an SkPath consisting of nested rrects using a paint.
+ * Does not support stroking. The result is undefined if outer does not contain
+ * inner.
+ *
+ * @param paint describes how to color pixels.
+ * @param outer the outer roundrect
+ * @param inner the inner roundrect
+ */
+ void drawDRRect(const GrPaint& paint, const SkRRect& outer, const SkRRect& inner);
+
+
+ /**
+ * Draws a path.
+ *
+ * @param paint describes how to color pixels.
+ * @param path the path to draw
+ * @param strokeInfo the stroke information (width, join, cap) and
+ * the dash information (intervals, count, phase).
+ */
+ void drawPath(const GrPaint& paint, const SkPath& path, const GrStrokeInfo& strokeInfo);
+
+ /**
+ * Draws vertices with a paint.
+ *
+ * @param paint describes how to color pixels.
+ * @param primitiveType primitives type to draw.
+ * @param vertexCount number of vertices.
+ * @param positions array of vertex positions, required.
+ * @param texCoords optional array of texture coordinates used
+ * to access the paint.
+ * @param colors optional array of per-vertex colors, supercedes
+ * the paint's color field.
+ * @param indices optional array of indices. If NULL vertices
+ * are drawn non-indexed.
+ * @param indexCount if indices is non-null then this is the
+ * number of indices.
+ */
+ void drawVertices(const GrPaint& paint,
+ GrPrimitiveType primitiveType,
+ int vertexCount,
+ const SkPoint positions[],
+ const SkPoint texs[],
+ const GrColor colors[],
+ const uint16_t indices[],
+ int indexCount);
+
+ /**
+ * Draws an oval.
+ *
+ * @param paint describes how to color pixels.
+ * @param oval the bounding rect of the oval.
+ * @param strokeInfo the stroke information (width, join, cap) and
+ * the dash information (intervals, count, phase).
+ */
+ void drawOval(const GrPaint& paint,
+ const SkRect& oval,
+ const GrStrokeInfo& strokeInfo);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Misc.
+
+ /**
+ * Flags that affect flush() behavior.
+ */
+ enum FlushBits {
+ /**
+ * A client may reach a point where it has partially rendered a frame
+ * through a GrContext that it knows the user will never see. This flag
+ * causes the flush to skip submission of deferred content to the 3D API
+ * during the flush.
+ */
+ kDiscard_FlushBit = 0x2,
+ };
+
+ /**
+ * Call to ensure all drawing to the context has been issued to the
+ * underlying 3D API.
+ * @param flagsBitfield flags that control the flushing behavior. See
+ * FlushBits.
+ */
+ void flush(int flagsBitfield = 0);
+
+ /**
+ * These flags can be used with the read/write pixels functions below.
+ */
+ enum PixelOpsFlags {
+ /** The GrContext will not be flushed. This means that the read or write may occur before
+ previous draws have executed. */
+ kDontFlush_PixelOpsFlag = 0x1,
+ /** The src for write or dst read is unpremultiplied. This is only respected if both the
+ config src and dst configs are an RGBA/BGRA 8888 format. */
+ kUnpremul_PixelOpsFlag = 0x2,
+ };
+
+ /**
+ * Reads a rectangle of pixels from a render target.
+ * @param target the render target to read from. NULL means the current render target.
+ * @param left left edge of the rectangle to read (inclusive)
+ * @param top top edge of the rectangle to read (inclusive)
+ * @param width width of rectangle to read in pixels.
+ * @param height height of rectangle to read in pixels.
+ * @param config the pixel config of the destination buffer
+ * @param buffer memory to read the rectangle into.
+ * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
+ * packed.
+ * @param pixelOpsFlags see PixelOpsFlags enum above.
+ *
+ * @return true if the read succeeded, false if not. The read can fail because of an unsupported
+ * pixel config or because no render target is currently set and NULL was passed for
+ * target.
+ */
+ bool readRenderTargetPixels(GrRenderTarget* target,
+ int left, int top, int width, int height,
+ GrPixelConfig config, void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0);
+
+ /**
+ * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified
+ * rectangle.
+ * @param target the render target to write into. NULL means the current render target.
+ * @param left left edge of the rectangle to write (inclusive)
+ * @param top top edge of the rectangle to write (inclusive)
+ * @param width width of rectangle to write in pixels.
+ * @param height height of rectangle to write in pixels.
+ * @param config the pixel config of the source buffer
+ * @param buffer memory to read the rectangle from.
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
+ * packed.
+ * @param pixelOpsFlags see PixelOpsFlags enum above.
+ *
+ * @return true if the write succeeded, false if not. The write can fail because of an
+ * unsupported combination of target and pixel configs.
+ */
+ bool writeRenderTargetPixels(GrRenderTarget* target,
+ int left, int top, int width, int height,
+ GrPixelConfig config, const void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0);
+
+ /**
+ * Reads a rectangle of pixels from a texture.
+ * @param texture the texture to read from.
+ * @param left left edge of the rectangle to read (inclusive)
+ * @param top top edge of the rectangle to read (inclusive)
+ * @param width width of rectangle to read in pixels.
+ * @param height height of rectangle to read in pixels.
+ * @param config the pixel config of the destination buffer
+ * @param buffer memory to read the rectangle into.
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
+ * packed.
+ * @param pixelOpsFlags see PixelOpsFlags enum above.
+ *
+ * @return true if the read succeeded, false if not. The read can fail because of an unsupported
+ * pixel config.
+ */
+ bool readTexturePixels(GrTexture* texture,
+ int left, int top, int width, int height,
+ GrPixelConfig config, void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0);
+
+ /**
+ * Writes a rectangle of pixels to a texture.
+ * @param texture the render target to read from.
+ * @param left left edge of the rectangle to write (inclusive)
+ * @param top top edge of the rectangle to write (inclusive)
+ * @param width width of rectangle to write in pixels.
+ * @param height height of rectangle to write in pixels.
+ * @param config the pixel config of the source buffer
+ * @param buffer memory to read pixels from
+ * @param rowBytes number of bytes between consecutive rows. Zero
+ * means rows are tightly packed.
+ * @param pixelOpsFlags see PixelOpsFlags enum above.
+ * @return true if the write succeeded, false if not. The write can fail because of an
+ * unsupported combination of texture and pixel configs.
+ */
+ bool writeTexturePixels(GrTexture* texture,
+ int left, int top, int width, int height,
+ GrPixelConfig config, const void* buffer,
+ size_t rowBytes,
+ uint32_t pixelOpsFlags = 0);
+
+ /**
+ * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle
+ * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's
+ * bounds.
+ * @param src the texture to copy from.
+ * @param dst the render target to copy to.
+ * @param topLeft the point in src that will be copied to the top-left of dst. If NULL,
+ * (0, 0) will be used.
+ */
+ void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL);
+
+ /**
+ * Resolves a render target that has MSAA. The intermediate MSAA buffer is
+ * down-sampled to the associated GrTexture (accessible via
+ * GrRenderTarget::asTexture()). Any pending draws to the render target will
+ * be executed before the resolve.
+ *
+ * This is only necessary when a client wants to access the object directly
+ * using the backend API directly. GrContext will detect when it must
+ * perform a resolve to a GrTexture used as the source of a draw or before
+ * reading pixels back from a GrTexture or GrRenderTarget.
+ */
+ void resolveRenderTarget(GrRenderTarget*);
+
+ /**
+ * Provides a perfomance hint that the render target's contents are allowed
+ * to become undefined.
+ */
+ void discardRenderTarget(GrRenderTarget*);
+
+#ifdef SK_DEVELOPER
+ void dumpFontCache() const;
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Helpers
+
+ class AutoRenderTarget : public ::SkNoncopyable {
+ public:
+ AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
+ fPrevTarget = context->getRenderTarget();
+ SkSafeRef(fPrevTarget);
+ context->setRenderTarget(target);
+ fContext = context;
+ }
+ AutoRenderTarget(GrContext* context) {
+ fPrevTarget = context->getRenderTarget();
+ SkSafeRef(fPrevTarget);
+ fContext = context;
+ }
+ ~AutoRenderTarget() {
+ if (fContext) {
+ fContext->setRenderTarget(fPrevTarget);
+ }
+ SkSafeUnref(fPrevTarget);
+ }
+ private:
+ GrContext* fContext;
+ GrRenderTarget* fPrevTarget;
+ };
+
+ /**
+ * Save/restore the view-matrix in the context. It can optionally adjust a paint to account
+ * for a coordinate system change. Here is an example of how the paint param can be used:
+ *
+ * A GrPaint is setup with GrProcessors. The stages will have access to the pre-matrix source
+ * geometry positions when the draw is executed. Later on a decision is made to transform the
+ * geometry to device space on the CPU. The effects now need to know that the space in which
+ * the geometry will be specified has changed.
+ *
+ * Note that when restore is called (or in the destructor) the context's matrix will be
+ * restored. However, the paint will not be restored. The caller must make a copy of the
+ * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally
+ * initialized.
+ */
+ class AutoMatrix : public ::SkNoncopyable {
+ public:
+ AutoMatrix() : fContext(NULL) {}
+
+ ~AutoMatrix() { this->restore(); }
+
+ /**
+ * Initializes by pre-concat'ing the context's current matrix with the preConcat param.
+ */
+ void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) {
+ SkASSERT(context);
+
+ this->restore();
+
+ fContext = context;
+ fMatrix = context->getMatrix();
+ this->preConcat(preConcat, paint);
+ }
+
+ /**
+ * Sets the context's matrix to identity. Returns false if the inverse matrix is required to
+ * update a paint but the matrix cannot be inverted.
+ */
+ bool setIdentity(GrContext* context, GrPaint* paint = NULL) {
+ SkASSERT(context);
+
+ this->restore();
+
+ if (paint) {
+ if (!paint->localCoordChangeInverse(context->getMatrix())) {
+ return false;
+ }
+ }
+ fMatrix = context->getMatrix();
+ fContext = context;
+ context->setIdentityMatrix();
+ return true;
+ }
+
+ /**
+ * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is
+ * required to update a paint but the matrix cannot be inverted.
+ */
+ bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) {
+ if (paint) {
+ if (!this->setIdentity(context, paint)) {
+ return false;
+ }
+ this->preConcat(newMatrix, paint);
+ } else {
+ this->restore();
+ fContext = context;
+ fMatrix = context->getMatrix();
+ context->setMatrix(newMatrix);
+ }
+ return true;
+ }
+
+ /**
+ * If this has been initialized then the context's matrix will be further updated by
+ * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged.
+ * The paint is assumed to be relative to the context's matrix at the time this call is
+ * made, not the matrix at the time AutoMatrix was first initialized. In other words, this
+ * performs an incremental update of the paint.
+ */
+ void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
+ if (paint) {
+ paint->localCoordChange(preConcat);
+ }
+ fContext->concatMatrix(preConcat);
+ }
+
+ /**
+ * Returns false if never initialized or the inverse matrix was required to update a paint
+ * but the matrix could not be inverted.
+ */
+ bool succeeded() const { return SkToBool(fContext); }
+
+ /**
+ * If this has been initialized then the context's original matrix is restored.
+ */
+ void restore() {
+ if (fContext) {
+ fContext->setMatrix(fMatrix);
+ fContext = NULL;
+ }
+ }
+
+ private:
+ GrContext* fContext;
+ SkMatrix fMatrix;
+ };
+
+ class AutoClip : public ::SkNoncopyable {
+ public:
+ // This enum exists to require a caller of the constructor to acknowledge that the clip will
+ // initially be wide open. It also could be extended if there are other desirable initial
+ // clip states.
+ enum InitialClip {
+ kWideOpen_InitialClip,
+ };
+
+ AutoClip(GrContext* context, InitialClip initialState)
+ : fContext(context) {
+ SkASSERT(kWideOpen_InitialClip == initialState);
+ fNewClipData.fClipStack = &fNewClipStack;
+
+ fOldClip = context->getClip();
+ context->setClip(&fNewClipData);
+ }
+
+ AutoClip(GrContext* context, const SkRect& newClipRect)
+ : fContext(context)
+ , fNewClipStack(newClipRect) {
+ fNewClipData.fClipStack = &fNewClipStack;
+
+ fOldClip = fContext->getClip();
+ fContext->setClip(&fNewClipData);
+ }
+
+ ~AutoClip() {
+ if (fContext) {
+ fContext->setClip(fOldClip);
+ }
+ }
+ private:
+ GrContext* fContext;
+ const GrClipData* fOldClip;
+
+ SkClipStack fNewClipStack;
+ GrClipData fNewClipData;
+ };
+
+ class AutoWideOpenIdentityDraw {
+ public:
+ AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
+ : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
+ , fAutoRT(ctx, rt) {
+ fAutoMatrix.setIdentity(ctx);
+ // should never fail with no paint param.
+ SkASSERT(fAutoMatrix.succeeded());
+ }
+
+ private:
+ AutoClip fAutoClip;
+ AutoRenderTarget fAutoRT;
+ AutoMatrix fAutoMatrix;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Functions intended for internal use only.
+ GrGpu* getGpu() { return fGpu; }
+ const GrGpu* getGpu() const { return fGpu; }
+ GrFontCache* getFontCache() { return fFontCache; }
+ GrLayerCache* getLayerCache() { return fLayerCache.get(); }
+ GrDrawTarget* getTextTarget();
+ const GrIndexBuffer* getQuadIndexBuffer() const;
+ GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
+ GrResourceCache2* getResourceCache2() { return fResourceCache2; }
+
+ // Called by tests that draw directly to the context via GrDrawTarget
+ void getTestTarget(GrTestTarget*);
+
+ void addGpuTraceMarker(const GrGpuTraceMarker* marker);
+ void removeGpuTraceMarker(const GrGpuTraceMarker* marker);
+
+ /**
+ * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is
+ * called to check the cache for a SB that matches an RT's criteria.
+ */
+ void addStencilBuffer(GrStencilBuffer* sb);
+ GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
+
+ GrPathRenderer* getPathRenderer(
+ const SkPath& path,
+ const SkStrokeRec& stroke,
+ const GrDrawTarget* target,
+ bool allowSW,
+ GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
+ GrPathRendererChain::StencilSupport* stencilSupport = NULL);
+
+ /**
+ * This returns a copy of the the GrContext::Options that was passed to the
+ * constructor of this class.
+ */
+ const Options& getOptions() const { return fOptions; }
+
+#if GR_CACHE_STATS
+ void printCacheStats() const;
+#endif
+
+ class GPUStats {
+ public:
+#if GR_GPU_STATS
+ GPUStats() { this->reset(); }
+
+ void reset() { fRenderTargetBinds = 0; fShaderCompilations = 0; }
+
+ int renderTargetBinds() const { return fRenderTargetBinds; }
+ void incRenderTargetBinds() { fRenderTargetBinds++; }
+ int shaderCompilations() const { return fShaderCompilations; }
+ void incShaderCompilations() { fShaderCompilations++; }
+ private:
+ int fRenderTargetBinds;
+ int fShaderCompilations;
+#else
+ void incRenderTargetBinds() {}
+ void incShaderCompilations() {}
+#endif
+ };
+
+#if GR_GPU_STATS
+ const GPUStats* gpuStats() const;
+#endif
+
+private:
+ // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
+ enum BufferedDraw {
+ kYes_BufferedDraw,
+ kNo_BufferedDraw,
+ };
+ BufferedDraw fLastDrawWasBuffered;
+
+ GrGpu* fGpu;
+ SkMatrix fViewMatrix;
+ SkAutoTUnref<GrRenderTarget> fRenderTarget;
+ const GrClipData* fClip; // TODO: make this ref counted
+ GrDrawState* fDrawState;
+
+ GrResourceCache* fResourceCache;
+ GrResourceCache2* fResourceCache2;
+ GrFontCache* fFontCache;
+ SkAutoTDelete<GrLayerCache> fLayerCache;
+
+ GrPathRendererChain* fPathRendererChain;
+ GrSoftwarePathRenderer* fSoftwarePathRenderer;
+
+ GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
+ GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
+ GrInOrderDrawBuffer* fDrawBuffer;
+
+ // Set by OverbudgetCB() to request that GrContext flush before exiting a draw.
+ bool fFlushToReduceCacheSize;
+
+ GrAARectRenderer* fAARectRenderer;
+ GrOvalRenderer* fOvalRenderer;
+
+ bool fDidTestPMConversions;
+ int fPMToUPMConversion;
+ int fUPMToPMConversion;
+
+ struct CleanUpData {
+ PFCleanUpFunc fFunc;
+ void* fInfo;
+ };
+
+ SkTDArray<CleanUpData> fCleanUpData;
+
+ int fMaxTextureSizeOverride;
+
+ const Options fOptions;
+
+ GrContext(const Options&); // init must be called after the constructor.
+ bool init(GrBackend, GrBackendContext);
+
+ void setupDrawBuffer();
+
+ class AutoRestoreEffects;
+ class AutoCheckFlush;
+ /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
+ /// draw state is left unmodified.
+ GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*, AutoCheckFlush*);
+
+ void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
+ const GrStrokeInfo& stroke);
+
+ GrTexture* createResizedTexture(const GrTextureDesc& desc,
+ const GrCacheID& cacheID,
+ const void* srcData,
+ size_t rowBytes,
+ bool filter);
+
+ // Needed so GrTexture's returnToCache helper function can call
+ // addExistingTextureToCache
+ friend class GrTexture;
+ friend class GrStencilAndCoverPathRenderer;
+ friend class GrStencilAndCoverTextContext;
+
+ // Add an existing texture to the texture cache. This is intended solely
+ // for use with textures released from an GrAutoScratchTexture.
+ void addExistingTextureToCache(GrTexture* texture);
+
+ /**
+ * These functions create premul <-> unpremul effects if it is possible to generate a pair
+ * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
+ * return NULL.
+ */
+ const GrFragmentProcessor* createPMToUPMEffect(GrTexture*, bool swapRAndB, const SkMatrix&);
+ const GrFragmentProcessor* createUPMToPMEffect(GrTexture*, bool swapRAndB, const SkMatrix&);
+
+ /**
+ * This callback allows the resource cache to callback into the GrContext
+ * when the cache is still overbudget after a purge.
+ */
+ static bool OverbudgetCB(void* data);
+
+ typedef SkRefCnt INHERITED;
+};
+
+/**
+ * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria.
+ * Unlocks texture in the destructor.
+ */
+class GrAutoScratchTexture : public ::SkNoncopyable {
+public:
+ GrAutoScratchTexture()
+ : fContext(NULL)
+ , fTexture(NULL) {
+ }
+
+ GrAutoScratchTexture(GrContext* context,
+ const GrTextureDesc& desc,
+ GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch)
+ : fContext(NULL)
+ , fTexture(NULL) {
+ this->set(context, desc, match);
+ }
+
+ ~GrAutoScratchTexture() {
+ this->reset();
+ }
+
+ void reset() {
+ if (fContext && fTexture) {
+ fContext->unlockScratchTexture(fTexture);
+ fTexture->unref();
+ fTexture = NULL;
+ }
+ }
+
+ /*
+ * When detaching a texture we do not unlock it in the texture cache but
+ * we do set the returnToCache flag. In this way the texture remains
+ * "locked" in the texture cache until it is freed and recycled in
+ * GrTexture::internal_dispose. In reality, the texture has been removed
+ * from the cache (because this is in AutoScratchTexture) and by not
+ * calling unlockScratchTexture we simply don't re-add it. It will be
+ * reattached in GrTexture::internal_dispose.
+ *
+ * Note that the caller is assumed to accept and manage the ref to the
+ * returned texture.
+ */
+ GrTexture* detach() {
+ if (NULL == fTexture) {
+ return NULL;
+ }
+ GrTexture* texture = fTexture;
+ fTexture = NULL;
+
+ // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now.
+ // The cache also has a ref which we are lending to the caller of detach(). When the caller
+ // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is
+ // set and re-ref the texture, thereby restoring the cache's ref.
+ SkASSERT(!texture->unique());
+ texture->impl()->setFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit);
+ texture->unref();
+ SkASSERT(texture->getCacheEntry());
+
+ return texture;
+ }
+
+ GrTexture* set(GrContext* context,
+ const GrTextureDesc& desc,
+ GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) {
+ this->reset();
+
+ fContext = context;
+ if (fContext) {
+ fTexture = fContext->lockAndRefScratchTexture(desc, match);
+ if (NULL == fTexture) {
+ fContext = NULL;
+ }
+ return fTexture;
+ } else {
+ return NULL;
+ }
+ }
+
+ GrTexture* texture() { return fTexture; }
+
+private:
+ GrContext* fContext;
+ GrTexture* fTexture;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrContextFactory.h b/src/third_party/skia/include/gpu/GrContextFactory.h
new file mode 100644
index 0000000..d78120c
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrContextFactory.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrContextFactory_DEFINED
+#define GrContextFactory_DEFINED
+
+#if SK_ANGLE
+ #include "gl/SkANGLEGLContext.h"
+#endif
+#include "gl/SkDebugGLContext.h"
+#if SK_MESA
+ #include "gl/SkMesaGLContext.h"
+#endif
+#include "gl/SkNativeGLContext.h"
+#include "gl/SkNullGLContext.h"
+
+#include "GrContext.h"
+#include "SkTArray.h"
+
+/**
+ * This is a simple class that is useful in test apps that use different
+ * GrContexts backed by different types of GL contexts. It manages creating the
+ * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
+ * factory is destroyed (though the caller can always grab a ref on the returned
+ * Gr and GL contexts to make them outlive the factory).
+ */
+class GrContextFactory : SkNoncopyable {
+public:
+ /**
+ * Types of GL contexts supported. For historical and testing reasons the native GrContext will
+ * not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
+ * type that does not remove NVPR support and which will fail when the driver does not support
+ * the extension.
+ */
+ enum GLContextType {
+ kNative_GLContextType,
+#if SK_ANGLE
+ kANGLE_GLContextType,
+#endif
+#if SK_MESA
+ kMESA_GLContextType,
+#endif
+ /** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
+ support NVPR */
+ kNVPR_GLContextType,
+ kNull_GLContextType,
+ kDebug_GLContextType,
+
+ kLastGLContextType = kDebug_GLContextType
+ };
+
+ static const int kGLContextTypeCnt = kLastGLContextType + 1;
+
+ static bool IsRenderingGLContext(GLContextType type) {
+ switch (type) {
+ case kNull_GLContextType:
+ case kDebug_GLContextType:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ static const char* GLContextTypeName(GLContextType type) {
+ switch (type) {
+ case kNative_GLContextType:
+ return "native";
+ case kNull_GLContextType:
+ return "null";
+#if SK_ANGLE
+ case kANGLE_GLContextType:
+ return "angle";
+#endif
+#if SK_MESA
+ case kMESA_GLContextType:
+ return "mesa";
+#endif
+ case kNVPR_GLContextType:
+ return "nvpr";
+ case kDebug_GLContextType:
+ return "debug";
+ default:
+ SkFAIL("Unknown GL Context type.");
+ }
+ }
+
+ explicit GrContextFactory(const GrContext::Options& opts) : fGlobalOptions(opts) { }
+ GrContextFactory() { }
+
+ ~GrContextFactory() { this->destroyContexts(); }
+
+ void destroyContexts() {
+ for (int i = 0; i < fContexts.count(); ++i) {
+ if (fContexts[i].fGLContext) { // could be abandoned.
+ fContexts[i].fGLContext->makeCurrent();
+ }
+ fContexts[i].fGrContext->unref();
+ if (fContexts[i].fGLContext) {
+ fContexts[i].fGLContext->unref();
+ }
+ }
+ fContexts.reset();
+ }
+
+ void abandonContexts() {
+ for (int i = 0; i < fContexts.count(); ++i) {
+ if (fContexts[i].fGLContext) {
+ fContexts[i].fGLContext->testAbandon();
+ SkSafeSetNull(fContexts[i].fGLContext);
+ }
+ fContexts[i].fGrContext->abandonContext();
+ }
+ }
+
+ /**
+ * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
+ */
+ GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard) {
+ for (int i = 0; i < fContexts.count(); ++i) {
+ if (forcedGpuAPI != kNone_GrGLStandard &&
+ forcedGpuAPI != fContexts[i].fGLContext->gl()->fStandard)
+ continue;
+
+ if (fContexts[i].fType == type) {
+ fContexts[i].fGLContext->makeCurrent();
+ return fContexts[i].fGrContext;
+ }
+ }
+ SkAutoTUnref<SkGLContextHelper> glCtx;
+ SkAutoTUnref<GrContext> grCtx;
+ switch (type) {
+ case kNVPR_GLContextType: // fallthru
+ case kNative_GLContextType:
+ glCtx.reset(SkNEW(SkNativeGLContext));
+ break;
+#ifdef SK_ANGLE
+ case kANGLE_GLContextType:
+ glCtx.reset(SkNEW(SkANGLEGLContext));
+ break;
+#endif
+#ifdef SK_MESA
+ case kMESA_GLContextType:
+ glCtx.reset(SkNEW(SkMesaGLContext));
+ break;
+#endif
+ case kNull_GLContextType:
+ glCtx.reset(SkNEW(SkNullGLContext));
+ break;
+ case kDebug_GLContextType:
+ glCtx.reset(SkNEW(SkDebugGLContext));
+ break;
+ }
+ static const int kBogusSize = 1;
+ if (!glCtx.get()) {
+ return NULL;
+ }
+ if (!glCtx.get()->init(forcedGpuAPI, kBogusSize, kBogusSize)) {
+ return NULL;
+ }
+
+ // Ensure NVPR is available for the NVPR type and block it from other types.
+ SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx.get()->gl()));
+ if (kNVPR_GLContextType == type) {
+ if (!glInterface->hasExtension("GL_NV_path_rendering")) {
+ return NULL;
+ }
+ } else {
+ glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
+ if (!glInterface) {
+ return NULL;
+ }
+ }
+
+ glCtx->makeCurrent();
+ GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
+ grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, &fGlobalOptions));
+ if (!grCtx.get()) {
+ return NULL;
+ }
+ GPUContext& ctx = fContexts.push_back();
+ ctx.fGLContext = glCtx.get();
+ ctx.fGLContext->ref();
+ ctx.fGrContext = grCtx.get();
+ ctx.fGrContext->ref();
+ ctx.fType = type;
+ return ctx.fGrContext;
+ }
+
+ // Returns the GLContext of the given type. If it has not been created yet,
+ // NULL is returned instead.
+ SkGLContextHelper* getGLContext(GLContextType type) {
+ for (int i = 0; i < fContexts.count(); ++i) {
+ if (fContexts[i].fType == type) {
+ return fContexts[i].fGLContext;
+ }
+ }
+
+ return NULL;
+ }
+
+ const GrContext::Options& getGlobalOptions() const { return fGlobalOptions; }
+
+private:
+ struct GPUContext {
+ GLContextType fType;
+ SkGLContextHelper* fGLContext;
+ GrContext* fGrContext;
+ };
+ SkTArray<GPUContext, true> fContexts;
+ const GrContext::Options fGlobalOptions;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrCoordTransform.h b/src/third_party/skia/include/gpu/GrCoordTransform.h
new file mode 100644
index 0000000..718bbe7
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrCoordTransform.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrCoordTransform_DEFINED
+#define GrCoordTransform_DEFINED
+
+#include "GrProcessor.h"
+#include "SkMatrix.h"
+#include "GrTexture.h"
+#include "GrTypes.h"
+
+/**
+ * Coordinates available to GrProcessor subclasses for requesting transformations. Transformed
+ * coordinates are made available in the the portion of fragment shader emitted by the effect.
+ */
+enum GrCoordSet {
+ /**
+ * The user-space coordinates that map to the fragment being rendered. These coords account for
+ * any change of coordinate system done on the CPU by GrContext before rendering, and also are
+ * correct for draws that take explicit local coords rather than inferring them from the
+ * primitive's positions (e.g. drawVertices). These are usually the coords a GrProcessor wants.
+ */
+ kLocal_GrCoordSet,
+
+ /**
+ * The actual vertex position. Note that GrContext may not draw using the original view matrix
+ * specified by the caller, as it may have transformed vertices into another space. These are
+ * usually not the coordinates a GrProcessor wants.
+ */
+ kPosition_GrCoordSet
+};
+
+/**
+ * A class representing a linear transformation from one of the built-in coordinate sets (local or
+ * position). GrProcessors just define these transformations, and the framework does the rest of the
+ * work to make the transformed coordinates available in their fragment shader.
+ */
+class GrCoordTransform : SkNoncopyable {
+public:
+ GrCoordTransform() { SkDEBUGCODE(fInEffect = false); }
+
+ /**
+ * Create a transformation that maps [0, 1] to a texture's boundaries.
+ */
+ GrCoordTransform(GrCoordSet sourceCoords, const GrTexture* texture) {
+ SkDEBUGCODE(fInEffect = false);
+ this->reset(sourceCoords, texture);
+ }
+
+ /**
+ * Create a transformation from a matrix. The optional texture parameter is used to infer if the
+ * framework should internally do a y reversal to account for it being upside down by Skia's
+ * coord convention.
+ */
+ GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
+ SkDEBUGCODE(fInEffect = false);
+ this->reset(sourceCoords, m, texture);
+ }
+
+ void reset(GrCoordSet sourceCoords, const GrTexture* texture) {
+ SkASSERT(!fInEffect);
+ SkASSERT(texture);
+ this->reset(sourceCoords, MakeDivByTextureWHMatrix(texture), texture);
+ }
+
+ void reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
+ SkASSERT(!fInEffect);
+ fSourceCoords = sourceCoords;
+ fMatrix = m;
+ fReverseY = texture && kBottomLeft_GrSurfaceOrigin == texture->origin();
+ }
+
+ GrCoordTransform& operator= (const GrCoordTransform& other) {
+ SkASSERT(!fInEffect);
+ fSourceCoords = other.fSourceCoords;
+ fMatrix = other.fMatrix;
+ fReverseY = other.fReverseY;
+ return *this;
+ }
+
+ /**
+ * Access the matrix for editing. Note, this must be done before adding the transform to an
+ * effect, since effects are immutable.
+ */
+ SkMatrix* accessMatrix() {
+ SkASSERT(!fInEffect);
+ return &fMatrix;
+ }
+
+ bool operator== (const GrCoordTransform& other) const {
+ return fSourceCoords == other.fSourceCoords &&
+ fMatrix.cheapEqualTo(other.fMatrix) &&
+ fReverseY == other.fReverseY;
+ }
+
+ GrCoordSet sourceCoords() const { return fSourceCoords; }
+ const SkMatrix& getMatrix() const { return fMatrix; }
+ bool reverseY() const { return fReverseY; }
+
+ /** Useful for effects that want to insert a texture matrix that is implied by the texture
+ dimensions */
+ static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
+ SkASSERT(texture);
+ SkMatrix mat;
+ mat.setIDiv(texture->width(), texture->height());
+ return mat;
+ }
+
+private:
+ GrCoordSet fSourceCoords;
+ SkMatrix fMatrix;
+ bool fReverseY;
+
+ typedef SkNoncopyable INHERITED;
+
+#ifdef SK_DEBUG
+public:
+ void setInEffect() const { fInEffect = true; }
+private:
+ mutable bool fInEffect;
+#endif
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrFontScaler.h b/src/third_party/skia/include/gpu/GrFontScaler.h
new file mode 100644
index 0000000..0376038
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrFontScaler.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrFontScaler_DEFINED
+#define GrFontScaler_DEFINED
+
+#include "GrGlyph.h"
+#include "GrTypes.h"
+
+#include "SkDescriptor.h"
+
+class SkPath;
+
+/*
+ * Wrapper class to turn a font cache descriptor into a key
+ * for GrFontScaler-related lookups
+ */
+class GrFontDescKey : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(GrFontDescKey)
+
+ typedef uint32_t Hash;
+
+ explicit GrFontDescKey(const SkDescriptor& desc);
+ virtual ~GrFontDescKey();
+
+ Hash getHash() const { return fHash; }
+
+ bool operator<(const GrFontDescKey& rh) const {
+ return fHash < rh.fHash || (fHash == rh.fHash && this->lt(rh));
+ }
+ bool operator==(const GrFontDescKey& rh) const {
+ return fHash == rh.fHash && this->eq(rh);
+ }
+
+private:
+ // helper functions for comparisons
+ bool lt(const GrFontDescKey& rh) const;
+ bool eq(const GrFontDescKey& rh) const;
+
+ SkDescriptor* fDesc;
+ enum {
+ kMaxStorageInts = 16
+ };
+ uint32_t fStorage[kMaxStorageInts];
+ const Hash fHash;
+
+ typedef SkRefCnt INHERITED;
+};
+
+/*
+ * This is Gr's interface to the host platform's font scaler.
+ *
+ * The client is responsible for instantiating this. The instance is created
+ * for a specific font+size+matrix.
+ */
+class GrFontScaler : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(GrFontScaler)
+
+ explicit GrFontScaler(SkGlyphCache* strike);
+ virtual ~GrFontScaler();
+
+ const GrFontDescKey* getKey();
+ GrMaskFormat getMaskFormat();
+ bool getPackedGlyphBounds(GrGlyph::PackedID, SkIRect* bounds);
+ bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+ int rowBytes, void* image);
+ bool getPackedGlyphDFBounds(GrGlyph::PackedID, SkIRect* bounds);
+ bool getPackedGlyphDFImage(GrGlyph::PackedID, int width, int height,
+ void* image);
+ bool getGlyphPath(uint16_t glyphID, SkPath*);
+
+private:
+ SkGlyphCache* fStrike;
+ GrFontDescKey* fKey;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrGeometryProcessor.h b/src/third_party/skia/include/gpu/GrGeometryProcessor.h
new file mode 100644
index 0000000..61659cf
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrGeometryProcessor.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGeometryProcessor_DEFINED
+#define GrGeometryProcessor_DEFINED
+
+#include "GrProcessor.h"
+class GrBackendGeometryProcessorFactory;
+
+/**
+ * A GrGeomteryProcessor is used to perform computation in the vertex shader and
+ * add support for custom vertex attributes. A GrGemeotryProcessor is typically
+ * tied to the code that does a specific type of high-level primitive rendering
+ * (e.g. anti-aliased circle rendering). The GrGeometryProcessor used for a draw is
+ * specified using GrDrawState. There can only be one geometry processor active for
+ * a draw. The custom vertex attributes required by the geometry processor must be
+ * added to the vertex attribute array specified on the GrDrawState.
+ * GrGeometryProcessor subclasses should be immutable after construction.
+ */
+class GrGeometryProcessor : public GrProcessor {
+public:
+ GrGeometryProcessor() {}
+
+ virtual const GrBackendGeometryProcessorFactory& getFactory() const = 0;
+
+ /*
+ * This only has a max because GLProgramsTest needs to generate test arrays, and these have to
+ * be static
+ * TODO make this truly dynamic
+ */
+ static const int kMaxVertexAttribs = 2;
+ typedef SkTArray<GrShaderVar, true> VertexAttribArray;
+
+ const VertexAttribArray& getVertexAttribs() const { return fVertexAttribs; }
+
+protected:
+ /**
+ * Subclasses call this from their constructor to register vertex attributes (at most
+ * kMaxVertexAttribs). This must only be called from the constructor because GrProcessors are
+ * immutable.
+ */
+ const GrShaderVar& addVertexAttrib(const GrShaderVar& var) {
+ SkASSERT(fVertexAttribs.count() < kMaxVertexAttribs);
+ return fVertexAttribs.push_back(var);
+ }
+
+private:
+ SkSTArray<kMaxVertexAttribs, GrShaderVar, true> fVertexAttribs;
+
+ typedef GrProcessor INHERITED;
+};
+
+/**
+ * This creates an effect outside of the effect memory pool. The effect's destructor will be called
+ * at global destruction time. NAME will be the name of the created GrProcessor.
+ */
+#define GR_CREATE_STATIC_GEOMETRY_PROCESSOR(NAME, GP_CLASS, ARGS) \
+static SkAlignedSStorage<sizeof(GP_CLASS)> g_##NAME##_Storage; \
+static GrGeometryProcessor* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), GP_CLASS, ARGS); \
+static SkAutoTDestroy<GrGeometryProcessor> NAME##_ad(NAME);
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrGlyph.h b/src/third_party/skia/include/gpu/GrGlyph.h
new file mode 100644
index 0000000..a379144
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrGlyph.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGlyph_DEFINED
+#define GrGlyph_DEFINED
+
+#include "GrRect.h"
+#include "SkPath.h"
+#include "SkChecksum.h"
+
+class GrPlot;
+
+/* Need this to be quad-state:
+ - complete w/ image
+ - just metrics
+ - failed to get image, but has metrics
+ - failed to get metrics
+ */
+struct GrGlyph {
+ typedef uint32_t PackedID;
+
+ GrPlot* fPlot;
+ SkPath* fPath;
+ PackedID fPackedID;
+ GrIRect16 fBounds;
+ SkIPoint16 fAtlasLocation;
+
+ void init(GrGlyph::PackedID packed, const SkIRect& bounds) {
+ fPlot = NULL;
+ fPath = NULL;
+ fPackedID = packed;
+ fBounds.set(bounds);
+ fAtlasLocation.set(0, 0);
+ }
+
+ void free() {
+ if (fPath) {
+ delete fPath;
+ fPath = NULL;
+ }
+ }
+
+ int width() const { return fBounds.width(); }
+ int height() const { return fBounds.height(); }
+ bool isEmpty() const { return fBounds.isEmpty(); }
+ uint16_t glyphID() const { return UnpackID(fPackedID); }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ static inline unsigned ExtractSubPixelBitsFromFixed(SkFixed pos) {
+ // two most significant fraction bits from fixed-point
+ return (pos >> 14) & 3;
+ }
+
+ static inline PackedID Pack(uint16_t glyphID, SkFixed x, SkFixed y) {
+ x = ExtractSubPixelBitsFromFixed(x);
+ y = ExtractSubPixelBitsFromFixed(y);
+ return (x << 18) | (y << 16) | glyphID;
+ }
+
+ static inline SkFixed UnpackFixedX(PackedID packed) {
+ return ((packed >> 18) & 3) << 14;
+ }
+
+ static inline SkFixed UnpackFixedY(PackedID packed) {
+ return ((packed >> 16) & 3) << 14;
+ }
+
+ static inline uint16_t UnpackID(PackedID packed) {
+ return (uint16_t)packed;
+ }
+
+ static inline const GrGlyph::PackedID& GetKey(const GrGlyph& glyph) {
+ return glyph.fPackedID;
+ }
+
+ static inline uint32_t Hash(GrGlyph::PackedID key) {
+ return SkChecksum::Murmur3(&key, sizeof(key));
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrGpuResource.h b/src/third_party/skia/include/gpu/GrGpuResource.h
new file mode 100644
index 0000000..61849e7
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrGpuResource.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGpuResource_DEFINED
+#define GrGpuResource_DEFINED
+
+#include "SkInstCnt.h"
+#include "SkTInternalLList.h"
+#include "GrResourceKey.h"
+
+class GrResourceCacheEntry;
+class GrResourceCache2;
+class GrGpu;
+class GrContext;
+
+/**
+ * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base
+ * class to isolate the ref-cnting behavior and provide friendship without exposing all of
+ * GrGpuResource.
+ *
+ * Gpu resources can have three types of refs:
+ * 1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls
+ * that read and write the resource via GrDrawTarget and by any object that must own a
+ * GrGpuResource and is itself owned (directly or indirectly) by Skia-client code.
+ * 2) Pending read (+ by addPendingRead(), - by readCompleted()): GrContext has scheduled a read
+ * of the resource by the GPU as a result of a skia API call but hasn't executed it yet.
+ * 3) Pending write (+ by addPendingWrite(), - by writeCompleted()): GrContext has scheduled a
+ * write to the resource by the GPU as a result of a skia API call but hasn't executed it yet.
+ *
+ * The latter two ref types are private and intended only for Gr core code.
+ */
+class GrIORef : public SkNoncopyable {
+public:
+ SK_DECLARE_INST_COUNT_ROOT(GrIORef)
+
+ enum IOType {
+ kRead_IOType,
+ kWrite_IOType,
+ kRW_IOType
+ };
+
+ virtual ~GrIORef();
+
+ // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with
+ // templated helper classes (e.g. SkAutoTUnref). However, we have different categories of
+ // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are
+ // not intended to cross thread boundaries.
+ // internal_dispose() exists because of GrTexture's reliance on it. It will be removed
+ // soon.
+ void ref() const {
+ ++fRefCnt;
+ // pre-validate once internal_dispose is removed (and therefore 0 ref cnt is not allowed).
+ this->validate();
+ }
+
+ void unref() const {
+ this->validate();
+ --fRefCnt;
+ if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) {
+ this->internal_dispose();
+ }
+ }
+
+ virtual void internal_dispose() const { SkDELETE(this); }
+
+ /** This is exists to service the old mechanism for recycling scratch textures. It will
+ be removed soon. */
+ bool unique() const { return 1 == (fRefCnt + fPendingReads + fPendingWrites); }
+
+ void validate() const {
+#ifdef SK_DEBUG
+ SkASSERT(fRefCnt >= 0);
+ SkASSERT(fPendingReads >= 0);
+ SkASSERT(fPendingWrites >= 0);
+ SkASSERT(fRefCnt + fPendingReads + fPendingWrites > 0);
+#endif
+ }
+
+
+protected:
+ GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) {}
+
+ bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
+ bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
+ bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
+
+private:
+ void addPendingRead() const {
+ this->validate();
+ ++fPendingReads;
+ }
+
+ void completedRead() const {
+ this->validate();
+ --fPendingReads;
+ if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) {
+ this->internal_dispose();
+ }
+ }
+
+ void addPendingWrite() const {
+ this->validate();
+ ++fPendingWrites;
+ }
+
+ void completedWrite() const {
+ this->validate();
+ --fPendingWrites;
+ if (0 == fRefCnt && 0 == fPendingReads && 0 == fPendingWrites) {
+ this->internal_dispose();
+ }
+ }
+
+private:
+ mutable int32_t fRefCnt;
+ mutable int32_t fPendingReads;
+ mutable int32_t fPendingWrites;
+
+ // This class is used to manage conversion of refs to pending reads/writes.
+ friend class GrGpuResourceRef;
+ template <typename, IOType> friend class GrPendingIOResource;
+};
+
+/**
+ * Base class for objects that can be kept in the GrResourceCache.
+ */
+class GrGpuResource : public GrIORef {
+public:
+ SK_DECLARE_INST_COUNT(GrGpuResource)
+
+ /**
+ * Frees the object in the underlying 3D API. It must be safe to call this
+ * when the object has been previously abandoned.
+ */
+ void release();
+
+ /**
+ * Removes references to objects in the underlying 3D API without freeing
+ * them. Used when the API context has been torn down before the GrContext.
+ */
+ void abandon();
+
+ /**
+ * Tests whether a object has been abandoned or released. All objects will
+ * be in this state after their creating GrContext is destroyed or has
+ * contextLost called. It's up to the client to test wasDestroyed() before
+ * attempting to use an object if it holds refs on objects across
+ * ~GrContext, freeResources with the force flag, or contextLost.
+ *
+ * @return true if the object has been released or abandoned,
+ * false otherwise.
+ */
+ bool wasDestroyed() const { return NULL == fGpu; }
+
+ /**
+ * Retrieves the context that owns the object. Note that it is possible for
+ * this to return NULL. When objects have been release()ed or abandon()ed
+ * they no longer have an owning context. Destroying a GrContext
+ * automatically releases all its resources.
+ */
+ const GrContext* getContext() const;
+ GrContext* getContext();
+
+ /**
+ * Retrieves the amount of GPU memory used by this resource in bytes. It is
+ * approximate since we aren't aware of additional padding or copies made
+ * by the driver.
+ *
+ * @return the amount of GPU memory used in bytes
+ */
+ virtual size_t gpuMemorySize() const = 0;
+
+ void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
+ GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
+
+ /**
+ * If this resource can be used as a scratch resource this returns a valid
+ * scratch key. Otherwise it returns a key for which isNullScratch is true.
+ */
+ const GrResourceKey& getScratchKey() const { return fScratchKey; }
+
+ /**
+ * Gets an id that is unique for this GrGpuResource object. It is static in that it does
+ * not change when the content of the GrGpuResource object changes. This will never return
+ * 0.
+ */
+ uint32_t getUniqueID() const { return fUniqueID; }
+
+protected:
+ // This must be called by every GrGpuObject. It should be called once the object is fully
+ // initialized (i.e. not in a base class constructor).
+ void registerWithCache();
+
+ GrGpuResource(GrGpu*, bool isWrapped);
+ virtual ~GrGpuResource();
+
+ bool isInCache() const { return SkToBool(fCacheEntry); }
+
+ GrGpu* getGpu() const { return fGpu; }
+
+ // Derived classes should always call their parent class' onRelease
+ // and onAbandon methods in their overrides.
+ virtual void onRelease() {};
+ virtual void onAbandon() {};
+
+ bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
+
+ /**
+ * This entry point should be called whenever gpuMemorySize() begins
+ * reporting a different size. If the object is in the cache, it will call
+ * gpuMemorySize() immediately and pass the new size on to the resource
+ * cache.
+ */
+ void didChangeGpuMemorySize() const;
+
+ /**
+ * Optionally called by the GrGpuResource subclass if the resource can be used as scratch.
+ * By default resources are not usable as scratch. This should only be called once.
+ **/
+ void setScratchKey(const GrResourceKey& scratchKey);
+
+private:
+#ifdef SK_DEBUG
+ friend class GrGpu; // for assert in GrGpu to access getGpu
+#endif
+
+ static uint32_t CreateUniqueID();
+
+ // We're in an internal doubly linked list owned by GrResourceCache2
+ SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuResource);
+
+ // This is not ref'ed but abandon() or release() will be called before the GrGpu object
+ // is destroyed. Those calls set will this to NULL.
+ GrGpu* fGpu;
+
+ enum Flags {
+ /**
+ * This object wraps a GPU object given to us by the user.
+ * Lifetime management is left up to the user (i.e., we will not
+ * free it).
+ */
+ kWrapped_FlagBit = 0x1,
+ };
+
+ uint32_t fFlags;
+
+ GrResourceCacheEntry* fCacheEntry; // NULL if not in cache
+ const uint32_t fUniqueID;
+
+ GrResourceKey fScratchKey;
+
+ typedef GrIORef INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrGpuResourceRef.h b/src/third_party/skia/include/gpu/GrGpuResourceRef.h
new file mode 100644
index 0000000..6b3937b
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrGpuResourceRef.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGpuResourceRef_DEFINED
+#define GrGpuResourceRef_DEFINED
+
+#include "GrGpuResource.h"
+#include "SkRefCnt.h"
+
+/**
+ * This class is intended only for internal use in core Gr code.
+ *
+ * Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages
+ * converting refs to pending IO operations. It allows a resource ownership to be in three
+ * states:
+ * 1. Owns a single ref
+ * 2. Owns a single ref and a pending IO operation (read, write, or read-write)
+ * 3. Owns a single pending IO operation.
+ *
+ * It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state
+ * 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from
+ * state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no
+ * valid way of going from state 3 back to 2 or 1.
+ *
+ * Like SkAutoTUnref, its constructor and setter adopt a ref from their caller.
+ *
+ * TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no
+ * longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef
+ * only settable via the constructor.
+ */
+class GrGpuResourceRef : SkNoncopyable {
+public:
+ SK_DECLARE_INST_COUNT_ROOT(GrGpuResourceRef);
+
+ ~GrGpuResourceRef();
+
+ GrGpuResource* getResource() const { return fResource; }
+
+ /** Does this object own a pending read or write on the resource it is wrapping. */
+ bool ownsPendingIO() const { return fPendingIO; }
+
+ /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
+ is called. */
+ void reset();
+
+protected:
+ GrGpuResourceRef();
+
+ /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ GrGpuResourceRef(GrGpuResource*, GrIORef::IOType);
+
+ /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ void setResource(GrGpuResource*, GrIORef::IOType);
+
+private:
+ /** Called by owning GrProgramElement when the program element is first scheduled for
+ execution. It can only be called once. */
+ void markPendingIO() const;
+
+ /** Called when the program element/draw state is no longer owned by GrDrawTarget-client code.
+ This lets the cache know that the drawing code will no longer schedule additional reads or
+ writes to the resource using the program element or draw state. It can only be called once.
+ */
+ void removeRef() const;
+
+ /** Called to indicate that the previous pending IO is complete. Useful when the owning object
+ still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
+ pending executions have been complete. Can only be called if removeRef() was not previously
+ called. */
+ void pendingIOComplete() const;
+
+ friend class GrRODrawState;
+ friend class GrProgramElement;
+
+ GrGpuResource* fResource;
+ mutable bool fOwnRef;
+ mutable bool fPendingIO;
+ GrIORef::IOType fIOType;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+/**
+ * Templated version of GrGpuResourceRef to enforce type safety.
+ */
+template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
+public:
+ GrTGpuResourceRef() {}
+
+ /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ GrTGpuResourceRef(T* resource, GrIORef::IOType ioType) : INHERITED(resource, ioType) {}
+
+ T* get() const { return static_cast<T*>(this->getResource()); }
+
+ /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ void set(T* resource, GrIORef::IOType ioType) { this->setResource(resource, ioType); }
+
+private:
+ typedef GrGpuResourceRef INHERITED;
+};
+
+/**
+ * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
+ * ref.
+ */
+template <typename T, GrIORef::IOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
+public:
+ GrPendingIOResource(T* resource) : fResource(resource) {
+ if (NULL != fResource) {
+ switch (IO_TYPE) {
+ case GrIORef::kRead_IOType:
+ fResource->addPendingRead();
+ break;
+ case GrIORef::kWrite_IOType:
+ fResource->addPendingWrite();
+ break;
+ case GrIORef::kRW_IOType:
+ fResource->addPendingRead();
+ fResource->addPendingWrite();
+ break;
+ }
+ }
+ }
+
+ ~GrPendingIOResource() {
+ if (NULL != fResource) {
+ switch (IO_TYPE) {
+ case GrIORef::kRead_IOType:
+ fResource->completedRead();
+ break;
+ case GrIORef::kWrite_IOType:
+ fResource->completedWrite();
+ break;
+ case GrIORef::kRW_IOType:
+ fResource->completedRead();
+ fResource->completedWrite();
+ break;
+ }
+ }
+ }
+
+ T* get() const { return fResource; }
+
+private:
+ T* fResource;
+};
+#endif
diff --git a/src/third_party/skia/include/gpu/GrPaint.h b/src/third_party/skia/include/gpu/GrPaint.h
new file mode 100644
index 0000000..d0531a3
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrPaint.h
@@ -0,0 +1,249 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrPaint_DEFINED
+#define GrPaint_DEFINED
+
+#include "GrColor.h"
+#include "GrProcessorStage.h"
+
+#include "SkXfermode.h"
+
+/**
+ * The paint describes how color and coverage are computed at each pixel by GrContext draw
+ * functions and the how color is blended with the destination pixel.
+ *
+ * The paint allows installation of custom color and coverage stages. New types of stages are
+ * created by subclassing GrProcessor.
+ *
+ * The primitive color computation starts with the color specified by setColor(). This color is the
+ * input to the first color stage. Each color stage feeds its output to the next color stage. The
+ * final color stage's output color is input to the color filter specified by
+ * setXfermodeColorFilter which produces the final source color, S.
+ *
+ * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
+ * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
+ * together in the same manner as color stages. The output of the last stage is modulated by any
+ * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
+ *
+ * setBlendFunc() specifies blending coefficients for S (described above) and D, the initial value
+ * of the destination pixel, labeled Bs and Bd respectively. The final value of the destination
+ * pixel is then D' = (1-C)*D + C*(Bd*D + Bs*S).
+ *
+ * Note that the coverage is applied after the blend. This is why they are computed as distinct
+ * values.
+ *
+ * TODO: Encapsulate setXfermodeColorFilter in a GrProcessor and remove from GrPaint.
+ */
+class GrPaint {
+public:
+ GrPaint() { this->reset(); }
+
+ GrPaint(const GrPaint& paint) { *this = paint; }
+
+ ~GrPaint() {}
+
+ /**
+ * Sets the blending coefficients to use to blend the final primitive color with the
+ * destination color. Defaults to kOne for src and kZero for dst (i.e. src mode).
+ */
+ void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ fSrcBlendCoeff = srcCoeff;
+ fDstBlendCoeff = dstCoeff;
+ }
+ GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlendCoeff; }
+ GrBlendCoeff getDstBlendCoeff() const { return fDstBlendCoeff; }
+
+ /**
+ * The initial color of the drawn primitive. Defaults to solid white.
+ */
+ void setColor(GrColor color) { fColor = color; }
+ GrColor getColor() const { return fColor; }
+
+ /**
+ * Applies fractional coverage to the entire drawn primitive. Defaults to 0xff.
+ */
+ void setCoverage(uint8_t coverage) { fCoverage = coverage; }
+ uint8_t getCoverage() const { return fCoverage; }
+
+ /**
+ * Should primitives be anti-aliased or not. Defaults to false.
+ */
+ void setAntiAlias(bool aa) { fAntiAlias = aa; }
+ bool isAntiAlias() const { return fAntiAlias; }
+
+ /**
+ * Should dithering be applied. Defaults to false.
+ */
+ void setDither(bool dither) { fDither = dither; }
+ bool isDither() const { return fDither; }
+
+ /**
+ * Appends an additional color processor to the color computation.
+ */
+ const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* fp) {
+ SkASSERT(fp);
+ if (!fp->willUseInputColor()) {
+ fColorStages.reset();
+ }
+ SkNEW_APPEND_TO_TARRAY(&fColorStages, GrProcessorStage, (fp));
+ return fp;
+ }
+
+ /**
+ * Appends an additional coverage processor to the coverage computation.
+ */
+ const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* fp) {
+ SkASSERT(fp);
+ if (!fp->willUseInputColor()) {
+ fCoverageStages.reset();
+ }
+ SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrProcessorStage, (fp));
+ return fp;
+ }
+
+ /**
+ * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
+ * to the src space position to compute texture coordinates.
+ */
+ void addColorTextureProcessor(GrTexture*, const SkMatrix&);
+ void addCoverageTextureProcessor(GrTexture*, const SkMatrix&);
+ void addColorTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
+ void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&);
+
+ int numColorStages() const { return fColorStages.count(); }
+ int numCoverageStages() const { return fCoverageStages.count(); }
+ int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
+
+ const GrFragmentStage& getColorStage(int s) const { return fColorStages[s]; }
+ const GrFragmentStage& getCoverageStage(int s) const { return fCoverageStages[s]; }
+
+ GrPaint& operator=(const GrPaint& paint) {
+ fSrcBlendCoeff = paint.fSrcBlendCoeff;
+ fDstBlendCoeff = paint.fDstBlendCoeff;
+ fAntiAlias = paint.fAntiAlias;
+ fDither = paint.fDither;
+
+ fColor = paint.fColor;
+ fCoverage = paint.fCoverage;
+
+ fColorStages = paint.fColorStages;
+ fCoverageStages = paint.fCoverageStages;
+
+ return *this;
+ }
+
+ /**
+ * Resets the paint to the defaults.
+ */
+ void reset() {
+ this->resetBlend();
+ this->resetOptions();
+ this->resetColor();
+ this->resetCoverage();
+ this->resetStages();
+ }
+
+ /**
+ * Determines whether the drawing with this paint is opaque with respect to both color blending
+ * and fractional coverage. It does not consider whether AA has been enabled on the paint or
+ * not. Depending upon whether multisampling or coverage-based AA is in use, AA may make the
+ * result only apply to the interior of primitives.
+ *
+ */
+ bool isOpaque() const;
+
+ /**
+ * Returns true if isOpaque would return true and the paint represents a solid constant color
+ * draw. If the result is true, constantColor will be updated to contain the constant color.
+ */
+ bool isOpaqueAndConstantColor(GrColor* constantColor) const;
+
+private:
+
+ /**
+ * Helper for isOpaque and isOpaqueAndConstantColor.
+ */
+ bool getOpaqueAndKnownColor(GrColor* solidColor, uint32_t* solidColorKnownComponents) const;
+
+ /**
+ * Called when the source coord system from which geometry is rendered changes. It ensures that
+ * the local coordinates seen by effects remains unchanged. oldToNew gives the transformation
+ * from the previous coord system to the new coord system.
+ */
+ void localCoordChange(const SkMatrix& oldToNew) {
+ for (int i = 0; i < fColorStages.count(); ++i) {
+ fColorStages[i].localCoordChange(oldToNew);
+ }
+ for (int i = 0; i < fCoverageStages.count(); ++i) {
+ fCoverageStages[i].localCoordChange(oldToNew);
+ }
+ }
+
+ bool localCoordChangeInverse(const SkMatrix& newToOld) {
+ SkMatrix oldToNew;
+ bool computed = false;
+ for (int i = 0; i < fColorStages.count(); ++i) {
+ if (!computed && !newToOld.invert(&oldToNew)) {
+ return false;
+ } else {
+ computed = true;
+ }
+ fColorStages[i].localCoordChange(oldToNew);
+ }
+ for (int i = 0; i < fCoverageStages.count(); ++i) {
+ if (!computed && !newToOld.invert(&oldToNew)) {
+ return false;
+ } else {
+ computed = true;
+ }
+ fCoverageStages[i].localCoordChange(oldToNew);
+ }
+ return true;
+ }
+
+ friend class GrContext; // To access above two functions
+ friend class GrStencilAndCoverTextContext; // To access above two functions
+
+ SkSTArray<4, GrFragmentStage> fColorStages;
+ SkSTArray<2, GrFragmentStage> fCoverageStages;
+
+ GrBlendCoeff fSrcBlendCoeff;
+ GrBlendCoeff fDstBlendCoeff;
+ bool fAntiAlias;
+ bool fDither;
+
+ GrColor fColor;
+ uint8_t fCoverage;
+
+ void resetBlend() {
+ fSrcBlendCoeff = kOne_GrBlendCoeff;
+ fDstBlendCoeff = kZero_GrBlendCoeff;
+ }
+
+ void resetOptions() {
+ fAntiAlias = false;
+ fDither = false;
+ }
+
+ void resetColor() {
+ fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
+ }
+
+ void resetCoverage() {
+ fCoverage = 0xff;
+ }
+
+ void resetStages() {
+ fColorStages.reset();
+ fCoverageStages.reset();
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrPathRendererChain.h b/src/third_party/skia/include/gpu/GrPathRendererChain.h
new file mode 100644
index 0000000..ca8c35b
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrPathRendererChain.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrPathRendererChain_DEFINED
+#define GrPathRendererChain_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+
+class GrContext;
+class GrDrawTarget;
+class GrPathRenderer;
+class SkPath;
+class SkStrokeRec;
+
+/**
+ * Keeps track of an ordered list of path renderers. When a path needs to be
+ * drawn this list is scanned to find the most preferred renderer. To add your
+ * path renderer to the list implement the GrPathRenderer::AddPathRenderers
+ * function.
+ */
+class GrPathRendererChain : public SkRefCnt {
+public:
+ // See comments in GrPathRenderer.h
+ enum StencilSupport {
+ kNoSupport_StencilSupport,
+ kStencilOnly_StencilSupport,
+ kNoRestriction_StencilSupport,
+ };
+
+ SK_DECLARE_INST_COUNT(GrPathRendererChain)
+
+ GrPathRendererChain(GrContext* context);
+
+ ~GrPathRendererChain();
+
+ // takes a ref and unrefs in destructor
+ GrPathRenderer* addPathRenderer(GrPathRenderer* pr);
+
+ /** Documents how the caller plans to use a GrPathRenderer to draw a path. It affects the PR
+ returned by getPathRenderer */
+ enum DrawType {
+ kColor_DrawType, // draw to the color buffer, no AA
+ kColorAntiAlias_DrawType, // draw to color buffer, with partial coverage AA
+ kStencilOnly_DrawType, // draw just to the stencil buffer
+ kStencilAndColor_DrawType, // draw the stencil and color buffer, no AA
+ kStencilAndColorAntiAlias_DrawType // draw the stencil and color buffer, with partial
+ // coverage AA.
+ };
+ /** Returns a GrPathRenderer compatible with the request if one is available. If the caller
+ is drawing the path to the stencil buffer then stencilSupport can be used to determine
+ whether the path can be rendered with arbitrary stencil rules or not. See comments on
+ StencilSupport in GrPathRenderer.h. */
+ GrPathRenderer* getPathRenderer(const SkPath& path,
+ const SkStrokeRec& rec,
+ const GrDrawTarget* target,
+ DrawType drawType,
+ StencilSupport* stencilSupport);
+
+private:
+ GrPathRendererChain();
+
+ void init();
+
+ enum {
+ kPreAllocCount = 8,
+ };
+ bool fInit;
+ GrContext* fOwner;
+ SkSTArray<kPreAllocCount, GrPathRenderer*, true> fChain;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrProcessor.h b/src/third_party/skia/include/gpu/GrProcessor.h
new file mode 100644
index 0000000..7053872
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrProcessor.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProcessor_DEFINED
+#define GrProcessor_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "GrColor.h"
+#include "GrProcessorUnitTest.h"
+#include "GrProgramElement.h"
+#include "GrShaderVar.h"
+#include "GrTextureAccess.h"
+#include "GrTypesPriv.h"
+#include "SkString.h"
+
+class GrBackendProcessorFactory;
+class GrContext;
+class GrCoordTransform;
+
+/** Provides custom vertex shader, fragment shader, uniform data for a particular stage of the
+ Ganesh shading pipeline.
+ Subclasses must have a function that produces a human-readable name:
+ static const char* Name();
+ GrProcessor objects *must* be immutable: after being constructed, their fields may not change.
+
+ Dynamically allocated GrProcessors are managed by a per-thread memory pool. The ref count of an
+ effect must reach 0 before the thread terminates and the pool is destroyed. To create a static
+ effect use the macro GR_CREATE_STATIC_EFFECT declared below.
+ */
+class GrProcessor : public GrProgramElement {
+public:
+ SK_DECLARE_INST_COUNT(GrProcessor)
+
+ virtual ~GrProcessor();
+
+ /**
+ * This function is used to perform optimizations. When called the color and validFlags params
+ * indicate whether the input components to this effect in the FS will have known values.
+ * validFlags is a bitfield of GrColorComponentFlags. The function updates both params to
+ * indicate known values of its output. A component of the color param only has meaning if the
+ * corresponding bit in validFlags is set.
+ */
+ virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const = 0;
+
+ /** This object, besides creating back-end-specific helper objects, is used for run-time-type-
+ identification. The factory should be an instance of templated class,
+ GrTBackendEffectFactory. It is templated on the subclass of GrProcessor. The subclass must
+ have a nested type (or typedef) named GLProcessor which will be the subclass of
+ GrGLProcessor created by the factory.
+
+ Example:
+ class MyCustomEffect : public GrProcessor {
+ ...
+ virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
+ return GrTBackendEffectFactory<MyCustomEffect>::getInstance();
+ }
+ ...
+ };
+ */
+ virtual const GrBackendProcessorFactory& getFactory() const = 0;
+
+ /** Returns true if this and other effect conservatively draw identically. It can only return
+ true when the two effects are of the same subclass (i.e. they return the same object from
+ from getFactory()).
+
+ A return value of true from isEqual() should not be used to test whether the effects would
+ generate the same shader code. To test for identical code generation use the effects' keys
+ computed by the GrBackendEffectFactory.
+ */
+ bool isEqual(const GrProcessor& other) const {
+ if (&this->getFactory() != &other.getFactory()) {
+ return false;
+ }
+ bool result = this->onIsEqual(other);
+#ifdef SK_DEBUG
+ if (result) {
+ this->assertEquality(other);
+ }
+#endif
+ return result;
+ }
+
+ /** Human-meaningful string to identify this effect; may be embedded
+ in generated shader code. */
+ const char* name() const;
+
+ int numTransforms() const { return fCoordTransforms.count(); }
+
+ /** Returns the coordinate transformation at index. index must be valid according to
+ numTransforms(). */
+ const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
+
+ int numTextures() const { return fTextureAccesses.count(); }
+
+ /** Returns the access pattern for the texture at index. index must be valid according to
+ numTextures(). */
+ const GrTextureAccess& textureAccess(int index) const { return *fTextureAccesses[index]; }
+
+ /** Shortcut for textureAccess(index).texture(); */
+ GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
+
+ /** Will this effect read the fragment position? */
+ bool willReadFragmentPosition() const { return fWillReadFragmentPosition; }
+
+ void* operator new(size_t size);
+ void operator delete(void* target);
+
+ void* operator new(size_t size, void* placement) {
+ return ::operator new(size, placement);
+ }
+ void operator delete(void* target, void* placement) {
+ ::operator delete(target, placement);
+ }
+
+ /**
+ * Helper for down-casting to a GrProcessor subclass
+ */
+ template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
+
+protected:
+ /**
+ * Subclasses call this from their constructor to register coordinate transformations. The
+ * effect subclass manages the lifetime of the transformations (this function only stores a
+ * pointer). The GrCoordTransform is typically a member field of the GrProcessor subclass. When
+ * the matrix has perspective, the transformed coordinates will have 3 components. Otherwise
+ * they'll have 2. This must only be called from the constructor because GrProcessors are
+ * immutable.
+ */
+ void addCoordTransform(const GrCoordTransform* coordTransform);
+
+ /**
+ * Subclasses call this from their constructor to register GrTextureAccesses. The effect
+ * subclass manages the lifetime of the accesses (this function only stores a pointer). The
+ * GrTextureAccess is typically a member field of the GrProcessor subclass. This must only be
+ * called from the constructor because GrProcessors are immutable.
+ */
+ void addTextureAccess(const GrTextureAccess* textureAccess);
+
+ GrProcessor()
+ : fWillReadFragmentPosition(false) {}
+
+ /**
+ * If the effect will generate a backend-specific effect that will read the fragment position
+ * in the FS then it must call this method from its constructor. Otherwise, the request to
+ * access the fragment position will be denied.
+ */
+ void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; }
+
+private:
+ SkDEBUGCODE(void assertEquality(const GrProcessor& other) const;)
+
+ /** Subclass implements this to support isEqual(). It will only be called if it is known that
+ the two effects are of the same subclass (i.e. they return the same object from
+ getFactory()).*/
+ virtual bool onIsEqual(const GrProcessor& other) const = 0;
+
+ friend class GrGeometryProcessor; // to set fRequiresVertexShader and build fVertexAttribTypes.
+
+ SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
+ SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
+ bool fWillReadFragmentPosition;
+
+ typedef GrProgramElement INHERITED;
+};
+
+class GrFragmentProcessor : public GrProcessor {
+public:
+ GrFragmentProcessor()
+ : INHERITED()
+ , fWillReadDstColor(false)
+ , fWillUseInputColor(true) {}
+
+ virtual const GrBackendFragmentProcessorFactory& getFactory() const = 0;
+
+ /** Will this effect read the destination pixel value? */
+ bool willReadDstColor() const { return fWillReadDstColor; }
+
+ /** Will this effect read the source color value? */
+ bool willUseInputColor() const { return fWillUseInputColor; }
+
+protected:
+ /**
+ * If the effect subclass will read the destination pixel value then it must call this function
+ * from its constructor. Otherwise, when its generated backend-specific effect class attempts
+ * to generate code that reads the destination pixel it will fail.
+ */
+ void setWillReadDstColor() { fWillReadDstColor = true; }
+
+ /**
+ * If the effect will generate a result that does not depend on the input color value then it
+ * must call this function from its constructor. Otherwise, when its generated backend-specific
+ * code might fail during variable binding due to unused variables.
+ */
+ void setWillNotUseInputColor() { fWillUseInputColor = false; }
+
+private:
+ bool fWillReadDstColor;
+ bool fWillUseInputColor;
+
+ typedef GrProcessor INHERITED;
+};
+
+/**
+ * This creates an effect outside of the effect memory pool. The effect's destructor will be called
+ * at global destruction time. NAME will be the name of the created GrProcessor.
+ */
+#define GR_CREATE_STATIC_FRAGMENT_PROCESSOR(NAME, EFFECT_CLASS, ARGS) \
+static SkAlignedSStorage<sizeof(EFFECT_CLASS)> g_##NAME##_Storage; \
+static GrFragmentProcessor* \
+NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), EFFECT_CLASS, ARGS); \
+static SkAutoTDestroy<GrFragmentProcessor> NAME##_ad(NAME);
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrProcessorStage.h b/src/third_party/skia/include/gpu/GrProcessorStage.h
new file mode 100644
index 0000000..1485ca7
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrProcessorStage.h
@@ -0,0 +1,178 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrProcessorStage_DEFINED
+#define GrProcessorStage_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "GrCoordTransform.h"
+#include "GrProcessor.h"
+#include "GrGeometryProcessor.h"
+#include "GrProgramElementRef.h"
+#include "SkMatrix.h"
+#include "SkShader.h"
+
+// TODO: Make two variations on this class: One for GrDrawState that only owns regular refs
+// and supports compatibility checks and changing local coords. The second is for GrOptDrawState,
+// is immutable, and only owns pending execution refs. This requries removing the common base
+// class from GrDrawState and GrOptDrawState called GrRODrawState and converting to GrOptDrawState
+// when draws are enqueued in the GrInOrderDrawBuffer.
+class GrProcessorStage {
+public:
+ explicit GrProcessorStage(const GrProcessor* proc)
+ : fProc(SkRef(proc)) {
+ fCoordChangeMatrixSet = false;
+ }
+
+ GrProcessorStage(const GrProcessorStage& other) {
+ fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
+ if (other.fCoordChangeMatrixSet) {
+ fCoordChangeMatrix = other.fCoordChangeMatrix;
+ }
+ fProc.initAndRef(other.fProc);
+ }
+
+ static bool AreCompatible(const GrProcessorStage& a, const GrProcessorStage& b,
+ bool usingExplicitLocalCoords) {
+ SkASSERT(a.fProc.get());
+ SkASSERT(b.fProc.get());
+
+ if (!a.getProcessor()->isEqual(*b.getProcessor())) {
+ return false;
+ }
+
+ // We always track the coord change matrix, but it has no effect when explicit local coords
+ // are used.
+ if (usingExplicitLocalCoords) {
+ return true;
+ }
+
+ if (a.fCoordChangeMatrixSet != b.fCoordChangeMatrixSet) {
+ return false;
+ }
+
+ if (!a.fCoordChangeMatrixSet) {
+ return true;
+ }
+
+ return a.fCoordChangeMatrix == b.fCoordChangeMatrix;
+ }
+
+ /**
+ * This is called when the coordinate system in which the geometry is specified will change.
+ *
+ * @param matrix The transformation from the old coord system in which geometry is specified
+ * to the new one from which it will actually be drawn.
+ */
+ void localCoordChange(const SkMatrix& matrix) {
+ if (fCoordChangeMatrixSet) {
+ fCoordChangeMatrix.preConcat(matrix);
+ } else {
+ fCoordChangeMatrixSet = true;
+ fCoordChangeMatrix = matrix;
+ }
+ }
+
+ class SavedCoordChange {
+ public:
+ SkDEBUGCODE(SavedCoordChange() : fEffectUniqueID(SK_InvalidUniqueID) {})
+ private:
+ bool fCoordChangeMatrixSet;
+ SkMatrix fCoordChangeMatrix;
+ SkDEBUGCODE(mutable uint32_t fEffectUniqueID;)
+
+ friend class GrProcessorStage;
+ };
+
+ /**
+ * This gets the current coordinate system change. It is the accumulation of
+ * localCoordChange calls since the effect was installed. It is used when then caller
+ * wants to temporarily change the source geometry coord system, draw something, and then
+ * restore the previous coord system (e.g. temporarily draw in device coords).
+ */
+ void saveCoordChange(SavedCoordChange* savedCoordChange) const {
+ savedCoordChange->fCoordChangeMatrixSet = fCoordChangeMatrixSet;
+ if (fCoordChangeMatrixSet) {
+ savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
+ }
+ SkASSERT(SK_InvalidUniqueID == savedCoordChange->fEffectUniqueID);
+ SkDEBUGCODE(savedCoordChange->fEffectUniqueID = fProc->getUniqueID();)
+ }
+
+ /**
+ * This balances the saveCoordChange call.
+ */
+ void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
+ fCoordChangeMatrixSet = savedCoordChange.fCoordChangeMatrixSet;
+ if (fCoordChangeMatrixSet) {
+ fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
+ }
+ SkASSERT(savedCoordChange.fEffectUniqueID == fProc->getUniqueID());
+ SkDEBUGCODE(savedCoordChange.fEffectUniqueID = SK_InvalidUniqueID);
+ }
+
+ /**
+ * Gets the matrix representing all changes of coordinate system since the GrProcessor was
+ * installed in the stage.
+ */
+ const SkMatrix& getCoordChangeMatrix() const {
+ if (fCoordChangeMatrixSet) {
+ return fCoordChangeMatrix;
+ } else {
+ return SkMatrix::I();
+ }
+ }
+
+ bool isPerspectiveCoordTransform(int matrixIndex, bool useExplicitLocalCoords) const {
+ const GrCoordTransform& coordTransform = this->getProcessor()->coordTransform(matrixIndex);
+ SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
+ SkMatrix::TypeMask type1 = SkMatrix::kIdentity_Mask;
+ if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
+ type1 = useExplicitLocalCoords ?
+ SkMatrix::kIdentity_Mask : this->getCoordChangeMatrix().getType();
+ }
+
+ int combinedTypes = type0 | type1;
+ if (SkMatrix::kPerspective_Mask & combinedTypes) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ const GrProcessor* getProcessor() const { return fProc.get(); }
+
+ void convertToPendingExec() { fProc.convertToPendingExec(); }
+
+private:
+ bool fCoordChangeMatrixSet;
+ SkMatrix fCoordChangeMatrix;
+ GrProgramElementRef<const GrProcessor> fProc;
+};
+
+class GrFragmentStage : public GrProcessorStage {
+public:
+ GrFragmentStage(const GrFragmentProcessor* fp) : GrProcessorStage(fp) {}
+
+ const GrFragmentProcessor* getFragmentProcessor() const {
+ return static_cast<const GrFragmentProcessor*>(this->getProcessor());
+ }
+};
+
+class GrGeometryStage : public GrProcessorStage {
+public:
+ GrGeometryStage(const GrGeometryProcessor* gp) : GrProcessorStage(gp) {}
+
+ const GrGeometryProcessor* getGeometryProcessor() const {
+ return static_cast<const GrGeometryProcessor*>(this->getProcessor());
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrProcessorUnitTest.h b/src/third_party/skia/include/gpu/GrProcessorUnitTest.h
new file mode 100644
index 0000000..04ab2d1
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrProcessorUnitTest.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProcessorUnitTest_DEFINED
+#define GrProcessorUnitTest_DEFINED
+
+#include "SkRandom.h"
+#include "SkTArray.h"
+#include "SkTypes.h"
+
+class SkMatrix;
+class GrDrawTargetCaps;
+
+namespace GrProcessorUnitTest {
+// Used to access the dummy textures in TestCreate procs.
+enum {
+ kSkiaPMTextureIdx = 0,
+ kAlphaTextureIdx = 1,
+};
+
+/**
+ * A helper for use in GrProcessor::TestCreate functions.
+ */
+const SkMatrix& TestMatrix(SkRandom*);
+
+}
+
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+class GrContext;
+class GrProcessor;
+class GrTexture;
+
+template <class Processor>
+class GrProcessorTestFactory : SkNoncopyable {
+public:
+
+ typedef Processor* (*CreateProc)(SkRandom*,
+ GrContext*,
+ const GrDrawTargetCaps& caps,
+ GrTexture* dummyTextures[]);
+
+ GrProcessorTestFactory(CreateProc createProc) {
+ fCreateProc = createProc;
+ GetFactories()->push_back(this);
+ }
+
+ static Processor* CreateStage(SkRandom* random,
+ GrContext* context,
+ const GrDrawTargetCaps& caps,
+ GrTexture* dummyTextures[]) {
+ uint32_t idx = random->nextRangeU(0, GetFactories()->count() - 1);
+ GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
+ return factory->fCreateProc(random, context, caps, dummyTextures);
+ }
+
+private:
+ CreateProc fCreateProc;
+
+ #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+ static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories() {
+ static SkTArray<GrProcessorTestFactory<Processor>*, true> gFactories;
+ return &gFactories;
+ }
+ #endif
+};
+
+/** GrProcessor subclasses should insert this macro in their declaration to be included in the
+ * program generation unit test.
+ */
+
+#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
+ static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory; \
+ static GrGeometryProcessor* TestCreate(SkRandom*, \
+ GrContext*, \
+ const GrDrawTargetCaps&, \
+ GrTexture* dummyTextures[2])
+
+#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
+ static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory; \
+ static GrFragmentProcessor* TestCreate(SkRandom*, \
+ GrContext*, \
+ const GrDrawTargetCaps&, \
+ GrTexture* dummyTextures[2])
+
+/** GrProcessor subclasses should insert this macro in their implementation file. They must then
+ * also implement this static function:
+ * GrProcessor* TestCreate(SkRandom*,
+ * GrContext*,
+ * const GrDrawTargetCaps&,
+ * GrTexture* dummyTextures[2]);
+ * dummyTextures[] are valid textures that can optionally be used to construct GrTextureAccesses.
+ * The first texture has config kSkia8888_GrPixelConfig and the second has
+ * kAlpha_8_GrPixelConfig. TestCreate functions are also free to create additional textures using
+ * the GrContext.
+ */
+#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect) \
+ GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate)
+
+#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect) \
+ GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate)
+
+#else // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+// The unit test relies on static initializers. Just declare the TestCreate function so that
+// its definitions will compile.
+#define GR_DECLARE_FRAGMENT_PROCESSOR_TEST \
+ static GrFragmentProcessor* TestCreate(SkRandom*, \
+ GrContext*, \
+ const GrDrawTargetCaps&, \
+ GrTexture* dummyTextures[2])
+#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
+
+// The unit test relies on static initializers. Just declare the TestCreate function so that
+// its definitions will compile.
+#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST \
+ static GrGeometryProcessor* TestCreate(SkRandom*, \
+ GrContext*, \
+ const GrDrawTargetCaps&, \
+ GrTexture* dummyTextures[2])
+#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
+
+#endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+#endif
diff --git a/src/third_party/skia/include/gpu/GrProgramElement.h b/src/third_party/skia/include/gpu/GrProgramElement.h
new file mode 100644
index 0000000..245dcd5
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrProgramElement.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProgramElement_DEFINED
+#define GrProgramElement_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+
+class GrGpuResourceRef;
+
+/**
+ * Base class for GrProcessor. GrDrawState uses this to manage
+ * transitioning a GrProcessor from being owned by a client to being scheduled for execution. It
+ * converts resources owned by the effect from being ref'ed to having pending reads/writes.
+ *
+ * All GrGpuResource objects owned by a GrProgramElement or derived classes (either directly or
+ * indirectly) must be wrapped in a GrGpuResourceRef and registered with the GrProgramElement using
+ * addGpuResource(). This allows the regular refs to be converted to pending IO events
+ * when the program element is scheduled for deferred execution.
+ */
+class GrProgramElement : public SkNoncopyable {
+public:
+ SK_DECLARE_INST_COUNT_ROOT(GrProgramElement)
+
+ virtual ~GrProgramElement() {
+ // fRefCnt can be one when an effect is created statically using GR_CREATE_STATIC_EFFECT
+ SkASSERT((0 == fRefCnt || 1 == fRefCnt) && 0 == fPendingExecutions);
+ // Set to invalid values.
+ SkDEBUGCODE(fRefCnt = fPendingExecutions = -10;)
+ }
+
+ void ref() const {
+ // Once the ref cnt reaches zero it should never be ref'ed again.
+ SkASSERT(fRefCnt > 0);
+ this->validate();
+ ++fRefCnt;
+ }
+
+ void unref() const {
+ this->validate();
+ --fRefCnt;
+ if (0 == fRefCnt && 0 == fPendingExecutions) {
+ SkDELETE(this);
+ }
+ }
+
+ /**
+ * Gets an id that is unique for this GrProgramElement object. This will never return 0.
+ */
+ uint32_t getUniqueID() const { return fUniqueID; }
+
+ void validate() const {
+#ifdef SK_DEBUG
+ SkASSERT(fRefCnt >= 0);
+ SkASSERT(fPendingExecutions >= 0);
+ SkASSERT(fRefCnt + fPendingExecutions > 0);
+#endif
+ }
+
+protected:
+ GrProgramElement() : fRefCnt(1), fPendingExecutions(0), fUniqueID(CreateUniqueID()) {}
+
+ /** Subclasses registers their resources using this function. It is assumed the GrProgramResouce
+ is and will remain owned by the subclass and this function will retain a raw ptr. Once a
+ GrGpuResourceRef is registered its setResource must not be called.
+ */
+ void addGpuResource(const GrGpuResourceRef* res) {
+ fGpuResources.push_back(res);
+ }
+
+private:
+ static uint32_t CreateUniqueID();
+
+ void convertRefToPendingExecution() const;
+
+ void completedExecution() const;
+
+ mutable int32_t fRefCnt;
+ // Count of deferred executions not yet issued to the 3D API.
+ mutable int32_t fPendingExecutions;
+ uint32_t fUniqueID;
+
+ SkSTArray<4, const GrGpuResourceRef*, true> fGpuResources;
+
+ // Only this class can access convertRefToPendingExecution() and completedExecution().
+ template <typename T> friend class GrProgramElementRef;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrProgramElementRef.h b/src/third_party/skia/include/gpu/GrProgramElementRef.h
new file mode 100644
index 0000000..ecc8023
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrProgramElementRef.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProgramElementRef_DEFINED
+#define GrProgramElementRef_DEFINED
+
+#include "SkRefCnt.h"
+#include "GrTypes.h"
+
+/**
+ * Helper for owning a GrProgramElement subclass and being able to convert a ref to pending
+ * execution. It is like an SkAutoTUnref for program elements whose execution can be deferred. Once
+ * in the pending execution state it is illegal to change the object that is owned by the
+ * GrProgramElementRef. Its destructor will either unref the GrProgramElement or signal that
+ * the pending execution has completed, depending on whether convertToPendingExec() was called.
+ */
+template <typename T> class GrProgramElementRef : SkNoncopyable {
+public:
+ GrProgramElementRef() : fOwnPendingExec(false), fObj(NULL) {};
+
+ // Adopts a ref from the caller.
+ explicit GrProgramElementRef(T* obj) : fOwnPendingExec(false), fObj(obj) {}
+
+ // Adopts a ref from the caller. Do not call after convertToPendingExec.
+ void reset(T* obj) {
+ SkASSERT(!fOwnPendingExec);
+ SkSafeUnref(fObj);
+ fObj = obj;
+ }
+
+ void convertToPendingExec() {
+ SkASSERT(!fOwnPendingExec);
+ fObj->convertRefToPendingExecution();
+ fOwnPendingExec = true;
+ }
+
+ // In the short term we need to support copying a GrProcessorStage and making the copy own
+ // the same type of ref as the source. This function exists to support this. TODO: Once
+ // GrDrawState and GrOptDrawState no longer share a base class they won't have to share
+ // GrProcessorStage and we can have GrOptDrawState always own pending executions rather than
+ // refs on GrProgramElements. At that point we should be able to delete this function.
+ // This function makes assumptions that are valid in the GrProcessorStage use case and should
+ // not be used elsewhere.
+ void initAndRef(const GrProgramElementRef& that) {
+ SkASSERT(!fObj);
+ SkASSERT(that.fObj);
+ if (that.fOwnPendingExec) {
+ SkASSERT(that.fObj->fPendingExecutions > 0);
+ that.fObj->fPendingExecutions++;
+ } else {
+ that.fObj->ref();
+ }
+ this->fOwnPendingExec = that.fOwnPendingExec;
+ this->fObj = that.fObj;
+ }
+
+ T* get() const { return fObj; }
+ operator T*() { return fObj; }
+
+ /** If T is const, the type returned from operator-> will also be const. */
+ typedef typename SkTConstType<typename SkAutoTUnref<T>::template BlockRef<T>,
+ SkTIsConst<T>::value>::type BlockRefType;
+
+ /**
+ * GrProgramElementRef assumes ownership of the ref and manages converting the ref to a
+ * pending execution. As a result, it is an error for the user to ref or unref through
+ * GrProgramElementRef. Therefore operator-> returns BlockRef<T>*.
+ */
+ BlockRefType *operator->() const {
+ return static_cast<BlockRefType*>(fObj);
+ }
+
+ ~GrProgramElementRef() {
+ if (fObj) {
+ if (fOwnPendingExec) {
+ fObj->completedExecution();
+ } else {
+ fObj->unref();
+ }
+ }
+ }
+
+private:
+ bool fOwnPendingExec;
+ T* fObj;
+
+ typedef SkNoncopyable INHERITED;
+};
+#endif
diff --git a/src/third_party/skia/include/gpu/GrRect.h b/src/third_party/skia/include/gpu/GrRect.h
new file mode 100644
index 0000000..14130f8
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrRect.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrRect_DEFINED
+#define GrRect_DEFINED
+
+#include "SkTypes.h"
+#include "SkRect.h"
+
+struct GrIRect16 {
+ int16_t fLeft, fTop, fRight, fBottom;
+
+ static GrIRect16 SK_WARN_UNUSED_RESULT MakeEmpty() {
+ GrIRect16 r;
+ r.setEmpty();
+ return r;
+ }
+
+ static GrIRect16 SK_WARN_UNUSED_RESULT MakeWH(int16_t w, int16_t h) {
+ GrIRect16 r;
+ r.set(0, 0, w, h);
+ return r;
+ }
+
+ static GrIRect16 SK_WARN_UNUSED_RESULT MakeXYWH(int16_t x, int16_t y, int16_t w, int16_t h) {
+ GrIRect16 r;
+ r.set(x, y, x + w, y + h);
+ return r;
+ }
+
+ int width() const { return fRight - fLeft; }
+ int height() const { return fBottom - fTop; }
+ int area() const { return this->width() * this->height(); }
+ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+
+ void setEmpty() { memset(this, 0, sizeof(*this)); }
+
+ void set(int16_t left, int16_t top, int16_t right, int16_t bottom) {
+ fLeft = left;
+ fTop = top;
+ fRight = right;
+ fBottom = bottom;
+ }
+
+ void set(const SkIRect& r) {
+ fLeft = SkToS16(r.fLeft);
+ fTop = SkToS16(r.fTop);
+ fRight = SkToS16(r.fRight);
+ fBottom = SkToS16(r.fBottom);
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrRenderTarget.h b/src/third_party/skia/include/gpu/GrRenderTarget.h
new file mode 100644
index 0000000..4c5ec18
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrRenderTarget.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrRenderTarget_DEFINED
+#define GrRenderTarget_DEFINED
+
+#include "GrSurface.h"
+#include "SkRect.h"
+
+class GrStencilBuffer;
+class GrTexture;
+
+/**
+ * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
+ * A context's render target is set by setRenderTarget(). Render targets are
+ * created by a createTexture with the kRenderTarget_TextureFlag flag.
+ * Additionally, GrContext provides methods for creating GrRenderTargets
+ * that wrap externally created render targets.
+ */
+class GrRenderTarget : public GrSurface {
+public:
+ SK_DECLARE_INST_COUNT(GrRenderTarget)
+
+ // GrResource overrides
+ virtual size_t gpuMemorySize() const SK_OVERRIDE;
+
+ // GrSurface overrides
+ /**
+ * @return the texture associated with the render target, may be NULL.
+ */
+ virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; }
+ virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; }
+
+ /**
+ * @return this render target.
+ */
+ virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return this; }
+ virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE {
+ return this;
+ }
+
+ virtual bool readPixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
+
+ virtual void writePixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ const void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
+
+ // GrRenderTarget
+ /**
+ * If this RT is multisampled, this is the multisample buffer
+ * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
+ */
+ virtual GrBackendObject getRenderTargetHandle() const = 0;
+
+ /**
+ * If this RT is multisampled, this is the buffer it is resolved to.
+ * Otherwise, same as getRenderTargetHandle().
+ * (In GL a separate FBO ID is used for the MSAA and resolved buffers)
+ * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
+ */
+ virtual GrBackendObject getRenderTargetResolvedHandle() const = 0;
+
+ /**
+ * @return true if the surface is multisampled, false otherwise
+ */
+ bool isMultisampled() const { return 0 != fDesc.fSampleCnt; }
+
+ /**
+ * @return the number of samples-per-pixel or zero if non-MSAA.
+ */
+ int numSamples() const { return fDesc.fSampleCnt; }
+
+ /**
+ * Call to indicate the multisample contents were modified such that the
+ * render target needs to be resolved before it can be used as texture. Gr
+ * tracks this for its own drawing and thus this only needs to be called
+ * when the render target has been modified outside of Gr. This has no
+ * effect on wrapped backend render targets.
+ *
+ * @param rect a rect bounding the area needing resolve. NULL indicates
+ * the whole RT needs resolving.
+ */
+ void flagAsNeedingResolve(const SkIRect* rect = NULL);
+
+ /**
+ * Call to override the region that needs to be resolved.
+ */
+ void overrideResolveRect(const SkIRect rect);
+
+ /**
+ * Call to indicate that GrRenderTarget was externally resolved. This may
+ * allow Gr to skip a redundant resolve step.
+ */
+ void flagAsResolved() { fResolveRect.setLargestInverted(); }
+
+ /**
+ * @return true if the GrRenderTarget requires MSAA resolving
+ */
+ bool needsResolve() const { return !fResolveRect.isEmpty(); }
+
+ /**
+ * Returns a rect bounding the region needing resolving.
+ */
+ const SkIRect& getResolveRect() const { return fResolveRect; }
+
+ /**
+ * If the render target is multisampled this will perform a multisample
+ * resolve. Any pending draws to the target are first flushed. This only
+ * applies to render targets that are associated with GrTextures. After the
+ * function returns the GrTexture will contain the resolved pixels.
+ */
+ void resolve();
+
+ /**
+ * Provide a performance hint that the render target's contents are allowed
+ * to become undefined.
+ */
+ void discard();
+
+ // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
+ // 0 in GL), or be unresolvable because the client didn't give us the
+ // resolve destination.
+ enum ResolveType {
+ kCanResolve_ResolveType,
+ kAutoResolves_ResolveType,
+ kCantResolve_ResolveType,
+ };
+ virtual ResolveType getResolveType() const = 0;
+
+ /**
+ * GrStencilBuffer is not part of the public API.
+ */
+ GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; }
+ void setStencilBuffer(GrStencilBuffer* stencilBuffer);
+
+protected:
+ GrRenderTarget(GrGpu* gpu,
+ bool isWrapped,
+ GrTexture* texture,
+ const GrTextureDesc& desc)
+ : INHERITED(gpu, isWrapped, desc)
+ , fStencilBuffer(NULL)
+ , fTexture(texture) {
+ fResolveRect.setLargestInverted();
+ }
+
+ // override of GrResource
+ virtual void onAbandon() SK_OVERRIDE;
+ virtual void onRelease() SK_OVERRIDE;
+
+private:
+ friend class GrTexture;
+ // called by ~GrTexture to remove the non-ref'ed back ptr.
+ void owningTextureDestroyed() {
+ SkASSERT(fTexture);
+ fTexture = NULL;
+ }
+
+ GrStencilBuffer* fStencilBuffer;
+ GrTexture* fTexture; // not ref'ed
+
+ SkIRect fResolveRect;
+
+ typedef GrSurface INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrResourceKey.h b/src/third_party/skia/include/gpu/GrResourceKey.h
new file mode 100644
index 0000000..d3e82c8
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrResourceKey.h
@@ -0,0 +1,113 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrResourceKey_DEFINED
+#define GrResourceKey_DEFINED
+
+#include "GrTypes.h"
+#include "GrBinHashKey.h"
+
+class GrResourceKey {
+public:
+ static GrCacheID::Domain ScratchDomain() {
+ static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain();
+ return gDomain;
+ }
+
+ /** Uniquely identifies the GrGpuResource subclass in the key to avoid collisions
+ across resource types. */
+ typedef uint8_t ResourceType;
+
+ /** Flags set by the GrGpuResource subclass. */
+ typedef uint8_t ResourceFlags;
+
+ /** Generate a unique ResourceType */
+ static ResourceType GenerateResourceType();
+
+ /** Creates a key for resource */
+ GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
+ this->init(id.getDomain(), id.getKey(), type, flags);
+ };
+
+ GrResourceKey(const GrResourceKey& src) { fKey = src.fKey; }
+
+ GrResourceKey() { fKey.reset(); }
+
+ void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
+ this->init(id.getDomain(), id.getKey(), type, flags);
+ }
+
+ uint32_t getHash() const { return fKey.getHash(); }
+
+ bool isScratch() const {
+ return ScratchDomain() ==
+ *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() +
+ kCacheIDDomainOffset);
+ }
+
+ ResourceType getResourceType() const {
+ return *reinterpret_cast<const ResourceType*>(fKey.getData() +
+ kResourceTypeOffset);
+ }
+
+ ResourceFlags getResourceFlags() const {
+ return *reinterpret_cast<const ResourceFlags*>(fKey.getData() +
+ kResourceFlagsOffset);
+ }
+
+ bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; }
+
+ // A key indicating that the resource is not usable as a scratch resource.
+ static GrResourceKey& NullScratchKey() {
+ static const GrCacheID::Key kBogusKey = { { {0} } };
+ static GrCacheID kBogusID(ScratchDomain(), kBogusKey);
+ static GrResourceKey kNullScratchKey(kBogusID, NoneResourceType(), 0);
+ return kNullScratchKey;
+ }
+
+ bool isNullScratch() const {
+ return this->isScratch() && NoneResourceType() == this->getResourceType();
+ }
+
+private:
+ enum {
+ kCacheIDKeyOffset = 0,
+ kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key),
+ kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain),
+ kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType),
+ kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags),
+ kKeySize = SkAlign4(kPadOffset),
+ kPadSize = kKeySize - kPadOffset
+ };
+
+ static ResourceType NoneResourceType() {
+ static const ResourceType gNoneResourceType = GenerateResourceType();
+ return gNoneResourceType;
+ }
+
+ void init(const GrCacheID::Domain domain,
+ const GrCacheID::Key& key,
+ ResourceType type,
+ ResourceFlags flags) {
+ union {
+ uint8_t fKey8[kKeySize];
+ uint32_t fKey32[kKeySize / 4];
+ } keyData;
+
+ uint8_t* k = keyData.fKey8;
+ memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key));
+ memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain));
+ memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType));
+ memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
+ memset(k + kPadOffset, 0, kPadSize);
+ fKey.setKeyData(keyData.fKey32);
+ }
+ GrBinHashKey<kKeySize> fKey;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrShaderVar.h b/src/third_party/skia/include/gpu/GrShaderVar.h
new file mode 100644
index 0000000..cbc074d
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrShaderVar.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrShaderVar_DEFINED
+#define GrShaderVar_DEFINED
+
+#include "GrTypesPriv.h"
+#include "SkString.h"
+
+class GrShaderVar {
+public:
+ /**
+ * Early versions of GLSL have Varying and Attribute; those are later
+ * deprecated, but we still need to know whether a Varying variable
+ * should be treated as In or Out.
+ *
+ * TODO This really shouldn't live here, but until we have c++11, there is really no good way
+ * to write extensible enums. In reality, only none, out, in, inout, and uniform really
+ * make sense on this base class
+ */
+ enum TypeModifier {
+ kNone_TypeModifier,
+ kOut_TypeModifier,
+ kIn_TypeModifier,
+ kInOut_TypeModifier,
+ kUniform_TypeModifier,
+ // GL Specific types below
+ kAttribute_TypeModifier,
+ kVaryingIn_TypeModifier,
+ kVaryingOut_TypeModifier
+ };
+
+ enum Precision {
+ kLow_Precision, // lowp
+ kMedium_Precision, // mediump
+ kHigh_Precision, // highp
+ kDefault_Precision, // Default for the current context. We make
+ // fragment shaders default to mediump on ES2
+ // because highp support is not guaranteed (and
+ // we haven't been motivated to test for it).
+ // Otherwise, highp.
+ };
+
+ /**
+ * Defaults to a float with no precision specifier
+ */
+ GrShaderVar()
+ : fType(kFloat_GrSLType)
+ , fTypeModifier(kNone_TypeModifier)
+ , fCount(kNonArray)
+ , fPrecision(kDefault_Precision) {
+ }
+
+ GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray,
+ Precision precision = kDefault_Precision)
+ : fType(type)
+ , fTypeModifier(kNone_TypeModifier)
+ , fName(name)
+ , fCount(arrayCount)
+ , fPrecision(precision) {
+ SkASSERT(kVoid_GrSLType != type);
+ }
+
+ GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
+ Precision precision = kDefault_Precision)
+ : fType(type)
+ , fTypeModifier(kNone_TypeModifier)
+ , fName(name)
+ , fCount(arrayCount)
+ , fPrecision(precision) {
+ SkASSERT(kVoid_GrSLType != type);
+ }
+
+ GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
+ int arrayCount = kNonArray, Precision precision = kDefault_Precision)
+ : fType(type)
+ , fTypeModifier(typeModifier)
+ , fName(name)
+ , fCount(arrayCount)
+ , fPrecision(precision) {
+ SkASSERT(kVoid_GrSLType != type);
+ }
+
+ /**
+ * Values for array count that have special meaning. We allow 1-sized arrays.
+ */
+ enum {
+ kNonArray = 0, // not an array
+ kUnsizedArray = -1, // an unsized array (declared with [])
+ };
+
+ /**
+ * Sets as a non-array.
+ */
+ void set(GrSLType type,
+ TypeModifier typeModifier,
+ const SkString& name,
+ Precision precision = kDefault_Precision) {
+ SkASSERT(kVoid_GrSLType != type);
+ fType = type;
+ fTypeModifier = typeModifier;
+ fName = name;
+ fCount = kNonArray;
+ fPrecision = precision;
+ }
+
+ /**
+ * Sets as a non-array.
+ */
+ void set(GrSLType type,
+ TypeModifier typeModifier,
+ const char* name,
+ Precision precision = kDefault_Precision) {
+ SkASSERT(kVoid_GrSLType != type);
+ fType = type;
+ fTypeModifier = typeModifier;
+ fName = name;
+ fCount = kNonArray;
+ fPrecision = precision;
+ }
+
+ /**
+ * Set all var options
+ */
+ void set(GrSLType type,
+ TypeModifier typeModifier,
+ const SkString& name,
+ int count,
+ Precision precision = kDefault_Precision) {
+ SkASSERT(kVoid_GrSLType != type);
+ fType = type;
+ fTypeModifier = typeModifier;
+ fName = name;
+ fCount = count;
+ fPrecision = precision;
+ }
+
+ /**
+ * Set all var options
+ */
+ void set(GrSLType type,
+ TypeModifier typeModifier,
+ const char* name,
+ int count,
+ Precision precision = kDefault_Precision) {
+ SkASSERT(kVoid_GrSLType != type);
+ fType = type;
+ fTypeModifier = typeModifier;
+ fName = name;
+ fCount = count;
+ fPrecision = precision;
+ }
+
+ /**
+ * Is the var an array.
+ */
+ bool isArray() const { return kNonArray != fCount; }
+ /**
+ * Is this an unsized array, (i.e. declared with []).
+ */
+ bool isUnsizedArray() const { return kUnsizedArray == fCount; }
+ /**
+ * Get the array length of the var.
+ */
+ int getArrayCount() const { return fCount; }
+ /**
+ * Set the array length of the var
+ */
+ void setArrayCount(int count) { fCount = count; }
+ /**
+ * Set to be a non-array.
+ */
+ void setNonArray() { fCount = kNonArray; }
+ /**
+ * Set to be an unsized array.
+ */
+ void setUnsizedArray() { fCount = kUnsizedArray; }
+
+ /**
+ * Access the var name as a writable string
+ */
+ SkString* accessName() { return &fName; }
+ /**
+ * Set the var name
+ */
+ void setName(const SkString& n) { fName = n; }
+ void setName(const char* n) { fName = n; }
+
+ /**
+ * Get the var name.
+ */
+ const SkString& getName() const { return fName; }
+
+ /**
+ * Shortcut for this->getName().c_str();
+ */
+ const char* c_str() const { return this->getName().c_str(); }
+
+ /**
+ * Get the type of the var
+ */
+ GrSLType getType() const { return fType; }
+ /**
+ * Set the type of the var
+ */
+ void setType(GrSLType type) { fType = type; }
+
+ TypeModifier getTypeModifier() const { return fTypeModifier; }
+ void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
+
+ /**
+ * Get the precision of the var
+ */
+ Precision getPrecision() const { return fPrecision; }
+
+ /**
+ * Set the precision of the var
+ */
+ void setPrecision(Precision p) { fPrecision = p; }
+
+protected:
+ GrSLType fType;
+ TypeModifier fTypeModifier;
+ SkString fName;
+ int fCount;
+ Precision fPrecision;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrSurface.h b/src/third_party/skia/include/gpu/GrSurface.h
new file mode 100644
index 0000000..24eb39a
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrSurface.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrSurface_DEFINED
+#define GrSurface_DEFINED
+
+#include "GrTypes.h"
+#include "GrGpuResource.h"
+#include "SkRect.h"
+
+class GrTexture;
+class GrRenderTarget;
+struct SkImageInfo;
+
+class GrSurface : public GrGpuResource {
+public:
+ SK_DECLARE_INST_COUNT(GrSurface);
+
+ /**
+ * Retrieves the width of the surface.
+ *
+ * @return the width in texels
+ */
+ int width() const { return fDesc.fWidth; }
+
+ /**
+ * Retrieves the height of the surface.
+ *
+ * @return the height in texels
+ */
+ int height() const { return fDesc.fHeight; }
+
+ /**
+ * Helper that gets the width and height of the surface as a bounding rectangle.
+ */
+ void getBoundsRect(SkRect* rect) const { rect->setWH(SkIntToScalar(this->width()),
+ SkIntToScalar(this->height())); }
+
+ GrSurfaceOrigin origin() const {
+ SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin || kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
+ return fDesc.fOrigin;
+ }
+
+ /**
+ * Retrieves the pixel config specified when the surface was created.
+ * For render targets this can be kUnknown_GrPixelConfig
+ * if client asked us to render to a target that has a pixel
+ * config that isn't equivalent with one of our configs.
+ */
+ GrPixelConfig config() const { return fDesc.fConfig; }
+
+ /**
+ * Return the descriptor describing the surface
+ */
+ const GrTextureDesc& desc() const { return fDesc; }
+
+ SkImageInfo info() const;
+
+ /**
+ * @return the texture associated with the surface, may be NULL.
+ */
+ virtual GrTexture* asTexture() = 0;
+ virtual const GrTexture* asTexture() const = 0;
+
+ /**
+ * @return the render target underlying this surface, may be NULL.
+ */
+ virtual GrRenderTarget* asRenderTarget() = 0;
+ virtual const GrRenderTarget* asRenderTarget() const = 0;
+
+ /**
+ * Checks whether this GrSurface refers to the same GPU object as other. This
+ * catches the case where a GrTexture and GrRenderTarget refer to the same
+ * GPU memory.
+ */
+ bool isSameAs(const GrSurface* other) const {
+ const GrRenderTarget* thisRT = this->asRenderTarget();
+ if (thisRT) {
+ return thisRT == other->asRenderTarget();
+ } else {
+ const GrTexture* thisTex = this->asTexture();
+ SkASSERT(thisTex); // We must be one or the other
+ return thisTex == other->asTexture();
+ }
+ }
+
+ /**
+ * Reads a rectangle of pixels from the surface.
+ * @param left left edge of the rectangle to read (inclusive)
+ * @param top top edge of the rectangle to read (inclusive)
+ * @param width width of rectangle to read in pixels.
+ * @param height height of rectangle to read in pixels.
+ * @param config the pixel config of the destination buffer
+ * @param buffer memory to read the rectangle into.
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
+ * packed.
+ * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
+ *
+ * @return true if the read succeeded, false if not. The read can fail because of an unsupported
+ * pixel config.
+ */
+ virtual bool readPixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) = 0;
+
+ /**
+ * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified
+ * rectangle.
+ * @param left left edge of the rectangle to write (inclusive)
+ * @param top top edge of the rectangle to write (inclusive)
+ * @param width width of rectangle to write in pixels.
+ * @param height height of rectangle to write in pixels.
+ * @param config the pixel config of the source buffer
+ * @param buffer memory to read the rectangle from.
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
+ * packed.
+ * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
+ */
+ virtual void writePixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ const void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) = 0;
+
+ /**
+ * Write the contents of the surface to a PNG. Returns true if successful.
+ * @param filename Full path to desired file
+ */
+ bool savePixels(const char* filename);
+
+ bool hasPendingRead() const;
+ bool hasPendingWrite() const;
+ bool hasPendingIO() const;
+
+protected:
+ GrSurface(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
+ : INHERITED(gpu, isWrapped)
+ , fDesc(desc) {
+ }
+
+ GrTextureDesc fDesc;
+
+private:
+ typedef GrGpuResource INHERITED;
+};
+
+#endif // GrSurface_DEFINED
diff --git a/src/third_party/skia/include/gpu/GrTBackendProcessorFactory.h b/src/third_party/skia/include/gpu/GrTBackendProcessorFactory.h
new file mode 100644
index 0000000..fa08201
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrTBackendProcessorFactory.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTBackendProcessorFactory_DEFINED
+#define GrTBackendProcessorFactory_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "gl/GrGLProgramEffects.h"
+
+/**
+ * Implements GrBackendEffectFactory for a GrProcessor subclass as a singleton. This can be used by
+ * most GrProcessor subclasses to implement the GrProcessor::getFactory() method:
+ *
+ * const GrBackendEffectFactory& MyEffect::getFactory() const {
+ * return GrTBackendEffectFactory<MyEffect>::getInstance();
+ * }
+ *
+ * Using this class requires that the GrProcessor subclass always produces the same GrGLProcessor
+ * subclass. Additionally, it adds the following requirements to the GrProcessor and GrGLProcessor
+ * subclasses:
+ *
+ * 1. The GrGLProcessor used by GrProcessor subclass MyEffect must be named or typedef'ed to
+ * MyEffect::GLProcessor.
+ * 2. MyEffect::GLProcessor must have a static function:
+ * EffectKey GenKey(const GrProcessor, const GrGLCaps&)
+ * which generates a key that maps 1 to 1 with code variations emitted by
+ * MyEffect::GLProcessor::emitCode().
+ * 3. MyEffect must have a static function:
+ * const char* Name()
+ * which returns a human-readable name for the effect.
+ */
+template <class ProcessorClass, class BackEnd, class ProcessorBase, class GLProcessorBase>
+class GrTBackendProcessorFactory : public BackEnd {
+public:
+ typedef typename ProcessorClass::GLProcessor GLProcessor;
+
+ /** Returns a human-readable name for the effect. Implemented using GLProcessor::Name as
+ * described in this class's comment. */
+ virtual const char* name() const SK_OVERRIDE { return ProcessorClass::Name(); }
+
+ /** Implemented using GLProcessor::GenKey as described in this class's comment. */
+ virtual void getGLProcessorKey(const GrProcessor& effect,
+ const GrGLCaps& caps,
+ GrProcessorKeyBuilder* b) const SK_OVERRIDE {
+#if !defined(SK_PS3_CUSTOM_BACKEND)
+ GLProcessor::GenKey(effect, caps, b);
+#endif
+ }
+
+ /** Returns a new instance of the appropriate *GL* implementation class
+ for the given GrProcessor; caller is responsible for deleting
+ the object. */
+ virtual GLProcessorBase* createGLInstance(const ProcessorBase& effect) const SK_OVERRIDE {
+#if !defined(SK_PS3_CUSTOM_BACKEND)
+ return SkNEW_ARGS(GLProcessor, (*this, effect));
+#else
+ return NULL;
+#endif
+ }
+
+ /** This class is a singleton. This function returns the single instance. */
+ static const BackEnd& getInstance() {
+ static SkAlignedSTStorage<1, GrTBackendProcessorFactory> gInstanceMem;
+ static const GrTBackendProcessorFactory* gInstance;
+ if (!gInstance) {
+ gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
+ GrTBackendProcessorFactory);
+ }
+ return *gInstance;
+ }
+
+protected:
+ GrTBackendProcessorFactory() {}
+};
+
+/*
+ * Every effect so far derives from one of the following subclasses of GrTBackendProcessorFactory.
+ * All of this machinery is necessary to ensure that creatGLInstace is typesafe and does not
+ * require any casting
+ */
+template <class ProcessorClass>
+class GrTBackendGeometryProcessorFactory
+ : public GrTBackendProcessorFactory<ProcessorClass,
+ GrBackendGeometryProcessorFactory,
+ GrGeometryProcessor,
+ GrGLGeometryProcessor> {
+protected:
+ GrTBackendGeometryProcessorFactory() {}
+};
+
+template <class ProcessorClass>
+class GrTBackendFragmentProcessorFactory
+ : public GrTBackendProcessorFactory<ProcessorClass,
+ GrBackendFragmentProcessorFactory,
+ GrFragmentProcessor,
+ GrGLFragmentProcessor> {
+protected:
+ GrTBackendFragmentProcessorFactory() {}
+};
+
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrTexture.h b/src/third_party/skia/include/gpu/GrTexture.h
new file mode 100644
index 0000000..06ba2e4
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrTexture.h
@@ -0,0 +1,219 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTexture_DEFINED
+#define GrTexture_DEFINED
+
+#include "GrSurface.h"
+#include "GrRenderTarget.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+
+class GrResourceKey;
+class GrTextureParams;
+class GrTextureImpl;
+
+class GrTexture : public GrSurface {
+public:
+ /**
+ * Approximate number of bytes used by the texture
+ */
+ virtual size_t gpuMemorySize() const SK_OVERRIDE;
+
+ // GrSurface overrides
+ virtual bool readPixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
+
+ virtual void writePixels(int left, int top, int width, int height,
+ GrPixelConfig config,
+ const void* buffer,
+ size_t rowBytes = 0,
+ uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
+
+ virtual GrTexture* asTexture() SK_OVERRIDE { return this; }
+ virtual const GrTexture* asTexture() const SK_OVERRIDE { return this; }
+ virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return fRenderTarget.get(); }
+ virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { return fRenderTarget.get(); }
+
+ /**
+ * Convert from texels to normalized texture coords for POT textures only. Please don't add
+ * new callsites for these functions. They are slated for removal.
+ */
+ SkFixed normalizeFixedX(SkFixed x) const {
+ SkASSERT(SkIsPow2(fDesc.fWidth));
+ return x >> fShiftFixedX;
+ }
+ SkFixed normalizeFixedY(SkFixed y) const {
+ SkASSERT(SkIsPow2(fDesc.fHeight));
+ return y >> fShiftFixedY;
+ }
+
+ /**
+ * Return the native ID or handle to the texture, depending on the
+ * platform. e.g. on OpenGL, return the texture ID.
+ */
+ virtual GrBackendObject getTextureHandle() const = 0;
+
+ /**
+ * This function indicates that the texture parameters (wrap mode, filtering, ...) have been
+ * changed externally to Skia.
+ */
+ virtual void textureParamsModified() = 0;
+ SK_ATTR_DEPRECATED("Renamed to textureParamsModified.")
+ void invalidateCachedState() { this->textureParamsModified(); }
+
+ /**
+ * Informational texture flags. This will be moved to the private GrTextureImpl class soon.
+ */
+ enum FlagBits {
+ kFirstBit = (kLastPublic_GrTextureFlagBit << 1),
+
+ /**
+ * This texture should be returned to the texture cache when
+ * it is no longer reffed
+ */
+ kReturnToCache_FlagBit = kFirstBit,
+ };
+
+ void resetFlag(GrTextureFlags flags) {
+ fDesc.fFlags = fDesc.fFlags & ~flags;
+ }
+
+#ifdef SK_DEBUG
+ void validate() const {
+ this->INHERITED::validate();
+ this->validateDesc();
+ }
+#endif
+
+ GrTextureImpl* impl() { return reinterpret_cast<GrTextureImpl*>(this); }
+ const GrTextureImpl* impl() const { return reinterpret_cast<const GrTextureImpl*>(this); }
+
+protected:
+ // A texture refs its rt representation but not vice-versa. It is up to
+ // the subclass constructor to initialize this pointer.
+ SkAutoTUnref<GrRenderTarget> fRenderTarget;
+
+ GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
+ : INHERITED(gpu, isWrapped, desc)
+ , fRenderTarget(NULL) {
+ // only make sense if alloc size is pow2
+ fShiftFixedX = 31 - SkCLZ(fDesc.fWidth);
+ fShiftFixedY = 31 - SkCLZ(fDesc.fHeight);
+ }
+
+ virtual ~GrTexture();
+
+ // GrResource overrides
+ virtual void onRelease() SK_OVERRIDE;
+ virtual void onAbandon() SK_OVERRIDE;
+
+ void validateDesc() const;
+
+private:
+ void abandonReleaseCommon();
+ virtual void internal_dispose() const SK_OVERRIDE;
+
+ // these two shift a fixed-point value into normalized coordinates
+ // for this texture if the texture is power of two sized.
+ int fShiftFixedX;
+ int fShiftFixedY;
+
+ typedef GrSurface INHERITED;
+};
+
+class GrTextureImpl : public GrTexture {
+public:
+ SK_DECLARE_INST_COUNT(GrTextureImpl)
+
+ void setFlag(GrTextureFlags flags) {
+ fDesc.fFlags = fDesc.fFlags | flags;
+ }
+ void resetFlag(GrTextureFlags flags) {
+ fDesc.fFlags = fDesc.fFlags & ~flags;
+ }
+ bool isSetFlag(GrTextureFlags flags) const {
+ return 0 != (fDesc.fFlags & flags);
+ }
+
+ void dirtyMipMaps(bool mipMapsDirty);
+
+ bool mipMapsAreDirty() const {
+ return kValid_MipMapsStatus != fMipMapsStatus;
+ }
+
+ bool hasMipMaps() const {
+ return kNotAllocated_MipMapsStatus != fMipMapsStatus;
+ }
+
+ static GrResourceKey ComputeKey(const GrGpu* gpu,
+ const GrTextureParams* params,
+ const GrTextureDesc& desc,
+ const GrCacheID& cacheID);
+ static GrResourceKey ComputeScratchKey(const GrTextureDesc& desc);
+ static bool NeedsResizing(const GrResourceKey& key);
+ static bool NeedsBilerp(const GrResourceKey& key);
+
+protected:
+ GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc);
+
+private:
+ enum MipMapsStatus {
+ kNotAllocated_MipMapsStatus,
+ kAllocated_MipMapsStatus,
+ kValid_MipMapsStatus
+ };
+
+ MipMapsStatus fMipMapsStatus;
+
+ typedef GrTexture INHERITED;
+};
+
+/**
+ * Represents a texture that is intended to be accessed in device coords with an offset.
+ */
+class GrDeviceCoordTexture {
+public:
+ GrDeviceCoordTexture() { fOffset.set(0, 0); }
+
+ GrDeviceCoordTexture(const GrDeviceCoordTexture& other) {
+ *this = other;
+ }
+
+ GrDeviceCoordTexture(GrTexture* texture, const SkIPoint& offset)
+ : fTexture(SkSafeRef(texture))
+ , fOffset(offset) {
+ }
+
+ GrDeviceCoordTexture& operator=(const GrDeviceCoordTexture& other) {
+ fTexture.reset(SkSafeRef(other.fTexture.get()));
+ fOffset = other.fOffset;
+ return *this;
+ }
+
+ const SkIPoint& offset() const { return fOffset; }
+
+ void setOffset(const SkIPoint& offset) { fOffset = offset; }
+ void setOffset(int ox, int oy) { fOffset.set(ox, oy); }
+
+ GrTexture* texture() const { return fTexture.get(); }
+
+ GrTexture* setTexture(GrTexture* texture) {
+ fTexture.reset(SkSafeRef(texture));
+ return texture;
+ }
+
+private:
+ SkAutoTUnref<GrTexture> fTexture;
+ SkIPoint fOffset;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrTextureAccess.h b/src/third_party/skia/include/gpu/GrTextureAccess.h
new file mode 100644
index 0000000..5055e10
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrTextureAccess.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTextureAccess_DEFINED
+#define GrTextureAccess_DEFINED
+
+#include "GrGpuResourceRef.h"
+#include "GrTexture.h"
+#include "SkRefCnt.h"
+#include "SkShader.h"
+
+/**
+ * Represents the filtering and tile modes used to access a texture. It is mostly used with
+ * GrTextureAccess (defined below). Also, some of the texture cache methods require knowledge about
+ * filtering and tiling to perform a cache lookup. If it wasn't for this latter usage this would
+ * be folded into GrTextureAccess. The default is clamp tile modes and no filtering.
+ */
+class GrTextureParams {
+public:
+ GrTextureParams() {
+ this->reset();
+ }
+
+ enum FilterMode {
+ kNone_FilterMode,
+ kBilerp_FilterMode,
+ kMipMap_FilterMode
+ };
+
+ GrTextureParams(SkShader::TileMode tileXAndY, FilterMode filterMode) {
+ this->reset(tileXAndY, filterMode);
+ }
+
+ GrTextureParams(const SkShader::TileMode tileModes[2], FilterMode filterMode) {
+ this->reset(tileModes, filterMode);
+ }
+
+ GrTextureParams(const GrTextureParams& params) {
+ *this = params;
+ }
+
+ GrTextureParams& operator= (const GrTextureParams& params) {
+ fTileModes[0] = params.fTileModes[0];
+ fTileModes[1] = params.fTileModes[1];
+ fFilterMode = params.fFilterMode;
+ return *this;
+ }
+
+ void reset() {
+ this->reset(SkShader::kClamp_TileMode, kNone_FilterMode);
+ }
+
+ void reset(SkShader::TileMode tileXAndY, FilterMode filterMode) {
+ fTileModes[0] = fTileModes[1] = tileXAndY;
+ fFilterMode = filterMode;
+ }
+
+ void reset(const SkShader::TileMode tileModes[2], FilterMode filterMode) {
+ fTileModes[0] = tileModes[0];
+ fTileModes[1] = tileModes[1];
+ fFilterMode = filterMode;
+ }
+
+ void setClampNoFilter() {
+ fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
+ fFilterMode = kNone_FilterMode;
+ }
+
+ void setClamp() {
+ fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
+ }
+
+ void setFilterMode(FilterMode filterMode) { fFilterMode = filterMode; }
+
+ void setTileModeX(const SkShader::TileMode tm) { fTileModes[0] = tm; }
+ void setTileModeY(const SkShader::TileMode tm) { fTileModes[1] = tm; }
+ void setTileModeXAndY(const SkShader::TileMode tm) { fTileModes[0] = fTileModes[1] = tm; }
+
+ SkShader::TileMode getTileModeX() const { return fTileModes[0]; }
+
+ SkShader::TileMode getTileModeY() const { return fTileModes[1]; }
+
+ bool isTiled() const {
+ return SkShader::kClamp_TileMode != fTileModes[0] ||
+ SkShader::kClamp_TileMode != fTileModes[1];
+ }
+
+ FilterMode filterMode() const { return fFilterMode; }
+
+ bool operator== (const GrTextureParams& other) const {
+ return fTileModes[0] == other.fTileModes[0] &&
+ fTileModes[1] == other.fTileModes[1] &&
+ fFilterMode == other.fFilterMode;
+ }
+
+ bool operator!= (const GrTextureParams& other) const { return !(*this == other); }
+
+private:
+
+ SkShader::TileMode fTileModes[2];
+ FilterMode fFilterMode;
+};
+
+/** A class representing the swizzle access pattern for a texture. Note that if the texture is
+ * an alpha-only texture then the alpha channel is substituted for other components. Any mangling
+ * to handle the r,g,b->a conversions for alpha textures is automatically included in the stage
+ * key. However, if a GrProcessor uses different swizzles based on its input then it must
+ * consider that variation in its key-generation.
+ */
+class GrTextureAccess : public SkNoncopyable {
+public:
+ SK_DECLARE_INST_COUNT_ROOT(GrTextureAccess);
+
+ /**
+ * A default GrTextureAccess must have reset() called on it in a GrProcessor subclass's
+ * constructor if it will be accessible via GrProcessor::textureAccess().
+ */
+ GrTextureAccess();
+
+ /**
+ * Uses the default swizzle, "rgba".
+ */
+ GrTextureAccess(GrTexture*, const GrTextureParams&);
+ explicit GrTextureAccess(GrTexture*,
+ GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
+ SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
+
+ /**
+ * swizzle must be a string between one and four (inclusive) characters containing only 'r',
+ * 'g', 'b', and/or 'a'.
+ */
+ GrTextureAccess(GrTexture*, const char* swizzle, const GrTextureParams&);
+ GrTextureAccess(GrTexture*,
+ const char* swizzle,
+ GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
+ SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
+
+ void reset(GrTexture*, const GrTextureParams&);
+ void reset(GrTexture*,
+ GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
+ SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
+ void reset(GrTexture*, const char* swizzle, const GrTextureParams&);
+ void reset(GrTexture*,
+ const char* swizzle,
+ GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
+ SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
+
+ bool operator== (const GrTextureAccess& other) const {
+#ifdef SK_DEBUG
+ // below assumes all chars in fSwizzle are initialized even if string is < 4 chars long.
+ SkASSERT(memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1) ==
+ strcmp(fSwizzle, other.fSwizzle));
+#endif
+ return fParams == other.fParams &&
+ (this->getTexture() == other.getTexture()) &&
+ (0 == memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1));
+ }
+
+ bool operator!= (const GrTextureAccess& other) const { return !(*this == other); }
+
+ GrTexture* getTexture() const { return fTexture.get(); }
+
+ /**
+ * For internal use by GrProcessor.
+ */
+ const GrGpuResourceRef* getProgramTexture() const { return &fTexture; }
+
+ /**
+ * Returns a string representing the swizzle. The string is is null-terminated.
+ */
+ const char* getSwizzle() const { return fSwizzle; }
+
+ /** Returns a mask indicating which components are referenced in the swizzle. The return
+ is a bitfield of GrColorComponentFlags. */
+ uint32_t swizzleMask() const { return fSwizzleMask; }
+
+ const GrTextureParams& getParams() const { return fParams; }
+
+private:
+ void setSwizzle(const char*);
+
+ typedef GrTGpuResourceRef<GrTexture> ProgramTexture;
+
+ ProgramTexture fTexture;
+ GrTextureParams fParams;
+ uint32_t fSwizzleMask;
+ char fSwizzle[5];
+
+ typedef SkNoncopyable INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrTypes.h b/src/third_party/skia/include/gpu/GrTypes.h
new file mode 100644
index 0000000..bf69afe
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrTypes.h
@@ -0,0 +1,727 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrTypes_DEFINED
+#define GrTypes_DEFINED
+
+#include "SkTypes.h"
+#include "GrConfig.h"
+#include "SkMath.h"
+
+//#define SK_SUPPORT_LEGACY_GRTYPES
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Defines overloaded bitwise operators to make it easier to use an enum as a
+ * bitfield.
+ */
+#define GR_MAKE_BITFIELD_OPS(X) \
+ inline X operator | (X a, X b) { \
+ return (X) (+a | +b); \
+ } \
+ \
+ inline X operator & (X a, X b) { \
+ return (X) (+a & +b); \
+ } \
+ template <typename T> \
+ inline X operator & (T a, X b) { \
+ return (X) (+a & +b); \
+ } \
+ template <typename T> \
+ inline X operator & (X a, T b) { \
+ return (X) (+a & +b); \
+ } \
+
+#define GR_DECL_BITFIELD_OPS_FRIENDS(X) \
+ friend X operator | (X a, X b); \
+ \
+ friend X operator & (X a, X b); \
+ \
+ template <typename T> \
+ friend X operator & (T a, X b); \
+ \
+ template <typename T> \
+ friend X operator & (X a, T b); \
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_SUPPORT_LEGACY_GRTYPES
+
+/**
+ * Macro to round n up to the next multiple of 4, or return it unchanged if
+ * n is already a multiple of 4
+ */
+#define GrALIGN4(n) SkAlign4(n)
+#define GrIsALIGN4(n) SkIsAlign4(n)
+
+template <typename T> const T& GrMin(const T& a, const T& b) {
+ return (a < b) ? a : b;
+}
+
+template <typename T> const T& GrMax(const T& a, const T& b) {
+ return (b < a) ? a : b;
+}
+
+/**
+ * Count elements in an array
+ */
+#define GR_ARRAY_COUNT(array) SK_ARRAY_COUNT(array)
+
+/**
+ * 16.16 fixed point type
+ */
+typedef int32_t GrFixed;
+
+#ifdef SK_DEBUG
+
+static inline int16_t GrToS16(intptr_t x) {
+ SkASSERT((int16_t)x == x);
+ return (int16_t)x;
+}
+
+#else
+
+#define GrToS16(x) x
+
+#endif
+
+#endif
+
+// compile time versions of min/max
+#define GR_CT_MAX(a, b) (((b) < (a)) ? (a) : (b))
+#define GR_CT_MIN(a, b) (((b) < (a)) ? (b) : (a))
+
+/**
+ * divide, rounding up
+ */
+static inline int32_t GrIDivRoundUp(int x, int y) {
+ SkASSERT(y > 0);
+ return (x + (y-1)) / y;
+}
+static inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
+ return (x + (y-1)) / y;
+}
+static inline size_t GrSizeDivRoundUp(size_t x, size_t y) {
+ return (x + (y-1)) / y;
+}
+
+// compile time, evaluates Y multiple times
+#define GR_CT_DIV_ROUND_UP(X, Y) (((X) + ((Y)-1)) / (Y))
+
+/**
+ * align up
+ */
+static inline uint32_t GrUIAlignUp(uint32_t x, uint32_t alignment) {
+ return GrUIDivRoundUp(x, alignment) * alignment;
+}
+static inline size_t GrSizeAlignUp(size_t x, size_t alignment) {
+ return GrSizeDivRoundUp(x, alignment) * alignment;
+}
+
+// compile time, evaluates A multiple times
+#define GR_CT_ALIGN_UP(X, A) (GR_CT_DIV_ROUND_UP((X),(A)) * (A))
+
+/**
+ * amount of pad needed to align up
+ */
+static inline uint32_t GrUIAlignUpPad(uint32_t x, uint32_t alignment) {
+ return (alignment - x % alignment) % alignment;
+}
+static inline size_t GrSizeAlignUpPad(size_t x, size_t alignment) {
+ return (alignment - x % alignment) % alignment;
+}
+
+/**
+ * align down
+ */
+static inline uint32_t GrUIAlignDown(uint32_t x, uint32_t alignment) {
+ return (x / alignment) * alignment;
+}
+static inline size_t GrSizeAlignDown(size_t x, uint32_t alignment) {
+ return (x / alignment) * alignment;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Return the next power of 2 >= n.
+ */
+static inline uint32_t GrNextPow2(uint32_t n) {
+ return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
+}
+
+static inline int GrNextPow2(int n) {
+ SkASSERT(n >= 0); // this impl only works for non-neg.
+ return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Possible 3D APIs that may be used by Ganesh.
+ */
+enum GrBackend {
+ kOpenGL_GrBackend,
+#if defined(COBALT)
+ kCobalt_GrBackend,
+#endif
+};
+
+/**
+ * Backend-specific 3D context handle
+ * GrGLInterface* for OpenGL. If NULL will use the default GL interface.
+ */
+typedef intptr_t GrBackendContext;
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+* Geometric primitives used for drawing.
+*/
+enum GrPrimitiveType {
+ kTriangles_GrPrimitiveType,
+ kTriangleStrip_GrPrimitiveType,
+ kTriangleFan_GrPrimitiveType,
+ kPoints_GrPrimitiveType,
+ kLines_GrPrimitiveType, // 1 pix wide only
+ kLineStrip_GrPrimitiveType // 1 pix wide only
+};
+
+static inline bool GrIsPrimTypeLines(GrPrimitiveType type) {
+ return kLines_GrPrimitiveType == type || kLineStrip_GrPrimitiveType == type;
+}
+
+static inline bool GrIsPrimTypeTris(GrPrimitiveType type) {
+ return kTriangles_GrPrimitiveType == type ||
+ kTriangleStrip_GrPrimitiveType == type ||
+ kTriangleFan_GrPrimitiveType == type;
+}
+
+/**
+ * Coeffecients for alpha-blending.
+ */
+enum GrBlendCoeff {
+ kInvalid_GrBlendCoeff = -1,
+
+ kZero_GrBlendCoeff, //<! 0
+ kOne_GrBlendCoeff, //<! 1
+ kSC_GrBlendCoeff, //<! src color
+ kISC_GrBlendCoeff, //<! one minus src color
+ kDC_GrBlendCoeff, //<! dst color
+ kIDC_GrBlendCoeff, //<! one minus dst color
+ kSA_GrBlendCoeff, //<! src alpha
+ kISA_GrBlendCoeff, //<! one minus src alpha
+ kDA_GrBlendCoeff, //<! dst alpha
+ kIDA_GrBlendCoeff, //<! one minus dst alpha
+ kConstC_GrBlendCoeff, //<! constant color
+ kIConstC_GrBlendCoeff, //<! one minus constant color
+ kConstA_GrBlendCoeff, //<! constant color alpha
+ kIConstA_GrBlendCoeff, //<! one minus constant color alpha
+
+ kPublicGrBlendCoeffCount
+};
+
+/**
+ * Formats for masks, used by the font cache.
+ * Important that these are 0-based.
+ */
+enum GrMaskFormat {
+ kA8_GrMaskFormat, //!< 1-byte per pixel
+ kA565_GrMaskFormat, //!< 2-bytes per pixel
+ kA888_GrMaskFormat, //!< 4-bytes per pixel
+ kARGB_GrMaskFormat, //!< 4-bytes per pixel, color format
+
+ kLast_GrMaskFormat = kARGB_GrMaskFormat
+};
+static const int kMaskFormatCount = kLast_GrMaskFormat + 1;
+
+/**
+ * Return the number of bytes-per-pixel for the specified mask format.
+ */
+static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
+ SkASSERT((unsigned)format <= 3);
+ // kA8 (0) -> 1
+ // kA565 (1) -> 2
+ // kA888 (2) -> 4
+ // kARGB (3) -> 4
+ static const int sBytesPerPixel[] = { 1, 2, 4, 4 };
+ SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sBytesPerPixel) == kMaskFormatCount, array_size_mismatch);
+
+ return sBytesPerPixel[(int) format];
+}
+
+/**
+ * Pixel configurations.
+ */
+enum GrPixelConfig {
+ kUnknown_GrPixelConfig,
+ kAlpha_8_GrPixelConfig,
+ kIndex_8_GrPixelConfig,
+ kRGB_565_GrPixelConfig,
+ /**
+ * Premultiplied
+ */
+ kRGBA_4444_GrPixelConfig,
+ /**
+ * Premultiplied. Byte order is r,g,b,a.
+ */
+ kRGBA_8888_GrPixelConfig,
+ /**
+ * Premultiplied. Byte order is b,g,r,a.
+ */
+ kBGRA_8888_GrPixelConfig,
+ /**
+ * ETC1 Compressed Data
+ */
+ kETC1_GrPixelConfig,
+ /**
+ * LATC/RGTC/3Dc/BC4 Compressed Data
+ */
+ kLATC_GrPixelConfig,
+ /**
+ * R11 EAC Compressed Data
+ * (Corresponds to section C.3.5 of the OpenGL 4.4 core profile spec)
+ */
+ kR11_EAC_GrPixelConfig,
+
+ /**
+ * 12x12 ASTC Compressed Data
+ * ASTC stands for Adaptive Scalable Texture Compression. It is a technique
+ * that allows for a lot of customization in the compressed representataion
+ * of a block. The only thing fixed in the representation is the block size,
+ * which means that a texture that contains ASTC data must be treated as
+ * having RGBA values. However, there are single-channel encodings which set
+ * the alpha to opaque and all three RGB channels equal effectively making the
+ * compression format a single channel such as R11 EAC and LATC.
+ */
+ kASTC_12x12_GrPixelConfig,
+
+ /**
+ * Byte order is r, g, b, a. This color format is 32 bits per channel
+ */
+ kRGBA_float_GrPixelConfig,
+ kLast_GrPixelConfig = kRGBA_float_GrPixelConfig
+};
+static const int kGrPixelConfigCnt = kLast_GrPixelConfig + 1;
+
+// Aliases for pixel configs that match skia's byte order.
+#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
+ static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
+#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
+ static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig;
+#else
+ #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
+#endif
+
+// Returns true if the pixel config is a GPU-specific compressed format
+// representation.
+static inline bool GrPixelConfigIsCompressed(GrPixelConfig config) {
+ switch (config) {
+ case kIndex_8_GrPixelConfig:
+ case kETC1_GrPixelConfig:
+ case kLATC_GrPixelConfig:
+ case kR11_EAC_GrPixelConfig:
+ case kASTC_12x12_GrPixelConfig:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Returns true if the pixel config is 32 bits per pixel
+static inline bool GrPixelConfigIs8888(GrPixelConfig config) {
+ switch (config) {
+ case kRGBA_8888_GrPixelConfig:
+ case kBGRA_8888_GrPixelConfig:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Takes a config and returns the equivalent config with the R and B order
+// swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
+static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
+ switch (config) {
+ case kBGRA_8888_GrPixelConfig:
+ return kRGBA_8888_GrPixelConfig;
+ case kRGBA_8888_GrPixelConfig:
+ return kBGRA_8888_GrPixelConfig;
+ default:
+ return kUnknown_GrPixelConfig;
+ }
+}
+
+static inline size_t GrBytesPerPixel(GrPixelConfig config) {
+ SkASSERT(!GrPixelConfigIsCompressed(config));
+ switch (config) {
+ case kAlpha_8_GrPixelConfig:
+ return 1;
+ case kRGB_565_GrPixelConfig:
+ case kRGBA_4444_GrPixelConfig:
+ return 2;
+ case kRGBA_8888_GrPixelConfig:
+ case kBGRA_8888_GrPixelConfig:
+ return 4;
+ case kRGBA_float_GrPixelConfig:
+ return 16;
+ default:
+ return 0;
+ }
+}
+
+static inline size_t GrUnpackAlignment(GrPixelConfig config) {
+ SkASSERT(!GrPixelConfigIsCompressed(config));
+ switch (config) {
+ case kAlpha_8_GrPixelConfig:
+ return 1;
+ case kRGB_565_GrPixelConfig:
+ case kRGBA_4444_GrPixelConfig:
+ return 2;
+ case kRGBA_8888_GrPixelConfig:
+ case kBGRA_8888_GrPixelConfig:
+ case kRGBA_float_GrPixelConfig:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
+ switch (config) {
+ case kETC1_GrPixelConfig:
+ case kRGB_565_GrPixelConfig:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
+ switch (config) {
+ case kR11_EAC_GrPixelConfig:
+ case kLATC_GrPixelConfig:
+ case kASTC_12x12_GrPixelConfig:
+ case kAlpha_8_GrPixelConfig:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Optional bitfield flags that can be passed to createTexture.
+ */
+enum GrTextureFlags {
+ kNone_GrTextureFlags = 0x0,
+ /**
+ * Creates a texture that can be rendered to as a GrRenderTarget. Use
+ * GrTexture::asRenderTarget() to access.
+ */
+ kRenderTarget_GrTextureFlagBit = 0x1,
+ /**
+ * By default all render targets have an associated stencil buffer that
+ * may be required for path filling. This flag overrides stencil buffer
+ * creation.
+ * MAKE THIS PRIVATE?
+ */
+ kNoStencil_GrTextureFlagBit = 0x2,
+ /**
+ * Hint that the CPU may modify this texture after creation.
+ */
+ kDynamicUpdate_GrTextureFlagBit = 0x4,
+ /**
+ * Indicates that all allocations (color buffer, FBO completeness, etc)
+ * should be verified.
+ */
+ kCheckAllocation_GrTextureFlagBit = 0x8,
+
+ kDummy_GrTextureFlagBit,
+ kLastPublic_GrTextureFlagBit = kDummy_GrTextureFlagBit-1,
+};
+
+GR_MAKE_BITFIELD_OPS(GrTextureFlags)
+
+/**
+ * Some textures will be stored such that the upper and left edges of the content meet at the
+ * the origin (in texture coord space) and for other textures the lower and left edges meet at
+ * the origin. kDefault_GrSurfaceOrigin sets textures to TopLeft, and render targets
+ * to BottomLeft.
+ */
+
+enum GrSurfaceOrigin {
+ kDefault_GrSurfaceOrigin, // DEPRECATED; to be removed
+ kTopLeft_GrSurfaceOrigin,
+ kBottomLeft_GrSurfaceOrigin,
+};
+
+/**
+ * Describes a texture to be created.
+ */
+struct GrTextureDesc {
+ GrTextureDesc()
+ : fFlags(kNone_GrTextureFlags)
+ , fOrigin(kDefault_GrSurfaceOrigin)
+ , fWidth(0)
+ , fHeight(0)
+ , fConfig(kUnknown_GrPixelConfig)
+ , fSampleCnt(0) {
+ }
+
+ GrTextureFlags fFlags; //!< bitfield of TextureFlags
+ GrSurfaceOrigin fOrigin; //!< origin of the texture
+ int fWidth; //!< Width of the texture
+ int fHeight; //!< Height of the texture
+
+ /**
+ * Format of source data of the texture. Not guaranteed to be the same as
+ * internal format used by 3D API.
+ */
+ GrPixelConfig fConfig;
+
+ /**
+ * The number of samples per pixel or 0 to disable full scene AA. This only
+ * applies if the kRenderTarget_GrTextureFlagBit is set. The actual number
+ * of samples may not exactly match the request. The request will be rounded
+ * up to the next supported sample count, or down if it is larger than the
+ * max supported count.
+ */
+ int fSampleCnt;
+};
+
+/**
+ * GrCacheID is used create and find cached GrResources (e.g. GrTextures). The ID has two parts:
+ * the domain and the key. Domains simply allow multiple clients to use 0-based indices as their
+ * cache key without colliding. The key uniquely identifies a GrResource within the domain.
+ * Users of the cache must obtain a domain via GenerateDomain().
+ */
+struct GrCacheID {
+public:
+ typedef uint8_t Domain;
+
+ struct Key {
+ union {
+ uint8_t fData8[16];
+ uint32_t fData32[4];
+ uint64_t fData64[2];
+ };
+ };
+
+ /**
+ * A default cache ID is invalid; a set method must be called before the object is used.
+ */
+ GrCacheID() { fDomain = kInvalid_Domain; }
+
+ /**
+ * Initialize the cache ID to a domain and key.
+ */
+ GrCacheID(Domain domain, const Key& key) {
+ SkASSERT(kInvalid_Domain != domain);
+ this->reset(domain, key);
+ }
+
+ void reset(Domain domain, const Key& key) {
+ fDomain = domain;
+ memcpy(&fKey, &key, sizeof(Key));
+ }
+
+ /** Has this been initialized to a valid domain */
+ bool isValid() const { return kInvalid_Domain != fDomain; }
+
+ const Key& getKey() const { SkASSERT(this->isValid()); return fKey; }
+ Domain getDomain() const { SkASSERT(this->isValid()); return fDomain; }
+
+ /** Creates a new unique ID domain. */
+ static Domain GenerateDomain();
+
+private:
+ Key fKey;
+ Domain fDomain;
+
+ static const Domain kInvalid_Domain = 0;
+};
+
+/**
+ * Clips are composed from these objects.
+ */
+enum GrClipType {
+ kRect_ClipType,
+ kPath_ClipType
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+// opaque type for 3D API object handles
+typedef intptr_t GrBackendObject;
+
+/**
+ * Gr can wrap an existing texture created by the client with a GrTexture
+ * object. The client is responsible for ensuring that the texture lives at
+ * least as long as the GrTexture object wrapping it. We require the client to
+ * explicitly provide information about the texture, such as width, height,
+ * and pixel config, rather than querying the 3D APIfor these values. We expect
+ * these to be immutable even if the 3D API doesn't require this (OpenGL).
+ *
+ * Textures that are also render targets are supported as well. Gr will manage
+ * any ancillary 3D API (stencil buffer, FBO id, etc) objects necessary for
+ * Gr to draw into the render target. To access the render target object
+ * call GrTexture::asRenderTarget().
+ *
+ * If in addition to the render target flag, the caller also specifies a sample
+ * count Gr will create an MSAA buffer that resolves into the texture. Gr auto-
+ * resolves when it reads from the texture. The client can explictly resolve
+ * using the GrRenderTarget interface.
+ *
+ * Note: These flags currently form a subset of GrTexture's flags.
+ */
+
+enum GrBackendTextureFlags {
+ /**
+ * No flags enabled
+ */
+ kNone_GrBackendTextureFlag = kNone_GrTextureFlags,
+ /**
+ * Indicates that the texture is also a render target, and thus should have
+ * a GrRenderTarget object.
+ *
+ * D3D (future): client must have created the texture with flags that allow
+ * it to be used as a render target.
+ */
+ kRenderTarget_GrBackendTextureFlag = kRenderTarget_GrTextureFlagBit,
+};
+GR_MAKE_BITFIELD_OPS(GrBackendTextureFlags)
+
+struct GrBackendTextureDesc {
+ GrBackendTextureDesc() { memset(this, 0, sizeof(*this)); }
+ GrBackendTextureFlags fFlags;
+ GrSurfaceOrigin fOrigin;
+ int fWidth; //<! width in pixels
+ int fHeight; //<! height in pixels
+ GrPixelConfig fConfig; //<! color format
+ /**
+ * If the render target flag is set and sample count is greater than 0
+ * then Gr will create an MSAA buffer that resolves to the texture.
+ */
+ int fSampleCnt;
+ /**
+ * Handle to the 3D API object.
+ * OpenGL: Texture ID.
+ */
+ GrBackendObject fTextureHandle;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Gr can wrap an existing render target created by the client in the 3D API
+ * with a GrRenderTarget object. The client is responsible for ensuring that the
+ * underlying 3D API object lives at least as long as the GrRenderTarget object
+ * wrapping it. We require the client to explicitly provide information about
+ * the target, such as width, height, and pixel config rather than querying the
+ * 3D API for these values. We expect these properties to be immutable even if
+ * the 3D API doesn't require this (OpenGL).
+ */
+
+struct GrBackendRenderTargetDesc {
+ GrBackendRenderTargetDesc() { memset(this, 0, sizeof(*this)); }
+ int fWidth; //<! width in pixels
+ int fHeight; //<! height in pixels
+ GrPixelConfig fConfig; //<! color format
+ GrSurfaceOrigin fOrigin; //<! pixel origin
+ /**
+ * The number of samples per pixel. Gr uses this to influence decisions
+ * about applying other forms of anti-aliasing.
+ */
+ int fSampleCnt;
+ /**
+ * Number of bits of stencil per-pixel.
+ */
+ int fStencilBits;
+ /**
+ * Handle to the 3D API object.
+ * OpenGL: FBO ID
+ */
+ GrBackendObject fRenderTargetHandle;
+};
+
+/**
+ * The GrContext's cache of backend context state can be partially invalidated.
+ * These enums are specific to the GL backend and we'd add a new set for an alternative backend.
+ */
+enum GrGLBackendState {
+ kRenderTarget_GrGLBackendState = 1 << 0,
+ kTextureBinding_GrGLBackendState = 1 << 1,
+ // View state stands for scissor and viewport
+ kView_GrGLBackendState = 1 << 2,
+ kBlend_GrGLBackendState = 1 << 3,
+ kMSAAEnable_GrGLBackendState = 1 << 4,
+ kVertex_GrGLBackendState = 1 << 5,
+ kStencil_GrGLBackendState = 1 << 6,
+ kPixelStore_GrGLBackendState = 1 << 7,
+ kProgram_GrGLBackendState = 1 << 8,
+ kFixedFunction_GrGLBackendState = 1 << 9,
+ kMisc_GrGLBackendState = 1 << 10,
+ kPathRendering_GrGLBackendState = 1 << 11,
+ kALL_GrGLBackendState = 0xffff
+};
+
+/**
+ * Returns the data size for the given compressed pixel config
+ */
+static inline size_t GrCompressedFormatDataSize(GrPixelConfig config,
+ int width, int height) {
+ SkASSERT(GrPixelConfigIsCompressed(config));
+ static const int kGrIndex8TableSize = 256 * 4; // 4 == sizeof(GrColor)
+
+ switch (config) {
+ case kIndex_8_GrPixelConfig:
+ return width * height + kGrIndex8TableSize;
+ case kR11_EAC_GrPixelConfig:
+ case kLATC_GrPixelConfig:
+ case kETC1_GrPixelConfig:
+ SkASSERT((width & 3) == 0);
+ SkASSERT((height & 3) == 0);
+ return (width >> 2) * (height >> 2) * 8;
+
+ case kASTC_12x12_GrPixelConfig:
+ SkASSERT((width % 12) == 0);
+ SkASSERT((height % 12) == 0);
+ return (width / 12) * (height / 12) * 16;
+
+ default:
+ SkFAIL("Unknown compressed pixel config");
+ return 4 * width * height;
+ }
+}
+
+/**
+ * This value translates to reseting all the context state for any backend.
+ */
+static const uint32_t kAll_GrBackendState = 0xffffffff;
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_ALWAYS_ALLOCATE_ON_HEAP
+ #define GrAutoMallocBaseType SkAutoMalloc
+#else
+ #define GrAutoMallocBaseType SkAutoSMalloc<S>
+#endif
+
+template <size_t S> class GrAutoMalloc : public GrAutoMallocBaseType {
+public:
+ GrAutoMalloc() : INHERITED() {}
+ explicit GrAutoMalloc(size_t size) : INHERITED(size) {}
+ virtual ~GrAutoMalloc() {}
+private:
+ typedef GrAutoMallocBaseType INHERITED;
+};
+
+#undef GrAutoMallocBaseType
+#endif
diff --git a/src/third_party/skia/include/gpu/GrTypesPriv.h b/src/third_party/skia/include/gpu/GrTypesPriv.h
new file mode 100644
index 0000000..94ec1d7
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrTypesPriv.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTypesPriv_DEFINED
+#define GrTypesPriv_DEFINED
+
+#include "GrTypes.h"
+#include "SkTArray.h"
+
+/**
+ * Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
+ * but should be applicable to other shader languages.)
+ */
+enum GrSLType {
+ kVoid_GrSLType,
+ kFloat_GrSLType,
+ kVec2f_GrSLType,
+ kVec3f_GrSLType,
+ kVec4f_GrSLType,
+ kMat33f_GrSLType,
+ kMat44f_GrSLType,
+ kSampler2D_GrSLType,
+
+ kLast_GrSLType = kSampler2D_GrSLType
+};
+static const int kGrSLTypeCount = kLast_GrSLType + 1;
+
+/**
+ * Gets the vector size of the SLType. Returns -1 for void, matrices, and samplers.
+ */
+static inline int GrSLTypeVectorCount(GrSLType type) {
+ SkASSERT(type >= 0 && type < static_cast<GrSLType>(kGrSLTypeCount));
+ static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1 };
+ return kCounts[type];
+
+ GR_STATIC_ASSERT(0 == kVoid_GrSLType);
+ GR_STATIC_ASSERT(1 == kFloat_GrSLType);
+ GR_STATIC_ASSERT(2 == kVec2f_GrSLType);
+ GR_STATIC_ASSERT(3 == kVec3f_GrSLType);
+ GR_STATIC_ASSERT(4 == kVec4f_GrSLType);
+ GR_STATIC_ASSERT(5 == kMat33f_GrSLType);
+ GR_STATIC_ASSERT(6 == kMat44f_GrSLType);
+ GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
+ GR_STATIC_ASSERT(SK_ARRAY_COUNT(kCounts) == kGrSLTypeCount);
+}
+
+/** Return the type enum for a vector of floats of length n (1..4),
+ e.g. 1 -> kFloat_GrSLType, 2 -> kVec2_GrSLType, ... */
+static inline GrSLType GrSLFloatVectorType(int count) {
+ SkASSERT(count > 0 && count <= 4);
+ return (GrSLType)(count);
+
+ GR_STATIC_ASSERT(kFloat_GrSLType == 1);
+ GR_STATIC_ASSERT(kVec2f_GrSLType == 2);
+ GR_STATIC_ASSERT(kVec3f_GrSLType == 3);
+ GR_STATIC_ASSERT(kVec4f_GrSLType == 4);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Types used to describe format of vertices in arrays.
+ */
+enum GrVertexAttribType {
+ kFloat_GrVertexAttribType = 0,
+ kVec2f_GrVertexAttribType,
+ kVec3f_GrVertexAttribType,
+ kVec4f_GrVertexAttribType,
+ kVec4ub_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors
+
+ kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
+};
+static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
+
+/**
+ * Returns the vector size of the type.
+ */
+static inline int GrVertexAttribTypeVectorCount(GrVertexAttribType type) {
+ SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount);
+ static const int kCounts[] = { 1, 2, 3, 4, 4 };
+ return kCounts[type];
+
+ GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
+ GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
+ GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
+ GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
+ GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
+ GR_STATIC_ASSERT(SK_ARRAY_COUNT(kCounts) == kGrVertexAttribTypeCount);
+}
+
+/**
+ * Returns the size of the attrib type in bytes.
+ */
+static inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
+ SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount);
+ static const size_t kSizes[] = {
+ sizeof(float), // kFloat_GrVertexAttribType
+ 2*sizeof(float), // kVec2f_GrVertexAttribType
+ 3*sizeof(float), // kVec3f_GrVertexAttribType
+ 4*sizeof(float), // kVec4f_GrVertexAttribType
+ 4*sizeof(char) // kVec4ub_GrVertexAttribType
+ };
+ return kSizes[type];
+
+ GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
+ GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
+ GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
+ GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
+ GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
+ GR_STATIC_ASSERT(SK_ARRAY_COUNT(kSizes) == kGrVertexAttribTypeCount);
+}
+
+/**
+ * Semantic bindings for vertex attributes. kEffect means that the attribute is input to a
+ * GrProcessor. Each binding other than kEffect may not appear more than once in the current set of
+ * attributes. kPosition must be appear for exactly one attribute.
+ */
+enum GrVertexAttribBinding {
+ kPosition_GrVertexAttribBinding, // required, must have vector count of 2
+ kLocalCoord_GrVertexAttribBinding, // must have vector count of 2
+ kColor_GrVertexAttribBinding, // must have vector count of 4
+ kCoverage_GrVertexAttribBinding, // must have vector count of 4
+
+ kLastFixedFunction_GrVertexAttribBinding = kCoverage_GrVertexAttribBinding,
+
+ kGeometryProcessor_GrVertexAttribBinding, // vector length must agree with
+ // GrProcessor::vertexAttribType() for each effect input to
+ // which the attribute is mapped by GrDrawState::setEffect()
+ kLast_GrVertexAttribBinding = kGeometryProcessor_GrVertexAttribBinding
+};
+
+static const int kGrVertexAttribBindingCnt = kLast_GrVertexAttribBinding + 1;
+static const int kGrFixedFunctionVertexAttribBindingCnt =
+ kLastFixedFunction_GrVertexAttribBinding + 1;
+
+static inline int GrFixedFunctionVertexAttribVectorCount(GrVertexAttribBinding binding) {
+ SkASSERT(binding >= 0 && binding < kGrFixedFunctionVertexAttribBindingCnt);
+ static const int kVecCounts[] = { 2, 2, 4, 4 };
+
+ return kVecCounts[binding];
+
+ GR_STATIC_ASSERT(0 == kPosition_GrVertexAttribBinding);
+ GR_STATIC_ASSERT(1 == kLocalCoord_GrVertexAttribBinding);
+ GR_STATIC_ASSERT(2 == kColor_GrVertexAttribBinding);
+ GR_STATIC_ASSERT(3 == kCoverage_GrVertexAttribBinding);
+ GR_STATIC_ASSERT(kGrFixedFunctionVertexAttribBindingCnt == SK_ARRAY_COUNT(kVecCounts));
+}
+
+struct GrVertexAttrib {
+ inline void set(GrVertexAttribType type, size_t offset, GrVertexAttribBinding binding) {
+ fType = type;
+ fOffset = offset;
+ fBinding = binding;
+ }
+ bool operator==(const GrVertexAttrib& other) const {
+ return fType == other.fType && fOffset == other.fOffset && fBinding == other.fBinding;
+ };
+ bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
+
+ GrVertexAttribType fType;
+ size_t fOffset;
+ GrVertexAttribBinding fBinding;
+};
+
+template <int N> class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+* We have coverage effects that clip rendering to the edge of some geometric primitive.
+* This enum specifies how that clipping is performed. Not all factories that take a
+* GrProcessorEdgeType will succeed with all values and it is up to the caller to check for
+* a NULL return.
+*/
+enum GrPrimitiveEdgeType {
+ kFillBW_GrProcessorEdgeType,
+ kFillAA_GrProcessorEdgeType,
+ kInverseFillBW_GrProcessorEdgeType,
+ kInverseFillAA_GrProcessorEdgeType,
+ kHairlineAA_GrProcessorEdgeType,
+
+ kLast_GrProcessorEdgeType = kHairlineAA_GrProcessorEdgeType
+};
+
+static const int kGrProcessorEdgeTypeCnt = kLast_GrProcessorEdgeType + 1;
+
+static inline bool GrProcessorEdgeTypeIsFill(const GrPrimitiveEdgeType edgeType) {
+ return (kFillAA_GrProcessorEdgeType == edgeType || kFillBW_GrProcessorEdgeType == edgeType);
+}
+
+static inline bool GrProcessorEdgeTypeIsInverseFill(const GrPrimitiveEdgeType edgeType) {
+ return (kInverseFillAA_GrProcessorEdgeType == edgeType ||
+ kInverseFillBW_GrProcessorEdgeType == edgeType);
+}
+
+static inline bool GrProcessorEdgeTypeIsAA(const GrPrimitiveEdgeType edgeType) {
+ return (kFillBW_GrProcessorEdgeType != edgeType && kInverseFillBW_GrProcessorEdgeType != edgeType);
+}
+
+static inline GrPrimitiveEdgeType GrInvertProcessorEdgeType(const GrPrimitiveEdgeType edgeType) {
+ switch (edgeType) {
+ case kFillBW_GrProcessorEdgeType:
+ return kInverseFillBW_GrProcessorEdgeType;
+ case kFillAA_GrProcessorEdgeType:
+ return kInverseFillAA_GrProcessorEdgeType;
+ case kInverseFillBW_GrProcessorEdgeType:
+ return kFillBW_GrProcessorEdgeType;
+ case kInverseFillAA_GrProcessorEdgeType:
+ return kFillAA_GrProcessorEdgeType;
+ case kHairlineAA_GrProcessorEdgeType:
+ SkFAIL("Hairline fill isn't invertible.");
+ }
+ return kFillAA_GrProcessorEdgeType; // suppress warning.
+}
+
+#endif
diff --git a/src/third_party/skia/include/gpu/GrUserConfig.h b/src/third_party/skia/include/gpu/GrUserConfig.h
new file mode 100644
index 0000000..092ff9d
--- /dev/null
+++ b/src/third_party/skia/include/gpu/GrUserConfig.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrUserConfig_DEFINED
+#define GrUserConfig_DEFINED
+
+#if defined(GR_USER_CONFIG_FILE)
+ #error "default user config pulled in but GR_USER_CONFIG_FILE is defined."
+#endif
+
+/**
+ * This gives a threshold in bytes of when to map a GrGeometryBuffer vs using
+ * updateData. (Note the depending on the underlying 3D API the update functions
+ * may always be implemented using a map)
+ */
+//#define GR_GEOM_BUFFER_MAP_THRESHOLD (1<<15)
+
+/**
+ * This gives a threshold in megabytes for the maximum size of the texture cache
+ * in vram. The value is only a default and can be overridden at runtime.
+ */
+//#define GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT 96
+
+/**
+ * This specifies the maximum number of textures the texture cache can hold
+ * in vram. The value is only a default and can be overridden at runtime.
+ */
+//#define GR_DEFAULT_RESOURCE_CACHE_COUNT_LIMIT 2048
+
+#endif
diff --git a/src/third_party/skia/include/gpu/SkGr.h b/src/third_party/skia/include/gpu/SkGr.h
new file mode 100644
index 0000000..df2ae5a
--- /dev/null
+++ b/src/third_party/skia/include/gpu/SkGr.h
@@ -0,0 +1,101 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef SkGr_DEFINED
+#define SkGr_DEFINED
+
+#include <stddef.h>
+
+// Gr headers
+#include "GrTypes.h"
+#include "GrContext.h"
+
+// skia headers
+#include "SkBitmap.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRegion.h"
+#include "SkClipStack.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// Sk to Gr Type conversions
+
+GR_STATIC_ASSERT((int)kZero_GrBlendCoeff == (int)SkXfermode::kZero_Coeff);
+GR_STATIC_ASSERT((int)kOne_GrBlendCoeff == (int)SkXfermode::kOne_Coeff);
+GR_STATIC_ASSERT((int)kSC_GrBlendCoeff == (int)SkXfermode::kSC_Coeff);
+GR_STATIC_ASSERT((int)kISC_GrBlendCoeff == (int)SkXfermode::kISC_Coeff);
+GR_STATIC_ASSERT((int)kDC_GrBlendCoeff == (int)SkXfermode::kDC_Coeff);
+GR_STATIC_ASSERT((int)kIDC_GrBlendCoeff == (int)SkXfermode::kIDC_Coeff);
+GR_STATIC_ASSERT((int)kSA_GrBlendCoeff == (int)SkXfermode::kSA_Coeff);
+GR_STATIC_ASSERT((int)kISA_GrBlendCoeff == (int)SkXfermode::kISA_Coeff);
+GR_STATIC_ASSERT((int)kDA_GrBlendCoeff == (int)SkXfermode::kDA_Coeff);
+GR_STATIC_ASSERT((int)kIDA_GrBlendCoeff == (int)SkXfermode::kIDA_Coeff);
+
+#define sk_blend_to_grblend(X) ((GrBlendCoeff)(X))
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkColorPriv.h"
+
+GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType, SkAlphaType);
+
+static inline GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info) {
+ return SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType());
+}
+
+bool GrPixelConfig2ColorType(GrPixelConfig, SkColorType*);
+
+static inline GrColor SkColor2GrColor(SkColor c) {
+ SkPMColor pm = SkPreMultiplyColor(c);
+ unsigned r = SkGetPackedR32(pm);
+ unsigned g = SkGetPackedG32(pm);
+ unsigned b = SkGetPackedB32(pm);
+ unsigned a = SkGetPackedA32(pm);
+ return GrColorPackRGBA(r, g, b, a);
+}
+
+static inline GrColor SkColor2GrColorJustAlpha(SkColor c) {
+ U8CPU a = SkColorGetA(c);
+ return GrColorPackRGBA(a, a, a, a);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool GrIsBitmapInCache(const GrContext*, const SkBitmap&, const GrTextureParams*);
+
+GrTexture* GrLockAndRefCachedBitmapTexture(GrContext*, const SkBitmap&, const GrTextureParams*);
+
+void GrUnlockAndUnrefCachedBitmapTexture(GrTexture*);
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Converts a SkPaint to a GrPaint, ignoring the SkPaint's shader.
+// Sets the color of GrPaint to the value of the parameter paintColor
+// Callers may subsequently modify the GrPaint. Setting constantColor indicates
+// that the final paint will draw the same color at every pixel. This allows
+// an optimization where the the color filter can be applied to the SkPaint's
+// color once while converting to GrPaint and then ignored.
+void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor,
+ bool constantColor, GrPaint* grPaint);
+
+// This function is similar to skPaint2GrPaintNoShader but also converts
+// skPaint's shader to a GrTexture/GrProcessorStage if possible.
+// constantColor has the same meaning as in skPaint2GrPaintNoShader.
+void SkPaint2GrPaintShader(GrContext* context, const SkPaint& skPaint,
+ bool constantColor, GrPaint* grPaint);
+
+////////////////////////////////////////////////////////////////////////////////
+// Classes
+
+class SkGlyphCache;
+
+////////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/src/third_party/skia/include/gpu/SkGrPixelRef.h b/src/third_party/skia/include/gpu/SkGrPixelRef.h
new file mode 100644
index 0000000..7e6a9d0
--- /dev/null
+++ b/src/third_party/skia/include/gpu/SkGrPixelRef.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkGrPixelRef_DEFINED
+#define SkGrPixelRef_DEFINED
+
+#include "SkBitmap.h"
+#include "SkPixelRef.h"
+#include "GrTexture.h"
+#include "GrRenderTarget.h"
+
+
+/**
+ * Common baseclass that implements onLockPixels() by calling onReadPixels().
+ * Since it has a copy, it always returns false for onLockPixelsAreWritable().
+ */
+class SK_API SkROLockPixelsPixelRef : public SkPixelRef {
+public:
+ SK_DECLARE_INST_COUNT(SkROLockPixelsPixelRef)
+ SkROLockPixelsPixelRef(const SkImageInfo&);
+ virtual ~SkROLockPixelsPixelRef();
+
+protected:
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+ virtual void onUnlockPixels() SK_OVERRIDE;
+ virtual bool onLockPixelsAreWritable() const SK_OVERRIDE; // return false;
+
+private:
+ SkBitmap fBitmap;
+ typedef SkPixelRef INHERITED;
+};
+
+/**
+ * PixelRef that wraps a GrSurface
+ */
+class SK_API SkGrPixelRef : public SkROLockPixelsPixelRef {
+public:
+ SK_DECLARE_INST_COUNT(SkGrPixelRef)
+ /**
+ * Constructs a pixel ref around a GrSurface. If the caller has locked the GrSurface in the
+ * cache and would like the pixel ref to unlock it in its destructor then transferCacheLock
+ * should be set to true.
+ */
+ SkGrPixelRef(const SkImageInfo&, GrSurface*, bool transferCacheLock = false);
+ virtual ~SkGrPixelRef();
+
+ // override from SkPixelRef
+ virtual GrTexture* getTexture() SK_OVERRIDE;
+
+protected:
+ // overrides from SkPixelRef
+ virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset) SK_OVERRIDE;
+ virtual SkPixelRef* deepCopy(SkColorType, const SkIRect* subset) SK_OVERRIDE;
+
+private:
+ GrSurface* fSurface;
+ bool fUnlock; // if true the pixel ref owns a texture cache lock on fSurface
+
+ typedef SkROLockPixelsPixelRef INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/SkGrTexturePixelRef.h b/src/third_party/skia/include/gpu/SkGrTexturePixelRef.h
new file mode 100644
index 0000000..7129512
--- /dev/null
+++ b/src/third_party/skia/include/gpu/SkGrTexturePixelRef.h
@@ -0,0 +1,19 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef SkGrTexturePixelRef_DEFINED
+#define SkGrTexturePixelRef_DEFINED
+
+#include "SkGrPixelRef.h"
+
+typedef SkGrPixelRef SkGrTexturePixelRef;
+typedef SkGrPixelRef SkGrRenderTargetPixelRef;
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/GrGLConfig.h b/src/third_party/skia/include/gpu/gl/GrGLConfig.h
new file mode 100644
index 0000000..444be00
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/GrGLConfig.h
@@ -0,0 +1,194 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrGLConfig_DEFINED
+#define GrGLConfig_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ * Optional GL config file.
+ */
+#ifdef GR_GL_CUSTOM_SETUP_HEADER
+ #include GR_GL_CUSTOM_SETUP_HEADER
+#endif
+
+#if !defined(GR_GL_FUNCTION_TYPE)
+ #define GR_GL_FUNCTION_TYPE
+#endif
+
+/**
+ * The following are optional defines that can be enabled at the compiler
+ * command line, in a IDE project, in a GrUserConfig.h file, or in a GL custom
+ * file (if one is in use). If a GR_GL_CUSTOM_SETUP_HEADER is used they can
+ * also be placed there.
+ *
+ * GR_GL_LOG_CALLS: if 1 Gr can print every GL call using GrPrintf. Defaults to
+ * 0. Logging can be enabled and disabled at runtime using a debugger via to
+ * global gLogCallsGL. The initial value of gLogCallsGL is controlled by
+ * GR_GL_LOG_CALLS_START.
+ *
+ * GR_GL_LOG_CALLS_START: controls the initial value of gLogCallsGL when
+ * GR_GL_LOG_CALLS is 1. Defaults to 0.
+ *
+ * GR_GL_CHECK_ERROR: if enabled Gr can do a glGetError() after every GL call.
+ * Defaults to 1 if SK_DEBUG is set, otherwise 0. When GR_GL_CHECK_ERROR is 1
+ * this can be toggled in a debugger using the gCheckErrorGL global. The initial
+ * value of gCheckErrorGL is controlled by by GR_GL_CHECK_ERROR_START.
+ *
+ * GR_GL_CHECK_ERROR_START: controls the initial value of gCheckErrorGL
+ * when GR_GL_CHECK_ERROR is 1. Defaults to 1.
+ *
+ * GR_GL_NO_CONSTANT_ATTRIBUTES: if this evaluates to true then the GL backend
+ * will use uniforms instead of attributes in all cases when there is not
+ * per-vertex data. This is important when the underlying GL implementation
+ * doesn't actually support immediate style attribute values (e.g. when
+ * the GL stream is converted to DX as in ANGLE on Chrome). Defaults to 0.
+ *
+ * GR_GL_USE_BUFFER_DATA_NULL_HINT: When specifing new data for a vertex/index
+ * buffer that replaces old data Ganesh can give a hint to the driver that the
+ * previous data will not be used in future draws like this:
+ * glBufferData(GL_..._BUFFER, size, NULL, usage); //<--hint, NULL means
+ * glBufferSubData(GL_..._BUFFER, 0, lessThanSize, data) // old data can't be
+ * // used again.
+ * However, this can be an unoptimization on some platforms, esp. Chrome.
+ * Chrome's cmd buffer will create a new allocation and memset the whole thing
+ * to zero (for security reasons). Defaults to 1 (enabled).
+ *
+ * GR_GL_PER_GL_FUNC_CALLBACK: When set to 1 the GrGLInterface object provides
+ * a function pointer that is called just before every gl function. The ptr must
+ * be valid (i.e. there is no NULL check). However, by default the callback will
+ * be set to a function that does nothing. The signature of the function is:
+ * void function(const GrGLInterface*)
+ * It is not extern "C".
+ * The GrGLInterface field fCallback specifies the function ptr and there is an
+ * additional field fCallbackData of type intptr_t for client data.
+ *
+ * GR_GL_RGBA_8888_PIXEL_OPS_SLOW: Set this to 1 if it is known that performing
+ * glReadPixels / glTex(Sub)Image with format=GL_RGBA, type=GL_UNISIGNED_BYTE is
+ * significantly slower than format=GL_BGRA, type=GL_UNISIGNED_BYTE.
+ *
+ * GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL: Set this to 1 if calling
+ * glReadPixels to read the entire framebuffer is faster than calling it with
+ * the same sized rectangle but with a framebuffer bound that is larger than
+ * the rectangle read.
+ *
+ * GR_GL_CHECK_ALLOC_WITH_GET_ERROR: If set to 1 this will then glTexImage,
+ * glBufferData, glRenderbufferStorage, etc will be checked for errors. This
+ * amounts to ensuring the error is GL_NO_ERROR, calling the allocating
+ * function, and then checking that the error is still GL_NO_ERROR. When the
+ * value is 0 we will assume no error was generated without checking.
+ *
+ * GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT: We will normally check the FBO status
+ * every time we bind a texture or renderbuffer to an FBO. However, in some
+ * environments CheckFrameBufferStatus is very expensive. If this is set we will
+ * check the first time we use a color format or a combination of color /
+ * stencil formats as attachments. If the FBO is complete we will assume
+ * subsequent attachments with the same formats are complete as well.
+ *
+ * GR_GL_MUST_USE_VBO: Indicates that all vertices and indices must be rendered
+ * from VBOs. Chromium's command buffer doesn't allow glVertexAttribArray with
+ * ARARY_BUFFER 0 bound or glDrawElements with ELEMENT_ARRAY_BUFFER 0 bound.
+ *
+ * GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE is for compatibility with the new version
+ * of the OpenGLES2.0 headers from Khronos. glShaderSource now takes a const char * const *,
+ * instead of a const char
+ */
+
+#if !defined(GR_GL_LOG_CALLS)
+ #ifdef SK_DEBUG
+ #define GR_GL_LOG_CALLS 1
+ #else
+ #define GR_GL_LOG_CALLS 0
+ #endif
+#endif
+
+#if !defined(GR_GL_LOG_CALLS_START)
+ #define GR_GL_LOG_CALLS_START 0
+#endif
+
+#if !defined(GR_GL_CHECK_ERROR)
+ #ifdef SK_DEBUG
+ #define GR_GL_CHECK_ERROR 1
+ #else
+ #define GR_GL_CHECK_ERROR 0
+ #endif
+#endif
+
+#if !defined(GR_GL_CHECK_ERROR_START)
+ #define GR_GL_CHECK_ERROR_START 1
+#endif
+
+#if !defined(GR_GL_NO_CONSTANT_ATTRIBUTES)
+ #define GR_GL_NO_CONSTANT_ATTRIBUTES 0
+#endif
+
+#if !defined(GR_GL_USE_BUFFER_DATA_NULL_HINT)
+ #define GR_GL_USE_BUFFER_DATA_NULL_HINT 1
+#endif
+
+#if !defined(GR_GL_PER_GL_FUNC_CALLBACK)
+ #define GR_GL_PER_GL_FUNC_CALLBACK 0
+#endif
+
+#if !defined(GR_GL_RGBA_8888_PIXEL_OPS_SLOW)
+ #define GR_GL_RGBA_8888_PIXEL_OPS_SLOW 0
+#endif
+
+#if !defined(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL)
+ #define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 0
+#endif
+
+#if !defined(GR_GL_CHECK_ALLOC_WITH_GET_ERROR)
+ #define GR_GL_CHECK_ALLOC_WITH_GET_ERROR 1
+#endif
+
+#if !defined(GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT)
+ #define GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 0
+#endif
+
+#if !defined(GR_GL_MUST_USE_VBO)
+ #define GR_GL_MUST_USE_VBO 0
+#endif
+
+#if !defined(GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE)
+ #define GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE 0
+#endif
+
+/**
+ * There is a strange bug that occurs on Macs with NVIDIA GPUs. We don't
+ * fully understand it. When (element) array buffers are continually
+ * respecified using glBufferData performance can fall off of a cliff. The
+ * driver winds up performing many DMA mapping / unmappings and chews up ~50% of
+ * the core. However, it has been observed that occaisonally respecifiying the
+ * buffer using glBufferData and then writing data using glBufferSubData
+ * prevents the bad behavior.
+ *
+ * There is a lot of uncertainty around this issue. In Chrome backgrounding
+ * the tab somehow initiates this behavior and we don't know what the connection
+ * is. Another observation is that Chrome's cmd buffer server will actually
+ * create a buffer full of zeros when it sees a NULL data param (for security
+ * reasons). If this is disabled and NULL is actually passed all the way to the
+ * driver then the workaround doesn't help.
+ *
+ * The issue is tracked at:
+ * http://code.google.com/p/chromium/issues/detail?id=114865
+ *
+ * When the workaround is enabled we will use the glBufferData / glBufferSubData
+ * trick every 128 array buffer uploads.
+ *
+ * Hopefully we will understand this better and have a cleaner fix or get a
+ * OS/driver level fix.
+ */
+#define GR_GL_MAC_BUFFER_OBJECT_PERFOMANCE_WORKAROUND \
+ (defined(SK_BUILD_FOR_MAC) && \
+ !GR_GL_USE_BUFFER_DATA_NULL_HINT)
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/GrGLConfig_chrome.h b/src/third_party/skia/include/gpu/gl/GrGLConfig_chrome.h
new file mode 100644
index 0000000..acad904
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/GrGLConfig_chrome.h
@@ -0,0 +1,54 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GrGLConfig_chrome_DEFINED
+#define GrGLConfig_chrome_DEFINED
+
+// glGetError() forces a sync with gpu process on chrome
+#define GR_GL_CHECK_ERROR_START 0
+
+#if defined(SK_BUILD_FOR_WIN32)
+// ANGLE creates a temp VB for vertex attributes not specified per-vertex.
+#define GR_GL_NO_CONSTANT_ATTRIBUTES 1
+
+// For RGBA teximage/readpixels ANGLE will sw-convert to/from BGRA.
+#define GR_GL_RGBA_8888_PIXEL_OPS_SLOW 1
+
+// ANGLE can go faster if the entire fbo is read rather than a subrect
+#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 1
+#else
+#define GR_GL_NO_CONSTANT_ATTRIBUTES 0
+#define GR_GL_RGBA_8888_PIXEL_OPS_SLOW 0
+#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 0
+#endif
+
+// cmd buffer allocates memory and memsets it to zero when it sees glBufferData
+// with NULL.
+#define GR_GL_USE_BUFFER_DATA_NULL_HINT 0
+
+// chrome uses this to set the context on each GL call.
+#define GR_GL_PER_GL_FUNC_CALLBACK 1
+
+// Check error is even more expensive in chrome (cmd buffer flush). The
+// compositor also doesn't check its allocations.
+#define GR_GL_CHECK_ALLOC_WITH_GET_ERROR 0
+
+// CheckFramebufferStatus in chrome synchronizes the gpu and renderer processes.
+#define GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 1
+
+// Non-VBO vertices and indices are not allowed in Chromium.
+#define GR_GL_MUST_USE_VBO 1
+
+// Use updated Khronos signature for glShaderSource
+// (const char* const instead of char**).
+#define GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE 1
+
+#if !defined(GR_GL_IGNORE_ES3_MSAA)
+ #define GR_GL_IGNORE_ES3_MSAA 1
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/GrGLExtensions.h b/src/third_party/skia/include/gpu/gl/GrGLExtensions.h
new file mode 100644
index 0000000..89adadf
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/GrGLExtensions.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLExtensions_DEFINED
+#define GrGLExtensions_DEFINED
+
+#include "GrGLFunctions.h"
+#include "SkString.h"
+#include "SkTArray.h"
+
+struct GrGLInterface;
+
+/**
+ * This helper queries the current GL context for its extensions, remembers them, and can be
+ * queried. It supports both glGetString- and glGetStringi-style extension string APIs and will
+ * use the latter if it is available.
+ */
+class SK_API GrGLExtensions {
+public:
+ GrGLExtensions() : fInitialized(false), fStrings(SkNEW(SkTArray<SkString>)) {}
+
+ GrGLExtensions(const GrGLExtensions&);
+
+ GrGLExtensions& operator=(const GrGLExtensions&);
+
+ void swap(GrGLExtensions* that) {
+ fStrings.swap(&that->fStrings);
+ SkTSwap(fInitialized, that->fInitialized);
+ }
+
+ /**
+ * We sometimes need to use this class without having yet created a GrGLInterface. This version
+ * of init expects that getString is always non-NULL while getIntegerv and getStringi are non-
+ * NULL if on desktop GL with version 3.0 or higher. Otherwise it will fail.
+ */
+ bool init(GrGLStandard standard,
+ GrGLGetStringProc getString,
+ GrGLGetStringiProc getStringi,
+ GrGLGetIntegervProc getIntegerv);
+
+ bool isInitialized() const { return fInitialized; }
+
+ /**
+ * Queries whether an extension is present. This will fail if init() has not been called.
+ */
+ bool has(const char[]) const;
+
+ /**
+ * Removes an extension if present. Returns true if the extension was present before the call.
+ */
+ bool remove(const char[]);
+
+ /**
+ * Adds an extension to list
+ */
+ void add(const char[]);
+
+ void reset() { fStrings->reset(); }
+
+ void print(const char* sep = "\n") const;
+
+private:
+ bool fInitialized;
+ SkAutoTDelete<SkTArray<SkString> > fStrings;
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/GrGLFunctions.h b/src/third_party/skia/include/gpu/gl/GrGLFunctions.h
new file mode 100644
index 0000000..45bf582
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/GrGLFunctions.h
@@ -0,0 +1,259 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLFunctions_DEFINED
+#define GrGLFunctions_DEFINED
+
+#include "GrGLConfig.h"
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Classifies GL contexts by which standard they implement (currently as Desktop
+ * vs. ES).
+ */
+enum GrGLStandard {
+ kNone_GrGLStandard,
+ kGL_GrGLStandard,
+ kGLES_GrGLStandard,
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Declares typedefs for all the GL functions used in GrGLInterface
+ */
+
+typedef unsigned int GrGLenum;
+typedef unsigned char GrGLboolean;
+typedef unsigned int GrGLbitfield;
+typedef signed char GrGLbyte;
+typedef char GrGLchar;
+typedef short GrGLshort;
+typedef int GrGLint;
+typedef int GrGLsizei;
+typedef int64_t GrGLint64;
+typedef unsigned char GrGLubyte;
+typedef unsigned short GrGLushort;
+typedef unsigned int GrGLuint;
+typedef uint64_t GrGLuint64;
+typedef float GrGLfloat;
+typedef float GrGLclampf;
+typedef double GrGLdouble;
+typedef double GrGLclampd;
+typedef void GrGLvoid;
+#ifndef SK_IGNORE_64BIT_OPENGL_CHANGES
+#ifdef _WIN64
+typedef signed long long int GrGLintptr;
+typedef signed long long int GrGLsizeiptr;
+#else
+typedef signed long int GrGLintptr;
+typedef signed long int GrGLsizeiptr;
+#endif
+#else
+typedef signed long int GrGLintptr;
+typedef signed long int GrGLsizeiptr;
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+extern "C" {
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLActiveTextureProc)(GrGLenum texture);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLAttachShaderProc)(GrGLuint program, GrGLuint shader);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBeginQueryProc)(GrGLenum target, GrGLuint id);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindAttribLocationProc)(GrGLuint program, GrGLuint index, const char* name);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindBufferProc)(GrGLenum target, GrGLuint buffer);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindFramebufferProc)(GrGLenum target, GrGLuint framebuffer);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindRenderbufferProc)(GrGLenum target, GrGLuint renderbuffer);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindTextureProc)(GrGLenum target, GrGLuint texture);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBlendColorProc)(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindFragDataLocationProc)(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindFragDataLocationIndexedProc)(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindVertexArrayProc)(GrGLuint array);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBlendFuncProc)(GrGLenum sfactor, GrGLenum dfactor);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBlitFramebufferProc)(GrGLint srcX0, GrGLint srcY0, GrGLint srcX1, GrGLint srcY1, GrGLint dstX0, GrGLint dstY0, GrGLint dstX1, GrGLint dstY1, GrGLbitfield mask, GrGLenum filter);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBufferDataProc)(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, GrGLenum usage);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBufferSubDataProc)(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data);
+ typedef GrGLenum (GR_GL_FUNCTION_TYPE* GrGLCheckFramebufferStatusProc)(GrGLenum target);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLClearProc)(GrGLbitfield mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLClearColorProc)(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLClearStencilProc)(GrGLint s);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLClientActiveTextureProc)(GrGLenum texture);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLColorMaskProc)(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCompileShaderProc)(GrGLuint shader);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCompressedTexImage2DProc)(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCompressedTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLsizei imageSize, const GrGLvoid* data);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCopyTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCopyTextureCHROMIUMProc)(GrGLenum target, GrGLenum src, GrGLenum dst, GrGLint level, GrGLint format, GrGLenum type);
+ typedef GrGLuint (GR_GL_FUNCTION_TYPE* GrGLCreateProgramProc)(void);
+ typedef GrGLuint (GR_GL_FUNCTION_TYPE* GrGLCreateShaderProc)(GrGLenum type);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCullFaceProc)(GrGLenum mode);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteBuffersProc)(GrGLsizei n, const GrGLuint* buffers);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteFramebuffersProc)(GrGLsizei n, const GrGLuint *framebuffers);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteProgramProc)(GrGLuint program);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteQueriesProc)(GrGLsizei n, const GrGLuint *ids);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteRenderbuffersProc)(GrGLsizei n, const GrGLuint *renderbuffers);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteShaderProc)(GrGLuint shader);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteTexturesProc)(GrGLsizei n, const GrGLuint* textures);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteVertexArraysProc)(GrGLsizei n, const GrGLuint *arrays);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDepthMaskProc)(GrGLboolean flag);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDisableProc)(GrGLenum cap);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDisableVertexAttribArrayProc)(GrGLuint index);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawArraysProc)(GrGLenum mode, GrGLint first, GrGLsizei count);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawBufferProc)(GrGLenum mode);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawBuffersProc)(GrGLsizei n, const GrGLenum* bufs);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableProc)(GrGLenum cap);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableVertexAttribArrayProc)(GrGLuint index);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEndQueryProc)(GrGLenum target);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFinishProc)();
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFlushProc)();
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFlushMappedBufferRangeProc)(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFramebufferRenderbufferProc)(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFramebufferTexture2DProc)(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFramebufferTexture2DMultisampleProc)(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level, GrGLsizei samples);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFrontFaceProc)(GrGLenum mode);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGenBuffersProc)(GrGLsizei n, GrGLuint* buffers);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGenFramebuffersProc)(GrGLsizei n, GrGLuint *framebuffers);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGenerateMipmapProc)(GrGLenum target);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGenQueriesProc)(GrGLsizei n, GrGLuint *ids);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGenRenderbuffersProc)(GrGLsizei n, GrGLuint *renderbuffers);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGenTexturesProc)(GrGLsizei n, GrGLuint* textures);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGenVertexArraysProc)(GrGLsizei n, GrGLuint *arrays);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetBufferParameterivProc)(GrGLenum target, GrGLenum pname, GrGLint* params);
+ typedef GrGLenum (GR_GL_FUNCTION_TYPE* GrGLGetErrorProc)();
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetFramebufferAttachmentParameterivProc)(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetIntegervProc)(GrGLenum pname, GrGLint* params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetProgramInfoLogProc)(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetProgramivProc)(GrGLuint program, GrGLenum pname, GrGLint* params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetQueryivProc)(GrGLenum GLtarget, GrGLenum pname, GrGLint *params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetQueryObjecti64vProc)(GrGLuint id, GrGLenum pname, GrGLint64 *params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetQueryObjectivProc)(GrGLuint id, GrGLenum pname, GrGLint *params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetQueryObjectui64vProc)(GrGLuint id, GrGLenum pname, GrGLuint64 *params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetQueryObjectuivProc)(GrGLuint id, GrGLenum pname, GrGLuint *params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetRenderbufferParameterivProc)(GrGLenum target, GrGLenum pname, GrGLint* params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetShaderInfoLogProc)(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length, char* infolog);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetShaderivProc)(GrGLuint shader, GrGLenum pname, GrGLint* params);
+ typedef const GrGLubyte* (GR_GL_FUNCTION_TYPE* GrGLGetStringProc)(GrGLenum name);
+ typedef const GrGLubyte* (GR_GL_FUNCTION_TYPE* GrGLGetStringiProc)(GrGLenum name, GrGLuint index);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetTexLevelParameterivProc)(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params);
+ typedef GrGLint (GR_GL_FUNCTION_TYPE* GrGLGetUniformLocationProc)(GrGLuint program, const char* name);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInsertEventMarkerProc)(GrGLsizei length, const char* marker);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInvalidateBufferDataProc)(GrGLuint buffer);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInvalidateBufferSubDataProc)(GrGLuint buffer, GrGLintptr offset, GrGLsizeiptr length);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInvalidateFramebufferProc)(GrGLenum target, GrGLsizei numAttachments, const GrGLenum *attachments);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInvalidateSubFramebufferProc)(GrGLenum target, GrGLsizei numAttachments, const GrGLenum *attachments, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInvalidateTexImageProc)(GrGLuint texture, GrGLint level);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInvalidateTexSubImageProc)(GrGLuint texture, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint zoffset, GrGLsizei width, GrGLsizei height, GrGLsizei depth);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLLineWidthProc)(GrGLfloat width);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLLinkProgramProc)(GrGLuint program);
+ typedef GrGLvoid* (GR_GL_FUNCTION_TYPE* GrGLMapBufferProc)(GrGLenum target, GrGLenum access);
+ typedef GrGLvoid* (GR_GL_FUNCTION_TYPE* GrGLMapBufferRangeProc)(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length, GrGLbitfield access);
+ typedef GrGLvoid* (GR_GL_FUNCTION_TYPE* GrGLMapBufferSubDataProc)(GrGLuint target, GrGLintptr offset, GrGLsizeiptr size, GrGLenum access);
+ typedef GrGLvoid* (GR_GL_FUNCTION_TYPE* GrGLMapTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLenum access);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPixelStoreiProc)(GrGLenum pname, GrGLint param);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPopGroupMarkerProc)();
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPushGroupMarkerProc)(GrGLsizei length, const char* marker);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLQueryCounterProc)(GrGLuint id, GrGLenum target);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLReadBufferProc)(GrGLenum src);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLReadPixelsProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLRenderbufferStorageProc)(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLRenderbufferStorageMultisampleProc)(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLResolveMultisampleFramebufferProc)();
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLScissorProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLBindUniformLocation)(GrGLuint program, GrGLint location, const char* name);
+
+#if GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLShaderSourceProc)(GrGLuint shader, GrGLsizei count, const char* const * str, const GrGLint* length);
+#else
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLShaderSourceProc)(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length);
+#endif
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilFuncProc)(GrGLenum func, GrGLint ref, GrGLuint mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilFuncSeparateProc)(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilMaskProc)(GrGLuint mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilMaskSeparateProc)(GrGLenum face, GrGLuint mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilOpProc)(GrGLenum fail, GrGLenum zfail, GrGLenum zpass);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilOpSeparateProc)(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTexImage2DProc)(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTexParameteriProc)(GrGLenum target, GrGLenum pname, GrGLint param);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTexParameterivProc)(GrGLenum target, GrGLenum pname, const GrGLint* params);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTexStorage2DProc)(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDiscardFramebufferProc)(GrGLenum target, GrGLsizei numAttachments, const GrGLenum* attachments);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform1fProc)(GrGLint location, GrGLfloat v0);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform1iProc)(GrGLint location, GrGLint v0);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform1fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform1ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform2fProc)(GrGLint location, GrGLfloat v0, GrGLfloat v1);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform2iProc)(GrGLint location, GrGLint v0, GrGLint v1);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform2fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform2ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform3fProc)(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform3iProc)(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform3fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform3ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform4fProc)(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform4iProc)(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform4fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniform4ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniformMatrix2fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniformMatrix3fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUniformMatrix4fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
+ typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLUnmapBufferProc)(GrGLenum target);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUnmapBufferSubDataProc)(const GrGLvoid* mem);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUnmapTexSubImage2DProc)(const GrGLvoid* mem);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUseProgramProc)(GrGLuint program);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttrib4fvProc)(GrGLuint indx, const GrGLfloat* values);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttribPointerProc)(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLViewportProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
+
+ // Experimental: Functions for GL_NV_path_rendering. These will be
+ // alphabetized with the above functions once this is fully supported
+ // (and functions we are unlikely to use will possibly be omitted).
+ // EXT_direct_state_access
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLMatrixLoadfProc)(GrGLenum matrixMode, const GrGLfloat* m);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLMatrixLoadIdentityProc)(GrGLenum);
+ // ARB_program_interface_query
+ typedef GrGLint (GR_GL_FUNCTION_TYPE* GrGLGetProgramResourceLocationProc)(GrGLuint program, GrGLenum programInterface, const GrGLchar *name);
+ // NV_path_rendering
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathCommandsProc)(GrGLuint path, GrGLsizei numCommands, const GrGLubyte *commands, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathCoordsProc)(GrGLuint path, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathSubCoordsProc)(GrGLuint path, GrGLsizei coordStart, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathStringProc)(GrGLuint path, GrGLenum format, GrGLsizei length, const GrGLvoid *pathString);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathGlyphsProc)(GrGLuint firstPathName, GrGLenum fontTarget, const GrGLvoid *fontName, GrGLbitfield fontStyle, GrGLsizei numGlyphs, GrGLenum type, const GrGLvoid *charcodes, GrGLenum handleMissingGlyphs, GrGLuint pathParameterTemplate, GrGLfloat emScale);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathGlyphRangeProc)(GrGLuint firstPathName, GrGLenum fontTarget, const GrGLvoid *fontName, GrGLbitfield fontStyle, GrGLuint firstGlyph, GrGLsizei numGlyphs, GrGLenum handleMissingGlyphs, GrGLuint pathParameterTemplate, GrGLfloat emScale);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLWeightPathsProc)(GrGLuint resultPath, GrGLsizei numPaths, const GrGLuint paths[], const GrGLfloat weights[]);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCopyPathProc)(GrGLuint resultPath, GrGLuint srcPath);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInterpolatePathsProc)(GrGLuint resultPath, GrGLuint pathA, GrGLuint pathB, GrGLfloat weight);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLTransformPathProc)(GrGLuint resultPath, GrGLuint srcPath, GrGLenum transformType, const GrGLfloat *transformValues);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathParameteriProc)(GrGLuint path, GrGLenum pname, GrGLint value);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathParameterfProc)(GrGLuint path, GrGLenum pname, GrGLfloat value);
+ typedef GrGLuint (GR_GL_FUNCTION_TYPE* GrGLGenPathsProc)(GrGLsizei range);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeletePathsProc)(GrGLuint path, GrGLsizei range);
+ typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLIsPathProc)(GrGLuint path);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathStencilFuncProc)(GrGLenum func, GrGLint ref, GrGLuint mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilFillPathProc)(GrGLuint path, GrGLenum fillMode, GrGLuint mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilStrokePathProc)(GrGLuint path, GrGLint reference, GrGLuint mask);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilFillPathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum transformType, const GrGLfloat *transformValues);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilStrokePathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum transformType, const GrGLfloat *transformValues);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPathTexGenProc)(GrGLenum texCoordSet, GrGLenum genMode, GrGLint components, const GrGLfloat *coeffs);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverFillPathProc)(GrGLuint path, GrGLenum coverMode);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverStrokePathProc)(GrGLuint name, GrGLenum coverMode);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverFillPathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLCoverStrokePathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transformValues);
+ // NV_path_rendering v1.2
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverFillPathProc)(GrGLuint path, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverStrokePathProc)(GrGLuint path, GrGLint reference, GrGLuint mask, GrGLenum coverMode);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverFillPathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues);
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLStencilThenCoverStrokePathInstancedProc)(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues);
+ // NV_path_rendering v1.3
+ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLProgramPathFragmentInputGenProc)(GrGLuint program, GrGLint location, GrGLenum genMode, GrGLint components,const GrGLfloat *coeffs);
+ typedef GrGLenum (GR_GL_FUNCTION_TYPE* GrGLPathMemoryGlyphIndexArrayProc)(GrGLuint firstPathName, GrGLenum fontTarget, GrGLsizeiptr fontSize, const GrGLvoid *fontData, GrGLsizei faceIndex, GrGLuint firstGlyphIndex, GrGLsizei numGlyphs, GrGLuint pathParameterTemplate, GrGLfloat emScale);
+} // extern "C"
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/GrGLInterface.h b/src/third_party/skia/include/gpu/gl/GrGLInterface.h
new file mode 100644
index 0000000..32552e6
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/GrGLInterface.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLInterface_DEFINED
+#define GrGLInterface_DEFINED
+
+#include "GrGLFunctions.h"
+#include "GrGLExtensions.h"
+#include "SkRefCnt.h"
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Rather than depend on platform-specific GL headers and libraries, we require
+ * the client to provide a struct of GL function pointers. This struct can be
+ * specified per-GrContext as a parameter to GrContext::Create. If NULL is
+ * passed to Create then a "default" GL interface is created. If the default is
+ * also NULL GrContext creation will fail.
+ *
+ * The default interface is returned by GrGLDefaultInterface. This function's
+ * implementation is platform-specific. Several have been provided, along with
+ * an implementation that simply returns NULL.
+ *
+ * By defining GR_GL_PER_GL_CALL_IFACE_CALLBACK to 1 the client can specify a
+ * callback function that will be called prior to each GL function call. See
+ * comments in GrGLConfig.h
+ */
+
+struct GrGLInterface;
+
+const GrGLInterface* GrGLDefaultInterface();
+
+/**
+ * Creates a GrGLInterface for a "native" GL context (e.g. WGL on windows,
+ * GLX on linux, AGL on Mac). The interface is only valid for the GL context
+ * that is current when the interface is created.
+ */
+const GrGLInterface* GrGLCreateNativeInterface();
+
+#if SK_MESA
+/**
+ * Creates a GrGLInterface for an OSMesa context.
+ */
+const GrGLInterface* GrGLCreateMesaInterface();
+#endif
+
+#if SK_ANGLE
+/**
+ * Creates a GrGLInterface for an ANGLE context.
+ */
+const GrGLInterface* GrGLCreateANGLEInterface();
+#endif
+
+/**
+ * Creates a null GrGLInterface that doesn't draw anything. Used for measuring
+ * CPU overhead.
+ */
+const SK_API GrGLInterface* GrGLCreateNullInterface();
+
+/**
+ * Creates a debugging GrGLInterface that doesn't draw anything. Used for
+ * finding memory leaks and invalid memory accesses.
+ */
+const GrGLInterface* GrGLCreateDebugInterface();
+
+#if GR_GL_PER_GL_FUNC_CALLBACK
+typedef void (*GrGLInterfaceCallbackProc)(const GrGLInterface*);
+typedef intptr_t GrGLInterfaceCallbackData;
+#endif
+
+/** Function that returns a new interface identical to "interface" but without support for
+ GL_NV_path_rendering. */
+const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface*);
+
+/** Function that returns a new interface identical to "interface" but with support for
+ test version of GL_EXT_debug_marker. */
+const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface*,
+ GrGLInsertEventMarkerProc insertEventMarkerFn,
+ GrGLPushGroupMarkerProc pushGroupMarkerFn,
+ GrGLPopGroupMarkerProc popGroupMarkerFn);
+
+/**
+ * GrContext uses the following interface to make all calls into OpenGL. When a
+ * GrContext is created it is given a GrGLInterface. The interface's function
+ * pointers must be valid for the OpenGL context associated with the GrContext.
+ * On some platforms, such as Windows, function pointers for OpenGL extensions
+ * may vary between OpenGL contexts. So the caller must be careful to use a
+ * GrGLInterface initialized for the correct context. All functions that should
+ * be available based on the OpenGL's version and extension string must be
+ * non-NULL or GrContext creation will fail. This can be tested with the
+ * validate() method when the OpenGL context has been made current.
+ */
+struct SK_API GrGLInterface : public SkRefCnt {
+private:
+ // simple wrapper class that exists only to initialize a pointer to NULL
+ template <typename FNPTR_TYPE> class GLPtr {
+ public:
+ GLPtr() : fPtr(NULL) {}
+ GLPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; }
+ operator FNPTR_TYPE() const { return fPtr; }
+ private:
+ FNPTR_TYPE fPtr;
+ };
+
+ // This is a temporary workaround to keep Chromium's GrGLInterface factories compiling until
+ // they're updated to use the Functions struct.
+ template <typename FNPTR_TYPE> class GLPtrAlias {
+ public:
+ GLPtrAlias(GLPtr<FNPTR_TYPE>* base) : fBase(base) {}
+ void operator=(FNPTR_TYPE ptr) { *fBase = ptr; }
+ private:
+ GLPtr<FNPTR_TYPE>* fBase;
+ };
+
+ typedef SkRefCnt INHERITED;
+
+public:
+ SK_DECLARE_INST_COUNT(GrGLInterface)
+
+ GrGLInterface();
+
+ static GrGLInterface* NewClone(const GrGLInterface*);
+
+ // Validates that the GrGLInterface supports its advertised standard. This means the necessary
+ // function pointers have been initialized for both the GL version and any advertised
+ // extensions.
+ bool validate() const;
+
+ // Indicates the type of GL implementation
+ union {
+ GrGLStandard fStandard;
+ GrGLStandard fBindingsExported; // Legacy name, will be remove when Chromium is updated.
+ };
+
+ GrGLExtensions fExtensions;
+
+ bool hasExtension(const char ext[]) const { return fExtensions.has(ext); }
+
+ /**
+ * The function pointers are in a struct so that we can have a compiler generated assignment
+ * operator.
+ */
+ struct Functions {
+ GLPtr<GrGLActiveTextureProc> fActiveTexture;
+ GLPtr<GrGLAttachShaderProc> fAttachShader;
+ GLPtr<GrGLBeginQueryProc> fBeginQuery;
+ GLPtr<GrGLBindAttribLocationProc> fBindAttribLocation;
+ GLPtr<GrGLBindBufferProc> fBindBuffer;
+ GLPtr<GrGLBindFragDataLocationProc> fBindFragDataLocation;
+ GLPtr<GrGLBindFragDataLocationIndexedProc> fBindFragDataLocationIndexed;
+ GLPtr<GrGLBindFramebufferProc> fBindFramebuffer;
+ GLPtr<GrGLBindRenderbufferProc> fBindRenderbuffer;
+ GLPtr<GrGLBindTextureProc> fBindTexture;
+ GLPtr<GrGLBindVertexArrayProc> fBindVertexArray;
+ GLPtr<GrGLBlendColorProc> fBlendColor;
+ GLPtr<GrGLBlendFuncProc> fBlendFunc;
+ GLPtr<GrGLBlitFramebufferProc> fBlitFramebuffer;
+ GLPtr<GrGLBufferDataProc> fBufferData;
+ GLPtr<GrGLBufferSubDataProc> fBufferSubData;
+ GLPtr<GrGLCheckFramebufferStatusProc> fCheckFramebufferStatus;
+ GLPtr<GrGLClearProc> fClear;
+ GLPtr<GrGLClearColorProc> fClearColor;
+ GLPtr<GrGLClearStencilProc> fClearStencil;
+ GLPtr<GrGLColorMaskProc> fColorMask;
+ GLPtr<GrGLCompileShaderProc> fCompileShader;
+ GLPtr<GrGLCompressedTexImage2DProc> fCompressedTexImage2D;
+ GLPtr<GrGLCompressedTexSubImage2DProc> fCompressedTexSubImage2D;
+ GLPtr<GrGLCopyTexSubImage2DProc> fCopyTexSubImage2D;
+ GLPtr<GrGLCopyTextureCHROMIUMProc> fCopyTextureCHROMIUM;
+ GLPtr<GrGLCreateProgramProc> fCreateProgram;
+ GLPtr<GrGLCreateShaderProc> fCreateShader;
+ GLPtr<GrGLCullFaceProc> fCullFace;
+ GLPtr<GrGLDeleteBuffersProc> fDeleteBuffers;
+ GLPtr<GrGLDeleteFramebuffersProc> fDeleteFramebuffers;
+ GLPtr<GrGLDeleteProgramProc> fDeleteProgram;
+ GLPtr<GrGLDeleteQueriesProc> fDeleteQueries;
+ GLPtr<GrGLDeleteRenderbuffersProc> fDeleteRenderbuffers;
+ GLPtr<GrGLDeleteShaderProc> fDeleteShader;
+ GLPtr<GrGLDeleteTexturesProc> fDeleteTextures;
+ GLPtr<GrGLDeleteVertexArraysProc> fDeleteVertexArrays;
+ GLPtr<GrGLDepthMaskProc> fDepthMask;
+ GLPtr<GrGLDisableProc> fDisable;
+ GLPtr<GrGLDisableVertexAttribArrayProc> fDisableVertexAttribArray;
+ GLPtr<GrGLDrawArraysProc> fDrawArrays;
+ GLPtr<GrGLDrawBufferProc> fDrawBuffer;
+ GLPtr<GrGLDrawBuffersProc> fDrawBuffers;
+ GLPtr<GrGLDrawElementsProc> fDrawElements;
+ GLPtr<GrGLEnableProc> fEnable;
+ GLPtr<GrGLEnableVertexAttribArrayProc> fEnableVertexAttribArray;
+ GLPtr<GrGLEndQueryProc> fEndQuery;
+ GLPtr<GrGLFinishProc> fFinish;
+ GLPtr<GrGLFlushProc> fFlush;
+ GLPtr<GrGLFlushMappedBufferRangeProc> fFlushMappedBufferRange;
+ GLPtr<GrGLFramebufferRenderbufferProc> fFramebufferRenderbuffer;
+ GLPtr<GrGLFramebufferTexture2DProc> fFramebufferTexture2D;
+ GLPtr<GrGLFramebufferTexture2DMultisampleProc> fFramebufferTexture2DMultisample;
+ GLPtr<GrGLFrontFaceProc> fFrontFace;
+ GLPtr<GrGLGenBuffersProc> fGenBuffers;
+ GLPtr<GrGLGenFramebuffersProc> fGenFramebuffers;
+ GLPtr<GrGLGenerateMipmapProc> fGenerateMipmap;
+ GLPtr<GrGLGenQueriesProc> fGenQueries;
+ GLPtr<GrGLGenRenderbuffersProc> fGenRenderbuffers;
+ GLPtr<GrGLGenTexturesProc> fGenTextures;
+ GLPtr<GrGLGenVertexArraysProc> fGenVertexArrays;
+ GLPtr<GrGLGetBufferParameterivProc> fGetBufferParameteriv;
+ GLPtr<GrGLGetErrorProc> fGetError;
+ GLPtr<GrGLGetFramebufferAttachmentParameterivProc> fGetFramebufferAttachmentParameteriv;
+ GLPtr<GrGLGetIntegervProc> fGetIntegerv;
+ GLPtr<GrGLGetQueryObjecti64vProc> fGetQueryObjecti64v;
+ GLPtr<GrGLGetQueryObjectivProc> fGetQueryObjectiv;
+ GLPtr<GrGLGetQueryObjectui64vProc> fGetQueryObjectui64v;
+ GLPtr<GrGLGetQueryObjectuivProc> fGetQueryObjectuiv;
+ GLPtr<GrGLGetQueryivProc> fGetQueryiv;
+ GLPtr<GrGLGetProgramInfoLogProc> fGetProgramInfoLog;
+ GLPtr<GrGLGetProgramivProc> fGetProgramiv;
+ GLPtr<GrGLGetRenderbufferParameterivProc> fGetRenderbufferParameteriv;
+ GLPtr<GrGLGetShaderInfoLogProc> fGetShaderInfoLog;
+ GLPtr<GrGLGetShaderivProc> fGetShaderiv;
+ GLPtr<GrGLGetStringProc> fGetString;
+ GLPtr<GrGLGetStringiProc> fGetStringi;
+ GLPtr<GrGLGetTexLevelParameterivProc> fGetTexLevelParameteriv;
+ GLPtr<GrGLGetUniformLocationProc> fGetUniformLocation;
+ GLPtr<GrGLInsertEventMarkerProc> fInsertEventMarker;
+ GLPtr<GrGLInvalidateBufferDataProc> fInvalidateBufferData;
+ GLPtr<GrGLInvalidateBufferSubDataProc> fInvalidateBufferSubData;
+ GLPtr<GrGLInvalidateFramebufferProc> fInvalidateFramebuffer;
+ GLPtr<GrGLInvalidateSubFramebufferProc> fInvalidateSubFramebuffer;
+ GLPtr<GrGLInvalidateTexImageProc> fInvalidateTexImage;
+ GLPtr<GrGLInvalidateTexSubImageProc> fInvalidateTexSubImage;
+ GLPtr<GrGLLineWidthProc> fLineWidth;
+ GLPtr<GrGLLinkProgramProc> fLinkProgram;
+ GLPtr<GrGLMapBufferProc> fMapBuffer;
+ GLPtr<GrGLMapBufferRangeProc> fMapBufferRange;
+ GLPtr<GrGLMapBufferSubDataProc> fMapBufferSubData;
+ GLPtr<GrGLMapTexSubImage2DProc> fMapTexSubImage2D;
+ GLPtr<GrGLMatrixLoadfProc> fMatrixLoadf;
+ GLPtr<GrGLMatrixLoadIdentityProc> fMatrixLoadIdentity;
+ GLPtr<GrGLPixelStoreiProc> fPixelStorei;
+ GLPtr<GrGLPopGroupMarkerProc> fPopGroupMarker;
+ GLPtr<GrGLPushGroupMarkerProc> fPushGroupMarker;
+ GLPtr<GrGLQueryCounterProc> fQueryCounter;
+ GLPtr<GrGLReadBufferProc> fReadBuffer;
+ GLPtr<GrGLReadPixelsProc> fReadPixels;
+ GLPtr<GrGLRenderbufferStorageProc> fRenderbufferStorage;
+
+ // On OpenGL ES there are multiple incompatible extensions that add support for MSAA
+ // and ES3 adds MSAA support to the standard. On an ES3 driver we may still use the
+ // older extensions for performance reasons or due to ES3 driver bugs. We want the function
+ // that creates the GrGLInterface to provide all available functions and internally
+ // we will select among them. They all have a method called glRenderbufferStorageMultisample*.
+ // So we have separate function pointers for GL_IMG/EXT_multisampled_to_texture,
+ // GL_CHROMIUM/ANGLE_framebuffer_multisample/ES3, and GL_APPLE_framebuffer_multisample
+ // variations.
+ //
+ // If a driver supports multiple GL_ARB_framebuffer_multisample-style extensions then we will
+ // assume the function pointers for the standard (or equivalent GL_ARB) version have
+ // been preferred over GL_EXT, GL_CHROMIUM, or GL_ANGLE variations that have reduced
+ // functionality.
+
+ // GL_EXT_multisampled_render_to_texture (preferred) or GL_IMG_multisampled_render_to_texture
+ GLPtr<GrGLRenderbufferStorageMultisampleProc> fRenderbufferStorageMultisampleES2EXT;
+ // GL_APPLE_framebuffer_multisample
+ GLPtr<GrGLRenderbufferStorageMultisampleProc> fRenderbufferStorageMultisampleES2APPLE;
+
+ // This is used to store the pointer for GL_ARB/EXT/ANGLE/CHROMIUM_framebuffer_multisample or
+ // the standard function in ES3+ or GL 3.0+.
+ GLPtr<GrGLRenderbufferStorageMultisampleProc> fRenderbufferStorageMultisample;
+
+ // Pointer to BindUniformLocationCHROMIUM from the GL_CHROMIUM_bind_uniform_location extension.
+ GLPtr<GrGLBindUniformLocation> fBindUniformLocation;
+
+ GLPtr<GrGLResolveMultisampleFramebufferProc> fResolveMultisampleFramebuffer;
+ GLPtr<GrGLScissorProc> fScissor;
+ GLPtr<GrGLShaderSourceProc> fShaderSource;
+ GLPtr<GrGLStencilFuncProc> fStencilFunc;
+ GLPtr<GrGLStencilFuncSeparateProc> fStencilFuncSeparate;
+ GLPtr<GrGLStencilMaskProc> fStencilMask;
+ GLPtr<GrGLStencilMaskSeparateProc> fStencilMaskSeparate;
+ GLPtr<GrGLStencilOpProc> fStencilOp;
+ GLPtr<GrGLStencilOpSeparateProc> fStencilOpSeparate;
+ GLPtr<GrGLTexImage2DProc> fTexImage2D;
+ GLPtr<GrGLTexParameteriProc> fTexParameteri;
+ GLPtr<GrGLTexParameterivProc> fTexParameteriv;
+ GLPtr<GrGLTexSubImage2DProc> fTexSubImage2D;
+ GLPtr<GrGLTexStorage2DProc> fTexStorage2D;
+ GLPtr<GrGLDiscardFramebufferProc> fDiscardFramebuffer;
+ GLPtr<GrGLUniform1fProc> fUniform1f;
+ GLPtr<GrGLUniform1iProc> fUniform1i;
+ GLPtr<GrGLUniform1fvProc> fUniform1fv;
+ GLPtr<GrGLUniform1ivProc> fUniform1iv;
+ GLPtr<GrGLUniform2fProc> fUniform2f;
+ GLPtr<GrGLUniform2iProc> fUniform2i;
+ GLPtr<GrGLUniform2fvProc> fUniform2fv;
+ GLPtr<GrGLUniform2ivProc> fUniform2iv;
+ GLPtr<GrGLUniform3fProc> fUniform3f;
+ GLPtr<GrGLUniform3iProc> fUniform3i;
+ GLPtr<GrGLUniform3fvProc> fUniform3fv;
+ GLPtr<GrGLUniform3ivProc> fUniform3iv;
+ GLPtr<GrGLUniform4fProc> fUniform4f;
+ GLPtr<GrGLUniform4iProc> fUniform4i;
+ GLPtr<GrGLUniform4fvProc> fUniform4fv;
+ GLPtr<GrGLUniform4ivProc> fUniform4iv;
+ GLPtr<GrGLUniformMatrix2fvProc> fUniformMatrix2fv;
+ GLPtr<GrGLUniformMatrix3fvProc> fUniformMatrix3fv;
+ GLPtr<GrGLUniformMatrix4fvProc> fUniformMatrix4fv;
+ GLPtr<GrGLUnmapBufferProc> fUnmapBuffer;
+ GLPtr<GrGLUnmapBufferSubDataProc> fUnmapBufferSubData;
+ GLPtr<GrGLUnmapTexSubImage2DProc> fUnmapTexSubImage2D;
+ GLPtr<GrGLUseProgramProc> fUseProgram;
+ GLPtr<GrGLVertexAttrib4fvProc> fVertexAttrib4fv;
+ GLPtr<GrGLVertexAttribPointerProc> fVertexAttribPointer;
+ GLPtr<GrGLViewportProc> fViewport;
+
+ // Experimental: Functions for GL_NV_path_rendering. These will be
+ // alphabetized with the above functions once this is fully supported
+ // (and functions we are unlikely to use will possibly be omitted).
+ GLPtr<GrGLGetProgramResourceLocationProc> fGetProgramResourceLocation;
+ GLPtr<GrGLPathCommandsProc> fPathCommands;
+ GLPtr<GrGLPathCoordsProc> fPathCoords;
+ GLPtr<GrGLPathParameteriProc> fPathParameteri;
+ GLPtr<GrGLPathParameterfProc> fPathParameterf;
+ GLPtr<GrGLGenPathsProc> fGenPaths;
+ GLPtr<GrGLDeletePathsProc> fDeletePaths;
+ GLPtr<GrGLIsPathProc> fIsPath;
+ GLPtr<GrGLPathStencilFuncProc> fPathStencilFunc;
+ GLPtr<GrGLStencilFillPathProc> fStencilFillPath;
+ GLPtr<GrGLStencilStrokePathProc> fStencilStrokePath;
+ GLPtr<GrGLStencilFillPathInstancedProc> fStencilFillPathInstanced;
+ GLPtr<GrGLStencilStrokePathInstancedProc> fStencilStrokePathInstanced;
+ GLPtr<GrGLPathTexGenProc> fPathTexGen;
+ GLPtr<GrGLCoverFillPathProc> fCoverFillPath;
+ GLPtr<GrGLCoverStrokePathProc> fCoverStrokePath;
+ GLPtr<GrGLCoverFillPathInstancedProc> fCoverFillPathInstanced;
+ GLPtr<GrGLCoverStrokePathInstancedProc> fCoverStrokePathInstanced;
+ // NV_path_rendering v1.2
+ GLPtr<GrGLStencilThenCoverFillPathProc> fStencilThenCoverFillPath;
+ GLPtr<GrGLStencilThenCoverStrokePathProc> fStencilThenCoverStrokePath;
+ GLPtr<GrGLStencilThenCoverFillPathInstancedProc> fStencilThenCoverFillPathInstanced;
+ GLPtr<GrGLStencilThenCoverStrokePathInstancedProc> fStencilThenCoverStrokePathInstanced;
+ // NV_path_rendering v1.3
+ GLPtr<GrGLProgramPathFragmentInputGenProc> fProgramPathFragmentInputGen;
+ GLPtr<GrGLPathMemoryGlyphIndexArrayProc> fPathMemoryGlyphIndexArray;
+ } fFunctions;
+
+ // Per-GL func callback
+#if GR_GL_PER_GL_FUNC_CALLBACK
+ GrGLInterfaceCallbackProc fCallback;
+ GrGLInterfaceCallbackData fCallbackData;
+#endif
+
+ // This exists for internal testing.
+ virtual void abandon() const {}
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/GrGLSLPrettyPrint.h b/src/third_party/skia/include/gpu/gl/GrGLSLPrettyPrint.h
new file mode 100644
index 0000000..7273aaa
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/GrGLSLPrettyPrint.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GrGLSLPrettyPrint_DEFINED
+#define GrGLSLPrettyPrint_DEFINED
+
+#include "SkString.h"
+
+namespace GrGLSLPrettyPrint {
+ SkString PrettyPrintGLSL(const SkString& input, bool countlines);
+};
+
+#endif /* GRGLPRETTYPRINTSL_H_ */
diff --git a/src/third_party/skia/include/gpu/gl/SkANGLEGLContext.h b/src/third_party/skia/include/gpu/gl/SkANGLEGLContext.h
new file mode 100644
index 0000000..c5f62ff
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/SkANGLEGLContext.h
@@ -0,0 +1,51 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkANGLEGLContext_DEFINED
+#define SkANGLEGLContext_DEFINED
+
+#if SK_ANGLE
+
+#include "SkGLContextHelper.h"
+
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+
+class SkANGLEGLContext : public SkGLContextHelper {
+public:
+ SkANGLEGLContext();
+
+ virtual ~SkANGLEGLContext();
+
+ virtual void makeCurrent() const SK_OVERRIDE;
+ virtual void swapBuffers() const SK_OVERRIDE;
+
+ class AutoContextRestore {
+ public:
+ AutoContextRestore();
+ ~AutoContextRestore();
+
+ private:
+ EGLContext fOldEGLContext;
+ EGLDisplay fOldDisplay;
+ EGLSurface fOldSurface;
+ };
+
+protected:
+ virtual const GrGLInterface* createGLContext(
+ GrGLStandard forcedGpuAPI) SK_OVERRIDE;
+ virtual void destroyGLContext() SK_OVERRIDE;
+
+private:
+ EGLContext fContext;
+ EGLDisplay fDisplay;
+ EGLSurface fSurface;
+};
+
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/SkDebugGLContext.h b/src/third_party/skia/include/gpu/gl/SkDebugGLContext.h
new file mode 100644
index 0000000..7db9579
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/SkDebugGLContext.h
@@ -0,0 +1,27 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkDebugGLContext_DEFINED
+#define SkDebugGLContext_DEFINED
+
+#include "SkGLContextHelper.h"
+
+class SkDebugGLContext : public SkGLContextHelper {
+
+public:
+ SkDebugGLContext() {}
+
+ virtual void makeCurrent() const SK_OVERRIDE {}
+ virtual void swapBuffers() const SK_OVERRIDE {}
+
+protected:
+ virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
+
+ virtual void destroyGLContext() SK_OVERRIDE {};
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/SkGLContextHelper.h b/src/third_party/skia/include/gpu/gl/SkGLContextHelper.h
new file mode 100644
index 0000000..c4d9bdf
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/SkGLContextHelper.h
@@ -0,0 +1,95 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkGLContextHelper_DEFINED
+#define SkGLContextHelper_DEFINED
+
+#include "GrGLInterface.h"
+
+/**
+ * Create an offscreen opengl context with an RGBA8 / 8bit stencil FBO.
+ * Provides a GrGLInterface struct of function pointers for the context.
+ */
+
+class SK_API SkGLContextHelper : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkGLContextHelper)
+
+ SkGLContextHelper();
+ virtual ~SkGLContextHelper();
+
+ /**
+ * Initializes the context and makes it current.
+ */
+ bool init(GrGLStandard forcedGpuAPI, const int width, const int height);
+
+ int getFBOID() const { return fFBO; }
+
+ const GrGLInterface* gl() const { return fGL; }
+
+ virtual void makeCurrent() const = 0;
+
+ /**
+ * The primary purpose of this function it to provide a means of scheduling
+ * work on the GPU (since all of the subclasses create primary buffers for
+ * testing that are small and not meant to be rendered to the screen).
+ *
+ * If the drawing surface provided by the platform is double buffered this
+ * call will cause the platform to swap which buffer is currently being
+ * targeted. If the current surface does not include a back buffer, this
+ * call has no effect.
+ */
+ virtual void swapBuffers() const = 0;
+
+ bool hasExtension(const char* extensionName) const {
+ SkASSERT(fGL);
+ return fGL->hasExtension(extensionName);
+ }
+
+ /**
+ * This notifies the context that we are deliberately testing abandoning
+ * the context. It is useful for debugging contexts that would otherwise
+ * test that GPU resources are properly deleted. It also allows a debugging
+ * context to test that further GL calls are not made by Skia GPU code.
+ */
+ void testAbandon();
+
+protected:
+ /**
+ * Subclass implements this to make a GL context. The returned GrGLInterface
+ * should be populated with functions compatible with the context. The
+ * format and size of backbuffers does not matter since an FBO will be
+ * created.
+ */
+ virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) = 0;
+
+ /**
+ * Subclass should destroy the underlying GL context.
+ */
+ virtual void destroyGLContext() = 0;
+
+private:
+ GrGLuint fFBO;
+ GrGLuint fColorBufferID;
+ GrGLuint fDepthStencilBufferID;
+ const GrGLInterface* fGL;
+
+ typedef SkRefCnt INHERITED;
+};
+
+/**
+ * Helper macros for using the GL context through the GrGLInterface. Example:
+ * SK_GL(glCtx, GenTextures(1, &texID));
+ */
+#define SK_GL(ctx, X) (ctx).gl()->fFunctions.f ## X; \
+ SkASSERT(0 == (ctx).gl()->fFunctions.fGetError())
+#define SK_GL_RET(ctx, RET, X) (RET) = (ctx).gl()->fFunctions.f ## X; \
+ SkASSERT(0 == (ctx).gl()->fFunctions.fGetError())
+#define SK_GL_NOERRCHECK(ctx, X) (ctx).gl()->fFunctions.f ## X
+#define SK_GL_RET_NOERRCHECK(ctx, RET, X) (RET) = (ctx).gl()->fFunctions.f ## X
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/SkMesaGLContext.h b/src/third_party/skia/include/gpu/gl/SkMesaGLContext.h
new file mode 100644
index 0000000..28349dd
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/SkMesaGLContext.h
@@ -0,0 +1,51 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkMesaGLContext_DEFINED
+#define SkMesaGLContext_DEFINED
+
+#include "SkGLContextHelper.h"
+
+#if SK_MESA
+
+class SkMesaGLContext : public SkGLContextHelper {
+private:
+ typedef intptr_t Context;
+
+public:
+ SkMesaGLContext();
+
+ virtual ~SkMesaGLContext();
+
+ virtual void makeCurrent() const SK_OVERRIDE;
+ virtual void swapBuffers() const SK_OVERRIDE;
+
+ class AutoContextRestore {
+ public:
+ AutoContextRestore();
+ ~AutoContextRestore();
+
+ private:
+ Context fOldContext;
+ GrGLint fOldWidth;
+ GrGLint fOldHeight;
+ GrGLint fOldFormat;
+ void* fOldImage;
+ };
+
+protected:
+ virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
+ virtual void destroyGLContext() SK_OVERRIDE;
+
+private:
+ Context fContext;
+ GrGLubyte *fImage;
+};
+
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/SkNativeGLContext.h b/src/third_party/skia/include/gpu/gl/SkNativeGLContext.h
new file mode 100644
index 0000000..3bb6530
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/SkNativeGLContext.h
@@ -0,0 +1,111 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkNativeGLContext_DEFINED
+#define SkNativeGLContext_DEFINED
+
+#include "SkGLContextHelper.h"
+
+/* This struct is taken from a mesa demo. Please update as required */
+static const struct { int major, minor; } gl_versions[] = {
+ {1, 0},
+ {1, 1},
+ {1, 2},
+ {1, 3},
+ {1, 4},
+ {1, 5},
+ {2, 0},
+ {2, 1},
+ {3, 0},
+ {3, 1},
+ {3, 2},
+ {3, 3},
+ {4, 0},
+ {4, 1},
+ {4, 2},
+ {4, 3},
+ {4, 4},
+ {0, 0} /* end of list */
+};
+#define NUM_GL_VERSIONS SK_ARRAY_COUNT(gl_versions)
+
+#if defined(SK_BUILD_FOR_MAC)
+ #include <OpenGL/OpenGL.h>
+#elif defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_NACL)
+ #include <GLES2/gl2.h>
+ #include <EGL/egl.h>
+#elif defined(SK_BUILD_FOR_UNIX)
+ #include <X11/Xlib.h>
+ #include <GL/glx.h>
+#elif defined(SK_BUILD_FOR_WIN32)
+ #include <windows.h>
+ #include <GL/GL.h>
+ #include "SkWGL.h"
+#endif
+
+class SkNativeGLContext : public SkGLContextHelper {
+public:
+ SkNativeGLContext();
+
+ virtual ~SkNativeGLContext();
+
+ virtual void makeCurrent() const SK_OVERRIDE;
+ virtual void swapBuffers() const SK_OVERRIDE;
+
+ class AutoContextRestore {
+ public:
+ AutoContextRestore();
+ ~AutoContextRestore();
+
+ private:
+ #if defined(SK_BUILD_FOR_MAC)
+ CGLContextObj fOldCGLContext;
+ #elif defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_NACL)
+ EGLContext fOldEGLContext;
+ EGLDisplay fOldDisplay;
+ EGLSurface fOldSurface;
+ #elif defined(SK_BUILD_FOR_UNIX)
+ GLXContext fOldGLXContext;
+ Display* fOldDisplay;
+ GLXDrawable fOldDrawable;
+ #elif defined(SK_BUILD_FOR_WIN32)
+ HDC fOldHDC;
+ HGLRC fOldHGLRC;
+
+ #elif defined(SK_BUILD_FOR_IOS)
+ void* fEAGLContext;
+ #endif
+ };
+
+protected:
+ virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
+ virtual void destroyGLContext() SK_OVERRIDE;
+
+private:
+#if defined(SK_BUILD_FOR_MAC)
+ CGLContextObj fContext;
+#elif defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_NACL)
+ EGLContext fContext;
+ EGLDisplay fDisplay;
+ EGLSurface fSurface;
+#elif defined(SK_BUILD_FOR_UNIX)
+ GLXContext fContext;
+ Display* fDisplay;
+ Pixmap fPixmap;
+ GLXPixmap fGlxPixmap;
+#elif defined(SK_BUILD_FOR_WIN32)
+ HWND fWindow;
+ HDC fDeviceContext;
+ HGLRC fGlRenderContext;
+ static ATOM gWC;
+ SkWGLPbufferContext* fPbufferContext;
+#elif defined(SK_BUILD_FOR_IOS)
+ void* fEAGLContext;
+#endif
+};
+
+#endif
diff --git a/src/third_party/skia/include/gpu/gl/SkNullGLContext.h b/src/third_party/skia/include/gpu/gl/SkNullGLContext.h
new file mode 100644
index 0000000..6c2a1d7
--- /dev/null
+++ b/src/third_party/skia/include/gpu/gl/SkNullGLContext.h
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkNullGLContext_DEFINED
+#define SkNullGLContext_DEFINED
+
+#include "SkGLContextHelper.h"
+
+class SK_API SkNullGLContext : public SkGLContextHelper {
+
+public:
+ SkNullGLContext() {};
+
+ virtual void makeCurrent() const SK_OVERRIDE {};
+
+ virtual void swapBuffers() const SK_OVERRIDE {};
+
+protected:
+ virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
+
+ virtual void destroyGLContext() SK_OVERRIDE {};
+};
+
+#endif
diff --git a/src/third_party/skia/include/images/SkDecodingImageGenerator.h b/src/third_party/skia/include/images/SkDecodingImageGenerator.h
new file mode 100644
index 0000000..6cb39be
--- /dev/null
+++ b/src/third_party/skia/include/images/SkDecodingImageGenerator.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDecodingImageGenerator_DEFINED
+#define SkDecodingImageGenerator_DEFINED
+
+#include "SkBitmap.h"
+#include "SkImageGenerator.h"
+
+class SkData;
+class SkStreamRewindable;
+
+/**
+ * An implementation of SkImageGenerator that calls into
+ * SkImageDecoder.
+ */
+namespace SkDecodingImageGenerator {
+ /**
+ * These options will be passed on to the image decoder. The
+ * defaults are sensible.
+ *
+ * @param fSampleSize If set to > 1, tells the decoder to return a
+ * smaller than original bitmap, sampling 1 pixel for
+ * every size pixels. e.g. if sample size is set to 3,
+ * then the returned bitmap will be 1/3 as wide and high,
+ * and will contain 1/9 as many pixels as the original.
+ * Note: this is a hint, and the codec may choose to
+ * ignore this, or only approximate the sample size.
+ *
+ * @param fDitherImage Set to true if the the decoder should try to
+ * dither the resulting image when decoding to a smaller
+ * color-space. The default is true.
+ *
+ * @param fRequestedColorType If not given, then use whichever
+ * config the decoder wants. Else try to use this color
+ * type. If the decoder won't support this color type,
+ * SkDecodingImageGenerator::Create will return
+ * NULL. kIndex_8_SkColorType is not supported.
+ *
+ * @param fRequireUnpremul If true, the decoder will attempt to
+ * decode without premultiplying the alpha. If it cannot,
+ * the pixels will be set to NULL.
+ */
+ struct Options {
+ Options()
+ : fSampleSize(1)
+ , fDitherImage(true)
+ , fUseRequestedColorType(false)
+ , fRequestedColorType()
+ , fRequireUnpremul(false) { }
+ Options(int sampleSize, bool dither)
+ : fSampleSize(sampleSize)
+ , fDitherImage(dither)
+ , fUseRequestedColorType(false)
+ , fRequestedColorType()
+ , fRequireUnpremul(false) { }
+ Options(int sampleSize, bool dither, SkColorType colorType)
+ : fSampleSize(sampleSize)
+ , fDitherImage(dither)
+ , fUseRequestedColorType(true)
+ , fRequestedColorType(colorType)
+ , fRequireUnpremul(false) { }
+ Options(int sampleSize, bool dither, SkColorType colorType,
+ bool requireUnpremul)
+ : fSampleSize(sampleSize)
+ , fDitherImage(dither)
+ , fUseRequestedColorType(true)
+ , fRequestedColorType(colorType)
+ , fRequireUnpremul(requireUnpremul) { }
+ const int fSampleSize;
+ const bool fDitherImage;
+ const bool fUseRequestedColorType;
+ const SkColorType fRequestedColorType;
+ const bool fRequireUnpremul;
+ };
+
+ /**
+ * These two functions return a SkImageGenerator that calls into
+ * SkImageDecoder. They return NULL on failure.
+ *
+ * The SkData version of this function is preferred. If the stream
+ * has an underlying SkData (such as a SkMemoryStream) pass that in.
+ *
+ * This object will unref the stream when done or on failure. Since
+ * streams have internal state (position), the caller should not pass
+ * a shared stream in. Pass either a new duplicated stream in or
+ * transfer ownership of the stream. This factory asserts
+ * stream->unique().
+ *
+ * For example:
+ * SkStreamRewindable* stream;
+ * ...
+ * SkImageGenerator* gen
+ * = SkDecodingImageGenerator::Create(
+ * stream->duplicate(), SkDecodingImageGenerator::Options());
+ * ...
+ * SkDELETE(gen);
+ *
+ * @param Options (see above)
+ *
+ * @return NULL on failure, a new SkImageGenerator on success.
+ */
+ SkImageGenerator* Create(SkStreamRewindable* stream,
+ const Options& opt);
+
+ /**
+ * @param data Contains the encoded image data that will be used by
+ * the SkDecodingImageGenerator. Will be ref()ed by the
+ * SkImageGenerator constructor and and unref()ed on deletion.
+ */
+ SkImageGenerator* Create(SkData* data, const Options& opt);
+};
+
+// // Example of most basic use case:
+//
+// bool install_data(SkData* data, SkBitmap* dst) {
+// return SkInstallDiscardablePixelRef(
+// SkDecodingImageGenerator::Create(
+// data, SkDecodingImageGenerator::Options()), dst, NULL);
+// }
+// bool install_stream(SkStreamRewindable* stream, SkBitmap* dst) {
+// return SkInstallDiscardablePixelRef(
+// SkDecodingImageGenerator::Create(
+// stream, SkDecodingImageGenerator::Options()), dst, NULL);
+// }
+
+#endif // SkDecodingImageGenerator_DEFINED
diff --git a/src/third_party/skia/include/images/SkForceLinking.h b/src/third_party/skia/include/images/SkForceLinking.h
new file mode 100644
index 0000000..39901f6
--- /dev/null
+++ b/src/third_party/skia/include/images/SkForceLinking.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * This function's sole purpose is to trick the linker into not discarding
+ * SkImageDecoder subclasses just because we do not directly call them.
+ * This is necessary in applications that will create image decoders from
+ * a stream.
+ * Call this function with an expression that evaluates to false to ensure
+ * that the linker includes the subclasses.
+ * Passing true will result in leaked objects.
+ */
+int SkForceLinking(bool doNotPassTrue);
+
+#define __SK_FORCE_IMAGE_DECODER_LINKING \
+static int linking_forced = SkForceLinking(false)
diff --git a/src/third_party/skia/include/images/SkMovie.h b/src/third_party/skia/include/images/SkMovie.h
new file mode 100644
index 0000000..e52a3a8
--- /dev/null
+++ b/src/third_party/skia/include/images/SkMovie.h
@@ -0,0 +1,80 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkMovie_DEFINED
+#define SkMovie_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkCanvas.h"
+
+class SkStreamRewindable;
+
+class SkMovie : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkMovie)
+
+ /** Try to create a movie from the stream. If the stream format is not
+ supported, return NULL.
+ */
+ static SkMovie* DecodeStream(SkStreamRewindable*);
+ /** Try to create a movie from the specified file path. If the file is not
+ found, or the format is not supported, return NULL. If a movie is
+ returned, the stream may be retained by the movie (via ref()) until
+ the movie is finished with it (by calling unref()).
+ */
+ static SkMovie* DecodeFile(const char path[]);
+ /** Try to create a movie from the specified memory.
+ If the format is not supported, return NULL. If a movie is returned,
+ the data will have been read or copied, and so the caller may free
+ it.
+ */
+ static SkMovie* DecodeMemory(const void* data, size_t length);
+
+ SkMSec duration();
+ int width();
+ int height();
+ int isOpaque();
+
+ /** Specify the time code (between 0...duration) to sample a bitmap
+ from the movie. Returns true if this time code generated a different
+ bitmap/frame from the previous state (i.e. true means you need to
+ redraw).
+ */
+ bool setTime(SkMSec);
+
+ // return the right bitmap for the current time code
+ const SkBitmap& bitmap();
+
+protected:
+ struct Info {
+ SkMSec fDuration;
+ int fWidth;
+ int fHeight;
+ bool fIsOpaque;
+ };
+
+ virtual bool onGetInfo(Info*) = 0;
+ virtual bool onSetTime(SkMSec) = 0;
+ virtual bool onGetBitmap(SkBitmap*) = 0;
+
+ // visible for subclasses
+ SkMovie();
+
+private:
+ Info fInfo;
+ SkMSec fCurrTime;
+ SkBitmap fBitmap;
+ bool fNeedBitmap;
+
+ void ensureInfo();
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/images/SkPageFlipper.h b/src/third_party/skia/include/images/SkPageFlipper.h
new file mode 100644
index 0000000..7779c30
--- /dev/null
+++ b/src/third_party/skia/include/images/SkPageFlipper.h
@@ -0,0 +1,62 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPageFlipper_DEFINED
+#define SkPageFlipper_DEFINED
+
+#include "SkRegion.h"
+
+/** SkPageFlipper manages alternating inval/dirty regions for a rectangular area
+ (like a bitmap). You call inval() to accumulate inval areas, and then when
+ you're ready to "flip" pages (i.e. draw into the one you've been
+ invalidating) you call update, which swaps the inval regions, and returns
+ two things to you: 1) the final inval region to be drawn into, and 2) the
+ region of pixels that should be copied from the "front" page onto the one
+ you're about to draw into. This copyBits region will be disjoint from the
+ inval region, so both need to be handled.
+ */
+class SkPageFlipper {
+public:
+ SkPageFlipper();
+ SkPageFlipper(int width, int height);
+
+ int width() const { return fWidth; }
+ int height() const { return fHeight; }
+
+ void resize(int width, int height);
+
+ bool isDirty() const { return !fDirty1->isEmpty(); }
+ const SkRegion& dirtyRgn() const { return *fDirty1; }
+
+ void inval();
+ void inval(const SkIRect&);
+ void inval(const SkRegion&);
+ void inval(const SkRect&, bool antialias);
+
+ /** When you're ready to write to the back page, call update. The returned
+ region is the invalidate are that needs to be drawn to. The copyBits
+ region (provided by the caller) is the area that should be copied from
+ the front page to the back page (will not intersect with the returned
+ inval region.
+
+ Once this is called, the two internal regions are swapped, so the *new*
+ back inval region is ready to receive new inval calls.
+ */
+ const SkRegion& update(SkRegion* copyBits);
+
+private:
+ SkRegion* fDirty0;
+ SkRegion* fDirty1;
+ SkRegion fDirty0Storage;
+ SkRegion fDirty1Storage;
+ int fWidth;
+ int fHeight;
+};
+
+#endif
diff --git a/src/third_party/skia/include/pathops/SkPathOps.h b/src/third_party/skia/include/pathops/SkPathOps.h
new file mode 100644
index 0000000..ba18f4b
--- /dev/null
+++ b/src/third_party/skia/include/pathops/SkPathOps.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOps_DEFINED
+#define SkPathOps_DEFINED
+
+#include "SkPreConfig.h"
+
+class SkPath;
+struct SkRect;
+
+// FIXME: move everything below into the SkPath class
+/**
+ * The logical operations that can be performed when combining two paths.
+ */
+enum SkPathOp {
+ kDifference_PathOp, //!< subtract the op path from the first path
+ kIntersect_PathOp, //!< intersect the two paths
+ kUnion_PathOp, //!< union (inclusive-or) the two paths
+ kXOR_PathOp, //!< exclusive-or the two paths
+ kReverseDifference_PathOp, //!< subtract the first path from the op path
+};
+
+/** Set this path to the result of applying the Op to this path and the
+ specified path: this = (this op operand).
+ The resulting path will be constructed from non-overlapping contours.
+ The curve order is reduced where possible so that cubics may be turned
+ into quadratics, and quadratics maybe turned into lines.
+
+ Returns true if operation was able to produce a result;
+ otherwise, result is unmodified.
+
+ @param one The first operand (for difference, the minuend)
+ @param two The second operand (for difference, the subtrahend)
+ @param result The product of the operands. The result may be one of the
+ inputs.
+ @return True if operation succeeded.
+ */
+bool SK_API Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result);
+
+/** Set this path to a set of non-overlapping contours that describe the
+ same area as the original path.
+ The curve order is reduced where possible so that cubics may
+ be turned into quadratics, and quadratics maybe turned into lines.
+
+ Returns true if operation was able to produce a result;
+ otherwise, result is unmodified.
+
+ @param path The path to simplify.
+ @param result The simplified path. The result may be the input.
+ @return True if simplification succeeded.
+ */
+bool SK_API Simplify(const SkPath& path, SkPath* result);
+
+/** Set the resulting rectangle to the tight bounds of the path.
+
+ @param path The path measured.
+ @param result The tight bounds of the path.
+ @return True if the bounds could be computed.
+ */
+bool SK_API TightBounds(const SkPath& path, SkRect* result);
+
+#endif
diff --git a/src/third_party/skia/include/pdf/SkPDFDevice.h b/src/third_party/skia/include/pdf/SkPDFDevice.h
new file mode 100644
index 0000000..6f770af
--- /dev/null
+++ b/src/third_party/skia/include/pdf/SkPDFDevice.h
@@ -0,0 +1,341 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPDFDevice_DEFINED
+#define SkPDFDevice_DEFINED
+
+#include "SkDevice.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPicture.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkTDArray.h"
+#include "SkTemplates.h"
+
+class SkPDFArray;
+class SkPDFDevice;
+class SkPDFDict;
+class SkPDFFont;
+class SkPDFFormXObject;
+class SkPDFGlyphSetMap;
+class SkPDFGraphicState;
+class SkPDFObject;
+class SkPDFResourceDict;
+class SkPDFShader;
+class SkPDFStream;
+class SkRRect;
+template <typename T> class SkTSet;
+
+// Private classes.
+struct ContentEntry;
+struct GraphicStateEntry;
+struct NamedDestination;
+
+/** \class SkPDFDevice
+
+ The drawing context for the PDF backend.
+*/
+class SkPDFDevice : public SkBaseDevice {
+public:
+ /** Create a PDF drawing context with the given width and height.
+ * 72 points/in means letter paper is 612x792.
+ * @param pageSize Page size in points.
+ * @param contentSize The content size of the page in points. This will be
+ * combined with the initial transform to determine the drawing area
+ * (as reported by the width and height methods). Anything outside
+ * of the drawing area will be clipped.
+ * @param initialTransform The initial transform to apply to the page.
+ * This may be useful to, for example, move the origin in and
+ * over a bit to account for a margin, scale the canvas,
+ * or apply a rotation. Note1: the SkPDFDevice also applies
+ * a scale+translate transform to move the origin from the
+ * bottom left (PDF default) to the top left. Note2: drawDevice
+ * (used by layer restore) draws the device after this initial
+ * transform is applied, so the PDF device does an
+ * inverse scale+translate to accommodate the one that SkPDFDevice
+ * always does.
+ */
+ // Deprecated, please use SkDocument::CreatePdf() instead.
+ SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
+ const SkMatrix& initialTransform);
+ SK_API virtual ~SkPDFDevice();
+
+ virtual void clear(SkColor color) SK_OVERRIDE;
+
+ /** These are called inside the per-device-layer loop for each draw call.
+ When these are called, we have already applied any saveLayer operations,
+ and are handling any looping from the paint, and any effects from the
+ DrawFilter.
+ */
+ virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
+ size_t count, const SkPoint[],
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
+ virtual void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPath(const SkDraw&, const SkPath& origpath,
+ const SkPaint& paint, const SkMatrix* prePathMatrix,
+ bool pathIsMutable) SK_OVERRIDE;
+ virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
+ const SkRect* src, const SkRect& dst,
+ const SkPaint& paint,
+ SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE;
+ virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint&) SK_OVERRIDE;
+ virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
+ virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
+ virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
+ int vertexCount, const SkPoint verts[],
+ const SkPoint texs[], const SkColor colors[],
+ SkXfermode* xmode, const uint16_t indices[],
+ int indexCount, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+ const SkPaint&) SK_OVERRIDE;
+
+ virtual void onAttachToCanvas(SkCanvas* canvas) SK_OVERRIDE;
+ virtual void onDetachFromCanvas() SK_OVERRIDE;
+ virtual SkImageInfo imageInfo() const SK_OVERRIDE;
+
+ enum DrawingArea {
+ kContent_DrawingArea, // Drawing area for the page content.
+ kMargin_DrawingArea, // Drawing area for the margin content.
+ };
+
+ /** Sets the drawing area for the device. Subsequent draw calls are directed
+ * to the specific drawing area (margin or content). The default drawing
+ * area is the content drawing area.
+ *
+ * Currently if margin content is drawn and then a complex (for PDF) xfer
+ * mode is used, like SrcIn, Clear, etc, the margin content will get
+ * clipped. A simple way to avoid the bug is to always draw the margin
+ * content last.
+ */
+ SK_API void setDrawingArea(DrawingArea drawingArea);
+
+ /** Sets the DCTEncoder for images.
+ * @param encoder The encoder to encode a bitmap as JPEG (DCT).
+ * Result of encodings are cached, if the encoder changes the
+ * behaivor dynamically and an image is added to a second catalog,
+ * we will likely use the result of the first encoding call.
+ * By returning false from the encoder function, the encoder result
+ * is not used.
+ * Callers might not want to encode small images, as the time spent
+ * encoding and decoding might not be worth the space savings,
+ * if any at all.
+ */
+ void setDCTEncoder(SkPicture::EncodeBitmap encoder) {
+ fEncoder = encoder;
+ }
+
+ // PDF specific methods.
+
+ /** Returns the resource dictionary for this device.
+ */
+ SK_API SkPDFResourceDict* getResourceDict();
+
+ /** Get the fonts used on this device.
+ */
+ SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;
+
+ /** Add our named destinations to the supplied dictionary.
+ * @param dict Dictionary to add destinations to.
+ * @param page The PDF object representing the page for this device.
+ */
+ void appendDestinations(SkPDFDict* dict, SkPDFObject* page);
+
+ /** Returns a copy of the media box for this device. The caller is required
+ * to unref() this when it is finished.
+ */
+ SK_API SkPDFArray* copyMediaBox() const;
+
+ /** Get the annotations from this page, or NULL if there are none.
+ */
+ SK_API SkPDFArray* getAnnotations() const { return fAnnotations; }
+
+ /** Returns a SkStream with the page contents. The caller is responsible
+ for a reference to the returned value.
+ DEPRECATED: use copyContentToData()
+ */
+ SK_API SkStream* content() const;
+
+ /** Returns a SkStream with the page contents. The caller is responsible
+ * for calling data->unref() when it is finished.
+ */
+ SK_API SkData* copyContentToData() const;
+
+ SK_API const SkMatrix& initialTransform() const {
+ return fInitialTransform;
+ }
+
+ /** Returns a SkPDFGlyphSetMap which represents glyph usage of every font
+ * that shows on this device.
+ */
+ const SkPDFGlyphSetMap& getFontGlyphUsage() const {
+ return *(fFontGlyphUsage.get());
+ }
+
+
+ /**
+ * rasterDpi - the DPI at which features without native PDF support
+ * will be rasterized (e.g. draw image with perspective,
+ * draw text with perspective, ...)
+ * A larger DPI would create a PDF that reflects the original
+ * intent with better fidelity, but it can make for larger
+ * PDF files too, which would use more memory while rendering,
+ * and it would be slower to be processed or sent online or
+ * to printer.
+ */
+ void setRasterDpi(SkScalar rasterDpi) {
+ fRasterDpi = rasterDpi;
+ }
+
+protected:
+ virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
+ return fLegacyBitmap;
+ }
+
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
+
+private:
+ // TODO(vandebo): push most of SkPDFDevice's state into a core object in
+ // order to get the right access levels without using friend.
+ friend class ScopedContentEntry;
+
+ SkISize fPageSize;
+ SkISize fContentSize;
+ SkMatrix fInitialTransform;
+ SkClipStack fExistingClipStack;
+ SkRegion fExistingClipRegion;
+ SkPDFArray* fAnnotations;
+ SkPDFResourceDict* fResourceDict;
+ SkTDArray<NamedDestination*> fNamedDestinations;
+
+ SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
+ SkTDArray<SkPDFObject*> fXObjectResources;
+ SkTDArray<SkPDFFont*> fFontResources;
+ SkTDArray<SkPDFObject*> fShaderResources;
+
+ SkAutoTDelete<ContentEntry> fContentEntries;
+ ContentEntry* fLastContentEntry;
+ SkAutoTDelete<ContentEntry> fMarginContentEntries;
+ ContentEntry* fLastMarginContentEntry;
+ DrawingArea fDrawingArea;
+
+ const SkClipStack* fClipStack;
+
+ // Accessor and setter functions based on the current DrawingArea.
+ SkAutoTDelete<ContentEntry>* getContentEntries();
+ ContentEntry* getLastContentEntry();
+ void setLastContentEntry(ContentEntry* contentEntry);
+
+ // Glyph ids used for each font on this device.
+ SkAutoTDelete<SkPDFGlyphSetMap> fFontGlyphUsage;
+
+ SkPicture::EncodeBitmap fEncoder;
+ SkScalar fRasterDpi;
+
+ SkBitmap fLegacyBitmap;
+
+ SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
+ const SkRegion& existingClipRegion);
+
+ // override from SkBaseDevice
+ virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
+
+ void init();
+ void cleanUp(bool clearFontUsage);
+ SkPDFFormXObject* createFormXObjectFromDevice();
+
+ void drawFormXObjectWithMask(int xObjectIndex,
+ SkPDFFormXObject* mask,
+ const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ SkXfermode::Mode mode,
+ bool invertClip);
+
+ // If the paint or clip is such that we shouldn't draw anything, this
+ // returns NULL and does not create a content entry.
+ // setUpContentEntry and finishContentEntry can be used directly, but
+ // the preferred method is to use the ScopedContentEntry helper class.
+ ContentEntry* setUpContentEntry(const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ const SkMatrix& matrix,
+ const SkPaint& paint,
+ bool hasText,
+ SkPDFFormXObject** dst);
+ void finishContentEntry(SkXfermode::Mode xfermode,
+ SkPDFFormXObject* dst,
+ SkPath* shape);
+ bool isContentEmpty();
+
+ void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
+ const SkClipStack& clipStack,
+ const SkRegion& clipRegion,
+ const SkPaint& paint,
+ bool hasText,
+ GraphicStateEntry* entry);
+ int addGraphicStateResource(SkPDFGraphicState* gs);
+ int addXObjectResource(SkPDFObject* xObject);
+
+ void updateFont(const SkPaint& paint, uint16_t glyphID,
+ ContentEntry* contentEntry);
+ int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
+
+ void internalDrawPaint(const SkPaint& paint, ContentEntry* contentEntry);
+ void internalDrawBitmap(const SkMatrix& matrix,
+ const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ const SkBitmap& bitmap,
+ const SkIRect* srcRect,
+ const SkPaint& paint);
+
+ /** Helper method for copyContentToData. It is responsible for copying the
+ * list of content entries |entry| to |data|.
+ */
+ void copyContentEntriesToData(ContentEntry* entry, SkWStream* data) const;
+
+#ifdef SK_PDF_USE_PATHOPS
+ bool handleInversePath(const SkDraw& d, const SkPath& origPath,
+ const SkPaint& paint, bool pathIsMutable,
+ const SkMatrix* prePathMatrix = NULL);
+#endif
+ bool handleRectAnnotation(const SkRect& r, const SkMatrix& matrix,
+ const SkPaint& paint);
+ bool handlePointAnnotation(const SkPoint* points, size_t count,
+ const SkMatrix& matrix, const SkPaint& paint);
+ SkPDFDict* createLinkAnnotation(const SkRect& r, const SkMatrix& matrix);
+ void handleLinkToURL(SkData* urlData, const SkRect& r,
+ const SkMatrix& matrix);
+ void handleLinkToNamedDest(SkData* nameData, const SkRect& r,
+ const SkMatrix& matrix);
+ void defineNamedDestination(SkData* nameData, const SkPoint& point,
+ const SkMatrix& matrix);
+
+ typedef SkBaseDevice INHERITED;
+
+ // TODO(edisonn): Only SkDocument_PDF and SkPDFImageShader should be able to create
+ // an SkPDFDevice
+ //friend class SkDocument_PDF;
+ //friend class SkPDFImageShader;
+};
+
+#endif
diff --git a/src/third_party/skia/include/pdf/SkPDFDocument.h b/src/third_party/skia/include/pdf/SkPDFDocument.h
new file mode 100644
index 0000000..07738a2
--- /dev/null
+++ b/src/third_party/skia/include/pdf/SkPDFDocument.h
@@ -0,0 +1,113 @@
+
+/*
+ * Copyright 2010 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPDFDocument_DEFINED
+#define SkPDFDocument_DEFINED
+
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+#include "SkTemplates.h"
+
+class SkPDFCatalog;
+class SkPDFDevice;
+class SkPDFDict;
+class SkPDFPage;
+class SkPDFObject;
+class SkWStream;
+template <typename T> class SkTSet;
+
+/** \class SkPDFDocument
+
+ A SkPDFDocument assembles pages together and generates the final PDF file.
+*/
+class SkPDFDocument {
+public:
+ enum Flags {
+ kNoCompression_Flags = 0x01, //!< DEPRECATED.
+ kFavorSpeedOverSize_Flags = 0x01, //!< Don't compress the stream, but
+ // if it is already compressed return
+ // the compressed stream.
+ kNoLinks_Flags = 0x02, //!< do not honor link annotations.
+
+ kDraftMode_Flags = 0x01,
+ };
+ /** Create a PDF document.
+ */
+ explicit SK_API SkPDFDocument(Flags flags = (Flags)0);
+ SK_API ~SkPDFDocument();
+
+ /** Output the PDF to the passed stream. It is an error to call this (it
+ * will return false and not modify stream) if no pages have been added
+ * or there are pages missing (i.e. page 1 and 3 have been added, but not
+ * page 2).
+ *
+ * @param stream The writable output stream to send the PDF to.
+ */
+ SK_API bool emitPDF(SkWStream* stream);
+
+ /** Sets the specific page to the passed PDF device. If the specified
+ * page is already set, this overrides it. Returns true if successful.
+ * Will fail if the document has already been emitted.
+ *
+ * @param pageNumber The position to add the passed device (1 based).
+ * @param pdfDevice The page to add to this document.
+ */
+ SK_API bool setPage(int pageNumber, SkPDFDevice* pdfDevice);
+
+ /** Append the passed pdf device to the document as a new page. Returns
+ * true if successful. Will fail if the document has already been emitted.
+ *
+ * @param pdfDevice The page to add to this document.
+ */
+ SK_API bool appendPage(SkPDFDevice* pdfDevice);
+
+ /** Get the count of unique font types used in the document.
+ * DEPRECATED.
+ */
+ SK_API void getCountOfFontTypes(
+ int counts[SkAdvancedTypefaceMetrics::kOther_Font + 2]) const;
+
+ /** Get the count of unique font types used in the document.
+ */
+ SK_API void getCountOfFontTypes(
+ int counts[SkAdvancedTypefaceMetrics::kOther_Font + 1],
+ int* notSubsettableCount,
+ int* notEmbedddableCount) const;
+
+private:
+ SkAutoTDelete<SkPDFCatalog> fCatalog;
+ int64_t fXRefFileOffset;
+
+ SkTDArray<SkPDFPage*> fPages;
+ SkTDArray<SkPDFDict*> fPageTree;
+ SkPDFDict* fDocCatalog;
+ SkTSet<SkPDFObject*>* fFirstPageResources;
+ SkTSet<SkPDFObject*>* fOtherPageResources;
+ SkTDArray<SkPDFObject*> fSubstitutes;
+
+ SkPDFDict* fTrailerDict;
+
+ /** Output the PDF header to the passed stream.
+ * @param stream The writable output stream to send the header to.
+ */
+ void emitHeader(SkWStream* stream);
+
+ /** Get the size of the header.
+ */
+ size_t headerSize();
+
+ /** Output the PDF footer to the passed stream.
+ * @param stream The writable output stream to send the footer to.
+ * @param objCount The number of objects in the PDF.
+ */
+ void emitFooter(SkWStream* stream, int64_t objCount);
+};
+
+#endif
diff --git a/src/third_party/skia/include/pipe/SkGPipe.h b/src/third_party/skia/include/pipe/SkGPipe.h
new file mode 100644
index 0000000..98e081d
--- /dev/null
+++ b/src/third_party/skia/include/pipe/SkGPipe.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef SkGPipe_DEFINED
+#define SkGPipe_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkPicture.h"
+#include "SkWriter32.h"
+
+class SkCanvas;
+
+// XLib.h might have defined Status already (ugh)
+#ifdef Status
+ #undef Status
+#endif
+
+class SkGPipeReader {
+public:
+ SkGPipeReader();
+ SkGPipeReader(SkCanvas* target);
+ ~SkGPipeReader();
+
+ enum Status {
+ kDone_Status, //!< no more data expected from reader
+ kEOF_Status, //!< need more data from reader
+ kError_Status, //!< encountered error
+ kReadAtom_Status//!< finished reading an atom
+ };
+
+ enum PlaybackFlags {
+ kReadAtom_PlaybackFlag = 0x1, //!< playback a single command from the stream
+ kSilent_PlaybackFlag = 0x2, //!< playback without drawing
+ };
+
+ void setCanvas(SkCanvas*);
+
+ /**
+ * Set a function for decoding bitmaps that have encoded data.
+ */
+ void setBitmapDecoder(SkPicture::InstallPixelRefProc proc) { fProc = proc; }
+
+ // data must be 4-byte aligned
+ // length must be a multiple of 4
+ Status playback(const void* data, size_t length, uint32_t playbackFlags = 0,
+ size_t* bytesRead = NULL);
+private:
+ SkCanvas* fCanvas;
+ class SkGPipeState* fState;
+ SkPicture::InstallPixelRefProc fProc;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkGPipeCanvas;
+
+class SkGPipeController {
+public:
+ SkGPipeController() : fCanvas(NULL) {}
+ virtual ~SkGPipeController();
+
+ /**
+ * Called periodically by the writer, to get a working buffer of RAM to
+ * write into. The actual size of the block is also returned, and must be
+ * actual >= minRequest. If NULL is returned, then actual is ignored and
+ * writing will stop.
+ *
+ * The returned block must be 4-byte aligned, and actual must be a
+ * multiple of 4.
+ * minRequest will always be a multiple of 4.
+ */
+ virtual void* requestBlock(size_t minRequest, size_t* actual) = 0;
+
+ /**
+ * This is called each time some atomic portion of the data has been
+ * written to the block (most recently returned by requestBlock()).
+ * If bytes == 0, then the writer has finished.
+ *
+ * bytes will always be a multiple of 4.
+ */
+ virtual void notifyWritten(size_t bytes) = 0;
+ virtual int numberOfReaders() const { return 1; }
+
+private:
+ friend class SkGPipeWriter;
+ void setCanvas(SkGPipeCanvas*);
+
+ SkGPipeCanvas* fCanvas;
+};
+
+class SkGPipeWriter {
+public:
+ SkGPipeWriter();
+ ~SkGPipeWriter();
+
+ bool isRecording() const { return SkToBool(fCanvas); }
+
+ enum Flags {
+ /**
+ * Tells the writer that the reader will be in a different process, so
+ * (for example) we cannot put function pointers in the stream.
+ */
+ kCrossProcess_Flag = 1 << 0,
+
+ /**
+ * Only meaningful if kCrossProcess_Flag is set. Tells the writer that
+ * in spite of being cross process, it will have shared address space
+ * with the reader, so the two can share large objects (like SkBitmaps).
+ */
+ kSharedAddressSpace_Flag = 1 << 1,
+
+ /**
+ * Tells the writer that there will be multiple threads reading the stream
+ * simultaneously.
+ */
+ kSimultaneousReaders_Flag = 1 << 2,
+ };
+
+ SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0,
+ uint32_t width = kDefaultRecordingCanvasSize,
+ uint32_t height = kDefaultRecordingCanvasSize);
+
+ // called in destructor, but can be called sooner once you know there
+ // should be no more drawing calls made into the recording canvas.
+ void endRecording();
+
+ /**
+ * Tells the writer to commit all recorded draw commands to the
+ * controller immediately.
+ * @param detachCurrentBlock Set to true to request that the next draw
+ * command be recorded in a new block.
+ */
+ void flushRecording(bool detachCurrentBlock);
+
+ /**
+ * Return the amount of bytes being used for recording. Note that this
+ * does not include the amount of storage written to the stream, which is
+ * controlled by the SkGPipeController.
+ * Currently only returns the amount used for SkBitmaps, since they are
+ * potentially unbounded (if the client is not calling playback).
+ */
+ size_t storageAllocatedForRecording() const;
+
+ /**
+ * Attempt to reduce the storage allocated for recording by evicting
+ * cache resources.
+ * @param bytesToFree minimum number of bytes that should be attempted to
+ * be freed.
+ * @return number of bytes actually freed.
+ */
+ size_t freeMemoryIfPossible(size_t bytesToFree);
+
+private:
+ enum {
+ kDefaultRecordingCanvasSize = 32767,
+ };
+
+ SkGPipeCanvas* fCanvas;
+ SkWriter32 fWriter;
+};
+
+#endif
diff --git a/src/third_party/skia/include/ports/SkFontConfigInterface.h b/src/third_party/skia/include/ports/SkFontConfigInterface.h
new file mode 100644
index 0000000..c596267
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkFontConfigInterface.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontConfigInterface_DEFINED
+#define SkFontConfigInterface_DEFINED
+
+#include "SkDataTable.h"
+#include "SkFontStyle.h"
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+#include "SkTypeface.h"
+
+struct SkBaseMutex;
+
+/**
+ * \class SkFontConfigInterface
+ *
+ * Provides SkFontHost clients with access to fontconfig services. They will
+ * access the global instance found in RefGlobal().
+ */
+class SK_API SkFontConfigInterface : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkFontConfigInterface)
+
+ /**
+ * Returns the global SkFontConfigInterface instance, and if it is not
+ * NULL, calls ref() on it. The caller must balance this with a call to
+ * unref().
+ */
+ static SkFontConfigInterface* RefGlobal();
+
+ /**
+ * Replace the current global instance with the specified one, safely
+ * ref'ing the new instance, and unref'ing the previous. Returns its
+ * parameter (the new global instance).
+ */
+ static SkFontConfigInterface* SetGlobal(SkFontConfigInterface*);
+
+ /**
+ * This should be treated as private to the impl of SkFontConfigInterface.
+ * Callers should not change or expect any particular values. It is meant
+ * to be a union of possible storage types to aid the impl.
+ */
+ struct FontIdentity {
+ FontIdentity() : fID(0), fTTCIndex(0) {}
+
+ bool operator==(const FontIdentity& other) const {
+ return fID == other.fID &&
+ fTTCIndex == other.fTTCIndex &&
+ fString == other.fString;
+ }
+ bool operator!=(const FontIdentity& other) const {
+ return !(*this == other);
+ }
+
+ uint32_t fID;
+ int32_t fTTCIndex;
+ SkString fString;
+ SkFontStyle fStyle;
+
+ // If buffer is NULL, just return the number of bytes that would have
+ // been written. Will pad contents to a multiple of 4.
+ size_t writeToMemory(void* buffer = NULL) const;
+
+ // Recreate from a flattened buffer, returning the number of bytes read.
+ size_t readFromMemory(const void* buffer, size_t length);
+ };
+
+ /**
+ * Given a familyName and style, find the best match.
+ *
+ * If a match is found, return true and set its outFontIdentifier.
+ * If outFamilyName is not null, assign the found familyName to it
+ * (which may differ from the requested familyName).
+ * If outStyle is not null, assign the found style to it
+ * (which may differ from the requested style).
+ *
+ * If a match is not found, return false, and ignore all out parameters.
+ */
+ virtual bool matchFamilyName(const char familyName[],
+ SkTypeface::Style requested,
+ FontIdentity* outFontIdentifier,
+ SkString* outFamilyName,
+ SkTypeface::Style* outStyle) = 0;
+
+ /**
+ * Given a FontRef, open a stream to access its data, or return null
+ * if the FontRef's data is not available. The caller is responsible for
+ * calling stream->unref() when it is done accessing the data.
+ */
+ virtual SkStream* openStream(const FontIdentity&) = 0;
+
+ /**
+ * Return a singleton instance of a direct subclass that calls into
+ * libfontconfig. This does not affect the refcnt of the returned instance.
+ * The mutex may be used to guarantee the singleton is only constructed once.
+ */
+ static SkFontConfigInterface* GetSingletonDirectInterface
+ (SkBaseMutex* mutex = NULL);
+
+ // New APIS, which have default impls for now (which do nothing)
+
+ virtual SkDataTable* getFamilyNames() { return SkDataTable::NewEmpty(); }
+ virtual bool matchFamilySet(const char inFamilyName[],
+ SkString* outFamilyName,
+ SkTArray<FontIdentity>*) {
+ return false;
+ }
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/ports/SkFontMgr.h b/src/third_party/skia/include/ports/SkFontMgr.h
new file mode 100644
index 0000000..0ffcc27
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkFontMgr.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontMgr_DEFINED
+#define SkFontMgr_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkFontStyle.h"
+
+class SkData;
+class SkStream;
+class SkString;
+class SkTypeface;
+
+class SK_API SkFontStyleSet : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkFontStyleSet)
+
+ virtual int count() = 0;
+ virtual void getStyle(int index, SkFontStyle*, SkString* style) = 0;
+ virtual SkTypeface* createTypeface(int index) = 0;
+ virtual SkTypeface* matchStyle(const SkFontStyle& pattern) = 0;
+
+ static SkFontStyleSet* CreateEmpty();
+
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+class SkTypeface;
+
+class SK_API SkFontMgr : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkFontMgr)
+
+ int countFamilies() const;
+ void getFamilyName(int index, SkString* familyName) const;
+ SkFontStyleSet* createStyleSet(int index) const;
+
+ /**
+ * The caller must call unref() on the returned object.
+ * Never returns NULL; will return an empty set if the name is not found.
+ *
+ * It is possible that this will return a style set not accessible from
+ * createStyleSet(int) due to hidden or auto-activated fonts.
+ */
+ SkFontStyleSet* matchFamily(const char familyName[]) const;
+
+ /**
+ * Find the closest matching typeface to the specified familyName and style
+ * and return a ref to it. The caller must call unref() on the returned
+ * object. Will never return NULL, as it will return the default font if
+ * no matching font is found.
+ *
+ * It is possible that this will return a style set not accessible from
+ * createStyleSet(int) or matchFamily(const char[]) due to hidden or
+ * auto-activated fonts.
+ */
+ SkTypeface* matchFamilyStyle(const char familyName[], const SkFontStyle&) const;
+
+ /**
+ * Use the system fallback to find a typeface for the given character.
+ * Note that bcp47 is a combination of ISO 639, 15924, and 3166-1 codes,
+ * so it is fine to just pass a ISO 639 here.
+ *
+ * Will return NULL if no family can be found for the character
+ * in the system fallback.
+ *
+ * bcp47[0] is the least significant fallback, bcp47[bcp47Count-1] is the
+ * most significant. If no specified bcp47 codes match, any font with the
+ * requested character will be matched.
+ */
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+ SkTypeface* matchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+ const char* bcp47[], int bcp47Count,
+ SkUnichar character) const;
+#else
+ SkTypeface* matchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+ const char bcp47[], SkUnichar character) const;
+#endif
+
+ SkTypeface* matchFaceStyle(const SkTypeface*, const SkFontStyle&) const;
+
+ /**
+ * Create a typeface for the specified data and TTC index (pass 0 for none)
+ * or NULL if the data is not recognized. The caller must call unref() on
+ * the returned object if it is not null.
+ */
+ SkTypeface* createFromData(SkData*, int ttcIndex = 0) const;
+
+ /**
+ * Create a typeface for the specified stream and TTC index
+ * (pass 0 for none) or NULL if the stream is not recognized. The caller
+ * must call unref() on the returned object if it is not null.
+ */
+ SkTypeface* createFromStream(SkStream*, int ttcIndex = 0) const;
+
+ /**
+ * Create a typeface for the specified fileName and TTC index
+ * (pass 0 for none) or NULL if the file is not found, or its contents are
+ * not recognized. The caller must call unref() on the returned object
+ * if it is not null.
+ */
+ SkTypeface* createFromFile(const char path[], int ttcIndex = 0) const;
+
+ SkTypeface* legacyCreateTypeface(const char familyName[],
+ unsigned typefaceStyleBits) const;
+
+ /**
+ * Return a ref to the default fontmgr. The caller must call unref() on
+ * the returned object.
+ */
+ static SkFontMgr* RefDefault();
+
+protected:
+ virtual int onCountFamilies() const = 0;
+ virtual void onGetFamilyName(int index, SkString* familyName) const = 0;
+ virtual SkFontStyleSet* onCreateStyleSet(int index)const = 0;
+
+ /** May return NULL if the name is not found. */
+ virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const = 0;
+
+ virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
+ const SkFontStyle&) const = 0;
+ // TODO: pure virtual, implement on all impls.
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+ virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+ const char* bcp47[], int bcp47Count,
+ SkUnichar character) const
+#else
+ virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+ const char bcp47[], SkUnichar character) const
+#endif
+ { return NULL; }
+ virtual SkTypeface* onMatchFaceStyle(const SkTypeface*,
+ const SkFontStyle&) const = 0;
+
+ virtual SkTypeface* onCreateFromData(SkData*, int ttcIndex) const = 0;
+ virtual SkTypeface* onCreateFromStream(SkStream*, int ttcIndex) const = 0;
+ virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const = 0;
+
+ virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits) const = 0;
+private:
+ static SkFontMgr* Factory(); // implemented by porting layer
+ static SkFontMgr* CreateDefault();
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/ports/SkFontMgr_indirect.h b/src/third_party/skia/include/ports/SkFontMgr_indirect.h
new file mode 100644
index 0000000..95a2355
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkFontMgr_indirect.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontMgr_indirect_DEFINED
+#define SkFontMgr_indirect_DEFINED
+
+#include "SkDataTable.h"
+#include "SkFontMgr.h"
+#include "SkFontStyle.h"
+#include "SkRemotableFontMgr.h"
+#include "SkTArray.h"
+#include "SkTypeface.h"
+
+class SkData;
+class SkStream;
+class SkString;
+class SkTypeface;
+
+class SK_API SkFontMgr_Indirect : public SkFontMgr {
+public:
+ // TODO: The SkFontMgr is only used for createFromStream/File/Data.
+ // In the future these calls should be broken out into their own interface
+ // with a name like SkFontRenderer.
+ SkFontMgr_Indirect(SkFontMgr* impl, SkRemotableFontMgr* proxy)
+ : fImpl(SkRef(impl)), fProxy(SkRef(proxy)), fFamilyNamesInited(false)
+ { }
+
+protected:
+ virtual int onCountFamilies() const SK_OVERRIDE;
+ virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE;
+ virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE;
+
+ virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE;
+
+ virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
+ const SkFontStyle& fontStyle) const SK_OVERRIDE;
+
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+ virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle&,
+ const char* bcp47[],
+ int bcp47Count,
+ SkUnichar character) const SK_OVERRIDE;
+#else
+ virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle&,
+ const char bcp47[],
+ SkUnichar character) const SK_OVERRIDE;
+#endif
+
+ virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
+ const SkFontStyle& fontStyle) const SK_OVERRIDE;
+
+ virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE;
+ virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE;
+ virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE;
+
+ virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits) const SK_OVERRIDE;
+
+private:
+ SkTypeface* createTypefaceFromFontId(const SkFontIdentity& fontId) const;
+
+ SkAutoTUnref<SkFontMgr> fImpl;
+ SkAutoTUnref<SkRemotableFontMgr> fProxy;
+
+ struct DataEntry {
+ uint32_t fDataId; // key1
+ uint32_t fTtcIndex; // key2
+ SkTypeface* fTypeface; // value: weak ref to typeface
+
+ DataEntry() { }
+
+ // This is a move!!!
+ DataEntry(DataEntry& that)
+ : fDataId(that.fDataId)
+ , fTtcIndex(that.fTtcIndex)
+ , fTypeface(that.fTypeface)
+ {
+ SkDEBUGCODE(that.fDataId = SkFontIdentity::kInvalidDataId;)
+ SkDEBUGCODE(that.fTtcIndex = 0xbbadbeef;)
+ that.fTypeface = NULL;
+ }
+
+ ~DataEntry() {
+ if (fTypeface) {
+ fTypeface->weak_unref();
+ }
+ }
+ };
+ /**
+ * This cache is essentially { dataId: { ttcIndex: typeface } }
+ * For data caching we want a mapping from data id to weak references to
+ * typefaces with that data id. By storing the index next to the typeface,
+ * this data cache also acts as a typeface cache.
+ */
+ mutable SkTArray<DataEntry> fDataCache;
+ mutable SkMutex fDataCacheMutex;
+
+ mutable SkAutoTUnref<SkDataTable> fFamilyNames;
+ mutable bool fFamilyNamesInited;
+ mutable SkMutex fFamilyNamesMutex;
+ static void set_up_family_names(const SkFontMgr_Indirect* self);
+
+ friend class SkStyleSet_Indirect;
+};
+
+#endif
diff --git a/src/third_party/skia/include/ports/SkFontStyle.h b/src/third_party/skia/include/ports/SkFontStyle.h
new file mode 100644
index 0000000..9d9a912
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkFontStyle.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontStyle_DEFINED
+#define SkFontStyle_DEFINED
+
+#include "SkTypes.h"
+
+class SK_API SkFontStyle {
+public:
+ enum Weight {
+ kThin_Weight = 100,
+ kExtraLight_Weight = 200,
+ kLight_Weight = 300,
+ kNormal_Weight = 400,
+ kMedium_Weight = 500,
+ kSemiBold_Weight = 600,
+ kBold_Weight = 700,
+ kExtraBold_Weight = 800,
+ kBlack_Weight = 900
+ };
+
+ enum Width {
+ kUltraCondensed_Width = 1,
+ kExtraCondensed_Width = 2,
+ kCondensed_Width = 3,
+ kSemiCondensed_Width = 4,
+ kNormal_Width = 5,
+ kSemiExpanded_Width = 6,
+ kExpanded_Width = 7,
+ kExtraExpanded_Width = 8,
+ kUltaExpanded_Width = 9
+ };
+
+ enum Slant {
+ kUpright_Slant,
+ kItalic_Slant,
+ };
+
+ SkFontStyle();
+ SkFontStyle(int weight, int width, Slant);
+
+ bool operator==(const SkFontStyle& rhs) const {
+ return fUnion.fU32 == rhs.fUnion.fU32;
+ }
+
+ int weight() const { return fUnion.fR.fWeight; }
+ int width() const { return fUnion.fR.fWidth; }
+ Slant slant() const { return (Slant)fUnion.fR.fSlant; }
+
+ bool isItalic() const {
+ return kItalic_Slant == fUnion.fR.fSlant;
+ }
+
+private:
+ union {
+ struct {
+ uint16_t fWeight; // 100 .. 900
+ uint8_t fWidth; // 1 .. 9
+ uint8_t fSlant; // 0 .. 2
+ } fR;
+ uint32_t fU32;
+ } fUnion;
+};
+
+#endif
diff --git a/src/third_party/skia/include/ports/SkRemotableFontMgr.h b/src/third_party/skia/include/ports/SkRemotableFontMgr.h
new file mode 100644
index 0000000..1ff96a3
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkRemotableFontMgr.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRemotableFontMgr_DEFINED
+#define SkRemotableFontMgr_DEFINED
+
+#include "SkFontStyle.h"
+#include "SkRefCnt.h"
+#include "SkTemplates.h"
+
+class SkDataTable;
+class SkStreamAsset;
+class SkString;
+
+struct SK_API SkFontIdentity {
+ static const uint32_t kInvalidDataId = 0xFFFFFFFF;
+
+ // Note that fDataId is a data identifier, not a font identifier.
+ // (fDataID, fTtcIndex) can be seen as a font identifier.
+ uint32_t fDataId;
+ uint32_t fTtcIndex;
+
+ // On Linux/FontConfig there is also the ability to specify preferences for rendering
+ // antialias, embedded bitmaps, autohint, hinting, hintstyle, lcd rendering
+ // may all be set or set to no-preference
+ // (No-preference is resolved against globals set by the platform)
+ // Since they may be selected against, these are really 'extensions' to SkFontStyle.
+ // SkFontStyle should pick these up.
+ SkFontStyle fFontStyle;
+};
+
+class SK_API SkRemotableFontIdentitySet : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkRemotableFontIdentitySet)
+
+ SkRemotableFontIdentitySet(int count, SkFontIdentity** data);
+
+ int count() const { return fCount; }
+ const SkFontIdentity& at(int index) const { return fData[index]; }
+
+ static SkRemotableFontIdentitySet* NewEmpty();
+
+private:
+ SkRemotableFontIdentitySet() : fCount(0), fData() { }
+ static SkRemotableFontIdentitySet* NewEmptyImpl();
+
+ int fCount;
+ SkAutoTMalloc<SkFontIdentity> fData;
+
+ typedef SkRefCnt INHERITED;
+};
+
+class SK_API SkRemotableFontMgr : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkRemotableFontMgr)
+
+ /**
+ * Returns the names of the known fonts on the system.
+ * Will not return NULL, will return an empty table if no families exist.
+ *
+ * The indexes may be used with getIndex(int) and
+ * matchIndexStyle(int, SkFontStyle).
+ *
+ * The caller must unref() the returned object.
+ */
+ virtual SkDataTable* getFamilyNames() const = 0;
+
+ /**
+ * Returns all of the fonts with the given familyIndex.
+ * Returns NULL if the index is out of bounds.
+ * Returns empty if there are no fonts at the given index.
+ *
+ * The caller must unref() the returned object.
+ */
+ virtual SkRemotableFontIdentitySet* getIndex(int familyIndex) const = 0;
+
+ /**
+ * Returns the closest match to the given style in the given index.
+ * If there are no available fonts at the given index, the return value's
+ * data id will be kInvalidDataId.
+ */
+ virtual SkFontIdentity matchIndexStyle(int familyIndex, const SkFontStyle&) const = 0;
+
+ /**
+ * Returns all the fonts on the system with the given name.
+ * If the given name is NULL, will return the default font family.
+ * Never returns NULL; will return an empty set if the name is not found.
+ *
+ * It is possible that this will return fonts not accessible from
+ * getIndex(int) or matchIndexStyle(int, SkFontStyle) due to
+ * hidden or auto-activated fonts.
+ *
+ * The matching may be done in a system dependent way. The name may be
+ * matched case-insensitive, there may be system aliases which resolve,
+ * and names outside the current locale may be considered. However, this
+ * should only return fonts which are somehow associated with the requested
+ * name.
+ *
+ * The caller must unref() the returned object.
+ */
+ virtual SkRemotableFontIdentitySet* matchName(const char familyName[]) const = 0;
+
+ /**
+ * Returns the closest matching font to the specified name and style.
+ * If there are no available fonts which match the name, the return value's
+ * data id will be kInvalidDataId.
+ * If the given name is NULL, the match will be against any default fonts.
+ *
+ * It is possible that this will return a font identity not accessible from
+ * methods returning sets due to hidden or auto-activated fonts.
+ *
+ * The matching may be done in a system dependent way. The name may be
+ * matched case-insensitive, there may be system aliases which resolve,
+ * and names outside the current locale may be considered. However, this
+ * should only return a font which is somehow associated with the requested
+ * name.
+ *
+ * The caller must unref() the returned object.
+ */
+ virtual SkFontIdentity matchNameStyle(const char familyName[], const SkFontStyle&) const = 0;
+
+ /**
+ * Use the system fall-back to find a font for the given character.
+ * If no font can be found for the character, the return value's data id
+ * will be kInvalidDataId.
+ * If the name is NULL, the match will start against any default fonts.
+ * If the bpc47 is NULL, a default locale will be assumed.
+ *
+ * Note that bpc47 is a combination of ISO 639, 15924, and 3166-1 codes,
+ * so it is fine to just pass a ISO 639 here.
+ */
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+ virtual SkFontIdentity matchNameStyleCharacter(const char familyName[], const SkFontStyle&,
+ const char* bcp47[], int bcp47Count,
+ SkUnichar character) const=0;
+#else
+ virtual SkFontIdentity matchNameStyleCharacter(const char familyName[], const SkFontStyle&,
+ const char bcp47[], SkUnichar character) const=0;
+#endif
+
+ /**
+ * Returns the data for the given data id.
+ * Will return NULL if the data id is invalid.
+ * Note that this is a data id, not a font id.
+ *
+ * The caller must unref() the returned object.
+ */
+ virtual SkStreamAsset* getData(int dataId) const = 0;
+
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/ports/SkTypeface_android.h b/src/third_party/skia/include/ports/SkTypeface_android.h
new file mode 100644
index 0000000..588f56d
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkTypeface_android.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTypeface_android_DEFINED
+#define SkTypeface_android_DEFINED
+
+#include "SkTypeface.h"
+
+#ifdef SK_BUILD_FOR_ANDROID
+
+/**
+ * For test only.
+ * Load font config from given xml files, instead of those from Android system.
+ */
+SK_API void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf,
+ const char* fontsdir);
+
+/**
+ * For test only.
+ * Returns the information set by SkUseTestFontConfigFile.
+ * TODO: this should be removed once SkFontConfigInterface_android is removed,
+ * and then Chromium should be given a better way to set up it's test environment
+ * than SkUseTestFontConfigFile.
+ */
+void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf,
+ const char** fontsdir);
+
+#endif // #ifdef SK_BUILD_FOR_ANDROID
+#endif // #ifndef SkTypeface_android_DEFINED
diff --git a/src/third_party/skia/include/ports/SkTypeface_mac.h b/src/third_party/skia/include/ports/SkTypeface_mac.h
new file mode 100644
index 0000000..0166ee5
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkTypeface_mac.h
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef SkTypeface_mac_DEFINED
+#define SkTypeface_mac_DEFINED
+
+#include "SkTypeface.h"
+#ifdef SK_BUILD_FOR_MAC
+#import <ApplicationServices/ApplicationServices.h>
+#endif
+
+#ifdef SK_BUILD_FOR_IOS
+#include <CoreText/CoreText.h>
+#endif
+/**
+ * Like the other Typeface create methods, this returns a new reference to the
+ * corresponding typeface for the specified CTFontRef. The caller must call
+ * unref() when it is finished.
+ */
+SK_API extern SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef);
+
+#endif
diff --git a/src/third_party/skia/include/ports/SkTypeface_win.h b/src/third_party/skia/include/ports/SkTypeface_win.h
new file mode 100644
index 0000000..07752d8
--- /dev/null
+++ b/src/third_party/skia/include/ports/SkTypeface_win.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTypeface_win_DEFINED
+#define SkTypeface_win_DEFINED
+
+#include "SkTypeface.h"
+
+/**
+ * Like the other Typeface create methods, this returns a new reference to the
+ * corresponding typeface for the specified logfont. The caller is responsible
+ * for calling unref() when it is finished.
+ */
+SK_API SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&);
+
+/**
+ * Copy the LOGFONT associated with this typeface into the lf parameter. Note
+ * that the lfHeight will need to be set afterwards, since the typeface does
+ * not track this (the paint does).
+ * typeface may be NULL, in which case we return the logfont for the default font.
+ */
+SK_API void SkLOGFONTFromTypeface(const SkTypeface* typeface, LOGFONT* lf);
+
+/**
+ * Set an optional callback to ensure that the data behind a LOGFONT is loaded.
+ * This will get called if Skia tries to access the data but hits a failure.
+ * Normally this is null, and is only required if the font data needs to be
+ * remotely (re)loaded.
+ */
+SK_API void SkTypeface_SetEnsureLOGFONTAccessibleProc(void (*)(const LOGFONT&));
+
+// Experimental!
+//
+class SkFontMgr;
+class SkRemotableFontMgr;
+struct IDWriteFactory;
+
+SK_API SkFontMgr* SkFontMgr_New_GDI();
+SK_API SkFontMgr* SkFontMgr_New_DirectWrite(IDWriteFactory* factory = NULL);
+
+/**
+ * Creates an SkFontMgr which renders using DirectWrite and obtains its data
+ * from the SkRemotableFontMgr.
+ *
+ * If DirectWrite could not be initialized, will return NULL.
+ */
+SK_API SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr*);
+
+/**
+ * Creates an SkRemotableFontMgr backed by DirectWrite using the default
+ * system font collection in the current locale.
+ *
+ * If DirectWrite could not be initialized, will return NULL.
+ */
+SK_API SkRemotableFontMgr* SkRemotableFontMgr_New_DirectWrite();
+
+#endif
diff --git a/src/third_party/skia/include/record/SkRecording.h b/src/third_party/skia/include/record/SkRecording.h
new file mode 100644
index 0000000..a4e8809
--- /dev/null
+++ b/src/third_party/skia/include/record/SkRecording.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRecording_DEFINED
+#define SkRecording_DEFINED
+
+#include "SkCanvas.h" // SkCanvas
+#include "SkRefCnt.h" // SkAutoTUnref
+#include "SkTemplates.h" // SkAutoTDelete
+#include "SkTypes.h" // SkNoncopyable
+
+// These are intentionally left opaque.
+class SkRecord;
+class SkRecorder;
+
+namespace EXPERIMENTAL {
+
+/** Easy mode interface to SkRecord-based SkCanvas recording.
+ *
+ * scoped_ptr<SkRecording> recording(new SkRecording(1920, 1080));
+ * skia::RefPtr<SkCanvas> canvas(skia::SharePtr(recording->canvas()));
+ *
+ * canvas->drawThis();
+ * canvas->clipThat();
+ * ...
+ *
+ * canvas.clear(); // You must deref the canvas before you may call releasePlayback().
+ * scoped_ptr<const SkPlayback> playback(recording->releasePlayback());
+ * playback->draw(&someCanvas);
+ * playback->draw(&someOtherCanvas);
+ *
+ * SkPlayback is thread safe; SkRecording is not.
+ */
+
+class SK_API SkPlayback : SkNoncopyable {
+public:
+ // Remember, if you've got an SkPlayback*, you probably own it. Don't forget to delete it!
+ ~SkPlayback();
+
+ // Draw recorded commands into a canvas.
+ void draw(SkCanvas*) const;
+
+private:
+ explicit SkPlayback(const SkRecord*);
+
+ SkAutoTDelete<const SkRecord> fRecord;
+
+ friend class SkRecording;
+};
+
+class SK_API SkRecording : SkNoncopyable {
+public:
+ SkRecording(int width, int height);
+ ~SkRecording();
+
+ // Draws issued to this canvas will be replayed by SkPlayback::draw().
+ // Any refs held on canvas() must be dropped before you may call releasePlayback().
+ SkCanvas* canvas();
+
+ // Release exclusive ownership of an SkPlayback to the caller.
+ // Any refs held on canvas() must be dropped before you may call releasePlayback().
+ SkPlayback* releasePlayback();
+
+private:
+ SkAutoTDelete<SkRecord> fRecord;
+ SkAutoTUnref<SkRecorder> fRecorder;
+};
+
+} // namespace EXPERIMENTAL
+
+#endif//SkRecording_DEFINED
diff --git a/src/third_party/skia/include/svg/SkSVGAttribute.h b/src/third_party/skia/include/svg/SkSVGAttribute.h
new file mode 100644
index 0000000..940ca5a
--- /dev/null
+++ b/src/third_party/skia/include/svg/SkSVGAttribute.h
@@ -0,0 +1,42 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkSVGAttribute_DEFINED
+#define SkSVGAttribute_DEFINED
+
+#include "SkTypes.h"
+
+struct SkSVGAttribute {
+ const char* fName;
+#ifdef SK_DEBUG
+ size_t fOffset;
+#endif
+};
+
+#ifndef SK_OFFSETOF
+#define SK_OFFSETOF(a, b) (((size_t) (&(((a*) 1)->b)))-1)
+#endif
+
+#ifdef SK_DEBUG
+#define SVG_ATTRIBUTE(attr) { #attr, SK_OFFSETOF(BASE_CLASS, f_##attr) }
+#define SVG_LITERAL_ATTRIBUTE(svgAttr, cAttr) { #svgAttr, SK_OFFSETOF(BASE_CLASS, cAttr) }
+#else
+#define SVG_ATTRIBUTE(attr) { #attr }
+#define SVG_LITERAL_ATTRIBUTE(svgAttr, cAttr) { #svgAttr }
+#endif
+
+#define SVG_ADD_ATTRIBUTE(attr) \
+ if (f_##attr.size() > 0) \
+ parser._addAttributeLen(#attr, f_##attr.c_str(), f_##attr.size())
+
+#define SVG_ADD_ATTRIBUTE_ALIAS(attr, alias) \
+ if (f_##alias.size() > 0) \
+ parser._addAttributeLen(#attr, f_##alias.c_str(), f_##alias.size())
+
+#endif // SkSVGAttribute_DEFINED
diff --git a/src/third_party/skia/include/svg/SkSVGBase.h b/src/third_party/skia/include/svg/SkSVGBase.h
new file mode 100644
index 0000000..6bfc39d
--- /dev/null
+++ b/src/third_party/skia/include/svg/SkSVGBase.h
@@ -0,0 +1,25 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkSVGBase_DEFINED
+#define SkSVGBase_DEFINED
+
+#include "SkSVGAttribute.h"
+
+class SkSVGParser;
+
+class SkSVGBase {
+public:
+ virtual ~SkSVGBase();
+ virtual void addAttribute(SkSVGParser& parser, int attrIndex,
+ const char* attrValue, size_t attrLength);
+ virtual int getAttributes(const SkSVGAttribute** attrPtr) = 0;
+};
+
+#endif // SkSVGBase_DEFINEDes(const SkSVGAttribute** attrPtr) = 0;
diff --git a/src/third_party/skia/include/svg/SkSVGPaintState.h b/src/third_party/skia/include/svg/SkSVGPaintState.h
new file mode 100644
index 0000000..211e9cf
--- /dev/null
+++ b/src/third_party/skia/include/svg/SkSVGPaintState.h
@@ -0,0 +1,89 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkSVGPaintState_DEFINED
+#define SkSVGPaintState_DEFINED
+
+#include "SkSVGBase.h"
+#include "SkString.h"
+
+class SkSVGPaint : public SkSVGBase {
+public:
+ enum Field {
+ kInitial = -1,
+ kClipPath,
+ kClipRule,
+ kEnableBackground,
+ kFill,
+ kFillRule,
+ kFilter,
+ kFontFamily,
+ kFontSize,
+ kLetterSpacing,
+ kMask,
+ kOpacity,
+ kStopColor,
+ kStopOpacity,
+ kStroke,
+ kStroke_Dasharray,
+ kStroke_Linecap,
+ kStroke_Linejoin,
+ kStroke_Miterlimit,
+ kStroke_Width,
+ kStyle,
+ kTransform,
+ kTerminal
+ };
+
+ SkSVGPaint();
+ virtual void addAttribute(SkSVGParser& parser, int attrIndex,
+ const char* attrValue, size_t attrLength);
+ bool flush(SkSVGParser& , bool isFlushable, bool isDef);
+ virtual int getAttributes(const SkSVGAttribute** attrPtr);
+ static void Push(SkSVGPaint** head, SkSVGPaint* add);
+ static void Pop(SkSVGPaint** head);
+ SkString* operator[](int index);
+ SkString fInitial;
+ SkString f_clipPath;
+ SkString f_clipRule;
+ SkString f_enableBackground;
+ SkString f_fill;
+ SkString f_fillRule;
+ SkString f_filter;
+ SkString f_fontFamily;
+ SkString f_fontSize;
+ SkString f_letterSpacing;
+ SkString f_mask;
+ SkString f_opacity;
+ SkString f_stopColor;
+ SkString f_stopOpacity;
+ SkString f_stroke;
+ SkString f_strokeDasharray;
+ SkString f_strokeLinecap;
+ SkString f_strokeLinejoin;
+ SkString f_strokeMiterlimit;
+ SkString f_strokeWidth;
+ SkString f_style; // unused, but allows array access to the rest
+ SkString f_transform;
+#ifdef SK_DEBUG
+ SkString fTerminal;
+#endif
+ SkString fTransformID;
+ static SkSVGAttribute gAttributes[];
+ static const int kAttributesSize;
+private:
+ void setSave(SkSVGParser& );
+ bool writeChangedAttributes(SkSVGParser& , SkSVGPaint& , bool* changed);
+ bool writeChangedElements(SkSVGParser& , SkSVGPaint& , bool* changed);
+ SkSVGPaint* fNext;
+ friend class SkSVGParser;
+ typedef SkSVGPaint BASE_CLASS;
+};
+
+#endif // SkSVGPaintState_DEFINED
diff --git a/src/third_party/skia/include/svg/SkSVGParser.h b/src/third_party/skia/include/svg/SkSVGParser.h
new file mode 100644
index 0000000..c2f9112
--- /dev/null
+++ b/src/third_party/skia/include/svg/SkSVGParser.h
@@ -0,0 +1,74 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkSVGParser_DEFINED
+#define SkSVGParser_DEFINED
+
+#include "SkMatrix.h"
+#include "SkTDict.h"
+#include "SkTDStack.h"
+#include "SkSVGPaintState.h"
+#include "SkSVGTypes.h"
+#include "SkStream.h"
+#include "SkString.h"
+#include "SkXMLParser.h"
+#include "SkXMLWriter.h"
+
+class SkSVGBase;
+class SkSVGElement;
+
+class SkSVGParser : public SkXMLParser {
+public:
+ SkSVGParser(SkXMLParserError* err = NULL);
+ virtual ~SkSVGParser();
+ void _addAttribute(const char* attrName, const char* attrValue) {
+ fXMLWriter.addAttribute(attrName, attrValue); }
+ void _addAttribute(const char* attrName, SkString& attrValue) {
+ fXMLWriter.addAttribute(attrName, attrValue.c_str()); }
+ void _addAttributeLen(const char* attrName, const char* attrValue, size_t len) {
+ fXMLWriter.addAttributeLen(attrName, attrValue, len); }
+ void _endElement() { fXMLWriter.endElement(); }
+ int findAttribute(SkSVGBase* , const char* attrValue, size_t len, bool isPaint);
+// const char* getFinal();
+ SkTDict<SkSVGElement*>& getIDs() { return fIDs; }
+ SkString& getPaintLast(SkSVGPaint::Field field);
+ void _startElement(const char name[]) { fXMLWriter.startElement(name); }
+ void translate(SkSVGElement*, bool isDef);
+ void translateMatrix(SkString& , SkString* id);
+ static void ConvertToArray(SkString& vals);
+protected:
+ virtual bool onAddAttribute(const char name[], const char value[]);
+ bool onAddAttributeLen(const char name[], const char value[], size_t len);
+ virtual bool onEndElement(const char elem[]);
+ virtual bool onStartElement(const char elem[]);
+ bool onStartElementLen(const char elem[], size_t len);
+ virtual bool onText(const char text[], int len);
+private:
+ bool isStrokeAndFill(SkSVGPaint** stroke, SkSVGPaint** fill);
+ static SkSVGElement* CreateElement(SkSVGTypes type, SkSVGElement* parent);
+ static void Delete(SkTDArray<SkSVGElement*>& fChildren);
+ static SkSVGTypes GetType(const char name[], size_t len);
+ SkSVGPaint* fHead;
+ SkSVGPaint fEmptyPaint;
+ SkSVGPaint fLastFlush;
+ SkString fLastColor;
+ SkMatrix fLastTransform;
+ SkTDArray<SkSVGElement*> fChildren;
+ SkTDict<SkSVGElement*> fIDs;
+ SkTDArray<SkSVGElement*> fParents;
+ SkDynamicMemoryWStream fStream;
+ SkXMLStreamWriter fXMLWriter;
+ SkSVGElement* fCurrElement;
+ SkBool8 fInSVG;
+ SkBool8 fSuppressPaint;
+ friend class SkSVGPaint;
+ friend class SkSVGGradient;
+};
+
+#endif // SkSVGParser_DEFINED
diff --git a/src/third_party/skia/include/svg/SkSVGTypes.h b/src/third_party/skia/include/svg/SkSVGTypes.h
new file mode 100644
index 0000000..b13bc6e
--- /dev/null
+++ b/src/third_party/skia/include/svg/SkSVGTypes.h
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkSVGTypes_DEFINED
+#define SkSVGTypes_DEFINED
+
+enum SkSVGTypes {
+ SkSVGType_Circle,
+ SkSVGType_ClipPath,
+ SkSVGType_Defs,
+ SkSVGType_Ellipse,
+ SkSVGType_FeColorMatrix,
+ SkSVGType_Filter,
+ SkSVGType_G,
+ SkSVGType_Image,
+ SkSVGType_Line,
+ SkSVGType_LinearGradient,
+ SkSVGType_Mask,
+ SkSVGType_Metadata,
+ SkSVGType_Path,
+ SkSVGType_Polygon,
+ SkSVGType_Polyline,
+ SkSVGType_RadialGradient,
+ SkSVGType_Rect,
+ SkSVGType_SVG,
+ SkSVGType_Stop,
+ SkSVGType_Symbol,
+ SkSVGType_Text,
+ SkSVGType_Tspan,
+ SkSVGType_Unknown,
+ SkSVGType_Use
+};
+
+#endif // SkSVGTypes_DEFINED
diff --git a/src/third_party/skia/include/utils/SkBoundaryPatch.h b/src/third_party/skia/include/utils/SkBoundaryPatch.h
new file mode 100644
index 0000000..cf001d5
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkBoundaryPatch.h
@@ -0,0 +1,66 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkBoundaryPatch_DEFINED
+#define SkBoundaryPatch_DEFINED
+
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+
+class SkBoundary : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkBoundary)
+
+ // These must be 0, 1, 2, 3 for efficiency in the subclass implementations
+ enum Edge {
+ kTop = 0,
+ kRight = 1,
+ kBottom = 2,
+ kLeft = 3
+ };
+ // Edge index goes clockwise around the boundary, beginning at the "top"
+ virtual SkPoint eval(Edge, SkScalar unitInterval) = 0;
+
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+class SkBoundaryPatch {
+public:
+ SkBoundaryPatch();
+ ~SkBoundaryPatch();
+
+ SkBoundary* getBoundary() const { return fBoundary; }
+ SkBoundary* setBoundary(SkBoundary*);
+
+ SkPoint eval(SkScalar unitU, SkScalar unitV);
+ bool evalPatch(SkPoint verts[], int rows, int cols);
+
+private:
+ SkBoundary* fBoundary;
+};
+
+////////////////////////////////////////////////////////////////////////
+
+class SkLineBoundary : public SkBoundary {
+public:
+ SkPoint fPts[4];
+
+ // override
+ virtual SkPoint eval(Edge, SkScalar);
+};
+
+class SkCubicBoundary : public SkBoundary {
+public:
+ // the caller sets the first 12 entries. The 13th is used by the impl.
+ SkPoint fPts[13];
+
+ // override
+ virtual SkPoint eval(Edge, SkScalar);
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkCamera.h b/src/third_party/skia/include/utils/SkCamera.h
new file mode 100644
index 0000000..b515be9
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkCamera.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// Inspired by Rob Johnson's most excellent QuickDraw GX sample code
+
+#ifndef SkCamera_DEFINED
+#define SkCamera_DEFINED
+
+#include "SkMatrix.h"
+
+class SkCanvas;
+
+struct SkUnit3D {
+ SkScalar fX, fY, fZ;
+
+ void set(SkScalar x, SkScalar y, SkScalar z) {
+ fX = x; fY = y; fZ = z;
+ }
+ static SkScalar Dot(const SkUnit3D&, const SkUnit3D&);
+ static void Cross(const SkUnit3D&, const SkUnit3D&, SkUnit3D* cross);
+};
+
+struct SkPoint3D {
+ SkScalar fX, fY, fZ;
+
+ void set(SkScalar x, SkScalar y, SkScalar z) {
+ fX = x; fY = y; fZ = z;
+ }
+ SkScalar normalize(SkUnit3D*) const;
+};
+typedef SkPoint3D SkVector3D;
+
+struct SkMatrix3D {
+ SkScalar fMat[3][4];
+
+ void reset();
+
+ void setRow(int row, SkScalar a, SkScalar b, SkScalar c, SkScalar d = 0) {
+ SkASSERT((unsigned)row < 3);
+ fMat[row][0] = a;
+ fMat[row][1] = b;
+ fMat[row][2] = c;
+ fMat[row][3] = d;
+ }
+
+ void setRotateX(SkScalar deg);
+ void setRotateY(SkScalar deg);
+ void setRotateZ(SkScalar deg);
+ void setTranslate(SkScalar x, SkScalar y, SkScalar z);
+
+ void preRotateX(SkScalar deg);
+ void preRotateY(SkScalar deg);
+ void preRotateZ(SkScalar deg);
+ void preTranslate(SkScalar x, SkScalar y, SkScalar z);
+
+ void setConcat(const SkMatrix3D& a, const SkMatrix3D& b);
+ void mapPoint(const SkPoint3D& src, SkPoint3D* dst) const;
+ void mapVector(const SkVector3D& src, SkVector3D* dst) const;
+
+ void mapPoint(SkPoint3D* v) const {
+ this->mapPoint(*v, v);
+ }
+
+ void mapVector(SkVector3D* v) const {
+ this->mapVector(*v, v);
+ }
+};
+
+class SkPatch3D {
+public:
+ SkPatch3D();
+
+ void reset();
+ void transform(const SkMatrix3D&, SkPatch3D* dst = NULL) const;
+
+ // dot a unit vector with the patch's normal
+ SkScalar dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const;
+ SkScalar dotWith(const SkVector3D& v) const {
+ return this->dotWith(v.fX, v.fY, v.fZ);
+ }
+
+ // deprecated, but still here for animator (for now)
+ void rotate(SkScalar x, SkScalar y, SkScalar z) {}
+ void rotateDegrees(SkScalar x, SkScalar y, SkScalar z) {}
+
+private:
+public: // make public for SkDraw3D for now
+ SkVector3D fU, fV;
+ SkPoint3D fOrigin;
+
+ friend class SkCamera3D;
+};
+
+class SkCamera3D {
+public:
+ SkCamera3D();
+
+ void reset();
+ void update();
+ void patchToMatrix(const SkPatch3D&, SkMatrix* matrix) const;
+
+ SkPoint3D fLocation;
+ SkPoint3D fAxis;
+ SkPoint3D fZenith;
+ SkPoint3D fObserver;
+
+private:
+ mutable SkMatrix fOrientation;
+ mutable bool fNeedToUpdate;
+
+ void doUpdate() const;
+};
+
+class Sk3DView : SkNoncopyable {
+public:
+ Sk3DView();
+ ~Sk3DView();
+
+ void save();
+ void restore();
+
+ void translate(SkScalar x, SkScalar y, SkScalar z);
+ void rotateX(SkScalar deg);
+ void rotateY(SkScalar deg);
+ void rotateZ(SkScalar deg);
+
+#ifdef SK_BUILD_FOR_ANDROID
+ void setCameraLocation(SkScalar x, SkScalar y, SkScalar z);
+ SkScalar getCameraLocationX();
+ SkScalar getCameraLocationY();
+ SkScalar getCameraLocationZ();
+#endif
+
+ void getMatrix(SkMatrix*) const;
+ void applyToCanvas(SkCanvas*) const;
+
+ SkScalar dotWithNormal(SkScalar dx, SkScalar dy, SkScalar dz) const;
+
+private:
+ struct Rec {
+ Rec* fNext;
+ SkMatrix3D fMatrix;
+ };
+ Rec* fRec;
+ Rec fInitialRec;
+ SkCamera3D fCamera;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkCanvasStateUtils.h b/src/third_party/skia/include/utils/SkCanvasStateUtils.h
new file mode 100644
index 0000000..6ea7b10
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkCanvasStateUtils.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkCanvasStateUtils_DEFINED
+#define SkCanvasStateUtils_DEFINED
+
+#include "SkCanvas.h"
+
+class SkCanvasState;
+
+/**
+ * A set of functions that are useful for copying the state of an SkCanvas
+ * across a library boundary where the Skia library on the other side of the
+ * boundary may be newer. The expected usage is outline below...
+ *
+ * Lib Boundary
+ * CaptureCanvasState(...) |||
+ * SkCanvas --> SkCanvasState |||
+ * ||| CreateFromCanvasState(...)
+ * ||| SkCanvasState --> SkCanvas`
+ * ||| Draw into SkCanvas`
+ * ||| Unref SkCanvas`
+ * ReleaseCanvasState(...) |||
+ *
+ */
+namespace SkCanvasStateUtils {
+ /**
+ * Captures the current state of the canvas into an opaque ptr that is safe
+ * to pass to a different instance of Skia (which may be the same version,
+ * or may be newer). The function will return NULL in the event that one of the
+ * following conditions are true.
+ * 1) the canvas device type is not supported (currently only raster is supported)
+ * 2) the canvas clip type is not supported (currently only non-AA clips are supported)
+ *
+ * It is recommended that the original canvas also not be used until all
+ * canvases that have been created using its captured state have been dereferenced.
+ *
+ * Finally, it is important to note that any draw filters attached to the
+ * canvas are NOT currently captured.
+ *
+ * @param canvas The canvas you wish to capture the current state of.
+ * @return NULL or an opaque ptr that can be passed to CreateFromCanvasState
+ * to reconstruct the canvas. The caller is responsible for calling
+ * ReleaseCanvasState to free the memory associated with this state.
+ */
+ SK_API SkCanvasState* CaptureCanvasState(SkCanvas* canvas);
+
+ /**
+ * Create a new SkCanvas from the captured state of another SkCanvas. The
+ * function will return NULL in the event that one of the
+ * following conditions are true.
+ * 1) the captured state is in an unrecognized format
+ * 2) the captured canvas device type is not supported
+ *
+ * @param state Opaque object created by CaptureCanvasState.
+ * @return NULL or an SkCanvas* whose devices and matrix/clip state are
+ * identical to the captured canvas. The caller is responsible for
+ * calling unref on the SkCanvas.
+ */
+ SK_API SkCanvas* CreateFromCanvasState(const SkCanvasState* state);
+
+ /**
+ * Free the memory associated with the captured canvas state. The state
+ * should not be released until all SkCanvas objects created using that
+ * state have been dereferenced. Must be called from the same library
+ * instance that created the state via CaptureCanvasState.
+ *
+ * @param state The captured state you wish to dispose of.
+ */
+ SK_API void ReleaseCanvasState(SkCanvasState* state);
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkCubicInterval.h b/src/third_party/skia/include/utils/SkCubicInterval.h
new file mode 100644
index 0000000..64d63cf
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkCubicInterval.h
@@ -0,0 +1,22 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#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/src/third_party/skia/include/utils/SkCullPoints.h b/src/third_party/skia/include/utils/SkCullPoints.h
new file mode 100644
index 0000000..fafa0fc
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkCullPoints.h
@@ -0,0 +1,71 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkCullPoints_DEFINED
+#define SkCullPoints_DEFINED
+
+#include "SkRect.h"
+
+class SkCullPoints {
+public:
+ SkCullPoints();
+ SkCullPoints(const SkIRect& r);
+
+ void reset(const SkIRect& r);
+
+ /** Start a contour at (x,y). Follow this with call(s) to lineTo(...)
+ */
+ void moveTo(int x, int y);
+
+ enum LineToResult {
+ kNo_Result, //!< line segment was completely clipped out
+ kLineTo_Result, //!< path.lineTo(pts[1]);
+ kMoveToLineTo_Result //!< path.moveTo(pts[0]); path.lineTo(pts[1]);
+ };
+ /** Connect a line to the previous call to lineTo (or moveTo).
+ */
+ LineToResult lineTo(int x, int y, SkIPoint pts[2]);
+
+private:
+ SkIRect fR; // the caller's rectangle
+ SkIPoint fAsQuad[4]; // cache of fR as 4 points
+ SkIPoint fPrevPt; // private state
+ LineToResult fPrevResult; // private state
+
+ bool sect_test(int x0, int y0, int x1, int y1) const;
+};
+
+/////////////////////////////////////////////////////////////////////////////////
+
+class SkPath;
+
+/** \class SkCullPointsPath
+
+ Similar to SkCullPoints, but this class handles the return values
+ from lineTo, and automatically builds a SkPath with the result(s).
+*/
+class SkCullPointsPath {
+public:
+ SkCullPointsPath();
+ SkCullPointsPath(const SkIRect& r, SkPath* dst);
+
+ void reset(const SkIRect& r, SkPath* dst);
+
+ void moveTo(int x, int y);
+ void lineTo(int x, int y);
+
+private:
+ SkCullPoints fCP;
+ SkPath* fPath;
+};
+
+bool SkHitTestPath(const SkPath&, SkRect& target, bool hires);
+bool SkHitTestPath(const SkPath&, SkScalar x, SkScalar y, bool hires);
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkDebugUtils.h b/src/third_party/skia/include/utils/SkDebugUtils.h
new file mode 100644
index 0000000..2fa6d41
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkDebugUtils.h
@@ -0,0 +1,94 @@
+
+/*
+ * Copyright 2013 Google, Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkDebugUtils_DEFINED
+#define SkDebugUtils_DEFINED
+
+#include "SkTypes.h"
+
+// These functions dump 0, 1, and 2d arrays of data in a format that's
+// compatible with Mathematica for quick visualization
+
+
+template<class T>
+inline void SkDebugDumpMathematica( const T val ) {
+ SkDEBUGFAIL("Need to specialize SkDebugDumpMathematica for your type, sorry.");
+}
+
+template<class T>
+inline void SkDebugDumpMathematica(const char *name, const T *array, int size) {
+ SkDebugf(name);
+ SkDebugf(" = {");
+ for (int i=0 ; i < size ; i++) {
+ SkDebugDumpMathematica<T>(array[i]);
+ if (i != size-1) SkDebugf(", ");
+ }
+ SkDebugf("};\n");
+}
+
+template<class T>
+inline void SkDebugDumpMathematica(const char *name, const T *array, int width, int height) {
+ SkDebugf(name);
+ SkDebugf(" = {\n");
+ for (int i=0 ; i < height ; i++) {
+ SkDebugf(" {");
+ for (int j = 0 ; j < width ; j++) {
+ SkDebugDumpMathematica<T>(array[i*width + j]);
+ if (j != width-1) {
+ SkDebugf(", ");
+ }
+ }
+ SkDebugf("}");
+ if (i != height-1) {
+ SkDebugf(", \n");
+ }
+ }
+ SkDebugf("\n};\n");
+}
+
+template<class T>
+inline void SkDebugDumpMathematica( const char *name, const T val ) {
+ SkDebugf(name);
+ SkDebugf(" = ");
+ SkDebugDumpMathematica<T>(val);
+ SkDebugf(";\n");
+}
+
+template<>
+inline void SkDebugDumpMathematica<uint8_t>( const uint8_t val ) {
+ SkDebugf("%u", val);
+}
+
+template<>
+inline void SkDebugDumpMathematica<unsigned int>( const unsigned int val ) {
+ SkDebugf("%u", val);
+}
+
+template<>
+inline void SkDebugDumpMathematica<int>( const int val ) {
+ SkDebugf("%d", val);
+}
+
+template<>
+inline void SkDebugDumpMathematica<size_t>( const size_t val ) {
+ SkDebugf("%u", val);
+}
+
+template<>
+void SkDebugDumpMathematica<const char *>( const char * val ) {
+ SkDebugf("%s", val);
+}
+
+template<>
+inline void SkDebugDumpMathematica<float>( float val ) {
+ SkDebugf("%f", val);
+}
+
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkDeferredCanvas.h b/src/third_party/skia/include/utils/SkDeferredCanvas.h
new file mode 100644
index 0000000..5f781f8
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkDeferredCanvas.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDeferredCanvas_DEFINED
+#define SkDeferredCanvas_DEFINED
+
+#include "SkCanvas.h"
+#include "SkPixelRef.h"
+
+class SkDeferredDevice;
+class SkImage;
+class SkSurface;
+
+/** \class SkDeferredCanvas
+ Subclass of SkCanvas that encapsulates an SkPicture or SkGPipe for deferred
+ drawing. The main difference between this class and SkPictureRecord (the
+ canvas provided by SkPicture) is that this is a full drop-in replacement
+ for SkCanvas, while SkPictureRecord only supports draw operations.
+ SkDeferredCanvas will transparently trigger the flushing of deferred
+ draw operations when an attempt is made to access the pixel data.
+*/
+class SK_API SkDeferredCanvas : public SkCanvas {
+public:
+ class SK_API NotificationClient;
+
+ /** Construct a canvas with the specified surface to draw into.
+ This factory must be used for newImageSnapshot to work.
+ @param surface Specifies a surface for the canvas to draw into.
+ */
+ static SkDeferredCanvas* Create(SkSurface* surface);
+
+// static SkDeferredCanvas* Create(SkBaseDevice* device);
+
+ virtual ~SkDeferredCanvas();
+
+ /**
+ * Specify the surface to be used by this canvas. Calling setSurface will
+ * release the previously set surface or device. Takes a reference on the
+ * surface.
+ *
+ * @param surface The surface that the canvas will raw into
+ * @return The surface argument, for convenience.
+ */
+ SkSurface* setSurface(SkSurface* surface);
+
+ /**
+ * Specify a NotificationClient to be used by this canvas. Calling
+ * setNotificationClient will release the previously set
+ * NotificationClient, if any. SkDeferredCanvas does not take ownership
+ * of the notification client. Therefore user code is resposible
+ * for its destruction. The notification client must be unregistered
+ * by calling setNotificationClient(NULL) if it is destroyed before
+ * this canvas.
+ * Note: Must be called after the device is set with setDevice.
+ *
+ * @param notificationClient interface for dispatching notifications
+ * @return The notificationClient argument, for convenience.
+ */
+ NotificationClient* setNotificationClient(NotificationClient* notificationClient);
+
+ /**
+ * Enable or disable deferred drawing. When deferral is disabled,
+ * pending draw operations are immediately flushed and from then on,
+ * the SkDeferredCanvas behaves just like a regular SkCanvas.
+ * This method must not be called while the save/restore stack is in use.
+ * @param deferred true/false
+ */
+ void setDeferredDrawing(bool deferred);
+
+ /**
+ * Returns true if deferred drawing is currenlty enabled.
+ */
+ bool isDeferredDrawing() const;
+
+ /**
+ * Returns true if the canvas contains a fresh frame. A frame is
+ * considered fresh when its content do not depend on the contents
+ * of the previous frame. For example, if a canvas is cleared before
+ * drawing each frame, the frames will all be considered fresh.
+ * A frame is defined as the graphics image produced by as a result
+ * of all the canvas draws operation executed between two successive
+ * calls to isFreshFrame. The result of isFreshFrame is computed
+ * conservatively, so it may report false negatives.
+ */
+ bool isFreshFrame() const;
+
+ /**
+ * Returns canvas's size.
+ */
+ SkISize getCanvasSize() const;
+
+ /**
+ * Returns true if the canvas has recorded draw commands that have
+ * not yet been played back.
+ */
+ bool hasPendingCommands() const;
+
+ /**
+ * Flushes pending draw commands, if any, and returns an image of the
+ * current state of the surface pixels up to this point. Subsequent
+ * changes to the surface (by drawing into its canvas) will not be
+ * reflected in this image. Will return NULL if the deferred canvas
+ * was not constructed from an SkSurface.
+ */
+ SkImage* newImageSnapshot();
+
+ /**
+ * Specify the maximum number of bytes to be allocated for the purpose
+ * of recording draw commands to this canvas. The default limit, is
+ * 64MB.
+ * @param maxStorage The maximum number of bytes to be allocated.
+ */
+ void setMaxRecordingStorage(size_t maxStorage);
+
+ /**
+ * Returns the number of bytes currently allocated for the purpose of
+ * recording draw commands.
+ */
+ size_t storageAllocatedForRecording() const;
+
+ /**
+ * Attempt to reduce the storage allocated for recording by evicting
+ * cache resources.
+ * @param bytesToFree minimum number of bytes that should be attempted to
+ * be freed.
+ * @return number of bytes actually freed.
+ */
+ size_t freeMemoryIfPossible(size_t bytesToFree);
+
+ /**
+ * Specifies the maximum size (in bytes) allowed for a given image to be
+ * rendered using the deferred canvas.
+ */
+ void setBitmapSizeThreshold(size_t sizeThreshold);
+ size_t getBitmapSizeThreshold() const { return fBitmapSizeThreshold; }
+
+ /**
+ * Executes all pending commands without drawing
+ */
+ void silentFlush();
+
+ // Overrides of the SkCanvas interface
+ virtual bool isDrawingToLayer() const SK_OVERRIDE;
+ virtual void clear(SkColor) SK_OVERRIDE;
+ virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPath(const SkPath& path, const SkPaint& paint)
+ SK_OVERRIDE;
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
+ SkScalar top, const SkPaint* paint)
+ SK_OVERRIDE;
+ virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
+ const SkRect& dst, const SkPaint* paint,
+ DrawBitmapRectFlags flags) SK_OVERRIDE;
+
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint* paint)
+ SK_OVERRIDE;
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawVertices(VertexMode vmode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
+
+protected:
+ virtual void willSave() SK_OVERRIDE;
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
+ virtual void willRestore() SK_OVERRIDE;
+
+ virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
+ virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
+
+ virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
+
+public:
+ class NotificationClient {
+ public:
+ virtual ~NotificationClient() {}
+
+ /**
+ * Called before executing one or several draw commands, which means
+ * once per flush when deferred rendering is enabled.
+ */
+ virtual void prepareForDraw() {}
+
+ /**
+ * Called after a recording a draw command if additional memory
+ * had to be allocated for recording.
+ * @param newAllocatedStorage same value as would be returned by
+ * storageAllocatedForRecording(), for convenience.
+ */
+ virtual void storageAllocatedForRecordingChanged(
+ size_t newAllocatedStorage) {}
+
+ /**
+ * Called after pending draw commands have been flushed
+ */
+ virtual void flushedDrawCommands() {}
+
+ /**
+ * Called after pending draw commands have been skipped, meaning
+ * that they were optimized-out because the canvas is cleared
+ * or completely overwritten by the command currently being recorded.
+ */
+ virtual void skippedPendingDrawCommands() {}
+ };
+
+protected:
+ virtual SkCanvas* canvasForDrawIter();
+ SkDeferredDevice* getDeferredDevice() const;
+
+private:
+ SkDeferredCanvas(SkDeferredDevice*);
+
+ void recordedDrawCommand();
+ SkCanvas* drawingCanvas() const;
+ SkCanvas* immediateCanvas() const;
+ bool isFullFrame(const SkRect*, const SkPaint*) const;
+ void validate() const;
+ void init();
+
+ size_t fBitmapSizeThreshold;
+ bool fDeferredDrawing;
+
+ mutable SkISize fCachedCanvasSize;
+ mutable bool fCachedCanvasSizeDirty;
+
+ friend class SkDeferredCanvasTester; // for unit testing
+ typedef SkCanvas INHERITED;
+};
+
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkDumpCanvas.h b/src/third_party/skia/include/utils/SkDumpCanvas.h
new file mode 100644
index 0000000..c0a105e
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkDumpCanvas.h
@@ -0,0 +1,178 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkDumpCanvas_DEFINED
+#define SkDumpCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+#ifdef SK_DEVELOPER
+
+/** This class overrides all the draw methods on SkCanvas, and formats them
+ as text, and then sends that to a Dumper helper object.
+
+ Typical use might be to dump a display list to a log file to see what is
+ being drawn.
+ */
+class SkDumpCanvas : public SkCanvas {
+public:
+ class Dumper;
+
+ explicit SkDumpCanvas(Dumper* = 0);
+ virtual ~SkDumpCanvas();
+
+ enum Verb {
+ kNULL_Verb,
+
+ kSave_Verb,
+ kRestore_Verb,
+
+ kMatrix_Verb,
+
+ kClip_Verb,
+
+ kDrawPaint_Verb,
+ kDrawPoints_Verb,
+ kDrawOval_Verb,
+ kDrawRect_Verb,
+ kDrawRRect_Verb,
+ kDrawDRRect_Verb,
+ kDrawPath_Verb,
+ kDrawBitmap_Verb,
+ kDrawText_Verb,
+ kDrawPicture_Verb,
+ kDrawVertices_Verb,
+ kDrawPatch_Verb,
+ kDrawData_Verb,
+
+ kBeginCommentGroup_Verb,
+ kAddComment_Verb,
+ kEndCommentGroup_Verb,
+
+ kCull_Verb
+ };
+
+ /** Subclasses of this are installed on the DumpCanvas, and then called for
+ each drawing command.
+ */
+ class Dumper : public SkRefCnt {
+ public:
+ SK_DECLARE_INST_COUNT(Dumper)
+
+ virtual void dump(SkDumpCanvas*, SkDumpCanvas::Verb, const char str[],
+ const SkPaint*) = 0;
+
+ private:
+ typedef SkRefCnt INHERITED;
+ };
+
+ Dumper* getDumper() const { return fDumper; }
+ void setDumper(Dumper*);
+
+ int getNestLevel() const { return fNestLevel; }
+
+ virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPath(const SkPath& path, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
+ const SkRect& dst, const SkPaint* paint,
+ DrawBitmapRectFlags flags) SK_OVERRIDE;
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawVertices(VertexMode vmode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawData(const void*, size_t) SK_OVERRIDE;
+ virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+ virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+ virtual void endCommentGroup() SK_OVERRIDE;
+
+protected:
+ virtual void willSave() SK_OVERRIDE;
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
+ virtual void willRestore() SK_OVERRIDE;
+
+ virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
+ virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void onPushCull(const SkRect& cullRect) SK_OVERRIDE;
+ virtual void onPopCull() SK_OVERRIDE;
+
+ virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
+
+ virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
+
+ static const char* EdgeStyleToAAString(ClipEdgeStyle edgeStyle);
+
+private:
+ Dumper* fDumper;
+ int fNestLevel; // for nesting recursive elements like pictures
+
+ void dump(Verb, const SkPaint*, const char format[], ...);
+
+ typedef SkCanvas INHERITED;
+};
+
+/** Formats the draw commands, and send them to a function-pointer provided
+ by the caller.
+ */
+class SkFormatDumper : public SkDumpCanvas::Dumper {
+public:
+ SkFormatDumper(void (*)(const char text[], void* refcon), void* refcon);
+
+ // override from baseclass that does the formatting, and in turn calls
+ // the function pointer that was passed to the constructor
+ virtual void dump(SkDumpCanvas*, SkDumpCanvas::Verb, const char str[],
+ const SkPaint*) SK_OVERRIDE;
+
+private:
+ void (*fProc)(const char*, void*);
+ void* fRefcon;
+
+ typedef SkDumpCanvas::Dumper INHERITED;
+};
+
+/** Subclass of Dumper that dumps the drawing command to SkDebugf
+ */
+class SkDebugfDumper : public SkFormatDumper {
+public:
+ SkDebugfDumper();
+
+private:
+ typedef SkFormatDumper INHERITED;
+};
+
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkEventTracer.h b/src/third_party/skia/include/utils/SkEventTracer.h
new file mode 100644
index 0000000..8d9fd11
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkEventTracer.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkEventTracer_DEFINED
+#define SkEventTracer_DEFINED
+
+// The class in this header defines the interface between Skia's internal
+// tracing macros and an external entity (e.g., Chrome) that will consume them.
+// Such an entity should subclass SkEventTracer and provide an instance of
+// that event to SkEventTracer::SetInstance.
+
+// If you're looking for the tracing macros to instrument Skia itself, those
+// live in src/core/SkTraceEvent.h
+
+#include "SkTypes.h"
+
+// This will mark the trace event as disabled by default. The user will need
+// to explicitly enable the event.
+#define TRACE_DISABLED_BY_DEFAULT(name) "disabled-by-default-" name
+
+class SK_API SkEventTracer {
+public:
+
+ typedef uint64_t Handle;
+
+ static SkEventTracer* GetInstance();
+
+ static void SetInstance(SkEventTracer* tracer) {
+ SkDELETE(SkEventTracer::gInstance);
+ SkEventTracer::gInstance = tracer;
+ }
+
+ virtual ~SkEventTracer() { }
+
+ // The pointer returned from GetCategoryGroupEnabled() points to a
+ // value with zero or more of the following bits. Used in this class only.
+ // The TRACE_EVENT macros should only use the value as a bool.
+ // These values must be in sync with macro values in trace_event.h in chromium.
+ enum CategoryGroupEnabledFlags {
+ // Category group enabled for the recording mode.
+ kEnabledForRecording_CategoryGroupEnabledFlags = 1 << 0,
+ // Category group enabled for the monitoring mode.
+ kEnabledForMonitoring_CategoryGroupEnabledFlags = 1 << 1,
+ // Category group enabled by SetEventCallbackEnabled().
+ kEnabledForEventCallback_CategoryGroupEnabledFlags = 1 << 2,
+ };
+
+ virtual const uint8_t* getCategoryGroupEnabled(const char* name) = 0;
+ virtual const char* getCategoryGroupName(
+ const uint8_t* categoryEnabledFlag) = 0;
+
+ virtual SkEventTracer::Handle
+ addTraceEvent(char phase,
+ const uint8_t* categoryEnabledFlag,
+ const char* name,
+ uint64_t id,
+ int32_t numArgs,
+ const char** argNames,
+ const uint8_t* argTypes,
+ const uint64_t* argValues,
+ uint8_t flags) = 0;
+
+ virtual void
+ updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
+ const char* name,
+ SkEventTracer::Handle handle) = 0;
+private:
+ static SkEventTracer *gInstance;
+};
+
+#endif // SkEventTracer_DEFINED
diff --git a/src/third_party/skia/include/utils/SkFrontBufferedStream.h b/src/third_party/skia/include/utils/SkFrontBufferedStream.h
new file mode 100644
index 0000000..68d9861
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkFrontBufferedStream.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTypes.h"
+
+class SkStream;
+class SkStreamRewindable;
+
+/**
+ * Specialized stream that buffers the first X bytes of a stream,
+ * where X is passed in by the user. Note that unlike some buffered
+ * stream APIs, once more bytes than can fit in the buffer are read,
+ * no more buffering is done. This stream is designed for a use case
+ * where the caller knows that rewind will only be called from within
+ * X bytes (inclusive), and the wrapped stream is not necessarily
+ * able to rewind at all.
+ */
+class SkFrontBufferedStream {
+public:
+ /**
+ * Creates a new stream that wraps and buffers an SkStream.
+ * @param stream SkStream to buffer. If stream is NULL, NULL is
+ * returned. When this call succeeds (i.e. returns non NULL),
+ * SkFrontBufferedStream is expected to be the only owner of
+ * stream, so it should be unreffed and no longer used directly.
+ * @param minBufferSize Minimum size of buffer required.
+ * @return An SkStream that can buffer at least minBufferSize, or
+ * NULL on failure.
+ */
+ static SkStreamRewindable* Create(SkStream* stream, size_t minBufferSize);
+};
diff --git a/src/third_party/skia/include/utils/SkInterpolator.h b/src/third_party/skia/include/utils/SkInterpolator.h
new file mode 100644
index 0000000..18203d0
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkInterpolator.h
@@ -0,0 +1,130 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkInterpolator_DEFINED
+#define SkInterpolator_DEFINED
+
+#include "SkScalar.h"
+
+class SkInterpolatorBase : SkNoncopyable {
+public:
+ enum Result {
+ kNormal_Result,
+ kFreezeStart_Result,
+ kFreezeEnd_Result
+ };
+protected:
+ SkInterpolatorBase();
+ ~SkInterpolatorBase();
+public:
+ void reset(int elemCount, int frameCount);
+
+ /** Return the start and end time for this interpolator.
+ If there are no key frames, return false.
+ @param startTime If not null, returns the time (in milliseconds) of the
+ first keyframe. If there are no keyframes, this param
+ is ignored (left unchanged).
+ @param endTime If not null, returns the time (in milliseconds) of the
+ last keyframe. If there are no keyframes, this parameter
+ is ignored (left unchanged).
+ @return True if there are key frames, or false if there are none.
+ */
+ bool getDuration(SkMSec* startTime, SkMSec* endTime) const;
+
+
+ /** Set the whether the repeat is mirrored.
+ @param mirror If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setMirror(bool mirror) {
+ fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror);
+ }
+
+ /** Set the repeat count. The repeat count may be fractional.
+ @param repeatCount Multiplies the total time by this scalar.
+ */
+ void setRepeatCount(SkScalar repeatCount) { fRepeat = repeatCount; }
+
+ /** Set the whether the repeat is mirrored.
+ @param reset If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setReset(bool reset) {
+ fFlags = SkToU8((fFlags & ~kReset) | (int)reset);
+ }
+
+ Result timeToT(SkMSec time, SkScalar* T, int* index, SkBool* exact) const;
+
+protected:
+ enum Flags {
+ kMirror = 1,
+ kReset = 2,
+ kHasBlend = 4
+ };
+ static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime,
+ SkMSec nextTime, const SkScalar blend[4] = NULL);
+ int16_t fFrameCount;
+ uint8_t fElemCount;
+ uint8_t fFlags;
+ SkScalar fRepeat;
+ struct SkTimeCode {
+ SkMSec fTime;
+ SkScalar fBlend[4];
+ };
+ SkTimeCode* fTimes; // pointer into fStorage
+ void* fStorage;
+#ifdef SK_DEBUG
+ SkTimeCode(* fTimesArray)[10];
+#endif
+};
+
+class SkInterpolator : public SkInterpolatorBase {
+public:
+ SkInterpolator();
+ SkInterpolator(int elemCount, int frameCount);
+ void reset(int elemCount, int frameCount);
+
+ /** Add or replace a key frame, copying the values[] data into the
+ interpolator.
+ @param index The index of this frame (frames must be ordered by time)
+ @param time The millisecond time for this frame
+ @param values The array of values [elemCount] for this frame. The data
+ is copied into the interpolator.
+ @param blend A positive scalar specifying how to blend between this
+ and the next key frame. [0...1) is a cubic lag/log/lag
+ blend (slow to change at the beginning and end)
+ 1 is a linear blend (default)
+ */
+ bool setKeyFrame(int index, SkMSec time, const SkScalar values[],
+ const SkScalar blend[4] = NULL);
+
+ /** Return the computed values given the specified time. Return whether
+ those values are the result of pinning to either the first
+ (kFreezeStart) or last (kFreezeEnd), or from interpolated the two
+ nearest key values (kNormal).
+ @param time The time to sample (in milliseconds)
+ @param (may be null) where to write the computed values.
+ */
+ Result timeToValues(SkMSec time, SkScalar values[] = NULL) const;
+
+private:
+ SkScalar* fValues; // pointer into fStorage
+#ifdef SK_DEBUG
+ SkScalar(* fScalarsArray)[10];
+#endif
+ typedef SkInterpolatorBase INHERITED;
+};
+
+/** Given all the parameters are [0...1], apply the cubic specified by (0,0)
+ (bx,by) (cx,cy) (1,1) to value, returning the answer, also [0...1].
+*/
+SkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by,
+ SkScalar cx, SkScalar cy);
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkJSONCPP.h b/src/third_party/skia/include/utils/SkJSONCPP.h
new file mode 100644
index 0000000..de82768
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkJSONCPP.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * A common place to put the jsoncpp library includes, as opposed to littering
+ * the pragmas repeatedly through our code.
+ */
+#ifndef SkJSONCPP_DEFINED
+#define SkJSONCPP_DEFINED
+
+#ifdef SK_BUILD_FOR_WIN
+ // json includes xlocale which generates warning 4530 because we're
+ // compiling without exceptions;
+ // see https://code.google.com/p/skia/issues/detail?id=1067
+ #pragma warning(push)
+ #pragma warning(disable : 4530)
+#endif
+#include "json/reader.h"
+#include "json/value.h"
+#include "json/writer.h"
+#ifdef SK_BUILD_FOR_WIN
+ #pragma warning(pop)
+#endif
+
+#endif // SkJSONCPP_DEFINED
diff --git a/src/third_party/skia/include/utils/SkLayer.h b/src/third_party/skia/include/utils/SkLayer.h
new file mode 100644
index 0000000..70fa01b
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkLayer.h
@@ -0,0 +1,130 @@
+
+/*
+ * Copyright 2010 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkLayer_DEFINED
+#define SkLayer_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+#include "SkColor.h"
+#include "SkMatrix.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+#include "SkSize.h"
+
+class SkCanvas;
+
+class SkLayer : public SkRefCnt {
+
+public:
+ SK_DECLARE_INST_COUNT(SkLayer)
+
+ SkLayer();
+ SkLayer(const SkLayer&);
+ virtual ~SkLayer();
+
+ bool isInheritFromRootTransform() const;
+ SkScalar getOpacity() const { return m_opacity; }
+ const SkSize& getSize() const { return m_size; }
+ const SkPoint& getPosition() const { return m_position; }
+ const SkPoint& getAnchorPoint() const { return m_anchorPoint; }
+ const SkMatrix& getMatrix() const { return fMatrix; }
+ const SkMatrix& getChildrenMatrix() const { return fChildrenMatrix; }
+
+ SkScalar getWidth() const { return m_size.width(); }
+ SkScalar getHeight() const { return m_size.height(); }
+
+ void setInheritFromRootTransform(bool);
+ void setOpacity(SkScalar opacity) { m_opacity = opacity; }
+ void setSize(SkScalar w, SkScalar h) { m_size.set(w, h); }
+ void setPosition(SkScalar x, SkScalar y) { m_position.set(x, y); }
+ void setAnchorPoint(SkScalar x, SkScalar y) { m_anchorPoint.set(x, y); }
+ void setMatrix(const SkMatrix&);
+ void setChildrenMatrix(const SkMatrix&);
+
+ // children
+
+ /** Return the number of layers in our child list.
+ */
+ int countChildren() const;
+
+ /** Return the child at the specified index (starting at 0). This does not
+ affect the reference count of the child.
+ */
+ SkLayer* getChild(int index) const;
+
+ /** Add this layer to our child list at the end (top-most), and ref() it.
+ If it was already in another hierarchy, remove it from that list.
+ Return the new child.
+ */
+ SkLayer* addChild(SkLayer* child);
+
+ /** Remove this layer from its parent's list (or do nothing if it has no
+ parent.) If it had a parent, then unref() is called.
+ */
+ void detachFromParent();
+
+ /** Remove, and unref(), all of the layers in our child list.
+ */
+ void removeChildren();
+
+ /** Return our parent layer, or NULL if we have none.
+ */
+ SkLayer* getParent() const { return fParent; }
+
+ /** Return the root layer in this hiearchy. If this layer is the root
+ (i.e. has no parent), then this returns itself.
+ */
+ SkLayer* getRootLayer() const;
+
+ // coordinate system transformations
+
+ /** Return, in matrix, the matix transfomations that are applied locally
+ when this layer draws (i.e. its position and matrix/anchorPoint).
+ This does not include the childrenMatrix, since that is only applied
+ after this layer draws (but before its children draw).
+ */
+ void getLocalTransform(SkMatrix* matrix) const;
+
+ /** Return, in matrix, the concatenation of transforms that are applied
+ from this layer's root parent to the layer itself.
+ This is the matrix that is applied to the layer during drawing.
+ */
+ void localToGlobal(SkMatrix* matrix) const;
+
+ // paint method
+
+ void draw(SkCanvas*, SkScalar opacity);
+ void draw(SkCanvas* canvas) {
+ this->draw(canvas, SK_Scalar1);
+ }
+
+protected:
+ virtual void onDraw(SkCanvas*, SkScalar opacity);
+
+private:
+ enum Flags {
+ kInheritFromRootTransform_Flag = 0x01
+ };
+
+ SkLayer* fParent;
+ SkScalar m_opacity;
+ SkSize m_size;
+ SkPoint m_position;
+ SkPoint m_anchorPoint;
+ SkMatrix fMatrix;
+ SkMatrix fChildrenMatrix;
+ uint32_t fFlags;
+
+ SkTDArray<SkLayer*> m_children;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkLua.h b/src/third_party/skia/include/utils/SkLua.h
new file mode 100644
index 0000000..ad6f996
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkLua.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLua_DEFINED
+#define SkLua_DEFINED
+
+#include "SkClipStack.h"
+#include "SkColor.h"
+#include "SkPathEffect.h"
+#include "SkScalar.h"
+#include "SkString.h"
+
+struct lua_State;
+
+class SkCanvas;
+class SkMatrix;
+class SkPaint;
+class SkPath;
+struct SkRect;
+class SkRRect;
+class SkTextBlob;
+
+#define SkScalarToLua(x) SkScalarToDouble(x)
+#define SkLuaToScalar(x) SkDoubleToScalar(x)
+
+class SkLua {
+public:
+ static void Load(lua_State*);
+
+ SkLua(const char termCode[] = NULL); // creates a new L, will close it
+ SkLua(lua_State*); // uses L, will not close it
+ ~SkLua();
+
+ lua_State* get() const { return fL; }
+ lua_State* operator*() const { return fL; }
+ lua_State* operator->() const { return fL; }
+
+ bool runCode(const char code[]);
+ bool runCode(const void* code, size_t size);
+
+ void pushBool(bool, const char tableKey[] = NULL);
+ void pushString(const char[], const char tableKey[] = NULL);
+ void pushString(const char[], size_t len, const char tableKey[] = NULL);
+ void pushString(const SkString&, const char tableKey[] = NULL);
+ void pushArrayU16(const uint16_t[], int count, const char tableKey[] = NULL);
+ void pushArrayPoint(const SkPoint[], int count, const char key[] = NULL);
+ void pushArrayScalar(const SkScalar[], int count, const char key[] = NULL);
+ void pushColor(SkColor, const char tableKey[] = NULL);
+ void pushU32(uint32_t, const char tableKey[] = NULL);
+ void pushScalar(SkScalar, const char tableKey[] = NULL);
+ void pushRect(const SkRect&, const char tableKey[] = NULL);
+ void pushRRect(const SkRRect&, const char tableKey[] = NULL);
+ void pushDash(const SkPathEffect::DashInfo&, const char tableKey[] = NULL);
+ void pushMatrix(const SkMatrix&, const char tableKey[] = NULL);
+ void pushPaint(const SkPaint&, const char tableKey[] = NULL);
+ void pushPath(const SkPath&, const char tableKey[] = NULL);
+ void pushCanvas(SkCanvas*, const char tableKey[] = NULL);
+ void pushClipStack(const SkClipStack&, const char tableKey[] = NULL);
+ void pushClipStackElement(const SkClipStack::Element& element, const char tableKey[] = NULL);
+ void pushTextBlob(const SkTextBlob*, const char tableKey[] = NULL);
+
+ // This SkCanvas lua methods is declared here to benefit from SkLua's friendship with SkCanvas.
+ static int lcanvas_getReducedClipStack(lua_State* L);
+
+private:
+ lua_State* fL;
+ SkString fTermCode;
+ bool fWeOwnL;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkLuaCanvas.h b/src/third_party/skia/include/utils/SkLuaCanvas.h
new file mode 100644
index 0000000..ea0e692
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkLuaCanvas.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLuaCanvas_DEFINED
+#define SkLuaCanvas_DEFINED
+
+#include "SkCanvas.h"
+#include "SkString.h"
+
+struct lua_State;
+
+class SkLuaCanvas : public SkCanvas {
+public:
+ void pushThis();
+
+ SkLuaCanvas(int width, int height, lua_State*, const char function[]);
+ virtual ~SkLuaCanvas();
+
+ virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPath(const SkPath& path, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
+ const SkRect& dst, const SkPaint* paint,
+ DrawBitmapRectFlags flags) SK_OVERRIDE;
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint) SK_OVERRIDE;
+ virtual void drawVertices(VertexMode vmode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawData(const void* data, size_t length) SK_OVERRIDE;
+
+protected:
+ virtual void willSave() SK_OVERRIDE;
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
+ virtual void willRestore() SK_OVERRIDE;
+
+ virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
+ virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
+
+ virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
+
+private:
+ lua_State* fL;
+ SkString fFunc;
+
+ void sendverb(const char verb[]);
+
+ typedef SkCanvas INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkMatrix44.h b/src/third_party/skia/include/utils/SkMatrix44.h
new file mode 100644
index 0000000..83b5443
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkMatrix44.h
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMatrix44_DEFINED
+#define SkMatrix44_DEFINED
+
+#include "SkMatrix.h"
+#include "SkScalar.h"
+
+#ifdef SK_MSCALAR_IS_DOUBLE
+#ifdef SK_MSCALAR_IS_FLOAT
+ #error "can't define MSCALAR both as DOUBLE and FLOAT"
+#endif
+ typedef double SkMScalar;
+
+ static inline double SkFloatToMScalar(float x) {
+ return static_cast<double>(x);
+ }
+ static inline float SkMScalarToFloat(double x) {
+ return static_cast<float>(x);
+ }
+ static inline double SkDoubleToMScalar(double x) {
+ return x;
+ }
+ static inline double SkMScalarToDouble(double x) {
+ return x;
+ }
+ static const SkMScalar SK_MScalarPI = 3.141592653589793;
+#elif defined SK_MSCALAR_IS_FLOAT
+#ifdef SK_MSCALAR_IS_DOUBLE
+ #error "can't define MSCALAR both as DOUBLE and FLOAT"
+#endif
+ typedef float SkMScalar;
+
+ static inline float SkFloatToMScalar(float x) {
+ return x;
+ }
+ static inline float SkMScalarToFloat(float x) {
+ return x;
+ }
+ static inline float SkDoubleToMScalar(double x) {
+ return static_cast<float>(x);
+ }
+ static inline double SkMScalarToDouble(float x) {
+ return static_cast<double>(x);
+ }
+ static const SkMScalar SK_MScalarPI = 3.14159265f;
+#endif
+
+#define SkMScalarToScalar SkMScalarToFloat
+#define SkScalarToMScalar SkFloatToMScalar
+
+static const SkMScalar SK_MScalar1 = 1;
+
+///////////////////////////////////////////////////////////////////////////////
+
+struct SkVector4 {
+ SkScalar fData[4];
+
+ SkVector4() {
+ this->set(0, 0, 0, 1);
+ }
+ SkVector4(const SkVector4& src) {
+ memcpy(fData, src.fData, sizeof(fData));
+ }
+ SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
+ fData[0] = x;
+ fData[1] = y;
+ fData[2] = z;
+ fData[3] = w;
+ }
+
+ SkVector4& operator=(const SkVector4& src) {
+ memcpy(fData, src.fData, sizeof(fData));
+ return *this;
+ }
+
+ bool operator==(const SkVector4& v) {
+ return fData[0] == v.fData[0] && fData[1] == v.fData[1] &&
+ fData[2] == v.fData[2] && fData[3] == v.fData[3];
+ }
+ bool operator!=(const SkVector4& v) {
+ return !(*this == v);
+ }
+ bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
+ return fData[0] == x && fData[1] == y &&
+ fData[2] == z && fData[3] == w;
+ }
+
+ void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
+ fData[0] = x;
+ fData[1] = y;
+ fData[2] = z;
+ fData[3] = w;
+ }
+};
+
+class SK_API SkMatrix44 {
+public:
+
+ enum Uninitialized_Constructor {
+ kUninitialized_Constructor
+ };
+ enum Identity_Constructor {
+ kIdentity_Constructor
+ };
+
+ SkMatrix44(Uninitialized_Constructor) { }
+ SkMatrix44(Identity_Constructor) { this->setIdentity(); }
+
+ SK_ATTR_DEPRECATED("use the constructors that take an enum")
+ SkMatrix44() { this->setIdentity(); }
+
+ SkMatrix44(const SkMatrix44& src) {
+ memcpy(fMat, src.fMat, sizeof(fMat));
+ fTypeMask = src.fTypeMask;
+ }
+
+ SkMatrix44(const SkMatrix44& a, const SkMatrix44& b) {
+ this->setConcat(a, b);
+ }
+
+ SkMatrix44& operator=(const SkMatrix44& src) {
+ if (&src != this) {
+ memcpy(fMat, src.fMat, sizeof(fMat));
+ fTypeMask = src.fTypeMask;
+ }
+ return *this;
+ }
+
+ bool operator==(const SkMatrix44& other) const;
+ bool operator!=(const SkMatrix44& other) const {
+ return !(other == *this);
+ }
+
+ /* When converting from SkMatrix44 to SkMatrix, the third row and
+ * column is dropped. When converting from SkMatrix to SkMatrix44
+ * the third row and column remain as identity:
+ * [ a b c ] [ a b 0 c ]
+ * [ d e f ] -> [ d e 0 f ]
+ * [ g h i ] [ 0 0 1 0 ]
+ * [ g h 0 i ]
+ */
+ SkMatrix44(const SkMatrix&);
+ SkMatrix44& operator=(const SkMatrix& src);
+ operator SkMatrix() const;
+
+ /**
+ * Return a reference to a const identity matrix
+ */
+ static const SkMatrix44& I();
+
+ enum TypeMask {
+ kIdentity_Mask = 0,
+ kTranslate_Mask = 0x01, //!< set if the matrix has translation
+ kScale_Mask = 0x02, //!< set if the matrix has any scale != 1
+ kAffine_Mask = 0x04, //!< set if the matrix skews or rotates
+ kPerspective_Mask = 0x08 //!< set if the matrix is in perspective
+ };
+
+ /**
+ * Returns a bitfield describing the transformations the matrix may
+ * perform. The bitfield is computed conservatively, so it may include
+ * false positives. For example, when kPerspective_Mask is true, all
+ * other bits may be set to true even in the case of a pure perspective
+ * transform.
+ */
+ inline TypeMask getType() const {
+ if (fTypeMask & kUnknown_Mask) {
+ fTypeMask = this->computeTypeMask();
+ }
+ SkASSERT(!(fTypeMask & kUnknown_Mask));
+ return (TypeMask)fTypeMask;
+ }
+
+ /**
+ * Return true if the matrix is identity.
+ */
+ inline bool isIdentity() const {
+ return kIdentity_Mask == this->getType();
+ }
+
+ /**
+ * Return true if the matrix contains translate or is identity.
+ */
+ inline bool isTranslate() const {
+ return !(this->getType() & ~kTranslate_Mask);
+ }
+
+ /**
+ * Return true if the matrix only contains scale or translate or is identity.
+ */
+ inline bool isScaleTranslate() const {
+ return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
+ }
+
+ inline bool hasPerspective() const {
+ return SkToBool(this->getType() & kPerspective_Mask);
+ }
+
+ void setIdentity();
+ inline void reset() { this->setIdentity();}
+
+ /**
+ * get a value from the matrix. The row,col parameters work as follows:
+ * (0, 0) scale-x
+ * (0, 3) translate-x
+ * (3, 0) perspective-x
+ */
+ inline SkMScalar get(int row, int col) const {
+ SkASSERT((unsigned)row <= 3);
+ SkASSERT((unsigned)col <= 3);
+ return fMat[col][row];
+ }
+
+ /**
+ * set a value in the matrix. The row,col parameters work as follows:
+ * (0, 0) scale-x
+ * (0, 3) translate-x
+ * (3, 0) perspective-x
+ */
+ inline void set(int row, int col, SkMScalar value) {
+ SkASSERT((unsigned)row <= 3);
+ SkASSERT((unsigned)col <= 3);
+ fMat[col][row] = value;
+ this->dirtyTypeMask();
+ }
+
+ inline double getDouble(int row, int col) const {
+ return SkMScalarToDouble(this->get(row, col));
+ }
+ inline void setDouble(int row, int col, double value) {
+ this->set(row, col, SkDoubleToMScalar(value));
+ }
+ inline float getFloat(int row, int col) const {
+ return SkMScalarToFloat(this->get(row, col));
+ }
+ inline void setFloat(int row, int col, float value) {
+ this->set(row, col, SkFloatToMScalar(value));
+ }
+
+ /** These methods allow one to efficiently read matrix entries into an
+ * array. The given array must have room for exactly 16 entries. Whenever
+ * possible, they will try to use memcpy rather than an entry-by-entry
+ * copy.
+ */
+ void asColMajorf(float[]) const;
+ void asColMajord(double[]) const;
+ void asRowMajorf(float[]) const;
+ void asRowMajord(double[]) const;
+
+ /** These methods allow one to efficiently set all matrix entries from an
+ * array. The given array must have room for exactly 16 entries. Whenever
+ * possible, they will try to use memcpy rather than an entry-by-entry
+ * copy.
+ */
+ void setColMajorf(const float[]);
+ void setColMajord(const double[]);
+ void setRowMajorf(const float[]);
+ void setRowMajord(const double[]);
+
+#ifdef SK_MSCALAR_IS_FLOAT
+ void setColMajor(const SkMScalar data[]) { this->setColMajorf(data); }
+ void setRowMajor(const SkMScalar data[]) { this->setRowMajorf(data); }
+#else
+ void setColMajor(const SkMScalar data[]) { this->setColMajord(data); }
+ void setRowMajor(const SkMScalar data[]) { this->setRowMajord(data); }
+#endif
+
+ /* This sets the top-left of the matrix and clears the translation and
+ * perspective components (with [3][3] set to 1). */
+ void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
+ SkMScalar m10, SkMScalar m11, SkMScalar m12,
+ SkMScalar m20, SkMScalar m21, SkMScalar m22);
+
+ void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
+ void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
+ void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
+
+ void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
+ void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
+ void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
+
+ inline void setScale(SkMScalar scale) {
+ this->setScale(scale, scale, scale);
+ }
+ inline void preScale(SkMScalar scale) {
+ this->preScale(scale, scale, scale);
+ }
+ inline void postScale(SkMScalar scale) {
+ this->postScale(scale, scale, scale);
+ }
+
+ void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar degrees) {
+ this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
+ }
+
+ /** Rotate about the vector [x,y,z]. If that vector is not unit-length,
+ it will be automatically resized.
+ */
+ void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar radians);
+ /** Rotate about the vector [x,y,z]. Does not check the length of the
+ vector, assuming it is unit-length.
+ */
+ void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar radians);
+
+ void setConcat(const SkMatrix44& a, const SkMatrix44& b);
+ inline void preConcat(const SkMatrix44& m) {
+ this->setConcat(*this, m);
+ }
+ inline void postConcat(const SkMatrix44& m) {
+ this->setConcat(m, *this);
+ }
+
+ friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) {
+ return SkMatrix44(a, b);
+ }
+
+ /** If this is invertible, return that in inverse and return true. If it is
+ not invertible, return false and ignore the inverse parameter.
+ */
+ bool invert(SkMatrix44* inverse) const;
+
+ /** Transpose this matrix in place. */
+ void transpose();
+
+ /** Apply the matrix to the src vector, returning the new vector in dst.
+ It is legal for src and dst to point to the same memory.
+ */
+ void mapScalars(const SkScalar src[4], SkScalar dst[4]) const;
+ inline void mapScalars(SkScalar vec[4]) const {
+ this->mapScalars(vec, vec);
+ }
+
+ SK_ATTR_DEPRECATED("use mapScalars")
+ void map(const SkScalar src[4], SkScalar dst[4]) const {
+ this->mapScalars(src, dst);
+ }
+
+ SK_ATTR_DEPRECATED("use mapScalars")
+ void map(SkScalar vec[4]) const {
+ this->mapScalars(vec, vec);
+ }
+
+#ifdef SK_MSCALAR_IS_DOUBLE
+ void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const;
+#elif defined SK_MSCALAR_IS_FLOAT
+ inline void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const {
+ this->mapScalars(src, dst);
+ }
+#endif
+ inline void mapMScalars(SkMScalar vec[4]) const {
+ this->mapMScalars(vec, vec);
+ }
+
+ friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) {
+ SkVector4 dst;
+ m.mapScalars(src.fData, dst.fData);
+ return dst;
+ }
+
+ /**
+ * map an array of [x, y, 0, 1] through the matrix, returning an array
+ * of [x', y', z', w'].
+ *
+ * @param src2 array of [x, y] pairs, with implied z=0 and w=1
+ * @param count number of [x, y] pairs in src2
+ * @param dst4 array of [x', y', z', w'] quads as the output.
+ */
+ void map2(const float src2[], int count, float dst4[]) const;
+ void map2(const double src2[], int count, double dst4[]) const;
+
+ void dump() const;
+
+ double determinant() const;
+
+private:
+ SkMScalar fMat[4][4];
+ mutable unsigned fTypeMask;
+
+ enum {
+ kUnknown_Mask = 0x80,
+
+ kAllPublic_Masks = 0xF
+ };
+
+ SkMScalar transX() const { return fMat[3][0]; }
+ SkMScalar transY() const { return fMat[3][1]; }
+ SkMScalar transZ() const { return fMat[3][2]; }
+
+ SkMScalar scaleX() const { return fMat[0][0]; }
+ SkMScalar scaleY() const { return fMat[1][1]; }
+ SkMScalar scaleZ() const { return fMat[2][2]; }
+
+ SkMScalar perspX() const { return fMat[0][3]; }
+ SkMScalar perspY() const { return fMat[1][3]; }
+ SkMScalar perspZ() const { return fMat[2][3]; }
+
+ int computeTypeMask() const;
+
+ inline void dirtyTypeMask() {
+ fTypeMask = kUnknown_Mask;
+ }
+
+ inline void setTypeMask(int mask) {
+ SkASSERT(0 == (~(kAllPublic_Masks | kUnknown_Mask) & mask));
+ fTypeMask = mask;
+ }
+
+ /**
+ * Does not take the time to 'compute' the typemask. Only returns true if
+ * we already know that this matrix is identity.
+ */
+ inline bool isTriviallyIdentity() const {
+ return 0 == fTypeMask;
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkMeshUtils.h b/src/third_party/skia/include/utils/SkMeshUtils.h
new file mode 100644
index 0000000..7e0e8f4
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkMeshUtils.h
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkMeshUtils_DEFINED
+#define SkMeshUtils_DEFINED
+
+#include "SkPoint.h"
+#include "SkColor.h"
+
+class SkBitmap;
+class SkCanvas;
+class SkPaint;
+
+class SkMeshIndices {
+public:
+ SkMeshIndices();
+ ~SkMeshIndices();
+
+ bool init(int texW, int texH, int rows, int cols) {
+ return this->init(NULL, NULL, texW, texH, rows, cols);
+ }
+
+ bool init(SkPoint tex[], uint16_t indices[],
+ int texW, int texH, int rows, int cols);
+
+ int indexCount() const { return fIndexCount; }
+ const uint16_t* indices() const { return fIndices; }
+
+ size_t texCount() const { return fTexCount; }
+ const SkPoint* tex() const { return fTex; }
+
+private:
+ int fIndexCount, fTexCount;
+ SkPoint* fTex;
+ uint16_t* fIndices;
+ void* fStorage; // may be null
+};
+
+class SkMeshUtils {
+public:
+ static void Draw(SkCanvas*, const SkBitmap&, int rows, int cols,
+ const SkPoint verts[], const SkColor colors[],
+ const SkPaint& paint);
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkNWayCanvas.h b/src/third_party/skia/include/utils/SkNWayCanvas.h
new file mode 100644
index 0000000..d3f5cca
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkNWayCanvas.h
@@ -0,0 +1,98 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkNWayCanvas_DEFINED
+#define SkNWayCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+class SK_API SkNWayCanvas : public SkCanvas {
+public:
+ SkNWayCanvas(int width, int height);
+ virtual ~SkNWayCanvas();
+
+ virtual void addCanvas(SkCanvas*);
+ virtual void removeCanvas(SkCanvas*);
+ virtual void removeAll();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // These are forwarded to the N canvases we're referencing
+
+ virtual void clear(SkColor) SK_OVERRIDE;
+ virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint&) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint*) SK_OVERRIDE;
+ virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
+ const SkRect& dst, const SkPaint* paint,
+ DrawBitmapRectFlags flags) SK_OVERRIDE;
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint*) SK_OVERRIDE;
+ virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst,
+ const SkPaint* paint = NULL) SK_OVERRIDE;
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint*) SK_OVERRIDE;
+ virtual void drawVertices(VertexMode vmode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint&) SK_OVERRIDE;
+ virtual void drawData(const void* data, size_t length) SK_OVERRIDE;
+
+ virtual SkDrawFilter* setDrawFilter(SkDrawFilter*) SK_OVERRIDE;
+
+ virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+ virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+ virtual void endCommentGroup() SK_OVERRIDE;
+
+protected:
+ SkTDArray<SkCanvas*> fList;
+
+ virtual void willSave() SK_OVERRIDE;
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
+ virtual void willRestore() SK_OVERRIDE;
+
+ virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
+ virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
+
+ virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
+
+ class Iter;
+
+private:
+ typedef SkCanvas INHERITED;
+};
+
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkNinePatch.h b/src/third_party/skia/include/utils/SkNinePatch.h
new file mode 100644
index 0000000..4d8788b
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkNinePatch.h
@@ -0,0 +1,33 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkNinePatch_DEFINED
+#define SkNinePatch_DEFINED
+
+#include "SkRect.h"
+#include "SkRegion.h"
+
+class SkBitmap;
+class SkCanvas;
+class SkPaint;
+
+class SkNinePatch {
+public:
+ static void DrawNine(SkCanvas* canvas, const SkRect& dst,
+ const SkBitmap& bitmap, const SkIRect& margins,
+ const SkPaint* paint = NULL);
+
+ static void DrawMesh(SkCanvas* canvas, const SkRect& dst,
+ const SkBitmap& bitmap,
+ const int32_t xDivs[], int numXDivs,
+ const int32_t yDivs[], int numYDivs,
+ const SkPaint* paint = NULL);
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkNoSaveLayerCanvas.h b/src/third_party/skia/include/utils/SkNoSaveLayerCanvas.h
new file mode 100644
index 0000000..b692697
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkNoSaveLayerCanvas.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkNoSaveLayerCanvas_DEFINED
+#define SkNoSaveLayerCanvas_DEFINED
+
+#include "SkCanvas.h"
+#include "SkRRect.h"
+
+// The NoSaveLayerCanvas is used to play back SkPictures when the saveLayer
+// functionality isn't required (e.g., during analysis of the draw calls).
+// It also simplifies the clipping calls to only use rectangles.
+class SK_API SkNoSaveLayerCanvas : public SkCanvas {
+public:
+ SkNoSaveLayerCanvas(SkBaseDevice* device)
+ : INHERITED(device, NULL, kConservativeRasterClip_InitFlag)
+ {}
+
+protected:
+ virtual SaveLayerStrategy willSaveLayer(const SkRect* bounds, const SkPaint* paint,
+ SaveFlags flags) SK_OVERRIDE {
+ this->INHERITED::willSaveLayer(bounds, paint, flags);
+ return kNoLayer_SaveLayerStrategy;
+ }
+
+private:
+ typedef SkCanvas INHERITED;
+};
+
+#endif // SkNoSaveLayerCanvas_DEFINED
diff --git a/src/third_party/skia/include/utils/SkNullCanvas.h b/src/third_party/skia/include/utils/SkNullCanvas.h
new file mode 100644
index 0000000..99a26da
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkNullCanvas.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkNullCanvas_DEFINED
+#define SkNullCanvas_DEFINED
+
+#include "SkBitmap.h"
+
+class SkCanvas;
+
+/**
+ * Creates a canvas that draws nothing. This is useful for performance testing.
+ */
+SK_API SkCanvas* SkCreateNullCanvas();
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkParse.h b/src/third_party/skia/include/utils/SkParse.h
new file mode 100644
index 0000000..c5aac7d
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkParse.h
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkParse_DEFINED
+#define SkParse_DEFINED
+
+#include "SkColor.h"
+
+class SkParse {
+public:
+ static int Count(const char str[]); // number of scalars or int values
+ static int Count(const char str[], char separator);
+ static const char* FindColor(const char str[], SkColor* value);
+ static const char* FindHex(const char str[], uint32_t* value);
+ static const char* FindMSec(const char str[], SkMSec* value);
+ static const char* FindNamedColor(const char str[], size_t len, SkColor* color);
+ static const char* FindS32(const char str[], int32_t* value);
+ static const char* FindScalar(const char str[], SkScalar* value);
+ static const char* FindScalars(const char str[], SkScalar value[], int count);
+
+ static bool FindBool(const char str[], bool* value);
+ // return the index of str in list[], or -1 if not found
+ static int FindList(const char str[], const char list[]);
+#ifdef SK_SUPPORT_UNITTEST
+ static void TestColor();
+ static void UnitTest();
+#endif
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkParsePaint.h b/src/third_party/skia/include/utils/SkParsePaint.h
new file mode 100644
index 0000000..066292f
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkParsePaint.h
@@ -0,0 +1,26 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkParsePaint_DEFINED
+#define SkParsePaint_DEFINED
+
+#include "SkPaint.h"
+#include "SkDOM.h"
+
+/** "color" color
+ "opacity" scalar [0..1]
+ "stroke-width" scalar (0...inf)
+ "text-size" scalar (0..inf)
+ "is-stroke" bool
+ "is-antialias" bool
+ "is-lineartext" bool
+*/
+void SkPaint_Inflate(SkPaint*, const SkDOM&, const SkDOM::Node*);
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkParsePath.h b/src/third_party/skia/include/utils/SkParsePath.h
new file mode 100644
index 0000000..c52b3c0
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkParsePath.h
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkParsePath_DEFINED
+#define SkParsePath_DEFINED
+
+#include "SkPath.h"
+
+class SkString;
+
+class SkParsePath {
+public:
+ static bool FromSVGString(const char str[], SkPath*);
+ static void ToSVGString(const SkPath&, SkString*);
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkPathUtils.h b/src/third_party/skia/include/utils/SkPathUtils.h
new file mode 100644
index 0000000..a27cbb8
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkPathUtils.h
@@ -0,0 +1,40 @@
+/*
+ * CAUTION: EXPERIMENTAL CODE
+ *
+ * This code is not to be used and will not be supported
+ * if it fails on you. DO NOT USE!
+ *
+ */
+
+#ifndef SkPathUtils_DEFINED
+#define SkPathUtils_DEFINED
+
+#include "SkPath.h"
+
+/*
+ * The following methods return the boundary path given a 1-bit bitmap, specified
+ * by width/height and stride. The bits are interpreted as 1 being "in" the path,
+ * and 0 being "out". The bits are interpreted as MSB on the left, and LSB on the right.
+ */
+
+class SK_API SkPathUtils {
+public:
+ /**
+ This variation iterates the binary data sequentially (as in scanline fashion)
+ and will add each run of 1's to the path as a rectangular path. Upon parsing
+ all binary data the path is simplified using the PathOps::Simplify() method.
+ */
+ static void BitsToPath_Path(SkPath* path, const char* bitmap,
+ int w, int h, int rowBytes);
+
+ /**
+ This variation utilizes the SkRegion class to generate paths, adding
+ each run of 1's to the SkRegion as an SkIRect. Upon parsing the entirety
+ of the binary the SkRegion is converted to a Path via getBoundaryPath().
+ */
+ static void BitsToPath_Region(SkPath* path, const char* bitmap,
+ int w, int h, int rowBytes);
+
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkPictureUtils.h b/src/third_party/skia/include/utils/SkPictureUtils.h
new file mode 100644
index 0000000..c35e1c7
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkPictureUtils.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPictureUtils_DEFINED
+#define SkPictureUtils_DEFINED
+
+#include "SkPicture.h"
+#include "SkTDArray.h"
+
+class SkData;
+struct SkRect;
+
+class SK_API SkPictureUtils {
+public:
+ /**
+ * Given a rectangular visible "window" into the picture, return an array
+ * of SkPixelRefs that might intersect that area. To keep the call fast,
+ * the returned list is not guaranteed to be exact, so it may miss some,
+ * and it may return false positives.
+ *
+ * The pixelrefs returned in the SkData are already owned by the picture,
+ * so the returned pointers are only valid while the picture is in scope
+ * and remains unchanged.
+ */
+ static SkData* GatherPixelRefs(const SkPicture* pict, const SkRect& area);
+
+ /**
+ * SkPixelRefContainer provides a base class for more elaborate pixel ref
+ * query structures (e.g., rtrees, quad-trees, etc.)
+ */
+ class SkPixelRefContainer : public SkRefCnt {
+ public:
+ virtual void add(SkPixelRef* pr, const SkRect& rect) = 0;
+
+ // The returned array may contain duplicates
+ virtual void query(const SkRect& queryRect, SkTDArray<SkPixelRef*> *result) = 0;
+
+ private:
+ typedef SkRefCnt INHERITED;
+ };
+
+ // Simple query structure that just stores a linked list of pixel refs
+ // and rects.
+ class SkPixelRefsAndRectsList : public SkPixelRefContainer {
+ public:
+ virtual void add(SkPixelRef* pr, const SkRect& rect) SK_OVERRIDE {
+ PixelRefAndRect *dst = fArray.append();
+
+ dst->fPixelRef = pr;
+ dst->fRect = rect;
+ }
+
+ virtual void query(const SkRect& queryRect, SkTDArray<SkPixelRef*> *result) SK_OVERRIDE {
+ for (int i = 0; i < fArray.count(); ++i) {
+ if (SkRect::Intersects(fArray[i].fRect, queryRect)) {
+ *result->append() = fArray[i].fPixelRef;
+ }
+ }
+ }
+
+ private:
+ struct PixelRefAndRect {
+ SkPixelRef* fPixelRef;
+ SkRect fRect;
+ };
+
+ SkTDArray<PixelRefAndRect> fArray;
+
+ typedef SkPixelRefContainer INHERITED;
+ };
+
+ /**
+ * Fill the provided pixel ref container with the picture's pixel ref
+ * and rect information.
+ */
+ static void GatherPixelRefsAndRects(SkPicture* pict, SkPixelRefContainer* prCont);
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkProxyCanvas.h b/src/third_party/skia/include/utils/SkProxyCanvas.h
new file mode 100644
index 0000000..27a8216
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkProxyCanvas.h
@@ -0,0 +1,94 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkProxyCanvas_DEFINED
+#define SkProxyCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+/** This class overrides all virtual methods on SkCanvas, and redirects them
+ to a "proxy", another SkCanvas instance. It can be the basis for
+ intercepting (and possibly modifying) calls to a canvas.
+
+ There must be a proxy installed before the proxycanvas can be used (i.e.
+ before its virtual methods can be called).
+ */
+class SK_API SkProxyCanvas : public SkCanvas {
+public:
+ SkProxyCanvas() : fProxy(NULL) {}
+ SkProxyCanvas(SkCanvas* proxy);
+ virtual ~SkProxyCanvas();
+
+ SkCanvas* getProxy() const { return fProxy; }
+ void setProxy(SkCanvas* proxy);
+
+ virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawPath(const SkPath& path, const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint = NULL) SK_OVERRIDE;
+ virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
+ const SkRect& dst, const SkPaint* paint,
+ DrawBitmapRectFlags flags) SK_OVERRIDE;
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint = NULL) SK_OVERRIDE;
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint = NULL) SK_OVERRIDE;
+ virtual void drawVertices(VertexMode vmode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawData(const void* data, size_t length) SK_OVERRIDE;
+
+ virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
+ virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
+ virtual void endCommentGroup() SK_OVERRIDE;
+
+ virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
+
+protected:
+ virtual void willSave() SK_OVERRIDE;
+ virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
+ virtual void willRestore() SK_OVERRIDE;
+
+ virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
+ virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
+
+ virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
+ const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
+ SkScalar constY, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+ virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode,
+ const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
+ virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
+
+ virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
+
+private:
+ SkCanvas* fProxy;
+
+ typedef SkCanvas INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkRTConf.h b/src/third_party/skia/include/utils/SkRTConf.h
new file mode 100644
index 0000000..5a30f1d
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkRTConf.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2013 Google, Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkRTConf_DEFINED
+#define SkRTConf_DEFINED
+
+#include "SkString.h"
+#include "SkStream.h"
+
+#include "SkTDict.h"
+#include "SkTArray.h"
+
+/** \class SkRTConfBase
+ Non-templated base class for the runtime configs
+*/
+
+class SkRTConfBase {
+public:
+ SkRTConfBase(const char *name) : fName(name) {}
+ virtual ~SkRTConfBase() {}
+ virtual const char *getName() const { return fName.c_str(); }
+ virtual bool isDefault() const = 0;
+ virtual void print(SkWStream *o) const = 0;
+ virtual bool equals(const SkRTConfBase *conf) const = 0;
+protected:
+ SkString fName;
+};
+
+/** \class SkRTConf
+ A class to provide runtime configurability.
+*/
+template<typename T> class SkRTConf: public SkRTConfBase {
+public:
+ SkRTConf(const char *name, const T &defaultValue, const char *description);
+ operator const T&() const { return fValue; }
+ void print(SkWStream *o) const;
+ bool equals(const SkRTConfBase *conf) const;
+ bool isDefault() const { return fDefault == fValue; }
+ void set(const T& value) { fValue = value; }
+protected:
+ void doPrint(char *s) const;
+
+ T fValue;
+ T fDefault;
+ SkString fDescription;
+};
+
+#ifdef SK_DEVELOPER
+#define SK_CONF_DECLARE(confType, varName, confName, defaultValue, description) static SkRTConf<confType> varName(confName, defaultValue, description)
+#define SK_CONF_SET(confname, value) \
+ skRTConfRegistry().set(confname, value, true)
+/* SK_CONF_TRY_SET() is like SK_CONF_SET(), but doesn't complain if
+ confname can't be found. This is useful if the SK_CONF_DECLARE is
+ inside a source file whose linkage is dependent on the system. */
+#define SK_CONF_TRY_SET(confname, value) \
+ skRTConfRegistry().set(confname, value, false)
+#else
+#define SK_CONF_DECLARE(confType, varName, confName, defaultValue, description) static confType varName = defaultValue
+#define SK_CONF_SET(confname, value) (void) confname, (void) value
+#define SK_CONF_TRY_SET(confname, value) (void) confname, (void) value
+#endif
+
+/** \class SkRTConfRegistry
+ A class that maintains a systemwide registry of all runtime configuration
+ parameters. Mainly used for printing them out and handling multiply-defined
+ knobs.
+*/
+
+class SkRTConfRegistry {
+public:
+ SkRTConfRegistry();
+ ~SkRTConfRegistry();
+ void printAll(const char *fname = NULL) const;
+ bool hasNonDefault() const;
+ void printNonDefault(const char *fname = NULL) const;
+ const char *configFileLocation() const;
+ void possiblyDumpFile() const;
+ void validate() const;
+ template <typename T> void set(const char *confname,
+ T value,
+ bool warnIfNotFound = true);
+
+private:
+ template<typename T> friend class SkRTConf;
+
+ void registerConf(SkRTConfBase *conf);
+
+ template <typename T> bool parse(const char *name, T* value);
+
+ SkTDArray<SkString *> fConfigFileKeys, fConfigFileValues;
+ typedef SkTDict< SkTDArray<SkRTConfBase *> * > ConfMap;
+ ConfMap fConfs;
+
+ template <typename T>
+ friend bool test_rt_conf_parse(SkRTConfRegistry*, const char* name, T* value);
+};
+
+// our singleton registry
+
+SkRTConfRegistry &skRTConfRegistry();
+
+template<typename T>
+SkRTConf<T>::SkRTConf(const char *name, const T &defaultValue, const char *description)
+ : SkRTConfBase(name)
+ , fValue(defaultValue)
+ , fDefault(defaultValue)
+ , fDescription(description) {
+
+ T value;
+ if (skRTConfRegistry().parse(fName.c_str(), &value)) {
+ fValue = value;
+ }
+ skRTConfRegistry().registerConf(this);
+}
+
+#if defined(SK_BUILD_FOR_STARBOARD)
+#include "starboard/string.h"
+#define sprintf SbStringFormatUnsafeF
+#endif
+
+template<typename T>
+void SkRTConf<T>::print(SkWStream *o) const {
+ char outline[200]; // should be ok because we specify a max. width for everything here.
+ char *outptr;
+ if (strlen(getName()) >= 30) {
+ o->writeText(getName());
+ o->writeText(" ");
+ outptr = &(outline[0]);
+ } else {
+ sprintf(outline, "%-30.30s", getName());
+ outptr = &(outline[30]);
+ }
+
+ doPrint(outptr);
+ sprintf(outptr+30, " %.128s", fDescription.c_str());
+ for (size_t i = strlen(outline); i --> 0 && ' ' == outline[i];) {
+ outline[i] = '\0';
+ }
+ o->writeText(outline);
+}
+
+template<typename T>
+void SkRTConf<T>::doPrint(char *s) const {
+ sprintf(s, "%-30.30s", "How do I print myself??");
+}
+
+template<> inline void SkRTConf<bool>::doPrint(char *s) const {
+ char tmp[30];
+ sprintf(tmp, "%s # [%s]", fValue ? "true" : "false", fDefault ? "true" : "false");
+ sprintf(s, "%-30.30s", tmp);
+}
+
+template<> inline void SkRTConf<int>::doPrint(char *s) const {
+ char tmp[30];
+ sprintf(tmp, "%d # [%d]", fValue, fDefault);
+ sprintf(s, "%-30.30s", tmp);
+}
+
+template<> inline void SkRTConf<unsigned int>::doPrint(char *s) const {
+ char tmp[30];
+ sprintf(tmp, "%u # [%u]", fValue, fDefault);
+ sprintf(s, "%-30.30s", tmp);
+}
+
+template<> inline void SkRTConf<float>::doPrint(char *s) const {
+ char tmp[30];
+ sprintf(tmp, "%6.6f # [%6.6f]", fValue, fDefault);
+ sprintf(s, "%-30.30s", tmp);
+}
+
+template<> inline void SkRTConf<double>::doPrint(char *s) const {
+ char tmp[30];
+ sprintf(tmp, "%6.6f # [%6.6f]", fValue, fDefault);
+ sprintf(s, "%-30.30s", tmp);
+}
+
+template<> inline void SkRTConf<const char *>::doPrint(char *s) const {
+ char tmp[30];
+ sprintf(tmp, "%s # [%s]", fValue, fDefault);
+ sprintf(s, "%-30.30s", tmp);
+}
+
+template<typename T>
+bool SkRTConf<T>::equals(const SkRTConfBase *conf) const {
+ // static_cast here is okay because there's only one kind of child class.
+ const SkRTConf<T> *child_pointer = static_cast<const SkRTConf<T> *>(conf);
+ return child_pointer &&
+ fName == child_pointer->fName &&
+ fDescription == child_pointer->fDescription &&
+ fValue == child_pointer->fValue &&
+ fDefault == child_pointer->fDefault;
+}
+
+#if defined(SK_BUILD_FOR_STARBOARD)
+#undef sprintf
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkRandom.h b/src/third_party/skia/include/utils/SkRandom.h
new file mode 100644
index 0000000..d083fc6
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkRandom.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRandom_DEFINED
+#define SkRandom_DEFINED
+
+#include "SkScalar.h"
+
+/** \class SkLCGRandom
+
+ Utility class that implements pseudo random 32bit numbers using a fast
+ linear equation. Unlike rand(), this class holds its own seed (initially
+ set to 0), so that multiple instances can be used with no side-effects.
+*/
+class SkLCGRandom {
+public:
+ SkLCGRandom() : fSeed(0) {}
+ SkLCGRandom(uint32_t seed) : fSeed(seed) {}
+
+ /** Return the next pseudo random number as an unsigned 32bit value.
+ */
+ uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }
+
+ /** Return the next pseudo random number as a signed 32bit value.
+ */
+ int32_t nextS() { return (int32_t)this->nextU(); }
+
+ /** Return the next pseudo random number as an unsigned 16bit value.
+ */
+ U16CPU nextU16() { return this->nextU() >> 16; }
+
+ /** Return the next pseudo random number as a signed 16bit value.
+ */
+ S16CPU nextS16() { return this->nextS() >> 16; }
+
+ /**
+ * Returns value [0...1) as a float
+ */
+ float nextF() {
+ // const is 1 / (2^32 - 1)
+ return (float)(this->nextU() * 2.32830644e-10);
+ }
+
+ /**
+ * Returns value [min...max) as a float
+ */
+ float nextRangeF(float min, float max) {
+ return min + this->nextF() * (max - min);
+ }
+
+ /** Return the next pseudo random number, as an unsigned value of
+ at most bitCount bits.
+ @param bitCount The maximum number of bits to be returned
+ */
+ uint32_t nextBits(unsigned bitCount) {
+ SkASSERT(bitCount > 0 && bitCount <= 32);
+ return this->nextU() >> (32 - bitCount);
+ }
+
+ /** Return the next pseudo random unsigned number, mapped to lie within
+ [min, max] inclusive.
+ */
+ uint32_t nextRangeU(uint32_t min, uint32_t max) {
+ SkASSERT(min <= max);
+ uint32_t range = max - min + 1;
+ if (0 == range) {
+ return this->nextU();
+ } else {
+ return min + this->nextU() % range;
+ }
+ }
+
+ /** Return the next pseudo random unsigned number, mapped to lie within
+ [0, count).
+ */
+ uint32_t nextULessThan(uint32_t count) {
+ SkASSERT(count > 0);
+ return this->nextRangeU(0, count - 1);
+ }
+
+ /** Return the next pseudo random number expressed as an unsigned SkFixed
+ in the range [0..SK_Fixed1).
+ */
+ SkFixed nextUFixed1() { return this->nextU() >> 16; }
+
+ /** Return the next pseudo random number expressed as a signed SkFixed
+ in the range (-SK_Fixed1..SK_Fixed1).
+ */
+ SkFixed nextSFixed1() { return this->nextS() >> 15; }
+
+ /** Return the next pseudo random number expressed as a SkScalar
+ in the range [0..SK_Scalar1).
+ */
+ SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
+
+ /** Return the next pseudo random number expressed as a SkScalar
+ in the range [min..max).
+ */
+ SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
+ return this->nextUScalar1() * (max - min) + min;
+ }
+
+ /** Return the next pseudo random number expressed as a SkScalar
+ in the range (-SK_Scalar1..SK_Scalar1).
+ */
+ SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
+
+ /** Return the next pseudo random number as a bool.
+ */
+ bool nextBool() { return this->nextU() >= 0x80000000; }
+
+ /** A biased version of nextBool().
+ */
+ bool nextBiasedBool(SkScalar fractionTrue) {
+ SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1);
+ return this->nextUScalar1() <= fractionTrue;
+ }
+
+ /**
+ * Return the next pseudo random number as a signed 64bit value.
+ */
+ int64_t next64() {
+ int64_t hi = this->nextS();
+ return (hi << 32) | this->nextU();
+ }
+
+ /**
+ * Return the current seed. This allows the caller to later reset to the
+ * same seed (using setSeed) so it can generate the same sequence.
+ */
+ int32_t getSeed() const { return fSeed; }
+
+ /** Set the seed of the random object. The seed is initialized to 0 when the
+ object is first created, and is updated each time the next pseudo random
+ number is requested.
+ */
+ void setSeed(int32_t seed) { fSeed = (uint32_t)seed; }
+
+private:
+ // See "Numerical Recipes in C", 1992 page 284 for these constants
+ enum {
+ kMul = 1664525,
+ kAdd = 1013904223
+ };
+ uint32_t fSeed;
+};
+
+/** \class SkRandom
+
+ Utility class that implements pseudo random 32bit numbers using Marsaglia's
+ multiply-with-carry "mother of all" algorithm. Unlike rand(), this class holds
+ its own state, so that multiple instances can be used with no side-effects.
+
+ Has a large period and all bits are well-randomized.
+ */
+class SkRandom {
+public:
+ SkRandom() { init(0); }
+ SkRandom(uint32_t seed) { init(seed); }
+ SkRandom(const SkRandom& rand) : fK(rand.fK), fJ(rand.fJ) {}
+
+ SkRandom& operator=(const SkRandom& rand) {
+ fK = rand.fK;
+ fJ = rand.fJ;
+
+ return *this;
+ }
+
+ /** Return the next pseudo random number as an unsigned 32bit value.
+ */
+ uint32_t nextU() {
+ fK = kKMul*(fK & 0xffff) + (fK >> 16);
+ fJ = kJMul*(fJ & 0xffff) + (fJ >> 16);
+ return (((fK << 16) | (fK >> 16)) + fJ);
+ }
+
+ /** Return the next pseudo random number as a signed 32bit value.
+ */
+ int32_t nextS() { return (int32_t)this->nextU(); }
+
+ /** Return the next pseudo random number as an unsigned 16bit value.
+ */
+ U16CPU nextU16() { return this->nextU() >> 16; }
+
+ /** Return the next pseudo random number as a signed 16bit value.
+ */
+ S16CPU nextS16() { return this->nextS() >> 16; }
+
+ /**
+ * Returns value [0...1) as an IEEE float
+ */
+ float nextF() {
+ unsigned int floatint = 0x3f800000 | (this->nextU() >> 9);
+ float f = SkBits2Float(floatint) - 1.0f;
+ return f;
+ }
+
+ /**
+ * Returns value [min...max) as a float
+ */
+ float nextRangeF(float min, float max) {
+ return min + this->nextF() * (max - min);
+ }
+
+ /** Return the next pseudo random number, as an unsigned value of
+ at most bitCount bits.
+ @param bitCount The maximum number of bits to be returned
+ */
+ uint32_t nextBits(unsigned bitCount) {
+ SkASSERT(bitCount > 0 && bitCount <= 32);
+ return this->nextU() >> (32 - bitCount);
+ }
+
+ /** Return the next pseudo random unsigned number, mapped to lie within
+ [min, max] inclusive.
+ */
+ uint32_t nextRangeU(uint32_t min, uint32_t max) {
+ SkASSERT(min <= max);
+ uint32_t range = max - min + 1;
+ if (0 == range) {
+ return this->nextU();
+ } else {
+ return min + this->nextU() % range;
+ }
+ }
+
+ /** Return the next pseudo random unsigned number, mapped to lie within
+ [0, count).
+ */
+ uint32_t nextULessThan(uint32_t count) {
+ SkASSERT(count > 0);
+ return this->nextRangeU(0, count - 1);
+ }
+
+ /** Return the next pseudo random number expressed as an unsigned SkFixed
+ in the range [0..SK_Fixed1).
+ */
+ SkFixed nextUFixed1() { return this->nextU() >> 16; }
+
+ /** Return the next pseudo random number expressed as a signed SkFixed
+ in the range (-SK_Fixed1..SK_Fixed1).
+ */
+ SkFixed nextSFixed1() { return this->nextS() >> 15; }
+
+ /** Return the next pseudo random number expressed as a SkScalar
+ in the range [0..SK_Scalar1).
+ */
+ SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
+
+ /** Return the next pseudo random number expressed as a SkScalar
+ in the range [min..max).
+ */
+ SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
+ return this->nextUScalar1() * (max - min) + min;
+ }
+
+ /** Return the next pseudo random number expressed as a SkScalar
+ in the range (-SK_Scalar1..SK_Scalar1).
+ */
+ SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
+
+ /** Return the next pseudo random number as a bool.
+ */
+ bool nextBool() { return this->nextU() >= 0x80000000; }
+
+ /** A biased version of nextBool().
+ */
+ bool nextBiasedBool(SkScalar fractionTrue) {
+ SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1);
+ return this->nextUScalar1() <= fractionTrue;
+ }
+
+ /**
+ * Return the next pseudo random number as a signed 64bit value.
+ */
+ int64_t next64() {
+ int64_t hi = this->nextS();
+ return (hi << 32) | this->nextU();
+ }
+
+ /** Reset the random object.
+ */
+ void setSeed(uint32_t seed) { init(seed); }
+
+private:
+ // Initialize state variables with LCG.
+ // We must ensure that both J and K are non-zero, otherwise the
+ // multiply-with-carry step will forevermore return zero.
+ void init(uint32_t seed) {
+ fK = NextLCG(seed);
+ if (0 == fK) {
+ fK = NextLCG(fK);
+ }
+ fJ = NextLCG(fK);
+ if (0 == fJ) {
+ fJ = NextLCG(fJ);
+ }
+ SkASSERT(0 != fK && 0 != fJ);
+ }
+ static uint32_t NextLCG(uint32_t seed) { return kMul*seed + kAdd; }
+
+ // See "Numerical Recipes in C", 1992 page 284 for these constants
+ // For the LCG that sets the initial state from a seed
+ enum {
+ kMul = 1664525,
+ kAdd = 1013904223
+ };
+ // Constants for the multiply-with-carry steps
+ enum {
+ kKMul = 30345,
+ kJMul = 18000,
+ };
+
+ uint32_t fK;
+ uint32_t fJ;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/SkWGL.h b/src/third_party/skia/include/utils/SkWGL.h
new file mode 100644
index 0000000..d502eb0
--- /dev/null
+++ b/src/third_party/skia/include/utils/SkWGL.h
@@ -0,0 +1,168 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkRefCnt.h"
+
+#ifndef SkWGL_DEFINED
+#define SkWGL_DEFINED
+
+/**
+ * Working with WGL extensions can be a pain. Among the reasons is that You must
+ * have a GL context to get the proc addresses, but you want to use the procs to
+ * create a context in the first place. So you have to create a dummy GL ctx to
+ * get the proc addresses.
+ *
+ * This file helps by providing SkCreateWGLInterface(). It returns a struct of
+ * function pointers that it initializes. It also has a helper function to query
+ * for WGL extensions. It handles the fact that wglGetExtensionsString is itself
+ * an extension.
+ */
+
+#if !defined(WIN32_LEAN_AND_MEAN)
+ #define WIN32_LEAN_AND_MEAN
+ #define SK_LOCAL_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#if defined(SK_LOCAL_LEAN_AND_MEAN)
+ #undef WIN32_LEAN_AND_MEAN
+ #undef SK_LOCAL_LEAN_AND_MEAN
+#endif
+
+#define SK_WGL_DRAW_TO_WINDOW 0x2001
+#define SK_WGL_ACCELERATION 0x2003
+#define SK_WGL_SUPPORT_OPENGL 0x2010
+#define SK_WGL_DOUBLE_BUFFER 0x2011
+#define SK_WGL_COLOR_BITS 0x2014
+#define SK_WGL_ALPHA_BITS 0x201B
+#define SK_WGL_STENCIL_BITS 0x2023
+#define SK_WGL_FULL_ACCELERATION 0x2027
+#define SK_WGL_SAMPLE_BUFFERS 0x2041
+#define SK_WGL_SAMPLES 0x2042
+#define SK_WGL_CONTEXT_MAJOR_VERSION 0x2091
+#define SK_WGL_CONTEXT_MINOR_VERSION 0x2092
+#define SK_WGL_CONTEXT_LAYER_PLANE 0x2093
+#define SK_WGL_CONTEXT_FLAGS 0x2094
+#define SK_WGL_CONTEXT_PROFILE_MASK 0x9126
+#define SK_WGL_CONTEXT_DEBUG_BIT 0x0001
+#define SK_WGL_CONTEXT_FORWARD_COMPATIBLE_BIT 0x0002
+#define SK_WGL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define SK_WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define SK_WGL_CONTEXT_ES2_PROFILE_BIT 0x00000004
+#define SK_ERROR_INVALID_VERSION 0x2095
+#define SK_ERROR_INVALID_PROFILE 0x2096
+
+DECLARE_HANDLE(HPBUFFER);
+
+class SkWGLExtensions {
+public:
+ SkWGLExtensions();
+ /**
+ * Determines if an extensions is available for a given DC.
+ * WGL_extensions_string is considered a prerequisite for all other
+ * extensions. It is necessary to check this before calling other class
+ * functions.
+ */
+ bool hasExtension(HDC dc, const char* ext) const;
+
+ const char* getExtensionsString(HDC hdc) const;
+ BOOL choosePixelFormat(HDC hdc, const int*, const FLOAT*, UINT, int*, UINT*) const;
+ BOOL getPixelFormatAttribiv(HDC, int, int, UINT, const int*, int*) const;
+ BOOL getPixelFormatAttribfv(HDC hdc, int, int, UINT, const int*, FLOAT*) const;
+ HGLRC createContextAttribs(HDC, HGLRC, const int *) const;
+
+ BOOL swapInterval(int interval) const;
+
+ HPBUFFER createPbuffer(HDC, int , int, int, const int*) const;
+ HDC getPbufferDC(HPBUFFER) const;
+ int releasePbufferDC(HPBUFFER, HDC) const;
+ BOOL destroyPbuffer(HPBUFFER) const;
+
+ /**
+ * WGL doesn't have precise rules for the ordering of formats returned
+ * by wglChoosePixelFormat. This function helps choose among the set of
+ * formats returned by wglChoosePixelFormat. The rules in decreasing
+ * priority are:
+ * * Choose formats with the smallest sample count that is >=
+ * desiredSampleCount (or the largest sample count if all formats have
+ * fewer samples than desiredSampleCount.)
+ * * Choose formats with the fewest color samples when coverage sampling
+ * is available.
+ * * If the above rules leave multiple formats, choose the one that
+ * appears first in the formats array parameter.
+ */
+ int selectFormat(const int formats[],
+ int formatCount,
+ HDC dc,
+ int desiredSampleCount) const;
+private:
+ typedef const char* (WINAPI *GetExtensionsStringProc)(HDC);
+ typedef BOOL (WINAPI *ChoosePixelFormatProc)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
+ typedef BOOL (WINAPI *GetPixelFormatAttribivProc)(HDC, int, int, UINT, const int*, int*);
+ typedef BOOL (WINAPI *GetPixelFormatAttribfvProc)(HDC, int, int, UINT, const int*, FLOAT*);
+ typedef HGLRC (WINAPI *CreateContextAttribsProc)(HDC, HGLRC, const int *);
+ typedef BOOL (WINAPI* SwapIntervalProc)(int);
+ typedef HPBUFFER (WINAPI* CreatePbufferProc)(HDC, int , int, int, const int*);
+ typedef HDC (WINAPI* GetPbufferDCProc)(HPBUFFER);
+ typedef int (WINAPI* ReleasePbufferDCProc)(HPBUFFER, HDC);
+ typedef BOOL (WINAPI* DestroyPbufferProc)(HPBUFFER);
+
+ GetExtensionsStringProc fGetExtensionsString;
+ ChoosePixelFormatProc fChoosePixelFormat;
+ GetPixelFormatAttribfvProc fGetPixelFormatAttribfv;
+ GetPixelFormatAttribivProc fGetPixelFormatAttribiv;
+ CreateContextAttribsProc fCreateContextAttribs;
+ SwapIntervalProc fSwapInterval;
+ CreatePbufferProc fCreatePbuffer;
+ GetPbufferDCProc fGetPbufferDC;
+ ReleasePbufferDCProc fReleasePbufferDC;
+ DestroyPbufferProc fDestroyPbuffer;
+};
+
+enum SkWGLContextRequest {
+ /** Requests to create core profile context if possible, otherwise
+ compatibility profile. */
+ kGLPreferCoreProfile_SkWGLContextRequest,
+ /** Requests to create compatibility profile context if possible, otherwise
+ core profile. */
+ kGLPreferCompatibilityProfile_SkWGLContextRequest,
+ /** Requests to create GL ES profile context. */
+ kGLES_SkWGLContextRequest
+};
+/**
+ * Helper to create an OpenGL context for a DC using WGL. Configs with a sample count >= to
+ * msaaSampleCount are preferred but if none is available then a context with a lower sample count
+ * (including non-MSAA) will be created. If preferCoreProfile is true but a core profile cannot be
+ * created then a compatible profile context will be created.
+ */
+HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest context);
+
+/**
+ * Helper class for creating a pbuffer context and deleting all the handles when finished. This
+ * requires that a device context has been created. However, the pbuffer gets its own device
+ * context. The original device context can be released once the pbuffer context is created.
+ */
+class SkWGLPbufferContext : public SkRefCnt {
+public:
+ static SkWGLPbufferContext* Create(HDC parentDC, int msaaSampleCount,
+ SkWGLContextRequest contextType);
+
+ virtual ~SkWGLPbufferContext();
+
+ HDC getDC() const { return fDC; }
+ HGLRC getGLRC() const { return fGLRC; }
+
+private:
+ SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc);
+
+ HPBUFFER fPbuffer;
+ HDC fDC;
+ HGLRC fGLRC;
+ SkWGLExtensions fExtensions;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/ios/SkStream_NSData.h b/src/third_party/skia/include/utils/ios/SkStream_NSData.h
new file mode 100644
index 0000000..8e6f064
--- /dev/null
+++ b/src/third_party/skia/include/utils/ios/SkStream_NSData.h
@@ -0,0 +1,41 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkStream_NSData_DEFINED
+#define SkStream_NSData_DEFINED
+
+#import <UIKit/UIKit.h>
+#include "SkStream.h"
+
+/** Returns an NSData with a copy of the stream's data. The caller must call
+ retain if it intends to keep the data object beyond the current stack-frame
+ (i.e. internally we're calling [NSData dataWithBytes...]
+ */
+NSData* NSData_dataWithStream(SkStream* stream);
+
+/** Returns an NSData from the named resource (from main bundle).
+ The caller must call retain if it intends to keep the data object beyond
+ the current stack-frame
+ (i.e. internally we're calling [NSData dataWithContentsOfMappedFile...]
+ */
+NSData* NSData_dataFromResource(const char name[], const char suffix[]);
+
+/** Wrap a stream around NSData.
+ */
+class SkStream_NSData : public SkMemoryStream {
+public:
+ SkStream_NSData(NSData* data);
+ virtual ~SkStream_NSData();
+
+ static SkStream_NSData* CreateFromResource(const char name[],
+ const char suffix[]);
+
+private:
+ NSData* fNSData;
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/mac/SkCGUtils.h b/src/third_party/skia/include/utils/mac/SkCGUtils.h
new file mode 100644
index 0000000..a0fe666
--- /dev/null
+++ b/src/third_party/skia/include/utils/mac/SkCGUtils.h
@@ -0,0 +1,84 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkCGUtils_DEFINED
+#define SkCGUtils_DEFINED
+
+#include "SkSize.h"
+#include "SkImageInfo.h"
+
+#ifdef SK_BUILD_FOR_MAC
+#include <ApplicationServices/ApplicationServices.h>
+#endif
+
+#ifdef SK_BUILD_FOR_IOS
+#include <CoreGraphics/CoreGraphics.h>
+#endif
+
+class SkBitmap;
+class SkData;
+class SkStream;
+
+/**
+ * Given a CGImage, allocate an SkBitmap and copy the image's pixels into it. If scaleToFit is not
+ * null, use it to determine the size of the bitmap, and scale the image to fill the bitmap.
+ * Otherwise use the image's width/height.
+ *
+ * On failure, return false, and leave bitmap unchanged.
+ */
+SK_API bool SkCreateBitmapFromCGImage(SkBitmap* dst, CGImageRef src, SkISize* scaleToFit = NULL);
+
+/**
+ * Copy the pixels from src into the memory specified by info/rowBytes/dstPixels. On failure,
+ * return false (e.g. ImageInfo incompatible with src).
+ */
+SK_API bool SkCopyPixelsFromCGImage(const SkImageInfo& info, size_t rowBytes, void* dstPixels,
+ CGImageRef src);
+
+/**
+ * Create an imageref from the specified bitmap using the specified colorspace.
+ * If space is NULL, then CGColorSpaceCreateDeviceRGB() is used.
+ */
+SK_API 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);
+
+bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output);
+
+/**
+ * Return a provider that wraps the specified stream. It will become an
+ * owner of the stream, so the caller must still manage its ownership.
+ *
+ * To hand-off ownership of the stream to the provider, the caller must do
+ * something like the following:
+ *
+ * SkStream* stream = new ...;
+ * CGDataProviderRef provider = SkStreamToDataProvider(stream);
+ * stream->unref();
+ *
+ * Now when the provider is finally deleted, it will delete the stream.
+ */
+CGDataProviderRef SkCreateDataProviderFromStream(SkStream*);
+
+CGDataProviderRef SkCreateDataProviderFromData(SkData*);
+
+#endif
diff --git a/src/third_party/skia/include/utils/win/SkAutoCoInitialize.h b/src/third_party/skia/include/utils/win/SkAutoCoInitialize.h
new file mode 100644
index 0000000..f671e68
--- /dev/null
+++ b/src/third_party/skia/include/utils/win/SkAutoCoInitialize.h
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkAutoCo_DEFINED
+#define SkAutoCo_DEFINED
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "SkTemplates.h"
+
+/**
+ * An instance of this class initializes COM on creation
+ * and closes the COM library on destruction.
+ */
+class SkAutoCoInitialize : SkNoncopyable {
+private:
+ HRESULT fHR;
+public:
+ SkAutoCoInitialize();
+ ~SkAutoCoInitialize();
+ bool succeeded();
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/win/SkHRESULT.h b/src/third_party/skia/include/utils/win/SkHRESULT.h
new file mode 100644
index 0000000..4f9d1be
--- /dev/null
+++ b/src/third_party/skia/include/utils/win/SkHRESULT.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkHRESULT_DEFINED
+#define SkHRESULT_DEFINED
+
+#include "SkTypes.h"
+
+void SkTraceHR(const char* file, unsigned long line,
+ HRESULT hr, const char* msg);
+
+#ifdef SK_DEBUG
+#define SK_TRACEHR(_hr, _msg) SkTraceHR(__FILE__, __LINE__, _hr, _msg)
+#else
+#define SK_TRACEHR(_hr, _msg) _hr
+#endif
+
+#define HR_GENERAL(_ex, _msg, _ret) {\
+ HRESULT _hr = _ex;\
+ if (FAILED(_hr)) {\
+ SK_TRACEHR(_hr, _msg);\
+ return _ret;\
+ }\
+}
+
+//@{
+/**
+These macros are for reporting HRESULT errors.
+The expression will be evaluated.
+If the resulting HRESULT SUCCEEDED then execution will continue normally.
+If the HRESULT FAILED then the macro will return from the current function.
+In variants ending with 'M' the given message will be traced when FAILED.
+The HR variants will return the HRESULT when FAILED.
+The HRB variants will return false when FAILED.
+The HRN variants will return NULL when FAILED.
+The HRV variants will simply return when FAILED.
+The HRZ variants will return 0 when FAILED.
+*/
+#define HR(ex) HR_GENERAL(ex, NULL, _hr)
+#define HRM(ex, msg) HR_GENERAL(ex, msg, _hr)
+
+#define HRB(ex) HR_GENERAL(ex, NULL, false)
+#define HRBM(ex, msg) HR_GENERAL(ex, msg, false)
+
+#define HRN(ex) HR_GENERAL(ex, NULL, NULL)
+#define HRNM(ex, msg) HR_GENERAL(ex, msg, NULL)
+
+#define HRV(ex) HR_GENERAL(ex, NULL, )
+#define HRVM(ex, msg) HR_GENERAL(ex, msg, )
+
+#define HRZ(ex) HR_GENERAL(ex, NULL, 0)
+#define HRZM(ex, msg) HR_GENERAL(ex, msg, 0)
+//@}
+#endif
diff --git a/src/third_party/skia/include/utils/win/SkIStream.h b/src/third_party/skia/include/utils/win/SkIStream.h
new file mode 100644
index 0000000..deb3f3b
--- /dev/null
+++ b/src/third_party/skia/include/utils/win/SkIStream.h
@@ -0,0 +1,131 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkIStream_DEFINED
+#define SkIStream_DEFINED
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <ole2.h>
+
+class SkStream;
+class SkWStream;
+
+/**
+ * A bare IStream implementation which properly reference counts
+ * but returns E_NOTIMPL for all ISequentialStream and IStream methods.
+ */
+class SkBaseIStream : public IStream {
+private:
+ LONG _refcount;
+
+protected:
+ explicit SkBaseIStream();
+ virtual ~SkBaseIStream();
+
+public:
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid
+ , void ** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // ISequentialStream Interface
+public:
+ virtual HRESULT STDMETHODCALLTYPE Read(void* pv, ULONG cb, ULONG* pcbRead);
+
+ virtual HRESULT STDMETHODCALLTYPE Write(void const* pv
+ , ULONG cb
+ , ULONG* pcbWritten);
+
+ // IStream Interface
+public:
+ virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER);
+
+ virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*
+ , ULARGE_INTEGER
+ , ULARGE_INTEGER*
+ , ULARGE_INTEGER*);
+
+ virtual HRESULT STDMETHODCALLTYPE Commit(DWORD);
+
+ virtual HRESULT STDMETHODCALLTYPE Revert(void);
+
+ virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER
+ , ULARGE_INTEGER
+ , DWORD);
+
+ virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER
+ , ULARGE_INTEGER
+ , DWORD);
+
+ virtual HRESULT STDMETHODCALLTYPE Clone(IStream **);
+
+ virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove
+ , DWORD dwOrigin
+ , ULARGE_INTEGER* lpNewFilePointer);
+
+ virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg
+ , DWORD grfStatFlag);
+};
+
+/**
+ * A minimal read-only IStream implementation which wraps an SkIStream.
+ */
+class SkIStream : public SkBaseIStream {
+private:
+ SkStream *fSkStream;
+ bool fUnrefOnRelease;
+ ULARGE_INTEGER fLocation;
+
+ SkIStream(SkStream* stream, bool unrefOnRelease);
+ virtual ~SkIStream();
+
+public:
+ HRESULT static CreateFromSkStream(SkStream* stream
+ , bool unrefOnRelease
+ , IStream ** ppStream);
+
+ virtual HRESULT STDMETHODCALLTYPE Read(void* pv, ULONG cb, ULONG* pcbRead);
+
+ virtual HRESULT STDMETHODCALLTYPE Write(void const* pv
+ , ULONG cb
+ , ULONG* pcbWritten);
+
+ virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove
+ , DWORD dwOrigin
+ , ULARGE_INTEGER* lpNewFilePointer);
+
+ virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg
+ , DWORD grfStatFlag);
+};
+
+/**
+ * A minimal write-only IStream implementation which wraps an SkWIStream.
+ */
+class SkWIStream : public SkBaseIStream {
+private:
+ SkWStream *fSkWStream;
+
+ SkWIStream(SkWStream* stream);
+ virtual ~SkWIStream();
+
+public:
+ HRESULT static CreateFromSkWStream(SkWStream* stream, IStream ** ppStream);
+
+ virtual HRESULT STDMETHODCALLTYPE Write(void const* pv
+ , ULONG cb
+ , ULONG* pcbWritten);
+
+ virtual HRESULT STDMETHODCALLTYPE Commit(DWORD);
+
+ virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg
+ , DWORD grfStatFlag);
+};
+
+#endif
diff --git a/src/third_party/skia/include/utils/win/SkTScopedComPtr.h b/src/third_party/skia/include/utils/win/SkTScopedComPtr.h
new file mode 100644
index 0000000..38d1048
--- /dev/null
+++ b/src/third_party/skia/include/utils/win/SkTScopedComPtr.h
@@ -0,0 +1,76 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTScopedComPtr_DEFINED
+#define SkTScopedComPtr_DEFINED
+
+#include "SkTypes.h"
+#include "SkTemplates.h"
+
+template<typename T>
+class SkBlockComRef : public T {
+private:
+ virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
+ virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
+};
+
+template<typename T> T* SkRefComPtr(T* ptr) {
+ ptr->AddRef();
+ return ptr;
+}
+
+template<typename T> T* SkSafeRefComPtr(T* ptr) {
+ if (ptr) {
+ ptr->AddRef();
+ }
+ return ptr;
+}
+
+template<typename T>
+class SkTScopedComPtr : SkNoncopyable {
+private:
+ T *fPtr;
+
+public:
+ explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { }
+ ~SkTScopedComPtr() {
+ this->reset();
+ }
+ T &operator*() const { SkASSERT(fPtr != NULL); return *fPtr; }
+ SkBlockComRef<T> *operator->() const {
+ return static_cast<SkBlockComRef<T>*>(fPtr);
+ }
+ /**
+ * Returns the address of the underlying pointer.
+ * This is dangerous -- it breaks encapsulation and the reference escapes.
+ * Must only be used on instances currently pointing to NULL,
+ * and only to initialize the instance.
+ */
+ T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
+ T *get() const { return fPtr; }
+ void reset() {
+ if (this->fPtr) {
+ this->fPtr->Release();
+ this->fPtr = NULL;
+ }
+ }
+
+ void swap(SkTScopedComPtr<T>& that) {
+ T* temp = this->fPtr;
+ this->fPtr = that.fPtr;
+ that.fPtr = temp;
+ }
+
+ T* release() {
+ T* temp = this->fPtr;
+ this->fPtr = NULL;
+ return temp;
+ }
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkApplication.h b/src/third_party/skia/include/views/SkApplication.h
new file mode 100644
index 0000000..8f63539
--- /dev/null
+++ b/src/third_party/skia/include/views/SkApplication.h
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkApplication_DEFINED
+#define SkApplication_DEFINED
+
+class SkOSWindow;
+
+extern SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv);
+extern void application_init();
+extern void application_term();
+
+#ifdef SK_BUILD_FOR_IOS
+enum IOS_launch_type {
+ kError_iOSLaunchType = -1,
+ kTool_iOSLaunchType = 0,
+ kApplication__iOSLaunchType = 1
+};
+
+extern IOS_launch_type set_cmd_line_args(int argc, char *argv[],
+ const char* resourceDir);
+#endif
+
+#endif // SkApplication_DEFINED
diff --git a/src/third_party/skia/include/views/SkBGViewArtist.h b/src/third_party/skia/include/views/SkBGViewArtist.h
new file mode 100644
index 0000000..33054c8
--- /dev/null
+++ b/src/third_party/skia/include/views/SkBGViewArtist.h
@@ -0,0 +1,33 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkBGViewArtist_DEFINED
+#define SkBGViewArtist_DEFINED
+
+#include "SkView.h"
+#include "SkPaint.h"
+
+class SkBGViewArtist : public SkView::Artist {
+public:
+ SkBGViewArtist(SkColor c = SK_ColorWHITE);
+ virtual ~SkBGViewArtist();
+
+ const SkPaint& paint() const { return fPaint; }
+ SkPaint& paint() { return fPaint; }
+
+protected:
+ // overrides
+ virtual void onDraw(SkView*, SkCanvas*);
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+
+private:
+ SkPaint fPaint;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkEvent.h b/src/third_party/skia/include/views/SkEvent.h
new file mode 100644
index 0000000..f4df448
--- /dev/null
+++ b/src/third_party/skia/include/views/SkEvent.h
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkEvent_DEFINED
+#define SkEvent_DEFINED
+
+#include "SkDOM.h"
+#include "SkMetaData.h"
+#include "SkString.h"
+
+/** 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,
+ its doEvent() method is called with the event.
+*/
+typedef uint32_t SkEventSinkID;
+
+/**
+ * \class SkEvent
+ *
+ * When an event is dispatched from the event queue, it is either sent to
+ * the eventsink matching the target ID (if not 0), or the target proc is
+ * called (if not NULL).
+ */
+class SkEvent {
+public:
+ /**
+ * Function pointer that takes an event, returns true if it "handled" it.
+ */
+ typedef bool (*Proc)(const SkEvent& evt);
+
+ SkEvent();
+ explicit SkEvent(const SkString& type, SkEventSinkID = 0);
+ explicit SkEvent(const char type[], SkEventSinkID = 0);
+ SkEvent(const SkEvent& src);
+ ~SkEvent();
+
+ /** Copy the event's type into the specified SkString parameter */
+ void getType(SkString* str) const;
+
+ /** Returns true if the event's type matches exactly the specified type (case sensitive) */
+ bool isType(const SkString& str) const;
+
+ /** Returns true if the event's type matches exactly the specified type (case sensitive) */
+ bool isType(const char type[], size_t len = 0) const;
+
+ /**
+ * Set the event's type to the specified string.
+ */
+ void setType(const SkString&);
+
+ /**
+ * Set the event's type to the specified string.
+ */
+ void setType(const char type[], size_t len = 0);
+
+ /**
+ * Return the target ID, or 0 if there is none.
+ *
+ * When an event is dispatched from the event queue, it is either sent to
+ * the eventsink matching the targetID (if not 0), or the target proc is
+ * called (if not NULL).
+ */
+ SkEventSinkID getTargetID() const { return fTargetID; }
+
+ /**
+ * Set the target ID for this event. 0 means none. Calling this will
+ * automatically clear the targetProc to null.
+ *
+ * When an event is dispatched from the event queue, it is either sent to
+ * the eventsink matching the targetID (if not 0), or the target proc is
+ * called (if not NULL).
+ */
+ SkEvent* setTargetID(SkEventSinkID targetID) {
+ fTargetProc = NULL;
+ fTargetID = targetID;
+ return this;
+ }
+
+ /**
+ * Return the target proc, or NULL if it has none.
+ *
+ * When an event is dispatched from the event queue, it is either sent to
+ * the eventsink matching the targetID (if not 0), or the target proc is
+ * called (if not NULL).
+ */
+ Proc getTargetProc() const { return fTargetProc; }
+
+ /**
+ * Set the target ID for this event. NULL means none. Calling this will
+ * automatically clear the targetID to 0.
+ *
+ * When an event is dispatched from the event queue, it is either sent to
+ * the eventsink matching the targetID (if not 0), or the target proc is
+ * called (if not NULL).
+ */
+ SkEvent* setTargetProc(Proc proc) {
+ fTargetID = 0;
+ fTargetProc = proc;
+ return this;
+ }
+
+ /**
+ * Return the event's unnamed 32bit field. Default value is 0
+ */
+ uint32_t getFast32() const { return f32; }
+
+ /**
+ * Set the event's unnamed 32bit field.
+ */
+ void setFast32(uint32_t x) { f32 = x; }
+
+ /** Return true if the event contains the named 32bit field, and return the field
+ in value (if value is non-null). If there is no matching named field, return false
+ and ignore the value parameter.
+ */
+ bool findS32(const char name[], int32_t* value = NULL) const { return fMeta.findS32(name, value); }
+ /** Return true if the event contains the named SkScalar field, and return the field
+ in value (if value is non-null). If there is no matching named field, return false
+ and ignore the value parameter.
+ */
+ bool findScalar(const char name[], SkScalar* value = NULL) const { return fMeta.findScalar(name, value); }
+ /** Return true if the event contains the named SkScalar field, and return the fields
+ in value[] (if value is non-null), and return the number of SkScalars in count (if count is non-null).
+ If there is no matching named field, return false and ignore the value and count parameters.
+ */
+ const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const { return fMeta.findScalars(name, count, values); }
+ /** Return the value of the named string field, or if no matching named field exists, return null.
+ */
+ const char* findString(const char name[]) const { return fMeta.findString(name); }
+ /** Return true if the event contains the named pointer field, and return the field
+ in value (if value is non-null). If there is no matching named field, return false
+ and ignore the value parameter.
+ */
+ 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); }
+ /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */
+ bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); }
+ /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */
+ bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); }
+ /** 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); }
+ /** Add/replace the named SkScalar field to the event. In XML use the subelement <data name=... scalar=... /> */
+ void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); }
+ /** Add/replace the named SkScalar[] field to the event. */
+ SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL) { return fMeta.setScalars(name, count, values); }
+ /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
+ void setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); }
+ /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
+ void setString(const char name[], const char value[]) { fMeta.setString(name, value); }
+ /** 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; }
+ /** Return the underlying metadata object */
+ const SkMetaData& getMetaData() const { return fMeta; }
+
+ /** Call this to initialize the event from the specified XML node */
+ void inflate(const SkDOM&, const SkDOM::Node*);
+
+ SkDEBUGCODE(void dump(const char title[] = NULL);)
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Post to the event queue using the event's targetID or target-proc.
+ *
+ * The event must be dynamically allocated, as ownership is transferred to
+ * the event queue. It cannot be allocated on the stack or in a global.
+ */
+ void post() {
+ return this->postDelay(0);
+ }
+
+ /**
+ * Post to the event queue using the event's targetID or target-proc and
+ * the specifed millisecond delay.
+ *
+ * The event must be dynamically allocated, as ownership is transferred to
+ * the event queue. It cannot be allocated on the stack or in a global.
+ */
+ void postDelay(SkMSec delay);
+
+ /**
+ * Post to the event queue using the event's targetID or target-proc.
+ * The event will be delivered no sooner than the specified millisecond
+ * time, as measured by SkTime::GetMSecs().
+ *
+ * The event must be dynamically allocated, as ownership is transferred to
+ * the event queue. It cannot be allocated on the stack or in a global.
+ */
+ void postTime(SkMSec time);
+
+ ///////////////////////////////////////////////
+ /** Porting layer must call these functions **/
+ ///////////////////////////////////////////////
+
+ /** Global initialization function for the SkEvent system. Should be called exactly
+ once before any other event method is called, and should be called after the
+ call to SkGraphics::Init().
+ */
+ static void Init();
+ /** Global cleanup function for the SkEvent system. Should be called exactly once after
+ all event methods have been called, and should be called before calling SkGraphics::Term().
+ */
+ static void Term();
+
+ /** Call this to process one event from the queue. If it returns true, there are more events
+ to process.
+ */
+ static bool ProcessEvent();
+ /** Call this whenever the requested timer has expired (requested by a call to SetQueueTimer).
+ It will post any delayed events whose time as "expired" onto the event queue.
+ It may also call SignalQueueTimer() and SignalNonEmptyQueue().
+ */
+ 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 **/
+ ////////////////////////////////////////////////////
+
+ /** Called whenever an SkEvent is posted to an empty queue, so that the OS
+ can be told to later call Dequeue().
+ */
+ static void SignalNonEmptyQueue();
+ /** Called whenever the delay until the next delayed event changes. If zero is
+ passed, then there are no more queued delay events.
+ */
+ static void SignalQueueTimer(SkMSec delay);
+
+#if defined(SK_BUILD_FOR_WIN)
+ static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+#endif
+
+private:
+ SkMetaData fMeta;
+ mutable char* fType; // may be characters with low bit set to know that it is not a pointer
+ uint32_t f32;
+
+ // 'there can be only one' (non-zero) between target-id and target-proc
+ SkEventSinkID fTargetID;
+ Proc fTargetProc;
+
+ // these are for our implementation of the event queue
+ SkMSec fTime;
+ SkEvent* fNextEvent; // either in the delay or normal event queue
+
+ void initialize(const char* type, size_t typeLen, SkEventSinkID);
+
+ static bool Enqueue(SkEvent* evt);
+ static SkMSec EnqueueTime(SkEvent* evt, SkMSec time);
+ static SkEvent* Dequeue();
+ static bool QHasEvents();
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkEventSink.h b/src/third_party/skia/include/views/SkEventSink.h
new file mode 100644
index 0000000..01d4f7a
--- /dev/null
+++ b/src/third_party/skia/include/views/SkEventSink.h
@@ -0,0 +1,112 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkEventSink_DEFINED
+#define SkEventSink_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkEvent.h"
+
+struct SkTagList;
+
+/** \class SkEventSink
+
+ SkEventSink is the base class for all objects that receive SkEvents.
+*/
+class SkEventSink : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkEventSink)
+
+ SkEventSink();
+ virtual ~SkEventSink();
+
+ /**
+ * Returns this eventsink's unique ID. Use this to post SkEvents to
+ * this eventsink.
+ */
+ SkEventSinkID getSinkID() const { return fID; }
+
+ /**
+ * Call this to pass an event to this object for processing. Returns true if the
+ * event was handled.
+ */
+ bool doEvent(const SkEvent&);
+
+ /** Returns true if the sink (or one of its subclasses) understands the event as a query.
+ If so, the sink may modify the event to communicate its "answer".
+ */
+ bool doQuery(SkEvent* query);
+
+ /**
+ * Add sinkID to the list of listeners, to receive events from calls to sendToListeners()
+ * and postToListeners(). If sinkID already exists in the listener list, no change is made.
+ */
+ void addListenerID(SkEventSinkID sinkID);
+
+ /**
+ * Copy listeners from one event sink to another, typically from parent to child.
+ * @param from the event sink to copy the listeners from
+ */
+ void copyListeners(const SkEventSink& from);
+
+ /**
+ * Remove sinkID from the list of listeners. If sinkID does not appear in the list,
+ * no change is made.
+ */
+ void removeListenerID(SkEventSinkID);
+
+ /**
+ * Returns true if there are 1 or more listeners attached to this eventsink
+ */
+ bool hasListeners() const;
+
+ /**
+ * Posts a copy of evt to each of the eventsinks in the lisener list.
+ * This ignores the targetID and target proc in evt.
+ */
+ void postToListeners(const SkEvent& evt, SkMSec delay = 0);
+
+ enum EventResult {
+ kHandled_EventResult, //!< the eventsink returned true from its doEvent method
+ kNotHandled_EventResult, //!< the eventsink returned false from its doEvent method
+ kSinkNotFound_EventResult //!< no matching eventsink was found for the event's getSink().
+ };
+
+ /**
+ * DoEvent handles dispatching the event to its target ID or proc.
+ */
+ static EventResult DoEvent(const SkEvent&);
+
+ /**
+ * Returns the matching eventsink, or null if not found
+ */
+ static SkEventSink* FindSink(SkEventSinkID);
+
+protected:
+ /** Override this to handle events in your subclass. Be sure to call the inherited version
+ for events that you don't handle.
+ */
+ virtual bool onEvent(const SkEvent&);
+ virtual bool onQuery(SkEvent*);
+
+ SkTagList* findTagList(U8CPU tag) const;
+ void addTagList(SkTagList*);
+ void removeTagList(U8CPU tag);
+
+private:
+ SkEventSinkID fID;
+ SkTagList* fTagHead;
+
+ // for our private link-list
+ SkEventSink* fNextSink;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkKey.h b/src/third_party/skia/include/views/SkKey.h
new file mode 100644
index 0000000..036e2c3
--- /dev/null
+++ b/src/third_party/skia/include/views/SkKey.h
@@ -0,0 +1,62 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkKey_DEFINED
+#define SkKey_DEFINED
+
+#include "SkTypes.h"
+
+enum SkKey {
+ //reordering these to match android.app.KeyEvent
+ kNONE_SkKey, //corresponds to android's UNKNOWN
+
+ kLeftSoftKey_SkKey,
+ kRightSoftKey_SkKey,
+
+ kHome_SkKey, //!< the home key - added to match android
+ kBack_SkKey, //!< (CLR)
+ kSend_SkKey, //!< the green (talk) key
+ kEnd_SkKey, //!< the red key
+
+ k0_SkKey,
+ k1_SkKey,
+ k2_SkKey,
+ k3_SkKey,
+ k4_SkKey,
+ k5_SkKey,
+ k6_SkKey,
+ k7_SkKey,
+ k8_SkKey,
+ k9_SkKey,
+ kStar_SkKey, //!< the * key
+ kHash_SkKey, //!< the # key
+
+ kUp_SkKey,
+ kDown_SkKey,
+ kLeft_SkKey,
+ kRight_SkKey,
+
+ kOK_SkKey, //!< the center key
+
+ kVolUp_SkKey, //!< volume up - match android
+ kVolDown_SkKey, //!< volume down - same
+ kPower_SkKey, //!< power button - same
+ kCamera_SkKey, //!< camera - same
+
+ kSkKeyCount
+};
+
+enum SkModifierKeys {
+ kShift_SkModifierKey = 1 << 0,
+ kControl_SkModifierKey = 1 << 1,
+ kOption_SkModifierKey = 1 << 2, // same as ALT
+ kCommand_SkModifierKey = 1 << 3,
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkOSMenu.h b/src/third_party/skia/include/views/SkOSMenu.h
new file mode 100644
index 0000000..7325418
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSMenu.h
@@ -0,0 +1,182 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkOSMenu_DEFINED
+#define SkOSMenu_DEFINED
+
+#include "SkEvent.h"
+#include "SkTDArray.h"
+
+class SkOSMenu {
+public:
+ explicit SkOSMenu(const char title[] = "");
+ ~SkOSMenu();
+
+ /**
+ * Each of these (except action) has an associated value, which is stored in
+ * the event payload for the item.
+ * Each type has a specific type for its value...
+ * Action : none
+ * List : int (selected index)
+ * Segmented : int (selected index)
+ * Slider : float
+ * Switch : bool
+ * TextField : string
+ * TriState : TriState
+ * Custom : custom object/value
+ */
+ enum Type {
+ kAction_Type,
+ kList_Type,
+ kSlider_Type,
+ kSwitch_Type,
+ kTriState_Type,
+ kTextField_Type,
+ kCustom_Type
+ };
+
+ enum TriState {
+ kMixedState = -1,
+ kOffState = 0,
+ kOnState = 1
+ };
+
+ class Item {
+ public:
+ /**
+ * Auto increments a global to generate an unique ID for each new item
+ * Note: Thread safe
+ */
+ Item(const char label[], SkOSMenu::Type type, const char slotName[],
+ SkEvent* evt);
+ ~Item() { delete fEvent; }
+
+ SkEvent* getEvent() const { return fEvent; }
+ int getID() const { return fID; }
+ const char* getLabel() const { return fLabel.c_str(); }
+ const char* getSlotName() const { return fSlotName.c_str(); }
+ Type getType() const { return fType; }
+ void setKeyEquivalent(SkUnichar key) { fKey = key; }
+ SkUnichar getKeyEquivalent() const { return fKey; }
+
+ /**
+ * Helper functions for predefined types
+ */
+ void setBool(bool value) const; //For Switch
+ void setScalar(SkScalar value) const; //For Slider
+ void setInt(int value) const; //For List
+ void setTriState(TriState value) const; //For Tristate
+ void setString(const char value[]) const; //For TextField
+
+ /**
+ * Post event associated with the menu item to target, any changes to
+ * the associated event must be made prior to calling this method
+ */
+ void postEvent() const { (new SkEvent(*(fEvent)))->post(); }
+
+ private:
+ int fID;
+ SkEvent* fEvent;
+ SkString fLabel;
+ SkString fSlotName;
+ Type fType;
+ SkUnichar fKey;
+ };
+
+ void reset();
+ const char* getTitle() const { return fTitle.c_str(); }
+ void setTitle (const char title[]) { fTitle.set(title); }
+ int getCount() const { return fItems.count(); }
+ const Item* getItemByID(int itemID) const;
+ void getItems(const Item* items[]) const;
+
+ /**
+ * Assign key to the menu item with itemID, will do nothing if there's no
+ * item with the id given
+ */
+ void assignKeyEquivalentToItem(int itemID, SkUnichar key);
+ /**
+ * Call this in a SkView's onHandleChar to trigger any menu items with the
+ * given key equivalent. If such an item is found, the method will return
+ * true and its corresponding event will be triggered (default behavior
+ * defined for switches(toggling), tristates(cycle), and lists(cycle),
+ * for anything else, the event attached is posted without state changes)
+ * If no menu item can be matched with the key, false will be returned
+ */
+ bool handleKeyEquivalent(SkUnichar key);
+
+ /**
+ * The following functions append new items to the menu and returns their
+ * associated unique id, which can be used to by the client to refer to
+ * the menu item created and change its state. slotName specifies the string
+ * identifier of any state/value to be returned in the item's SkEvent object
+ * NOTE: evt must be dynamically allocated
+ */
+ int appendItem(const char label[], Type type, const char slotName[],
+ SkEvent* evt);
+
+ /**
+ * Create predefined items with the given parameters. To be used with the
+ * other helper functions below to retrive/update state information.
+ * Note: the helper functions below assume that slotName is UNIQUE for all
+ * menu items of the same type since it's used to identify the event
+ */
+ int appendAction(const char label[], SkEventSinkID target);
+ int appendList(const char label[], const char slotName[],
+ SkEventSinkID target, int defaultIndex, const char* ...);
+ int appendSlider(const char label[], const char slotName[],
+ SkEventSinkID target, SkScalar min, SkScalar max,
+ SkScalar defaultValue);
+ int appendSwitch(const char label[], const char slotName[],
+ SkEventSinkID target, bool defaultState = false);
+ int appendTriState(const char label[], const char slotName[],
+ SkEventSinkID target, TriState defaultState = kOffState);
+ int appendTextField(const char label[], const char slotName[],
+ SkEventSinkID target, const char placeholder[] = "");
+
+
+ /**
+ * Helper functions to retrieve information other than the stored value for
+ * some predefined types
+ */
+ static bool FindListItemCount(const SkEvent& evt, int* count);
+ /**
+ * Ensure that the items array can store n SkStrings where n is the count
+ * extracted using FindListItemCount
+ */
+ static bool FindListItems(const SkEvent& evt, SkString items[]);
+ static bool FindSliderMin(const SkEvent& evt, SkScalar* min);
+ static bool FindSliderMax(const SkEvent& evt, SkScalar* max);
+
+ /**
+ * Returns true if an action with the given label is found, false otherwise
+ */
+ static bool FindAction(const SkEvent& evt, const char label[]);
+ /**
+ * The following helper functions will return true if evt is generated from
+ * a predefined item type and retrieve the corresponding state information.
+ * They will return false and leave value unchanged if there's a type
+ * mismatch or slotName is incorrect
+ */
+ static bool FindListIndex(const SkEvent& evt, const char slotName[], int* value);
+ static bool FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value);
+ static bool FindSwitchState(const SkEvent& evt, const char slotName[], bool* value);
+ static bool FindTriState(const SkEvent& evt, const char slotName[], TriState* value);
+ static bool FindText(const SkEvent& evt, const char slotName[], SkString* value);
+
+private:
+ SkString fTitle;
+ SkTDArray<Item*> fItems;
+
+ // illegal
+ SkOSMenu(const SkOSMenu&);
+ SkOSMenu& operator=(const SkOSMenu&);
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkOSWindow_Android.h b/src/third_party/skia/include/views/SkOSWindow_Android.h
new file mode 100644
index 0000000..ae4e880
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSWindow_Android.h
@@ -0,0 +1,48 @@
+
+/*
+ * Copyright 2011 Skia
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkOSWindow_Android_DEFINED
+#define SkOSWindow_Android_DEFINED
+
+#include "SkWindow.h"
+
+class SkIRect;
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void*) {}
+ ~SkOSWindow() {}
+
+ enum SkBackEndTypes {
+ kNone_BackEndType,
+ kNativeGL_BackEndType,
+ };
+
+ struct AttachmentInfo {
+ int fSampleCount;
+ int fStencilBits;
+ };
+
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo* info);
+ void detach() {}
+ void present() {}
+
+ virtual void onPDFSaved(const char title[], const char desc[],
+ const char path[]);
+
+protected:
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ virtual void onSetTitle(const char title[]);
+
+private:
+ typedef SkWindow INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkOSWindow_Mac.h b/src/third_party/skia/include/views/SkOSWindow_Mac.h
new file mode 100644
index 0000000..5dea2fc
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSWindow_Mac.h
@@ -0,0 +1,58 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkOSWindow_MacCocoa_DEFINED
+#define SkOSWindow_MacCocoa_DEFINED
+
+#include "SkWindow.h"
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void* hwnd);
+ ~SkOSWindow();
+ void* getHWND() const { return fHWND; }
+
+ virtual bool onDispatchClick(int x, int y, Click::State state,
+ void* owner, unsigned modi);
+ enum SkBackEndTypes {
+ kNone_BackEndType,
+#if SK_SUPPORT_GPU
+ kNativeGL_BackEndType,
+#endif
+ };
+
+ struct AttachmentInfo {
+ int fSampleCount;
+ int fStencilBits;
+ };
+
+ void detach();
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo*);
+ void present();
+
+protected:
+ // overrides from SkEventSink
+ virtual bool onEvent(const SkEvent& evt);
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+ virtual void onUpdateMenu(const SkOSMenu*);
+ virtual void onSetTitle(const char[]);
+
+private:
+ void* fHWND;
+ bool fInvalEventIsPending;
+ void* fNotifier;
+#if SK_SUPPORT_GPU
+ void* fGLContext;
+#endif
+ typedef SkWindow INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkOSWindow_NaCl.h b/src/third_party/skia/include/views/SkOSWindow_NaCl.h
new file mode 100644
index 0000000..2296023
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSWindow_NaCl.h
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright 2012 Skia
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkOSWindow_NaCl_DEFINED
+#define SkOSWindow_NaCl_DEFINED
+
+#include "SkWindow.h"
+
+class SkIRect;
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void*) {}
+ ~SkOSWindow() {}
+
+ enum SkBackEndTypes {
+ kNone_BackEndType,
+ kNativeGL_BackEndType,
+ };
+
+ struct AttachmentInfo {
+ int fSampleCount;
+ int fStencilBits;
+ };
+
+ bool attach(SkBackEndTypes /* attachType */, int /* msaaSampleCount */, AttachmentInfo* info) {
+ info->fSampleCount = 0;
+ info->fStencilBits = 0;
+ return true;
+ }
+ void detach() {}
+ void present() {}
+
+ virtual void onPDFSaved(const char title[], const char desc[],
+ const char path[]);
+
+protected:
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ virtual void onSetTitle(const char title[]);
+
+private:
+ typedef SkWindow INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkOSWindow_SDL.h b/src/third_party/skia/include/views/SkOSWindow_SDL.h
new file mode 100644
index 0000000..e6b59e6
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSWindow_SDL.h
@@ -0,0 +1,44 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#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/src/third_party/skia/include/views/SkOSWindow_Unix.h b/src/third_party/skia/include/views/SkOSWindow_Unix.h
new file mode 100644
index 0000000..8a55ef4
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSWindow_Unix.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkOSWindow_Unix_DEFINED
+#define SkOSWindow_Unix_DEFINED
+
+#include <GL/glx.h>
+#include <X11/Xlib.h>
+
+#include "SkWindow.h"
+
+class SkEvent;
+
+struct SkUnixWindow {
+ Display* fDisplay;
+ Window fWin;
+ size_t fOSWin;
+ GC fGc;
+ GLXContext fGLContext;
+};
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void*);
+ ~SkOSWindow();
+
+ void* getHWND() const { return (void*)fUnixWindow.fWin; }
+ void* getDisplay() const { return (void*)fUnixWindow.fDisplay; }
+ void* getUnixWindow() const { return (void*)&fUnixWindow; }
+ void loop();
+
+ enum SkBackEndTypes {
+ kNone_BackEndType,
+ kNativeGL_BackEndType,
+ };
+
+ struct AttachmentInfo {
+ int fSampleCount;
+ int fStencilBits;
+ };
+
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo*);
+ void detach();
+ void present();
+
+ int getMSAASampleCount() const { return fMSAASampleCount; }
+
+ //static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+protected:
+ // Overridden from from SkWindow:
+ virtual void onSetTitle(const char title[]) SK_OVERRIDE;
+
+private:
+ enum NextXEventResult {
+ kContinue_NextXEventResult,
+ kQuitRequest_NextXEventResult,
+ kPaintRequest_NextXEventResult
+ };
+
+ NextXEventResult nextXEvent();
+ void doPaint();
+ void mapWindowAndWait();
+
+ void closeWindow();
+ void initWindow(int newMSAASampleCount, AttachmentInfo* info);
+
+ SkUnixWindow fUnixWindow;
+
+ // Needed for GL
+ XVisualInfo* fVi;
+ // we recreate the underlying xwindow if this changes
+ int fMSAASampleCount;
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkOSWindow_Win.h b/src/third_party/skia/include/views/SkOSWindow_Win.h
new file mode 100644
index 0000000..6b5977c
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSWindow_Win.h
@@ -0,0 +1,101 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkOSWindow_Win_DEFINED
+#define SkOSWindow_Win_DEFINED
+
+#include "SkWindow.h"
+
+#if SK_ANGLE
+#include "EGL/egl.h"
+#endif
+
+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);
+
+ enum SkBackEndTypes {
+ kNone_BackEndType,
+#if SK_SUPPORT_GPU
+ kNativeGL_BackEndType,
+#if SK_ANGLE
+ kANGLE_BackEndType,
+#endif // SK_ANGLE
+#endif // SK_SUPPORT_GPU
+ };
+
+ struct AttachmentInfo {
+ int fSampleCount;
+ int fStencilBits;
+ };
+
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo*);
+ void detach();
+ void present();
+
+ bool wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static bool QuitOnDeactivate(HWND hWnd);
+
+ enum {
+ SK_WM_SkEvent = WM_APP + 1000,
+ SK_WM_SkTimerID = 0xFFFF // just need a non-zero value
+ };
+
+protected:
+ virtual bool quitOnDeactivate() { return true; }
+
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+
+ virtual void onSetTitle(const char title[]);
+
+private:
+ void* fHWND;
+
+ void doPaint(void* ctx);
+
+#if SK_SUPPORT_GPU
+ void* fHGLRC;
+#if SK_ANGLE
+ EGLDisplay fDisplay;
+ EGLContext fContext;
+ EGLSurface fSurface;
+ EGLConfig fConfig;
+#endif // SK_ANGLE
+#endif // SK_SUPPORT_GPU
+
+ HMENU fMBar;
+
+ SkBackEndTypes fAttached;
+
+#if SK_SUPPORT_GPU
+ bool attachGL(int msaaSampleCount, AttachmentInfo* info);
+ void detachGL();
+ void presentGL();
+
+#if SK_ANGLE
+ bool attachANGLE(int msaaSampleCount, AttachmentInfo* info);
+ void detachANGLE();
+ void presentANGLE();
+#endif // SK_ANGLE
+#endif // SK_SUPPORT_GPU
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkOSWindow_iOS.h b/src/third_party/skia/include/views/SkOSWindow_iOS.h
new file mode 100644
index 0000000..1984900
--- /dev/null
+++ b/src/third_party/skia/include/views/SkOSWindow_iOS.h
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkOSWindow_iOS_DEFINED
+#define SkOSWindow_iOS_DEFINED
+
+#include "SkWindow.h"
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void* hwnd);
+ ~SkOSWindow();
+ void* getHWND() const { return fHWND; }
+
+ enum SkBackEndTypes {
+ kNone_BackEndType,
+ kNativeGL_BackEndType,
+ };
+
+ struct AttachmentInfo {
+ int fSampleCount;
+ int fStencilBits;
+ };
+
+ void detach();
+ bool attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo*);
+ void present();
+
+protected:
+ // overrides from SkEventSink
+ virtual bool onEvent(const SkEvent& evt);
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+ virtual void onUpdateMenu(SkOSMenu*);
+ virtual void onSetTitle(const char[]);
+
+private:
+ void* fHWND;
+ bool fInvalEventIsPending;
+ void* fNotifier;
+ typedef SkWindow INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkStackViewLayout.h b/src/third_party/skia/include/views/SkStackViewLayout.h
new file mode 100644
index 0000000..f2a7cf0
--- /dev/null
+++ b/src/third_party/skia/include/views/SkStackViewLayout.h
@@ -0,0 +1,88 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkStackViewLayout_DEFINED
+#define SkStackViewLayout_DEFINED
+
+#include "SkView.h"
+
+class SkStackViewLayout : public SkView::Layout {
+public:
+ SkStackViewLayout();
+
+ enum Orient {
+ kHorizontal_Orient,
+ kVertical_Orient,
+
+ kOrientCount
+ };
+ Orient getOrient() const { return (Orient)fOrient; }
+ void setOrient(Orient);
+
+ void getMargin(SkRect*) const;
+ void setMargin(const SkRect&);
+
+ SkScalar getSpacer() const { return fSpacer; }
+ void setSpacer(SkScalar);
+
+ /** Controls the posititioning in the same direction as the orientation
+ */
+ enum Pack {
+ kStart_Pack,
+ kCenter_Pack,
+ kEnd_Pack,
+
+ kPackCount
+ };
+ Pack getPack() const { return (Pack)fPack; }
+ void setPack(Pack);
+
+ /** Controls the posititioning at right angles to the orientation
+ */
+ enum Align {
+ kStart_Align,
+ kCenter_Align,
+ kEnd_Align,
+ kStretch_Align,
+
+ kAlignCount
+ };
+ Align getAlign() const { return (Align)fAlign; }
+ void setAlign(Align);
+
+ bool getRound() const { return SkToBool(fRound); }
+ void setRound(bool);
+
+protected:
+ virtual void onLayoutChildren(SkView* parent);
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+
+private:
+ SkRect fMargin;
+ SkScalar fSpacer;
+ uint8_t fOrient, fPack, fAlign, fRound;
+};
+
+class SkFillViewLayout : public SkView::Layout {
+public:
+ SkFillViewLayout();
+ void getMargin(SkRect*) const;
+ void setMargin(const SkRect&);
+
+protected:
+ // overrides;
+ virtual void onLayoutChildren(SkView* parent);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkRect fMargin;
+ typedef SkView::Layout INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkSystemEventTypes.h b/src/third_party/skia/include/views/SkSystemEventTypes.h
new file mode 100644
index 0000000..bb2b5d5
--- /dev/null
+++ b/src/third_party/skia/include/views/SkSystemEventTypes.h
@@ -0,0 +1,25 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkSystemEventTypes_DEFINED
+#define SkSystemEventTypes_DEFINED
+
+/*
+ The goal of these strings is two-fold:
+ 1) make funny strings (containing at least one char < 32) to avoid colliding with "user" strings
+ 2) keep them <= 4 bytes, so we can avoid an allocation in SkEvent::setType()
+*/
+#define SK_EventType_Delay "\xd" "lay"
+#define SK_EventType_Inval "nv" "\xa" "l"
+#define SK_EventType_Key "key" "\x1"
+#define SK_EventType_OnEnd "on" "\xe" "n"
+#define SK_EventType_Unichar "\xc" "har"
+#define SK_EventType_KeyUp "key" "\xf"
+
+#endif
diff --git a/src/third_party/skia/include/views/SkTextBox.h b/src/third_party/skia/include/views/SkTextBox.h
new file mode 100644
index 0000000..e217076
--- /dev/null
+++ b/src/third_party/skia/include/views/SkTextBox.h
@@ -0,0 +1,77 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkTextBox_DEFINED
+#define SkTextBox_DEFINED
+
+#include "SkCanvas.h"
+
+/** \class SkTextBox
+
+ SkTextBox is a helper class for drawing 1 or more lines of text
+ within a rectangle. The textbox is positioned and clipped by its Frame.
+ The Margin rectangle controls where the text is drawn relative to
+ the Frame. Line-breaks occur inside the Margin rectangle.
+
+ Spacing is a linear equation used to compute the distance between lines
+ of text. Spacing consists of two scalars: mul and add, and the spacing
+ between lines is computed as: spacing = paint.getTextSize() * mul + add
+*/
+class SkTextBox {
+public:
+ SkTextBox();
+
+ enum Mode {
+ kOneLine_Mode,
+ kLineBreak_Mode,
+
+ kModeCount
+ };
+ Mode getMode() const { return (Mode)fMode; }
+ void setMode(Mode);
+
+ enum SpacingAlign {
+ kStart_SpacingAlign,
+ kCenter_SpacingAlign,
+ kEnd_SpacingAlign,
+
+ kSpacingAlignCount
+ };
+ SpacingAlign getSpacingAlign() const { return (SpacingAlign)fSpacingAlign; }
+ void setSpacingAlign(SpacingAlign);
+
+ void getBox(SkRect*) const;
+ void setBox(const SkRect&);
+ void setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
+
+ void getSpacing(SkScalar* mul, SkScalar* add) const;
+ void setSpacing(SkScalar mul, SkScalar add);
+
+ 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 {
+public:
+ static int CountLines(const char text[], size_t len, const SkPaint&, SkScalar width);
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkTouchGesture.h b/src/third_party/skia/include/views/SkTouchGesture.h
new file mode 100644
index 0000000..3a0cfce
--- /dev/null
+++ b/src/third_party/skia/include/views/SkTouchGesture.h
@@ -0,0 +1,77 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkTouchGesture_DEFINED
+#define SkTouchGesture_DEFINED
+
+#include "SkTDArray.h"
+#include "SkMatrix.h"
+
+struct SkFlingState {
+ SkFlingState() : fActive(false) {}
+
+ bool isActive() const { return fActive; }
+ void stop() { fActive = false; }
+
+ void reset(float sx, float sy);
+ bool evaluateMatrix(SkMatrix* matrix);
+
+private:
+ SkPoint fDirection;
+ SkScalar fSpeed0;
+ double fTime0;
+ bool fActive;
+};
+
+class SkTouchGesture {
+public:
+ SkTouchGesture();
+ ~SkTouchGesture();
+
+ void touchBegin(void* owner, float x, float y);
+ void touchMoved(void* owner, float x, float y);
+ void touchEnd(void* owner);
+ void reset();
+
+ bool isActive() { return fFlinger.isActive(); }
+ void stop() { fFlinger.stop(); }
+
+ const SkMatrix& localM();
+ const SkMatrix& globalM() const { return fGlobalM; }
+
+private:
+ enum State {
+ kEmpty_State,
+ kTranslate_State,
+ kZoom_State,
+ };
+
+ struct Rec {
+ void* fOwner;
+ float fStartX, fStartY;
+ float fPrevX, fPrevY;
+ float fLastX, fLastY;
+ SkMSec fPrevT, fLastT;
+ };
+ SkTDArray<Rec> fTouches;
+
+ State fState;
+ SkMatrix fLocalM, fGlobalM;
+ SkFlingState fFlinger;
+ SkMSec fLastUpT;
+ SkPoint fLastUpP;
+
+
+ void flushLocalM();
+ int findRec(void* owner) const;
+ void appendNewRec(void* owner, float x, float y);
+ float computePinch(const Rec&, const Rec&);
+ float limitTotalZoom(float scale) const;
+ bool handleDblTap(float, float);
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkView.h b/src/third_party/skia/include/views/SkView.h
new file mode 100644
index 0000000..c083cf1
--- /dev/null
+++ b/src/third_party/skia/include/views/SkView.h
@@ -0,0 +1,405 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkView_DEFINED
+#define SkView_DEFINED
+
+#include "SkEventSink.h"
+#include "SkRect.h"
+#include "SkDOM.h"
+#include "SkTDict.h"
+#include "SkMatrix.h"
+#include "SkMetaData.h"
+
+class SkCanvas;
+class SkLayerView;
+
+/** \class SkView
+
+ SkView is the base class for screen management. All widgets and controls inherit
+ from SkView.
+*/
+class SkView : public SkEventSink {
+public:
+ enum Flag_Shift {
+ kVisible_Shift,
+ kEnabled_Shift,
+ kFocusable_Shift,
+ kFlexH_Shift,
+ kFlexV_Shift,
+ kNoClip_Shift,
+
+ kFlagShiftCount
+ };
+ enum Flag_Mask {
+ kVisible_Mask = 1 << kVisible_Shift, //!< set if the view is visible
+ kEnabled_Mask = 1 << kEnabled_Shift, //!< set if the view is enabled
+ 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)
+ };
+
+ SkView(uint32_t flags = 0);
+ virtual ~SkView();
+
+ /** Return the flags associated with the view
+ */
+ uint32_t getFlags() const { return fFlags; }
+ /** Set the flags associated with the view
+ */
+ void setFlags(uint32_t flags);
+
+ /** Helper that returns non-zero if the kVisible_Mask bit is set in the view's flags
+ */
+ 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; }
+ /** Return the view's height */
+ SkScalar height() const { return fHeight; }
+ /** Set the view's width and height. These must both be >= 0. This does not affect the view's loc */
+ void setSize(SkScalar width, SkScalar height);
+ void setSize(const SkPoint& size) { this->setSize(size.fX, size.fY); }
+ void setWidth(SkScalar width) { this->setSize(width, fHeight); }
+ void setHeight(SkScalar height) { this->setSize(fWidth, height); }
+ /** Return a rectangle set to [0, 0, width, height] */
+ void getLocalBounds(SkRect* bounds) const;
+
+ /** Loc - the view's offset with respect to its parent in its view hiearchy.
+ NOTE: For more complex transforms, use Local Matrix. The tranformations
+ are applied in the following order:
+ canvas->translate(fLoc.fX, fLoc.fY);
+ canvas->concat(fMatrix);
+ */
+ /** Return the view's left edge */
+ SkScalar locX() const { return fLoc.fX; }
+ /** Return the view's top edge */
+ SkScalar locY() const { return fLoc.fY; }
+ /** Set the view's left and top edge. This does not affect the view's size */
+ void setLoc(SkScalar x, SkScalar y);
+ void setLoc(const SkPoint& loc) { this->setLoc(loc.fX, loc.fY); }
+ void setLocX(SkScalar x) { this->setLoc(x, fLoc.fY); }
+ void setLocY(SkScalar y) { this->setLoc(fLoc.fX, y); }
+
+ /** Local Matrix - matrix used to tranform the view with respect to its
+ parent in its view hiearchy. Use setLocalMatrix to apply matrix
+ transformations to the current view and in turn affect its children.
+ NOTE: For simple offsets, use Loc. The transformations are applied in
+ the following order:
+ canvas->translate(fLoc.fX, fLoc.fY);
+ canvas->concat(fMatrix);
+ */
+ const SkMatrix& getLocalMatrix() const { return fMatrix; }
+ void setLocalMatrix(const SkMatrix& matrix);
+
+ /** Offset (move) the view by the specified dx and dy. This does not affect the view's size */
+ void offset(SkScalar dx, SkScalar dy);
+
+ /** Call this to have the view draw into the specified canvas. */
+ virtual void draw(SkCanvas* canvas);
+
+ /** Call this to invalidate part of all of a view, requesting that the view's
+ draw method be called. The rectangle parameter specifies the part of the view
+ that should be redrawn. If it is null, it specifies the entire view bounds.
+ */
+ void inval(SkRect* rectOrNull);
+
+ // Focus management
+
+ SkView* getFocusView() const;
+ bool hasFocus() const;
+
+ enum FocusDirection {
+ kNext_FocusDirection,
+ kPrev_FocusDirection,
+
+ kFocusDirectionCount
+ };
+ bool acceptFocus();
+ SkView* moveFocus(FocusDirection);
+
+ // Click handling
+
+ class Click {
+ public:
+ Click(SkView* target);
+ virtual ~Click();
+
+ const char* getType() const { return fType; }
+ bool isType(const char type[]) const;
+ void setType(const char type[]); // does NOT make a copy of the string
+ void copyType(const char type[]); // makes a copy of the string
+
+ enum State {
+ kDown_State,
+ kMoved_State,
+ kUp_State
+ };
+ SkPoint fOrig, fPrev, fCurr;
+ SkIPoint fIOrig, fIPrev, fICurr;
+ State fState;
+ void* fOwner;
+ unsigned fModifierKeys;
+
+ SkMetaData fMeta;
+ private:
+ SkEventSinkID fTargetID;
+ char* fType;
+ bool fWeOwnTheType;
+
+ void resetType();
+
+ friend class SkView;
+ };
+ Click* findClickHandler(SkScalar x, SkScalar y, unsigned modifierKeys);
+
+ static void DoClickDown(Click*, int x, int y, unsigned modi);
+ static void DoClickMoved(Click*, int x, int y, unsigned modi);
+ static void DoClickUp(Click*, int x, int y, unsigned modi);
+
+ /** Send the event to the view's parent, and its parent etc. until one of them
+ returns true from its onEvent call. This view is returned. If no parent handles
+ the event, null is returned.
+ */
+ SkView* sendEventToParents(const SkEvent&);
+ /** Send the query to the view's parent, and its parent etc. until one of them
+ returns true from its onQuery call. This view is returned. If no parent handles
+ the query, null is returned.
+ */
+ SkView* sendQueryToParents(SkEvent*);
+
+ // View hierarchy management
+
+ /** Return the view's parent, or null if it has none. This does not affect the parent's reference count. */
+ SkView* getParent() const { return fParent; }
+ SkView* attachChildToFront(SkView* child);
+ /** Attach the child view to this view, and increment the child's reference count. The child view is added
+ such that it will be drawn before all other child views.
+ The child view parameter is returned.
+ */
+ SkView* attachChildToBack(SkView* child);
+ /** If the view has a parent, detach the view from its parent and decrement the view's reference count.
+ If the parent was the only owner of the view, this will cause the view to be deleted.
+ */
+ void detachFromParent();
+ /** Attach the child view to this view, and increment the child's reference count. The child view is added
+ such that it will be drawn after all other child views.
+ The child view parameter is returned.
+ */
+ /** Detach all child views from this view. */
+ void detachAllChildren();
+
+ /** Convert the specified point from global coordinates into view-local coordinates
+ * Return true on success; false on failure
+ */
+ bool globalToLocal(SkPoint* pt) const {
+ if (pt) {
+ return this->globalToLocal(pt->fX, pt->fY, pt);
+ }
+ return true; // nothing to do so return true
+ }
+ /** Convert the specified x,y from global coordinates into view-local coordinates, returning
+ the answer in the local parameter.
+ */
+ bool globalToLocal(SkScalar globalX, SkScalar globalY, SkPoint* local) const;
+
+ /** \class F2BIter
+
+ Iterator that will return each of this view's children, in
+ front-to-back order (the order used for clicking). The first
+ call to next() returns the front-most child view. When
+ next() returns null, there are no more child views.
+ */
+ class F2BIter {
+ public:
+ F2BIter(const SkView* parent);
+ SkView* next();
+ private:
+ SkView* fFirstChild, *fChild;
+ };
+
+ /** \class B2FIter
+
+ Iterator that will return each of this view's children, in
+ back-to-front order (the order they are drawn). The first
+ call to next() returns the back-most child view. When
+ next() returns null, there are no more child views.
+ */
+ class B2FIter {
+ public:
+ B2FIter(const SkView* parent);
+ SkView* next();
+ private:
+ SkView* fFirstChild, *fChild;
+ };
+
+ /** \class Artist
+
+ Install a subclass of this in a view (calling setArtist()), and then the
+ default implementation of that view's onDraw() will invoke this object
+ automatically.
+ */
+ class Artist : public SkRefCnt {
+ public:
+ SK_DECLARE_INST_COUNT(Artist)
+
+ void draw(SkView*, SkCanvas*);
+ void inflate(const SkDOM&, const SkDOM::Node*);
+ protected:
+ virtual void onDraw(SkView*, SkCanvas*) = 0;
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+ private:
+ typedef SkRefCnt INHERITED;
+ };
+ /** Return the artist attached to this view (or null). The artist's reference
+ count is not affected.
+ */
+ Artist* getArtist() const;
+ /** Attach the specified artist (or null) to the view, replacing any existing
+ artist. If the new artist is not null, its reference count is incremented.
+ The artist parameter is returned.
+ */
+ Artist* setArtist(Artist* artist);
+
+ /** \class Layout
+
+ Install a subclass of this in a view (calling setLayout()), and then the
+ default implementation of that view's onLayoutChildren() will invoke
+ this object automatically.
+ */
+ class Layout : public SkRefCnt {
+ public:
+ SK_DECLARE_INST_COUNT(Layout)
+
+ void layoutChildren(SkView* parent);
+ void inflate(const SkDOM&, const SkDOM::Node*);
+ protected:
+ virtual void onLayoutChildren(SkView* parent) = 0;
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+ private:
+ typedef SkRefCnt INHERITED;
+ };
+
+ /** Return the layout attached to this view (or null). The layout's reference
+ count is not affected.
+ */
+ Layout* getLayout() const;
+ /** Attach the specified layout (or null) to the view, replacing any existing
+ layout. If the new layout is not null, its reference count is incremented.
+ The layout parameter is returned.
+ */
+ Layout* setLayout(Layout*, bool invokeLayoutNow = true);
+ /** If a layout is attached to this view, call its layoutChildren() method
+ */
+ void invokeLayout();
+
+ /** Call this to initialize this view based on the specified XML node
+ */
+ void inflate(const SkDOM& dom, const SkDOM::Node* node);
+ /** After a view hierarchy is inflated, this may be called with a dictionary
+ containing pairs of <name, view*>, where the name string was the view's
+ "id" attribute when it was inflated.
+
+ This will call the virtual onPostInflate for this view, and the recursively
+ call postInflate on all of the view's children.
+ */
+ void postInflate(const SkTDict<SkView*>& ids);
+
+ SkDEBUGCODE(void dump(bool recurse) const;)
+
+protected:
+ /** Override this to draw inside the view. Be sure to call the inherited version too */
+ virtual void onDraw(SkCanvas*);
+ /** Override this to be notified when the view's size changes. Be sure to call the inherited version too */
+ virtual void onSizeChange();
+ /** Override this if you want to handle an inval request from this view or one of its children.
+ 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*);
+ //! 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)
+ virtual void afterChildren(SkCanvas* orig) {}
+
+ //! called right before this child's onDraw is called
+ virtual void beforeChild(SkView* child, SkCanvas* canvas) {}
+ //! called right after this child's onDraw is called
+ virtual void afterChild(SkView* child, SkCanvas* canvas) {}
+
+ /** Override this if you might handle the click
+ */
+ virtual Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi);
+ /** Override this to decide if your children are targets for a click.
+ The default returns true, in which case your children views will be
+ candidates for onFindClickHandler. Returning false wil skip the children
+ and just call your onFindClickHandler.
+ */
+ virtual bool onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi);
+ /** Override this to track clicks, returning true as long as you want to track
+ the pen/mouse.
+ */
+ virtual bool onClick(Click*);
+ /** Override this to initialize your subclass from the XML node. Be sure to call the inherited version too */
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ /** Override this if you want to perform post initialization work based on the ID dictionary built
+ during XML parsing. Be sure to call the inherited version too.
+ */
+ virtual void onPostInflate(const SkTDict<SkView*>&);
+
+public:
+#ifdef SK_DEBUG
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+ // default action is to inval the view
+ virtual void onFocusChange(bool gainFocusP);
+
+protected:
+
+ // override these if you're acting as a layer/host
+ virtual bool onGetFocusView(SkView**) const { return false; }
+ virtual bool onSetFocusView(SkView*) { return false; }
+
+private:
+ SkScalar fWidth, fHeight;
+ SkMatrix fMatrix;
+ SkPoint fLoc;
+ SkView* fParent;
+ SkView* fFirstChild;
+ SkView* fNextSibling;
+ SkView* fPrevSibling;
+ uint8_t fFlags;
+ uint8_t fContainsFocus;
+
+ friend class B2FIter;
+ friend class F2BIter;
+
+ friend class SkLayerView;
+
+ bool setFocusView(SkView* fvOrNull);
+ SkView* acceptFocus(FocusDirection);
+ void detachFromParent_NoLayout();
+ /** Compute the matrix to transform view-local coordinates into global ones */
+ void localToGlobal(SkMatrix* matrix) const;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkViewInflate.h b/src/third_party/skia/include/views/SkViewInflate.h
new file mode 100644
index 0000000..db3689a
--- /dev/null
+++ b/src/third_party/skia/include/views/SkViewInflate.h
@@ -0,0 +1,71 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkViewInflate_DEFINED
+#define SkViewInflate_DEFINED
+
+#include "SkDOM.h"
+#include "SkTDict.h"
+#include "SkEvent.h"
+
+class SkView;
+
+class SkViewInflate {
+public:
+ SkViewInflate();
+ virtual ~SkViewInflate();
+
+ /** Return the tree of inflated views. If root is null, create the root element
+ as a view, otherwise assume root is that view, and just "inflate" it.
+
+ Returns null if the tree cannot be built.
+ */
+ SkView* inflate(const SkDOM& dom, const SkDOM::Node* node, SkView* root = NULL);
+ SkView* inflate(const char xml[], size_t len, SkView* root = NULL);
+
+ /** Given an id attribute value, return the corresponding view, or null
+ if no match is found.
+ */
+ SkView* findViewByID(const char id[]) const;
+
+ SkDEBUGCODE(void dump() const;)
+
+protected:
+ /* Override this in your subclass to handle instantiating views
+ Call the inherited version for nodes you don't recognize.
+
+ Do not call "inflate" on the view, just return it. This will
+ get called automatically after createView returns.
+ */
+ virtual SkView* createView(const SkDOM& dom, const SkDOM::Node* node);
+ /** Base implementation calls view->inflate(dom, node). Subclasses may override this
+ to perform additional initializations to view, either before or after calling
+ the inherited version.
+ */
+ virtual void inflateView(SkView* view, const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ enum {
+ kMinIDStrAlloc = 64
+ };
+ SkTDict<SkView*> fIDs;
+
+ struct IDStr {
+ SkView* fView;
+ char* fStr;
+ };
+ SkTDArray<IDStr> fListenTo, fBroadcastTo;
+ SkChunkAlloc fStrings;
+
+ void addIDStr(SkTDArray<IDStr>* list, SkView*, const char* str);
+
+ void rInflate(const SkDOM& dom, const SkDOM::Node* node, SkView* parent);
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkWidget.h b/src/third_party/skia/include/views/SkWidget.h
new file mode 100644
index 0000000..115e9a4
--- /dev/null
+++ b/src/third_party/skia/include/views/SkWidget.h
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkWidget_DEFINED
+#define SkWidget_DEFINED
+
+#include "SkBitmap.h"
+#include "SkDOM.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkTDArray.h"
+#include "SkTextBox.h"
+#include "SkView.h"
+
+class SkEvent;
+class SkInterpolator;
+class SkShader;
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkWidget : public SkView {
+public:
+ SkWidget(uint32_t flags = 0) : SkView(flags | kFocusable_Mask | kEnabled_Mask) {}
+
+ /** Call this to post the widget's event to its listeners */
+ void postWidgetEvent();
+
+ static void Init();
+ static void Term();
+protected:
+ // override to add slots to an event before posting
+ virtual void prepareWidgetEvent(SkEvent*);
+ virtual void onEnabledChange();
+
+ // <event ...> to initialize the event from XML
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkEvent fEvent;
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkHasLabelWidget : public SkWidget {
+public:
+ SkHasLabelWidget(uint32_t flags = 0) : SkWidget(flags) {}
+
+ size_t getLabel(SkString* label = NULL) const;
+ size_t getLabel(char lable[] = NULL) const;
+ void setLabel(const SkString&);
+ void setLabel(const char label[]);
+ void setLabel(const char label[], size_t len);
+
+protected:
+ // called when the label changes
+ virtual void onLabelChange();
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkString fLabel;
+ typedef SkWidget INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkButtonWidget : public SkHasLabelWidget {
+public:
+ SkButtonWidget(uint32_t flags = 0) : SkHasLabelWidget(flags), fState(kOff_State) {}
+
+ enum State {
+ kOff_State, //!< XML: buttonState="off"
+ kOn_State, //!< XML: buttonState="on"
+ kUnknown_State //!< XML: buttonState="unknown"
+ };
+ State getButtonState() const { return fState; }
+ void setButtonState(State);
+
+protected:
+ /** called when the label changes. default behavior is to inval the widget */
+ virtual void onButtonStateChange();
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ State fState;
+ typedef SkHasLabelWidget INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkPushButtonWidget : public SkButtonWidget {
+public:
+ SkPushButtonWidget(uint32_t flags = 0) : SkButtonWidget(flags) {}
+
+protected:
+ virtual bool onEvent(const SkEvent&);
+ virtual void onDraw(SkCanvas*);
+ virtual Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) SK_OVERRIDE;
+ virtual bool onClick(Click* click);
+
+private:
+ typedef SkButtonWidget INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkCheckBoxWidget : public SkButtonWidget {
+public:
+ SkCheckBoxWidget(uint32_t flags = 0);
+
+protected:
+ virtual bool onEvent(const SkEvent&);
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ typedef SkButtonWidget INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkStaticTextView : public SkView {
+public:
+ SkStaticTextView(uint32_t flags = 0);
+ virtual ~SkStaticTextView();
+
+ enum Mode {
+ kFixedSize_Mode,
+ kAutoWidth_Mode,
+ kAutoHeight_Mode,
+
+ kModeCount
+ };
+ Mode getMode() const { return (Mode)fMode; }
+ void setMode(Mode);
+
+ SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
+ void setSpacingAlign(SkTextBox::SpacingAlign);
+
+ void getMargin(SkPoint* margin) const;
+ void setMargin(SkScalar dx, SkScalar dy);
+
+ size_t getText(SkString* text = NULL) const;
+ size_t getText(char text[] = NULL) const;
+ void setText(const SkString&);
+ void setText(const char text[]);
+ void setText(const char text[], size_t len);
+
+ void getPaint(SkPaint*) const;
+ void setPaint(const SkPaint&);
+
+protected:
+ // overrides
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkPoint fMargin;
+ SkString fText;
+ SkPaint fPaint;
+ uint8_t fMode;
+ uint8_t fSpacingAlign;
+
+ void computeSize();
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkBitmapView : public SkView {
+public:
+ SkBitmapView(uint32_t flags = 0);
+ virtual ~SkBitmapView();
+
+ bool getBitmap(SkBitmap*) const;
+ void setBitmap(const SkBitmap*, bool viewOwnsPixels);
+ bool loadBitmapFromFile(const char path[]);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+
+private:
+ SkBitmap fBitmap;
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkHasLabelView : public SkView {
+public:
+ void getLabel(SkString*) const;
+ void setLabel(const SkString&);
+ void setLabel(const char label[]);
+
+protected:
+ SkString fLabel;
+
+ // called when the label changes
+ virtual void onLabelChange();
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkPushButtonView : public SkHasLabelView {
+public:
+ SkPushButtonView(uint32_t flags = 0);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkCheckBoxView : public SkHasLabelView {
+public:
+ SkCheckBoxView(uint32_t flags = 0);
+
+ enum State {
+ kOff_State,
+ kOn_State,
+ kMaybe_State
+ };
+ State getState() const { return fState; }
+ void setState(State);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ State fState;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkProgressView : public SkView {
+public:
+ SkProgressView(uint32_t flags = 0);
+ virtual ~SkProgressView();
+
+ uint16_t getValue() const { return fValue; }
+ uint16_t getMax() const { return fMax; }
+
+ void setMax(U16CPU max);
+ void setValue(U16CPU value);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ uint16_t fValue, fMax;
+ SkShader* fOnShader, *fOffShader;
+ SkInterpolator* fInterp;
+ bool fDoInterp;
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkListSource : public SkEventSink {
+public:
+ virtual int countRows() = 0;
+ virtual void getRow(int index, SkString* left, SkString* right) = 0;
+ virtual SkEvent* getEvent(int index);
+
+ static SkListSource* CreateFromDir(const char path[], const char suffix[],
+ const char targetPrefix[]);
+ static SkListSource* CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkListView : public SkView {
+public:
+ SkListView(uint32_t flags = 0);
+ virtual ~SkListView();
+
+ SkScalar getRowHeight() const { return fRowHeight; }
+ void setRowHeight(SkScalar);
+
+ /** Return the index of the selected row, or -1 if none
+ */
+ int getSelection() const { return fCurrIndex; }
+ /** Set the index of the selected row, or -1 for none
+ */
+ void setSelection(int);
+
+ void moveSelectionUp();
+ void moveSelectionDown();
+
+ enum Attr {
+ kBG_Attr,
+ kNormalText_Attr,
+ kHiliteText_Attr,
+ kHiliteCell_Attr,
+ kAttrCount
+ };
+ SkPaint& paint(Attr);
+
+ SkListSource* getListSource() const { return fSource; }
+ SkListSource* setListSource(SkListSource*);
+
+#if 0
+ enum Action {
+ kSelectionChange_Action,
+ kSelectionPicked_Action,
+ kActionCount
+ };
+ /** If event is not null, it is retained by the view, and a copy
+ of the event will be posted to its listeners when the specified
+ action occurs. If event is null, then no event will be posted for
+ the specified action.
+ */
+ void setActionEvent(Action, SkEvent* event);
+#endif
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onSizeChange();
+ virtual bool onEvent(const SkEvent&);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkPaint fPaint[kAttrCount];
+ SkListSource* fSource;
+ SkScalar fRowHeight;
+ int fCurrIndex; // logical index
+ int fScrollIndex; // logical index of top-most visible row
+ int fVisibleRowCount;
+ SkString* fStrCache;
+
+ void dirtyStrCache();
+ void ensureStrCache(int visibleCount);
+
+ int logicalToVisualIndex(int index) const { return index - fScrollIndex; }
+ void invalSelection();
+ bool getRowRect(int index, SkRect*) const;
+ void ensureSelectionIsVisible();
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SkGridView : public SkView {
+public:
+ SkGridView(uint32_t flags = 0);
+ virtual ~SkGridView();
+
+ void getCellSize(SkPoint*) const;
+ void setCellSize(SkScalar x, SkScalar y);
+
+ /** Return the index of the selected item, or -1 if none
+ */
+ int getSelection() const { return fCurrIndex; }
+ /** Set the index of the selected row, or -1 for none
+ */
+ void setSelection(int);
+
+ void moveSelectionUp();
+ void moveSelectionDown();
+
+ enum Attr {
+ kBG_Attr,
+ kHiliteCell_Attr,
+ kAttrCount
+ };
+ SkPaint& paint(Attr);
+
+ SkListSource* getListSource() const { return fSource; }
+ SkListSource* setListSource(SkListSource*);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onSizeChange();
+ virtual bool onEvent(const SkEvent&);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkView* fScrollBar;
+ SkPaint fPaint[kAttrCount];
+ SkListSource* fSource;
+ int fCurrIndex; // logical index
+
+ SkPoint fCellSize;
+ SkIPoint fVisibleCount;
+
+ int logicalToVisualIndex(int index) const { return index; }
+ void invalSelection();
+ bool getCellRect(int index, SkRect*) const;
+ void ensureSelectionIsVisible();
+
+ typedef SkView INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/SkWindow.h b/src/third_party/skia/include/views/SkWindow.h
new file mode 100644
index 0000000..40cc5ec
--- /dev/null
+++ b/src/third_party/skia/include/views/SkWindow.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkWindow_DEFINED
+#define SkWindow_DEFINED
+
+#include "SkView.h"
+#include "SkBitmap.h"
+#include "SkMatrix.h"
+#include "SkRegion.h"
+#include "SkEvent.h"
+#include "SkKey.h"
+#include "SkTDArray.h"
+
+#ifdef SK_BUILD_FOR_WINCEx
+ #define SHOW_FPS
+#endif
+//#define USE_GX_SCREEN
+
+class SkSurface;
+class SkOSMenu;
+
+class SkWindow : public SkView {
+public:
+ SkWindow();
+ virtual ~SkWindow();
+
+ const SkBitmap& getBitmap() const { return fBitmap; }
+
+ void setColorType(SkColorType);
+ void resize(int width, int height, SkColorType = kUnknown_SkColorType);
+
+ bool isDirty() const { return !fDirtyRgn.isEmpty(); }
+ bool update(SkIRect* updateArea);
+ // 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, void* owner, unsigned modi = 0);
+ bool handleChar(SkUnichar);
+ bool handleKey(SkKey);
+ bool handleKeyUp(SkKey);
+
+ void addMenu(SkOSMenu*);
+ const SkTDArray<SkOSMenu*>* getMenus() { return &fMenus; }
+
+ 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&);
+
+ virtual SkSurface* createSurface();
+
+ virtual void onPDFSaved(const char title[], const char desc[],
+ const char path[]) {}
+protected:
+ virtual bool onEvent(const SkEvent&);
+ virtual bool onDispatchClick(int x, int y, Click::State, void* owner, unsigned modi);
+ // called if part of our bitmap is invalidated
+ virtual void onHandleInval(const SkIRect&);
+ virtual bool onHandleChar(SkUnichar);
+ virtual bool onHandleKey(SkKey);
+ virtual bool onHandleKeyUp(SkKey);
+ virtual void onAddMenu(const SkOSMenu*) {};
+ virtual void onUpdateMenu(const SkOSMenu*) {};
+ virtual void onSetTitle(const char title[]) {}
+
+ // overrides from SkView
+ virtual bool handleInval(const SkRect*);
+ virtual bool onGetFocusView(SkView** focus) const;
+ virtual bool onSetFocusView(SkView* focus);
+
+private:
+ SkColorType fColorType;
+ SkBitmap fBitmap;
+ SkRegion fDirtyRgn;
+
+ SkTDArray<Click*> fClicks; // to track clicks
+
+ SkTDArray<SkOSMenu*> fMenus;
+
+ SkView* fFocusView;
+ bool fWaitingOnInval;
+
+ SkString fTitle;
+ SkMatrix fMatrix;
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(SK_BUILD_FOR_NACL)
+ #include "SkOSWindow_NaCl.h"
+#elif defined(SK_BUILD_FOR_MAC)
+ #include "SkOSWindow_Mac.h"
+#elif defined(SK_BUILD_FOR_WIN)
+ #include "SkOSWindow_Win.h"
+#elif defined(SK_BUILD_FOR_ANDROID)
+ #include "SkOSWindow_Android.h"
+#elif defined(SK_BUILD_FOR_UNIX)
+ #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
diff --git a/src/third_party/skia/include/views/android/AndroidKeyToSkKey.h b/src/third_party/skia/include/views/android/AndroidKeyToSkKey.h
new file mode 100644
index 0000000..6bcb148
--- /dev/null
+++ b/src/third_party/skia/include/views/android/AndroidKeyToSkKey.h
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright 2011 Skia
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef _ANDROID_TO_SKIA_KEYCODES_H
+#define _ANDROID_TO_SKIA_KEYCODES_H
+
+#include "android/keycodes.h"
+#include "SkKey.h"
+
+// Convert an Android keycode to an SkKey. This is an incomplete list, only
+// including keys used by the sample app.
+SkKey AndroidKeycodeToSkKey(int keycode) {
+ switch (keycode) {
+ case AKEYCODE_DPAD_LEFT:
+ return kLeft_SkKey;
+ case AKEYCODE_DPAD_RIGHT:
+ return kRight_SkKey;
+ case AKEYCODE_DPAD_UP:
+ return kUp_SkKey;
+ case AKEYCODE_DPAD_DOWN:
+ return kDown_SkKey;
+ case AKEYCODE_BACK:
+ return kBack_SkKey;
+ default:
+ return kNONE_SkKey;
+ }
+}
+
+#endif
diff --git a/src/third_party/skia/include/views/animated/SkBorderView.h b/src/third_party/skia/include/views/animated/SkBorderView.h
new file mode 100644
index 0000000..8b1e537
--- /dev/null
+++ b/src/third_party/skia/include/views/animated/SkBorderView.h
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkBorderView_DEFINED
+#define SkBorderView_DEFINED
+
+#include "SkView.h"
+#include "SkWidgetViews.h"
+#include "SkAnimator.h"
+
+class SkBorderView : public SkWidgetView {
+public:
+ SkBorderView();
+ ~SkBorderView();
+ void setSkin(const char skin[]);
+ SkScalar getLeft() const { return fLeft; }
+ SkScalar getRight() const { return fRight; }
+ SkScalar getTop() const { return fTop; }
+ SkScalar getBottom() const { return fBottom; }
+protected:
+ //overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual void onSizeChange();
+ virtual void onDraw(SkCanvas* canvas);
+ virtual bool onEvent(const SkEvent& evt);
+private:
+ SkAnimator fAnim;
+ SkScalar fLeft, fRight, fTop, fBottom; //margin on each side
+ SkRect fMargin;
+
+ typedef SkWidgetView INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/animated/SkImageView.h b/src/third_party/skia/include/views/animated/SkImageView.h
new file mode 100644
index 0000000..a21da0b
--- /dev/null
+++ b/src/third_party/skia/include/views/animated/SkImageView.h
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkImageView_DEFINED
+#define SkImageView_DEFINED
+
+#include "SkView.h"
+#include "SkString.h"
+
+class SkAnimator;
+class SkBitmap;
+class SkMatrix;
+
+class SkImageView : public SkView {
+public:
+ SkImageView();
+ virtual ~SkImageView();
+
+ void getUri(SkString*) const;
+ void setUri(const char []);
+ void setUri(const SkString&);
+
+
+ enum ScaleType {
+ kMatrix_ScaleType,
+ kFitXY_ScaleType,
+ kFitStart_ScaleType,
+ kFitCenter_ScaleType,
+ kFitEnd_ScaleType
+ };
+ ScaleType getScaleType() const { return (ScaleType)fScaleType; }
+ void setScaleType(ScaleType);
+
+ bool getImageMatrix(SkMatrix*) const;
+ void setImageMatrix(const SkMatrix*);
+
+protected:
+ // overrides
+ virtual bool onEvent(const SkEvent&);
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM&, const SkDOMNode*);
+
+private:
+ SkString fUri;
+ SkMatrix* fMatrix; // null or copy of caller's matrix ,,,,,
+ union {
+ SkAnimator* fAnim;
+ SkBitmap* fBitmap;
+ } fData;
+ uint8_t fScaleType;
+ SkBool8 fDataIsAnim; // as opposed to bitmap
+ SkBool8 fUriIsValid;
+
+ void onUriChange();
+ bool getDataBounds(SkRect* bounds);
+ bool freeData();
+ bool ensureUriIsLoaded();
+
+ typedef SkView INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/animated/SkProgressBarView.h b/src/third_party/skia/include/views/animated/SkProgressBarView.h
new file mode 100644
index 0000000..7e670a9
--- /dev/null
+++ b/src/third_party/skia/include/views/animated/SkProgressBarView.h
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkProgressBarView_DEFINED
+#define SkProgressBarView_DEFINED
+
+#include "SkView.h"
+#include "SkWidgetViews.h"
+#include "SkAnimator.h"
+
+class SkProgressBarView : public SkWidgetView {
+ public:
+ SkProgressBarView();
+ //SkProgressBarView(int max);
+
+ //inflate: "sk-progress"
+
+ void reset(); //reset progress to zero
+ void setProgress(int progress);
+ void changeProgress(int diff);
+ void setMax(int max);
+
+ int getProgress() const { return fProgress; }
+ int getMax() const { return fMax; }
+
+ protected:
+ //overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual void onSizeChange();
+ virtual void onDraw(SkCanvas* canvas);
+ virtual bool onEvent(const SkEvent& evt);
+
+ private:
+ SkAnimator fAnim;
+ int fProgress;
+ int fMax;
+
+ typedef SkWidgetView INHERITED;
+};
+
+
+
+
+#endif
diff --git a/src/third_party/skia/include/views/animated/SkScrollBarView.h b/src/third_party/skia/include/views/animated/SkScrollBarView.h
new file mode 100644
index 0000000..05042f0
--- /dev/null
+++ b/src/third_party/skia/include/views/animated/SkScrollBarView.h
@@ -0,0 +1,44 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkScrollBarView_DEFINED
+#define SkScrollBarView_DEFINED
+
+#include "SkView.h"
+#include "SkWidgetViews.h"
+#include "SkAnimator.h"
+
+class SkScrollBarView : public SkWidgetView {
+public:
+ SkScrollBarView();
+
+ unsigned getStart() const { return fStartPoint; }
+ unsigned getShown() const { return fShownLength; }
+ unsigned getTotal() const { return fTotalLength; }
+
+ void setStart(unsigned start);
+ void setShown(unsigned shown);
+ void setTotal(unsigned total);
+
+protected:
+ //overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual void onSizeChange();
+ virtual void onDraw(SkCanvas* canvas);
+ virtual bool onEvent(const SkEvent& evt);
+
+private:
+ SkAnimator fAnim;
+ unsigned fTotalLength, fStartPoint, fShownLength;
+
+ void adjust();
+
+ typedef SkWidgetView INHERITED;
+};
+#endif
diff --git a/src/third_party/skia/include/views/animated/SkWidgetViews.h b/src/third_party/skia/include/views/animated/SkWidgetViews.h
new file mode 100644
index 0000000..4034660
--- /dev/null
+++ b/src/third_party/skia/include/views/animated/SkWidgetViews.h
@@ -0,0 +1,309 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkWidgetViews_DEFINED
+#define SkWidgetViews_DEFINED
+
+#include "SkView.h"
+
+
+enum SkWidgetEnum {
+ kBorder_WidgetEnum, //!< <sk-border>
+ kButton_WidgetEnum, //!< <sk-button>
+ kImage_WidgetEnum, //!< <sk-image>
+ kList_WidgetEnum, //!< <sk-list>
+ kProgress_WidgetEnum, //!< <sk-progress>
+ kScroll_WidgetEnum, //!< <sk-scroll>
+ kText_WidgetEnum, //!< <sk-text>
+
+ kWidgetEnumCount
+};
+
+//determines which skin to use
+enum SkinEnum {
+ kBorder_SkinEnum,
+ kButton_SkinEnum,
+ kProgress_SkinEnum,
+ kScroll_SkinEnum,
+ kStaticText_SkinEnum,
+
+ kSkinEnumCount
+};
+
+#include "SkAnimator.h"
+//used for inflates
+const char* get_skin_enum_path(SkinEnum se);
+void init_skin_anim(const char path[], SkAnimator* anim);
+void init_skin_anim(SkinEnum se, SkAnimator* anim);
+void init_skin_paint(SkinEnum se, SkPaint* paint);
+void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint);
+
+/** Given an enum value, return an instance of the specified widget.
+ If the enum is out of range, returns null
+*/
+SkView* SkWidgetFactory(SkWidgetEnum);
+/** Given the inflate/element name of a widget, return an instance of
+ the specified widget, or null if name does not match any known
+ widget type.
+*/
+SkView* SkWidgetFactory(const char name[]);
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkWidgetView : public SkView {
+public:
+ SkWidgetView();
+
+ const char* getLabel() const;
+ void getLabel(SkString* label) const;
+
+ void setLabel(const char[]);
+ void setLabel(const char[], size_t len);
+ void setLabel(const SkString&);
+
+ SkEvent& event() { return fEvent; }
+ const SkEvent& event() const { return fEvent; }
+
+ /** Returns true if the widget can post its event to its listeners.
+ */
+ bool postWidgetEvent();
+
+ /** Returns the sinkID of the widgetview that posted the event, or 0
+ */
+ static SkEventSinkID GetWidgetEventSinkID(const SkEvent&);
+
+protected:
+ /** called when the label changes. override in subclasses. default action invals the view's bounds.
+ called with the old and new labels, before the label has actually changed.
+ */
+ virtual void onLabelChange(const char oldLabel[], const char newLabel[]);
+ /** called before posting the event to our listeners. Override to add slots to the event
+ before posting. Return true to proceed with posting, or false to not post the event to any
+ listener. Note: the event passed in may not be the same as calling this->event().
+ Be sure to call your INHERITED method as well, so that all classes in the hierarchy get a shot
+ at modifying the event (and possibly returning false to abort).
+ */
+ virtual bool onPrepareWidgetEvent(SkEvent* evt);
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkString fLabel;
+ SkEvent fEvent;
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkButtonView : public SkWidgetView {
+public:
+ // inflate: "sk-button"
+
+protected:
+ // overrides
+ virtual bool onEvent(const SkEvent&);
+private:
+ typedef SkWidgetView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkCheckButtonView : public SkWidgetView {
+public:
+ SkCheckButtonView();
+
+ // inflate: "sk-checkbutton"
+
+ enum CheckState {
+ kOff_CheckState, //!< inflate: check-state="off"
+ kOn_CheckState, //!< inflate: check-state="on"
+ kUnknown_CheckState //!< inflate: check-state="unknown"
+ };
+ CheckState getCheckState() const { return (CheckState)fCheckState; }
+ void setCheckState(CheckState);
+
+ /** use this to extract the CheckState from an event (i.e. one that as posted
+ by a SkCheckButtonView). Returns true if the proper slot was present in the event,
+ and sets state to that value. If no proper slot is found, returns false and does not
+ modify state.
+ */
+ static bool GetWidgetEventCheckState(const SkEvent&, CheckState* state);
+
+protected:
+ // called when the check-state is about to change, but before it actually has
+ virtual void onCheckStateChange(CheckState oldState, CheckState newState);
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+ virtual bool onPrepareWidgetEvent(SkEvent* evt);
+
+private:
+ uint8_t fCheckState;
+
+ typedef SkWidgetView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkTextBox.h"
+
+class SkStaticTextView : public SkView {
+public:
+ SkStaticTextView();
+ virtual ~SkStaticTextView();
+
+ enum Mode {
+ kFixedSize_Mode,
+ kAutoWidth_Mode,
+ kAutoHeight_Mode,
+
+ kModeCount
+ };
+ Mode getMode() const { return (Mode)fMode; }
+ void setMode(Mode);
+
+ SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
+ void setSpacingAlign(SkTextBox::SpacingAlign);
+
+ void getMargin(SkPoint* margin) const;
+ void setMargin(SkScalar dx, SkScalar dy);
+
+ size_t getText(SkString* text = NULL) const;
+ size_t getText(char text[] = NULL) const;
+ void setText(const SkString&);
+ void setText(const char text[]);
+ void setText(const char text[], size_t len);
+
+ void getPaint(SkPaint*) const;
+ void setPaint(const SkPaint&);
+
+protected:
+ // overrides
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkPoint fMargin;
+ SkString fText;
+ SkPaint fPaint;
+ uint8_t fMode;
+ uint8_t fSpacingAlign;
+
+ void computeSize();
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkAnimator;
+class SkListSource;
+class SkScrollBarView;
+
+class SkListView : public SkWidgetView {
+public:
+ SkListView();
+ virtual ~SkListView();
+
+ bool hasScrollBar() const { return fScrollBar != NULL; }
+ void setHasScrollBar(bool);
+
+ /** Return the number of visible rows
+ */
+ int getVisibleRowCount() const { return fVisibleRowCount; }
+ /** Return the index of the selected row, or -1 if none
+ */
+ int getSelection() const { return fCurrIndex; }
+ /** Set the index of the selected row, or -1 for none
+ */
+ void setSelection(int);
+ /** If possible, move the selection up and return true,
+ else do nothing and return false
+ If nothing is selected, select the last item (unless there are no items).
+ */
+ bool moveSelectionUp();
+ /** If possible, move the selection down and return true,
+ else do nothing and return false.
+ If nothing is selected, select the first item (unless there are no items).
+ */
+ bool moveSelectionDown();
+
+ SkListSource* getListSource() const { return fSource; }
+ SkListSource* setListSource(SkListSource*);
+
+ /** Call this in your event handler. If the specified event is from a SkListView,
+ then it returns the index of the selected item in this list, otherwise it
+ returns -1
+ */
+ static int GetWidgetEventListIndex(const SkEvent&);
+
+protected:
+ // overrides
+ virtual void onDraw(SkCanvas*);
+ virtual void onSizeChange();
+ virtual bool onEvent(const SkEvent&);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual bool onPrepareWidgetEvent(SkEvent*);
+
+private:
+ enum DirtyFlags {
+ kAnimCount_DirtyFlag = 0x01,
+ kAnimContent_DirtyFlag = 0x02
+ };
+ void dirtyCache(unsigned dirtyFlags);
+ bool ensureCache();
+
+ int logicalToVisualIndex(int index) const { return index - fScrollIndex; }
+ void invalSelection();
+ SkScalar getContentWidth() const;
+ bool getRowRect(int index, SkRect*) const;
+ void ensureSelectionIsVisible();
+ void ensureVisibleRowCount();
+
+ struct BindingRec;
+
+ enum Heights {
+ kNormal_Height,
+ kSelected_Height
+ };
+ SkListSource* fSource;
+ SkScrollBarView* fScrollBar;
+ SkAnimator* fAnims;
+ BindingRec* fBindings;
+ SkString fSkinName;
+ SkScalar fHeights[2];
+ int16_t fScrollIndex, fCurrIndex;
+ uint16_t fVisibleRowCount, fBindingCount;
+ SkBool8 fAnimContentDirty;
+ SkBool8 fAnimFocusDirty;
+
+ typedef SkWidgetView INHERITED;
+};
+
+class SkListSource : public SkRefCnt {
+public:
+ SK_DECLARE_INST_COUNT(SkListSource)
+
+ virtual int countFields();
+ virtual void getFieldName(int index, SkString* field);
+ /** Return the index of the named field, or -1 if not found */
+ virtual int findFieldIndex(const char field[]);
+
+ virtual int countRecords();
+ virtual void getRecord(int rowIndex, int fieldIndex, SkString* data);
+
+ virtual bool prepareWidgetEvent(SkEvent*, int rowIndex);
+
+ static SkListSource* Factory(const char name[]);
+private:
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/third_party/skia/include/views/unix/XkeysToSkKeys.h b/src/third_party/skia/include/views/unix/XkeysToSkKeys.h
new file mode 100644
index 0000000..30eb97d
--- /dev/null
+++ b/src/third_party/skia/include/views/unix/XkeysToSkKeys.h
@@ -0,0 +1,38 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "X11/Xlib.h"
+#include "X11/keysym.h"
+
+#include "SkKey.h"
+
+#ifndef XKEYS_TOSKKEYS_H
+#define XKEYS_TOSKKEYS_H
+
+SkKey XKeyToSkKey(KeySym keysym) {
+ switch (keysym) {
+ case XK_BackSpace:
+ return kBack_SkKey;
+ case XK_Return:
+ return kOK_SkKey;
+ case XK_Home:
+ return kHome_SkKey;
+ case XK_End:
+ return kEnd_SkKey;
+ case XK_Right:
+ return kRight_SkKey;
+ case XK_Left:
+ return kLeft_SkKey;
+ case XK_Down:
+ return kDown_SkKey;
+ case XK_Up:
+ return kUp_SkKey;
+ default:
+ return kNONE_SkKey;
+ }
+}
+#endif
diff --git a/src/third_party/skia/include/views/unix/keysym2ucs.h b/src/third_party/skia/include/views/unix/keysym2ucs.h
new file mode 100644
index 0000000..255a930
--- /dev/null
+++ b/src/third_party/skia/include/views/unix/keysym2ucs.h
@@ -0,0 +1,15 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+/*
+ * This module converts keysym values into the corresponding ISO 10646-1
+ * (UCS, Unicode) values.
+ */
+
+#include <X11/X.h>
+
+long keysym2ucs(KeySym keysym);
diff --git a/src/third_party/skia/include/xml/SkBML_WXMLParser.h b/src/third_party/skia/include/xml/SkBML_WXMLParser.h
new file mode 100644
index 0000000..74f164c
--- /dev/null
+++ b/src/third_party/skia/include/xml/SkBML_WXMLParser.h
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkBML_WXMLParser_DEFINED
+#define SkBML_WXMLParser_DEFINED
+
+#include "SkString.h"
+#include "SkXMLParser.h"
+
+class SkStream;
+class SkWStream;
+
+class BML_WXMLParser : public SkXMLParser {
+public:
+ BML_WXMLParser(SkWStream& writer);
+ virtual ~BML_WXMLParser();
+ static void Write(SkStream& s, const char filename[]);
+
+ /** @cond UNIT_TEST */
+ SkDEBUGCODE(static void UnitTest();)
+ /** @endcond */
+private:
+ virtual bool onAddAttribute(const char name[], const char value[]);
+ virtual bool onEndElement(const char name[]);
+ virtual bool onStartElement(const char name[]);
+ BML_WXMLParser& operator=(const BML_WXMLParser& src);
+#ifdef SK_DEBUG
+ int fElemsCount, fElemsReused;
+ int fAttrsCount, fNamesReused, fValuesReused;
+#endif
+ SkWStream& fWriter;
+ char* fElems[256];
+ char* fAttrNames[256];
+ char* fAttrValues[256];
+
+ // important that these are U8, so we get automatic wrap-around
+ U8 fNextElem, fNextAttrName, fNextAttrValue;
+};
+
+#endif // SkBML_WXMLParser_DEFINED
diff --git a/src/third_party/skia/include/xml/SkBML_XMLParser.h b/src/third_party/skia/include/xml/SkBML_XMLParser.h
new file mode 100644
index 0000000..9bdbf51
--- /dev/null
+++ b/src/third_party/skia/include/xml/SkBML_XMLParser.h
@@ -0,0 +1,31 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkBML_XMLParser_DEFINED
+#define SkBML_XMLParser_DEFINED
+
+class SkStream;
+class SkWStream;
+class SkXMLParser;
+class SkXMLWriter;
+
+class BML_XMLParser {
+public:
+ /** Read the byte XML stream and write the decompressed XML.
+ */
+ static void Read(SkStream& s, SkXMLWriter& writer);
+ /** Read the byte XML stream and write the decompressed XML into a writable stream.
+ */
+ static void Read(SkStream& s, SkWStream& output);
+ /** Read the byte XML stream and write the decompressed XML into an XML parser.
+ */
+ static void Read(SkStream& s, SkXMLParser& output);
+};
+
+#endif // SkBML_XMLParser_DEFINED
diff --git a/src/third_party/skia/include/xml/SkDOM.h b/src/third_party/skia/include/xml/SkDOM.h
new file mode 100644
index 0000000..e0bb744
--- /dev/null
+++ b/src/third_party/skia/include/xml/SkDOM.h
@@ -0,0 +1,91 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkDOM_DEFINED
+#define SkDOM_DEFINED
+
+#include "SkChunkAlloc.h"
+#include "SkScalar.h"
+#include "SkTemplates.h"
+
+struct SkDOMNode;
+struct SkDOMAttr;
+
+class SkDOM {
+public:
+ SkDOM();
+ ~SkDOM();
+
+ typedef SkDOMNode Node;
+ typedef SkDOMAttr Attr;
+
+ /** Returns null on failure
+ */
+ const Node* build(const char doc[], size_t len);
+ const Node* copy(const SkDOM& dom, const Node* node);
+
+ const Node* getRootNode() const;
+
+ enum Type {
+ kElement_Type,
+ kText_Type
+ };
+ Type getType(const Node*) const;
+
+ const char* getName(const Node*) const;
+ const Node* getFirstChild(const Node*, const char elem[] = NULL) const;
+ const Node* getNextSibling(const Node*, const char elem[] = NULL) const;
+
+ const char* findAttr(const Node*, const char attrName[]) const;
+ const Attr* getFirstAttr(const Node*) const;
+ const Attr* getNextAttr(const Node*, const Attr*) const;
+ const char* getAttrName(const Node*, const Attr*) const;
+ const char* getAttrValue(const Node*, const Attr*) const;
+
+ // helpers for walking children
+ int countChildren(const Node* node, const char elem[] = NULL) const;
+
+ // helpers for calling SkParse
+ bool findS32(const Node*, const char name[], int32_t* value) const;
+ bool findScalars(const Node*, const char name[], SkScalar value[], int count) const;
+ bool findHex(const Node*, const char name[], uint32_t* value) const;
+ bool findBool(const Node*, const char name[], bool*) const;
+ int findList(const Node*, const char name[], const char list[]) const;
+
+ bool findScalar(const Node* node, const char name[], SkScalar value[]) const
+ {
+ return this->findScalars(node, name, value, 1);
+ }
+
+ bool hasAttr(const Node*, const char name[], const char value[]) const;
+ bool hasS32(const Node*, const char name[], int32_t value) const;
+ bool hasScalar(const Node*, const char name[], SkScalar value) const;
+ bool hasHex(const Node*, const char name[], uint32_t value) const;
+ bool hasBool(const Node*, const char name[], bool value) const;
+
+ class AttrIter {
+ public:
+ AttrIter(const class SkDOM&, const Node*);
+ const char* next(const char** value);
+ private:
+ const Attr* fAttr;
+ const Attr* fStop;
+ };
+
+ SkDEBUGCODE(void dump(const Node* node = NULL, int tabLevel = 0) const;)
+ SkDEBUGCODE(static void UnitTest();)
+
+private:
+ SkChunkAlloc fAlloc;
+ Node* fRoot;
+ friend class AttrIter;
+ friend class SkDOMParser;
+};
+
+#endif
diff --git a/src/third_party/skia/include/xml/SkJS.h b/src/third_party/skia/include/xml/SkJS.h
new file mode 100644
index 0000000..8a11097
--- /dev/null
+++ b/src/third_party/skia/include/xml/SkJS.h
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkTypes.h"
+#include "SkWindow.h"
+
+extern "C" {
+ typedef long JSWord;
+ typedef JSWord jsword;
+ typedef jsword jsval;
+ typedef struct JSRuntime JSRuntime;
+ typedef struct JSContext JSContext;
+ typedef struct JSObject JSObject;
+}
+
+class SkString;
+
+class SkJS : public SkOSWindow {
+public:
+ SkJS(void* hwnd);
+ ~SkJS();
+ SkBool EvaluateScript(const char* script, jsval* rVal);
+ SkBool ValueToString(jsval value, SkString* string);
+#ifdef SK_DEBUG
+ static void Test(void* hwnd);
+#endif
+protected:
+ void InitializeDisplayables(const SkBitmap& , JSContext *, JSObject *, JSObject *);
+ void DisposeDisplayables();
+ JSRuntime *fRuntime;
+ JSContext *fContext;
+ JSObject *fGlobal;
+};
diff --git a/src/third_party/skia/include/xml/SkXMLParser.h b/src/third_party/skia/include/xml/SkXMLParser.h
new file mode 100644
index 0000000..1a90bf7
--- /dev/null
+++ b/src/third_party/skia/include/xml/SkXMLParser.h
@@ -0,0 +1,155 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkXMLParser_DEFINED
+#define SkXMLParser_DEFINED
+
+#include "SkString.h"
+
+class SkStream;
+
+class SkDOM;
+struct SkDOMNode;
+
+class SkXMLParserError {
+public:
+ enum ErrorCode {
+ kNoError,
+ kEmptyFile,
+ kUnknownElement,
+ kUnknownAttributeName,
+ kErrorInAttributeValue,
+ kDuplicateIDs,
+ kUnknownError
+ };
+
+ SkXMLParserError();
+ virtual ~SkXMLParserError();
+ ErrorCode getErrorCode() const { return fCode; }
+ virtual void getErrorString(SkString* str) const;
+ int getLineNumber() const { return fLineNumber; }
+ int getNativeCode() const { return fNativeCode; }
+ bool hasError() const { return fCode != kNoError || fNativeCode != -1; }
+ bool hasNoun() const { return fNoun.size() > 0; }
+ void reset();
+ void setCode(ErrorCode code) { fCode = code; }
+ void setNoun(const SkString& str) { fNoun.set(str); }
+ void setNoun(const char* ch) { fNoun.set(ch); }
+ void setNoun(const char* ch, size_t len) { fNoun.set(ch, len); }
+protected:
+ ErrorCode fCode;
+private:
+ int fLineNumber;
+ int fNativeCode;
+ SkString fNoun;
+ friend class SkXMLParser;
+};
+
+class SkXMLParser {
+public:
+ SkXMLParser(SkXMLParserError* parserError = NULL);
+ virtual ~SkXMLParser();
+
+ /** Returns true for success
+ */
+ bool parse(const char doc[], size_t len);
+ bool parse(SkStream& docStream);
+ bool parse(const SkDOM&, const SkDOMNode*);
+
+ static void GetNativeErrorString(int nativeErrorCode, SkString* str);
+
+protected:
+ // override in subclasses; return true to stop parsing
+ virtual bool onStartElement(const char elem[]);
+ virtual bool onAddAttribute(const char name[], const char value[]);
+ virtual bool onEndElement(const char elem[]);
+ virtual bool onText(const char text[], int len);
+
+public:
+ // public for ported implementation, not meant for clients to call
+ virtual bool startElement(const char elem[]);
+ virtual bool addAttribute(const char name[], const char value[]);
+ virtual bool endElement(const char elem[]);
+ virtual bool text(const char text[], int len);
+ void* fParser;
+protected:
+ SkXMLParserError* fError;
+private:
+ void reportError(void* parser);
+};
+
+#if 0
+class SkXMLPullParser {
+public:
+ SkXMLPullParser();
+ explicit SkXMLPullParser(SkStream*);
+ virtual ~SkXMLPullParser();
+
+ SkStream* getStream() const { return fStream; }
+ SkStream* setStream(SkStream* stream);
+
+ enum EventType {
+ ERROR = -1,
+ START_DOCUMENT,
+ END_DOCUMENT,
+ START_TAG,
+ END_TAG,
+ TEXT,
+ CDSECT,
+ ENTITY_REF,
+ IGNORABLE_WHITESPACE,
+ PROCESSING_INSTRUCTION,
+ COMMENT,
+ DOCDECL
+ };
+
+ EventType nextToken();
+ EventType getEventType() const { return fCurr.fEventType; }
+
+ struct AttrInfo {
+ const char* fName;
+ const char* fValue;
+ };
+
+ int getDepth() const { return fDepth; }
+ const char* getName();
+ int getAttributeCount();
+ void getAttributeInfo(int, AttrInfo*);
+ const char* getText();
+ bool isWhitespace();
+
+protected:
+ virtual bool onEntityReplacement(const char name[],
+ SkString* replacement);
+
+public:
+ struct Curr {
+ EventType fEventType;
+ const char* fName;
+ AttrInfo* fAttrInfos;
+ int fAttrInfoCount;
+ bool fIsWhitespace;
+ };
+
+private:
+ // implemented in the porting layer
+ bool onInit(); // return false on failure
+ EventType onNextToken();
+ void onExit();
+
+ SkStream* fStream;
+ Curr fCurr;
+ int fDepth;
+
+ struct Impl;
+ Impl* fImpl;
+};
+#endif
+
+#endif
diff --git a/src/third_party/skia/include/xml/SkXMLWriter.h b/src/third_party/skia/include/xml/SkXMLWriter.h
new file mode 100644
index 0000000..214fefe
--- /dev/null
+++ b/src/third_party/skia/include/xml/SkXMLWriter.h
@@ -0,0 +1,85 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkXMLWriter_DEFINED
+#define SkXMLWriter_DEFINED
+
+#include "SkTDArray.h"
+#include "SkString.h"
+#include "SkDOM.h"
+
+class SkWStream;
+class SkXMLParser;
+
+class SkXMLWriter {
+public:
+ SkXMLWriter(bool doEscapeMarkup = true);
+ virtual ~SkXMLWriter();
+
+ void addS32Attribute(const char name[], int32_t value);
+ void addAttribute(const char name[], const char value[]);
+ void addAttributeLen(const char name[], const char value[], size_t length);
+ void addHexAttribute(const char name[], uint32_t value, int minDigits = 0);
+ void addScalarAttribute(const char name[], SkScalar value);
+ void endElement() { this->onEndElement(); }
+ void startElement(const char elem[]);
+ void startElementLen(const char elem[], size_t length);
+ void writeDOM(const SkDOM&, const SkDOM::Node*, bool skipRoot);
+ void flush();
+ virtual void writeHeader();
+
+protected:
+ virtual void onStartElementLen(const char elem[], size_t length) = 0;
+ virtual void onAddAttributeLen(const char name[], const char value[], size_t length) = 0;
+ virtual void onEndElement() = 0;
+
+ struct Elem {
+ SkString fName;
+ bool fHasChildren;
+ };
+ void doEnd(Elem* elem);
+ bool doStart(const char name[], size_t length);
+ Elem* getEnd();
+ const char* getHeader();
+ SkTDArray<Elem*> fElems;
+
+private:
+ bool fDoEscapeMarkup;
+ // illegal
+ SkXMLWriter& operator=(const SkXMLWriter&);
+};
+
+class SkXMLStreamWriter : public SkXMLWriter {
+public:
+ SkXMLStreamWriter(SkWStream*);
+ virtual ~SkXMLStreamWriter();
+ virtual void writeHeader();
+ SkDEBUGCODE(static void UnitTest();)
+protected:
+ virtual void onStartElementLen(const char elem[], size_t length);
+ virtual void onEndElement();
+ virtual void onAddAttributeLen(const char name[], const char value[], size_t length);
+private:
+ SkWStream& fStream;
+};
+
+class SkXMLParserWriter : public SkXMLWriter {
+public:
+ SkXMLParserWriter(SkXMLParser*);
+ virtual ~SkXMLParserWriter();
+protected:
+ virtual void onStartElementLen(const char elem[], size_t length);
+ virtual void onEndElement();
+ virtual void onAddAttributeLen(const char name[], const char value[], size_t length);
+private:
+ SkXMLParser& fParser;
+};
+
+
+#endif