aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
commit8a1c16ff38322f0210116fa7293eb8817c7e477e (patch)
treefe40e07f6c8983318a2f79032b9a706ede1090c1 /include
parent2559c629078f738ac37095d896d580b681ac6a30 (diff)
grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r--include/animator/SkAnimator.h508
-rw-r--r--include/animator/SkAnimatorView.h47
-rw-r--r--include/core/Sk64.h245
-rw-r--r--include/core/SkBitmap.h684
-rw-r--r--include/core/SkBounder.h72
-rw-r--r--include/core/SkBuffer.h141
-rw-r--r--include/core/SkCanvas.h794
-rw-r--r--include/core/SkChunkAlloc.h61
-rw-r--r--include/core/SkColor.h155
-rw-r--r--include/core/SkColorFilter.h125
-rw-r--r--include/core/SkColorPriv.h657
-rw-r--r--include/core/SkColorShader.h63
-rw-r--r--include/core/SkComposeShader.h66
-rw-r--r--include/core/SkDeque.h74
-rw-r--r--include/core/SkDescriptor.h187
-rw-r--r--include/core/SkDevice.h142
-rw-r--r--include/core/SkDither.h205
-rw-r--r--include/core/SkDraw.h124
-rw-r--r--include/core/SkDrawFilter.h56
-rw-r--r--include/core/SkDrawLooper.h64
-rw-r--r--include/core/SkEndian.h98
-rw-r--r--include/core/SkFDot6.h67
-rw-r--r--include/core/SkFixed.h253
-rw-r--r--include/core/SkFlattenable.h207
-rw-r--r--include/core/SkFloatBits.h150
-rw-r--r--include/core/SkFloatingPoint.h75
-rw-r--r--include/core/SkFontHost.h122
-rw-r--r--include/core/SkGlobals.h67
-rw-r--r--include/core/SkGraphics.h46
-rw-r--r--include/core/SkMMapStream.h38
-rw-r--r--include/core/SkMallocPixelRef.h60
-rw-r--r--include/core/SkMask.h86
-rw-r--r--include/core/SkMaskFilter.h100
-rw-r--r--include/core/SkMath.h230
-rw-r--r--include/core/SkMatrix.h479
-rw-r--r--include/core/SkPackBits.h86
-rw-r--r--include/core/SkPaint.h814
-rw-r--r--include/core/SkPath.h588
-rw-r--r--include/core/SkPathEffect.h144
-rw-r--r--include/core/SkPathMeasure.h115
-rw-r--r--include/core/SkPerspIter.h55
-rw-r--r--include/core/SkPicture.h124
-rw-r--r--include/core/SkPixelRef.h158
-rw-r--r--include/core/SkPoint.h288
-rw-r--r--include/core/SkPorterDuff.h79
-rw-r--r--include/core/SkPostConfig.h216
-rw-r--r--include/core/SkPreConfig.h110
-rw-r--r--include/core/SkPtrRecorder.h48
-rw-r--r--include/core/SkRandom.h110
-rw-r--r--include/core/SkRasterizer.h50
-rw-r--r--include/core/SkReader32.h115
-rw-r--r--include/core/SkRect.h435
-rw-r--r--include/core/SkRefCnt.h134
-rw-r--r--include/core/SkRegion.h352
-rw-r--r--include/core/SkScalar.h254
-rw-r--r--include/core/SkScalarCompare.h34
-rw-r--r--include/core/SkScalerContext.h219
-rw-r--r--include/core/SkShader.h184
-rw-r--r--include/core/SkStream.h315
-rw-r--r--include/core/SkString.h170
-rw-r--r--include/core/SkStroke.h71
-rw-r--r--include/core/SkTDArray.h293
-rw-r--r--include/core/SkTDStack.h120
-rw-r--r--include/core/SkTDict.h169
-rw-r--r--include/core/SkTSearch.h167
-rw-r--r--include/core/SkTemplates.h217
-rw-r--r--include/core/SkThread.h68
-rw-r--r--include/core/SkThread_platform.h71
-rw-r--r--include/core/SkTime.h72
-rw-r--r--include/core/SkTypeface.h131
-rw-r--r--include/core/SkTypes.h377
-rw-r--r--include/core/SkUnPreMultiply.h63
-rw-r--r--include/core/SkUnitMapper.h38
-rw-r--r--include/core/SkUserConfig.h104
-rw-r--r--include/core/SkUtils.h140
-rw-r--r--include/core/SkWriter32.h112
-rw-r--r--include/core/SkXfermode.h115
-rw-r--r--include/effects/Sk1DPathEffect.h93
-rw-r--r--include/effects/Sk2DPathEffect.h73
-rw-r--r--include/effects/SkAvoidXfermode.h73
-rw-r--r--include/effects/SkBlurDrawLooper.h69
-rw-r--r--include/effects/SkBlurMaskFilter.h58
-rw-r--r--include/effects/SkColorMatrix.h53
-rw-r--r--include/effects/SkColorMatrixFilter.h67
-rw-r--r--include/effects/SkCornerPathEffect.h61
-rw-r--r--include/effects/SkDashPathEffect.h65
-rw-r--r--include/effects/SkDiscretePathEffect.h56
-rw-r--r--include/effects/SkDrawExtraPathEffect.h22
-rw-r--r--include/effects/SkEmbossMaskFilter.h63
-rw-r--r--include/effects/SkGradientShader.h97
-rw-r--r--include/effects/SkKernel33MaskFilter.h73
-rw-r--r--include/effects/SkLayerDrawLooper.h70
-rw-r--r--include/effects/SkLayerRasterizer.h63
-rw-r--r--include/effects/SkPaintFlagsDrawFilter.h37
-rw-r--r--include/effects/SkPixelXorXfermode.h50
-rw-r--r--include/effects/SkTransparentShader.h55
-rw-r--r--include/images/SkFlipPixelRef.h114
-rw-r--r--include/images/SkImageDecoder.h301
-rw-r--r--include/images/SkImageRef.h97
-rw-r--r--include/images/SkImageRef_GlobalPool.h72
-rw-r--r--include/images/SkMovie.h83
-rw-r--r--include/images/SkPageFlipper.h70
-rw-r--r--include/ports/SkOSFile.h85
-rw-r--r--include/ports/SkStream_Win.h53
-rw-r--r--include/svg/SkSVGAttribute.h49
-rw-r--r--include/svg/SkSVGBase.h33
-rw-r--r--include/svg/SkSVGPaintState.h96
-rw-r--r--include/svg/SkSVGParser.h81
-rw-r--r--include/svg/SkSVGTypes.h46
-rw-r--r--include/utils/SkCamera.h176
-rw-r--r--include/utils/SkCullPoints.h75
-rw-r--r--include/utils/SkDumpCanvas.h139
-rw-r--r--include/utils/SkGLCanvas.h80
-rw-r--r--include/utils/SkInterpolator.h139
-rw-r--r--include/utils/SkNinePatch.h40
-rw-r--r--include/utils/SkParse.h45
-rw-r--r--include/utils/SkParsePaint.h34
-rw-r--r--include/utils/SkProxyCanvas.h90
-rw-r--r--include/utils/SkTextBox.h77
-rw-r--r--include/utils/SkUnitMappers.h65
-rw-r--r--include/views/SkApplication.h26
-rw-r--r--include/views/SkBGViewArtist.h41
-rw-r--r--include/views/SkBorderView.h48
-rw-r--r--include/views/SkEvent.h244
-rw-r--r--include/views/SkEventSink.h103
-rw-r--r--include/views/SkImageView.h75
-rw-r--r--include/views/SkKey.h63
-rw-r--r--include/views/SkMetaData.h154
-rw-r--r--include/views/SkOSMenu.h55
-rw-r--r--include/views/SkOSSound.h36
-rw-r--r--include/views/SkOSWindow_Mac.h49
-rw-r--r--include/views/SkOSWindow_Unix.h60
-rw-r--r--include/views/SkOSWindow_Win.h59
-rw-r--r--include/views/SkOSWindow_wxwidgets.h52
-rw-r--r--include/views/SkProgressBarView.h57
-rw-r--r--include/views/SkScrollBarView.h52
-rw-r--r--include/views/SkStackViewLayout.h96
-rw-r--r--include/views/SkSystemEventTypes.h32
-rw-r--r--include/views/SkView.h345
-rw-r--r--include/views/SkViewInflate.h79
-rw-r--r--include/views/SkWidget.h476
-rw-r--r--include/views/SkWidgetViews.h310
-rw-r--r--include/views/SkWindow.h102
-rw-r--r--include/xml/SkBML_WXMLParser.h54
-rw-r--r--include/xml/SkBML_XMLParser.h39
-rw-r--r--include/xml/SkDOM.h100
-rw-r--r--include/xml/SkJS.h47
-rw-r--r--include/xml/SkXMLParser.h161
-rw-r--r--include/xml/SkXMLWriter.h93
149 files changed, 20519 insertions, 0 deletions
diff --git a/include/animator/SkAnimator.h b/include/animator/SkAnimator.h
new file mode 100644
index 0000000000..04d342cdaa
--- /dev/null
+++ b/include/animator/SkAnimator.h
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/animator/SkAnimatorView.h b/include/animator/SkAnimatorView.h
new file mode 100644
index 0000000000..3c6c8a1291
--- /dev/null
+++ b/include/animator/SkAnimatorView.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/core/Sk64.h b/include/core/Sk64.h
new file mode 100644
index 0000000000..c4ae41eb68
--- /dev/null
+++ b/include/core/Sk64.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef Sk64_DEFINED
+#define Sk64_DEFINED
+
+#include "SkFixed.h"
+#include "SkMath.h"
+
+/** \class Sk64
+
+ Sk64 is a 64-bit math package that does not require long long support from the compiler.
+*/
+struct Sk64 {
+ int32_t fHi; //!< the high 32 bits of the number (including sign)
+ uint32_t fLo; //!< the low 32 bits of the number
+
+ /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integer
+ */
+ SkBool is32() const { return fHi == ((int32_t)fLo >> 31); }
+
+ /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit integer
+ */
+ SkBool is64() const { return fHi != ((int32_t)fLo >> 31); }
+
+ /** Returns non-zero if the Sk64 can be represented as a signed 48 bit integer. Used to know
+ if we can shift the value down by 16 to treat it as a SkFixed.
+ */
+ SkBool isFixed() const;
+
+ /** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero.
+ */
+ int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; }
+
+ /** Return the number >> 16. Asserts that this does not loose any significant high bits.
+ */
+ SkFixed getFixed() const {
+ SkASSERT(this->isFixed());
+
+ uint32_t sum = fLo + (1 << 15);
+ int32_t hi = fHi;
+ if (sum < fLo) {
+ hi += 1;
+ }
+ return (hi << 16) | (sum >> 16);
+ }
+
+ /** Return the number >> 30. Asserts that this does not loose any
+ significant high bits.
+ */
+ SkFract getFract() const;
+
+ /** Returns the square-root of the number as a signed 32 bit value. */
+ int32_t getSqrt() const;
+
+ /** Returns the number of leading zeros of the absolute value of this.
+ Will return in the range [0..64]
+ */
+ int getClzAbs() const;
+
+ /** Returns non-zero if the number is zero */
+ SkBool isZero() const { return (fHi | fLo) == 0; }
+
+ /** Returns non-zero if the number is non-zero */
+ SkBool nonZero() const { return fHi | fLo; }
+
+ /** Returns non-zero if the number is negative (number < 0) */
+ SkBool isNeg() const { return (uint32_t)fHi >> 31; }
+
+ /** Returns non-zero if the number is positive (number > 0) */
+ SkBool isPos() const { return ~(fHi >> 31) & (fHi | fLo); }
+
+ /** Returns -1,0,+1 based on the sign of the number */
+ int sign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); }
+
+ /** Negate the number */
+ void negate();
+
+ /** If the number < 0, negate the number
+ */
+ void abs();
+
+ /** Returns the number of bits needed to shift the Sk64 to the right
+ in order to make it fit in a signed 32 bit integer.
+ */
+ int shiftToMake32() const;
+
+ /** Set the number to zero */
+ void setZero() { fHi = fLo = 0; }
+
+ /** Set the high and low 32 bit values of the number */
+ void set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; }
+
+ /** Set the number to the specified 32 bit integer */
+ void set(int32_t a) { fHi = a >> 31; fLo = a; }
+
+ /** Set the number to the product of the two 32 bit integers */
+ void setMul(int32_t a, int32_t b);
+
+ /** extract 32bits after shifting right by bitCount.
+ Note: itCount must be [0..63].
+ Asserts that no significant high bits were lost.
+ */
+ int32_t getShiftRight(unsigned bitCount) const;
+
+ /** Shift the number left by the specified number of bits.
+ @param bits How far to shift left, must be [0..63]
+ */
+ void shiftLeft(unsigned bits);
+
+ /** Shift the number right by the specified number of bits.
+ @param bits How far to shift right, must be [0..63]. This
+ performs an arithmetic right-shift (sign extending).
+ */
+ void shiftRight(unsigned bits);
+
+ /** Shift the number right by the specified number of bits, but
+ round the result.
+ @param bits How far to shift right, must be [0..63]. This
+ performs an arithmetic right-shift (sign extending).
+ */
+ void roundRight(unsigned bits);
+
+ /** Add the specified 32 bit integer to the number */
+ void add(int32_t lo) {
+ int32_t hi = lo >> 31; // 0 or -1
+ uint32_t sum = fLo + (uint32_t)lo;
+
+ fHi = fHi + hi + (sum < fLo);
+ fLo = sum;
+ }
+
+ /** Add the specified Sk64 to the number */
+ void add(int32_t hi, uint32_t lo) {
+ uint32_t sum = fLo + lo;
+
+ fHi = fHi + hi + (sum < fLo);
+ fLo = sum;
+ }
+
+ /** Add the specified Sk64 to the number */
+ void add(const Sk64& other) { this->add(other.fHi, other.fLo); }
+
+ /** Subtract the specified Sk64 from the number. (*this) = (*this) - num
+ */
+ void sub(const Sk64& num);
+
+ /** Subtract the number from the specified Sk64. (*this) = num - (*this)
+ */
+ void rsub(const Sk64& num);
+
+ /** Multiply the number by the specified 32 bit integer
+ */
+ void mul(int32_t);
+
+ enum DivOptions {
+ kTrunc_DivOption, //!< truncate the result when calling div()
+ kRound_DivOption //!< round the result when calling div()
+ };
+
+ /** Divide the number by the specified 32 bit integer, using the specified
+ divide option (either truncate or round).
+ */
+ void div(int32_t, DivOptions);
+
+ /** return (this + other >> 16) as a 32bit result */
+ SkFixed addGetFixed(const Sk64& other) const {
+ return this->addGetFixed(other.fHi, other.fLo);
+ }
+
+ /** return (this + Sk64(hi, lo) >> 16) as a 32bit result */
+ SkFixed addGetFixed(int32_t hi, uint32_t lo) const {
+#ifdef SK_DEBUG
+ Sk64 tmp(*this);
+ tmp.add(hi, lo);
+#endif
+
+ uint32_t sum = fLo + lo;
+ hi += fHi + (sum < fLo);
+ lo = sum;
+
+ sum = lo + (1 << 15);
+ if (sum < lo)
+ hi += 1;
+
+ hi = (hi << 16) | (sum >> 16);
+ SkASSERT(hi == tmp.getFixed());
+ return hi;
+ }
+
+ /** Return the result of dividing the number by denom, treating the answer
+ as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0.
+ */
+ SkFixed getFixedDiv(const Sk64& denom) const;
+
+ friend bool operator==(const Sk64& a, const Sk64& b) {
+ return a.fHi == b.fHi && a.fLo == b.fLo;
+ }
+
+ friend bool operator!=(const Sk64& a, const Sk64& b) {
+ return a.fHi != b.fHi || a.fLo != b.fLo;
+ }
+
+ friend bool operator<(const Sk64& a, const Sk64& b) {
+ return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo);
+ }
+
+ friend bool operator<=(const Sk64& a, const Sk64& b) {
+ return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo);
+ }
+
+ friend bool operator>(const Sk64& a, const Sk64& b) {
+ return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo);
+ }
+
+ friend bool operator>=(const Sk64& a, const Sk64& b) {
+ return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo);
+ }
+
+#ifdef SkLONGLONG
+ SkLONGLONG getLongLong() const;
+#endif
+
+#ifdef SK_DEBUG
+ /** @cond UNIT_TEST */
+ static void UnitTest();
+ /** @endcond */
+#endif
+};
+
+#endif
+
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
new file mode 100644
index 0000000000..02c8cd9621
--- /dev/null
+++ b/include/core/SkBitmap.h
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkBitmap_DEFINED
+#define SkBitmap_DEFINED
+
+#include "Sk64.h"
+#include "SkColor.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+
+#if defined(SK_BUILD_FOR_MAC)
+#include <carbon/carbon.h>
+#endif
+
+struct SkIRect;
+class SkColorTable;
+class SkPaint;
+class SkPixelRef;
+class SkRegion;
+class SkFlattenableReadBuffer;
+class SkFlattenableWriteBuffer;
+
+/** \class SkBitmap
+
+ The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
+ and height, and a format (config), 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.
+*/
+class SkBitmap {
+public:
+ class Allocator;
+
+ enum Config {
+ kNo_Config, //!< bitmap has not been configured
+ kA1_Config, //!< 1-bit per pixel, (0 is transparent, 1 is opaque)
+ kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
+ kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
+ kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
+ kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
+ kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
+ kRLE_Index8_Config,
+
+ kConfigCount
+ };
+
+ /** Default construct creates a bitmap with zero width and height, and no pixels.
+ Its config is set to kNo_Config.
+ */
+ SkBitmap();
+ /** Constructor initializes the new bitmap by copying the src bitmap. All fields are copied,
+ but ownership of the pixels remains with the src bitmap.
+ */
+ SkBitmap(const SkBitmap& src);
+ /** Decrements our (shared) pixel ownership if needed.
+ */
+ ~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);
+
+ /** Return true iff the bitmap has empty dimensions.
+ */
+ bool empty() const { return 0 == fWidth || 0 == fHeight; }
+
+ /** Return true iff the bitmap has no pixels nor a pixelref. Note: this can
+ return true even if the dimensions of the bitmap are > 0 (see empty()).
+ */
+ bool isNull() const { return NULL == fPixels && NULL == fPixelRef; }
+
+ /** Return the config for the bitmap.
+ */
+ Config config() const { return (Config)fConfig; }
+ /** DEPRECATED, use config()
+ */
+ Config getConfig() const { return this->config(); }
+ /** Return the bitmap's width, in pixels.
+ */
+ int width() const { return fWidth; }
+ /** Return the bitmap's height, in pixels.
+ */
+ int height() const { return fHeight; }
+ /** Return the number of bytes between subsequent rows of the bitmap.
+ */
+ int rowBytes() const { return fRowBytes; }
+
+ /** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
+ 2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
+ for configs that are not at least 1-byte per pixel (e.g. kA1_Config
+ or kNo_Config)
+ */
+ int shiftPerPixel() const { return fBytesPerPixel >> 1; }
+
+ /** Return the number of bytes per pixel based on the config. If the config
+ does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
+ */
+ int bytesPerPixel() const { return fBytesPerPixel; }
+
+ /** Return the rowbytes expressed as a number of pixels (like width and
+ height). Note, for 1-byte per pixel configs like kA8_Config, this will
+ return the same as rowBytes(). Is undefined for configs that are less
+ than 1-byte per pixel (e.g. kA1_Config)
+ */
+ int rowBytesAsPixels() const { return fRowBytes >> (fBytesPerPixel >> 1); }
+
+ /** 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 fHeight * fRowBytes; }
+
+ /** Return the byte size of the pixels, based on the height and rowBytes.
+ This routine is slightly slower than getSize(), but does not truncate
+ the answer to 32bits.
+ */
+ Sk64 getSize64() const {
+ Sk64 size;
+ size.setMul(fHeight, fRowBytes);
+ return size;
+ }
+
+ /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
+ */
+ bool isOpaque() const;
+ /** Specify if this bitmap's pixels are all opaque or not. Is only meaningful for configs
+ that support per-pixel alpha (RGB32, A1, A8).
+ */
+ void setIsOpaque(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();
+
+ /** Given a config and a width, this computes the optimal rowBytes value. This is called automatically
+ if you pass 0 for rowBytes to setConfig().
+ */
+ static int ComputeRowBytes(Config c, int width);
+
+ /** Return the bytes-per-pixel for the specified config. If the config is
+ not at least 1-byte per pixel, return 0, including for kNo_Config.
+ */
+ static int ComputeBytesPerPixel(Config c);
+
+ /** Return the shift-per-pixel for the specified config. If the config is
+ not at least 1-byte per pixel, return 0, including for kNo_Config.
+ */
+ static int ComputeShiftPerPixel(Config c) {
+ return ComputeBytesPerPixel(c) >> 1;
+ }
+
+ static Sk64 ComputeSize64(Config, int width, int height);
+ static size_t ComputeSize(Config, int width, int height);
+
+ /** Set the bitmap's config and dimensions. If rowBytes is 0, then
+ ComputeRowBytes() is called to compute the optimal value. This resets
+ any pixel/colortable ownership, just like reset().
+ */
+ void setConfig(Config, int width, int height, int rowBytes = 0);
+ /** 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);
+
+ /** Use the standard HeapAllocator to create the pixelref that manages the
+ pixel memory. It will be sized based on the current width/height/config.
+ If this is called multiple times, a new pixelref object will be created
+ 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 config == Index8_Config
+ @return true if the allocation succeeds. If not the pixelref field of
+ the bitmap will be unchanged.
+ */
+ bool 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 width/height/config.
+ 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
+ width/height/config. 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 config == Index8_Config.
+ If it is non-null and the config is not Index8, it will
+ be ignored.
+ @return true if the allocation succeeds. If not the pixelref field of
+ the bitmap will be unchanged.
+ */
+ bool allocPixels(Allocator* allocator, SkColorTable* ctable);
+
+ /** Return the current pixelref object, of any
+ */
+ SkPixelRef* pixelRef() const { return fPixelRef; }
+ /** Return the offset into the pixelref, if any. Will return 0 if there is
+ no pixelref installed.
+ */
+ size_t pixelRefOffset() const { return fPixelRefOffset; }
+ /** Assign a pixelref and optional offset. Pixelrefs are reference counted,
+ so the existing one (if any) will be unref'd and the new one will be
+ ref'd.
+ */
+ SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset = 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;
+
+ /** 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 config, it has a
+ non-null colortable. Returns true if all of the above are met.
+ */
+ bool readyToDraw() const {
+ return this->getPixels() != NULL &&
+ ((this->config() != kIndex8_Config && this->config() != kRLE_Index8_Config) ||
+ fColorTable != NULL);
+ }
+
+ /** Return the bitmap's colortable (if any). 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, or 0 if we do not have a 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() const;
+
+ /** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
+ for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is ignored.
+ If the config is kA8_Config, then the r,g,b parameters are ignored.
+ */
+ void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
+ /** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
+ for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is presumed
+ to be 0xFF. If the config is kA8_Config, then the r,g,b parameters are ignored and the
+ pixels are all set to 0xFF.
+ */
+ void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
+ this->eraseARGB(0xFF, r, g, b);
+ }
+ /** Initialize the bitmap's pixels with the specified color, automatically converting into the correct format
+ for the bitmap's config. If the config is kRGB_565_Config, then the color's alpha value is presumed
+ to be 0xFF. If the config is kA8_Config, then only the color's alpha value is used.
+ */
+ void eraseColor(SkColor c) const {
+ this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
+ SkColorGetB(c));
+ }
+
+ /** 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).
+
+ @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 bitmap
+ uses an unsupported config for scrolling (only kA8,
+ kIndex8, kRGB_565, kARGB_4444, kARGB_8888 are supported).
+ 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;
+
+ /** 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.
+ */
+ inline uint32_t* getAddr32(int x, int y) const;
+ /** Returns the address of the pixel specified by x,y for 16bit pixels.
+ */
+ inline uint16_t* getAddr16(int x, int y) const;
+ /** Returns the address of the pixel specified by x,y for 8bit pixels.
+ */
+ inline uint8_t* getAddr8(int x, int y) const;
+ /** Returns the address of the byte containing the pixel specified by x,y
+ for 1bit pixels.
+ */
+ inline uint8_t* getAddr1(int x, int y) const;
+
+ /** Returns the color corresponding to the pixel specified by x,y for
+ colortable based bitmaps.
+ */
+ inline SkPMColor getIndex8Color(int x, int y) const;
+
+ // OS-specific helpers
+#ifndef SK_USE_WXWIDGETS
+#ifdef SK_BUILD_FOR_WIN
+ /** On Windows and PocketPC builds, this will draw the SkBitmap onto the
+ specified HDC
+ */
+ void drawToHDC(HDC, int left, int top) const;
+#elif defined(SK_BUILD_FOR_MAC)
+ /** On Mac OS X and Carbon builds, this will draw the SkBitmap onto the
+ specified WindowRef
+ */
+ void drawToPort(WindowRef, CGContextRef) const;
+#endif
+#endif
+
+ /** 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 config
+ 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 config, 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;
+
+ /** Tries to make a new bitmap based on the dimensions of this bitmap,
+ setting the new bitmap's config to the one specified, and then copying
+ this bitmap's pixels into the new bitmap. If the conversion is not
+ supported, or the allocator fails, then this method returns false and
+ dst is left unchanged.
+ @param dst The bitmap to be sized and allocated
+ @param c The desired config 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 could be made.
+ */
+ bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const;
+
+ bool hasMipMap() const;
+ void buildMipMap(bool forceRebuild = false);
+ void freeMipMap();
+
+ /** Given scale factors sx, sy, determine the miplevel available in the
+ bitmap, and return it (this is the amount to shift matrix iterators
+ by). If dst is not null, it is set to the correct level.
+ */
+ int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
+
+ void extractAlpha(SkBitmap* dst) const {
+ this->extractAlpha(dst, NULL, NULL);
+ }
+
+ void extractAlpha(SkBitmap* dst, const SkPaint* paint,
+ SkIPoint* offset) const;
+
+ void flatten(SkFlattenableWriteBuffer&) const;
+ void unflatten(SkFlattenableReadBuffer&);
+
+ SkDEBUGCODE(void validate() const;)
+
+ class Allocator : public SkRefCnt {
+ public:
+ /** Allocate the pixel memory for the bitmap, given its dimensions and
+ config. Return true on success, where success means either setPixels
+ or setPixelRef was called. The pixels need not be locked when this
+ returns. If the config 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;
+ };
+
+ /** 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*);
+ };
+
+ 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;
+ };
+
+private:
+#ifdef SK_SUPPORT_MIPMAP
+ struct MipMap;
+ mutable MipMap* fMipMap;
+#endif
+
+ mutable SkPixelRef* fPixelRef;
+ mutable size_t fPixelRefOffset;
+ mutable int fPixelLockCount;
+ // either user-specified (in which case it is not treated as mutable)
+ // or a cache of the returned value from fPixelRef->lockPixels()
+ mutable void* fPixels;
+ mutable SkColorTable* fColorTable; // only meaningful for kIndex8
+
+ enum Flags {
+ kImageIsOpaque_Flag = 0x01
+ };
+
+ uint32_t fRowBytes;
+ uint16_t fWidth, fHeight;
+ uint8_t fConfig;
+ uint8_t fFlags;
+ uint8_t fBytesPerPixel; // based on config
+
+ /* Unreference any pixelrefs or colortables
+ */
+ void freePixels();
+ void updatePixelsFromRef() const;
+
+ static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy);
+};
+
+/** \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 SkColorTable : public SkRefCnt {
+public:
+ /** Constructs an empty color table (zero colors).
+ */
+ explicit SkColorTable(int count);
+ explicit SkColorTable(SkFlattenableReadBuffer&);
+ SkColorTable(const SkPMColor colors[], int count);
+ virtual ~SkColorTable();
+
+ enum Flags {
+ kColorsAreOpaque_Flag = 0x01 //!< if set, all of the colors in the table are opaque (alpha==0xFF)
+ };
+ /** Returns the flag bits for the color table. These can be changed with setFlags().
+ */
+ unsigned getFlags() const { return fFlags; }
+ /** Set the flags for the color table. See the Flags enum for possible values.
+ */
+ void setFlags(unsigned flags);
+
+ /** 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];
+ }
+
+ /** Specify the number of colors in the color table. This does not initialize the colors
+ to any value, just allocates memory for them. To initialize the values, either call
+ setColors(array, count), or follow setCount(count) with a call to
+ lockColors()/{set the values}/unlockColors(true).
+ */
+// void setColors(int count) { this->setColors(NULL, count); }
+// void setColors(const SkPMColor[], int count);
+
+ /** Return the array of colors for reading and/or writing. This must be
+ balanced by a call to unlockColors(changed?), telling the colortable if
+ the colors were changed during the lock.
+ */
+ SkPMColor* lockColors() {
+ SkDEBUGCODE(fColorLockCount += 1;)
+ return fColors;
+ }
+ /** Balancing call to lockColors(). If the colors have been changed, pass true.
+ */
+ void unlockColors(bool changed);
+
+ /** 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);
+ }
+
+ void flatten(SkFlattenableWriteBuffer&) const;
+
+private:
+ SkPMColor* fColors;
+ uint16_t* f16BitCache;
+ uint16_t fCount;
+ uint8_t fFlags;
+ SkDEBUGCODE(int fColorLockCount;)
+ SkDEBUGCODE(int f16BitCacheLockCount;)
+
+ void inval16BitCache();
+};
+
+class SkAutoLockPixels {
+public:
+ SkAutoLockPixels(const SkBitmap& bitmap) : fBitmap(bitmap) {
+ bitmap.lockPixels();
+ }
+ ~SkAutoLockPixels() {
+ fBitmap.unlockPixels();
+ }
+
+private:
+ const SkBitmap& fBitmap;
+};
+
+/** 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 : public 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(false);
+ }
+ }
+
+ /** Return the currently locked colors, or NULL if no bitmap's colortable
+ is currently locked.
+ */
+ const SkPMColor* colors() const { return fColors; }
+
+ /** If a previous bitmap has been locked by this object, unlock its colors
+ first. If the specified bitmap has a colortable, lock its colors and
+ return them.
+ */
+ const SkPMColor* lockColors(const SkBitmap& bm) {
+ if (fCTable) {
+ fCTable->unlockColors(false);
+ }
+ fCTable = bm.getColorTable();
+ fColors = fCTable ? fCTable->lockColors() : NULL;
+ return fColors;
+ }
+
+private:
+ SkColorTable* fCTable;
+ const SkPMColor* fColors;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(fConfig == kARGB_8888_Config);
+ SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
+}
+
+inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(fConfig == kRGB_565_Config || fConfig == kARGB_4444_Config);
+ SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
+}
+
+inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
+ SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ return (uint8_t*)fPixels + y * fRowBytes + x;
+}
+
+inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(fConfig == kIndex8_Config);
+ SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ SkASSERT(fColorTable);
+ return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
+}
+
+// returns the address of the byte that contains the x coordinate
+inline uint8_t* SkBitmap::getAddr1(int x, int y) const {
+ SkASSERT(fPixels);
+ SkASSERT(fConfig == kA1_Config);
+ SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
+ return (uint8_t*)fPixels + y * fRowBytes + (x >> 3);
+}
+
+#endif
+
diff --git a/include/core/SkBounder.h b/include/core/SkBounder.h
new file mode 100644
index 0000000000..f20961d2ed
--- /dev/null
+++ b/include/core/SkBounder.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkBounder_DEFINED
+#define SkBounder_DEFINED
+
+#include "SkTypes.h"
+#include "SkRefCnt.h"
+
+struct SkIRect;
+struct SkPoint;
+struct SkRect;
+class SkPaint;
+class SkPath;
+class SkRegion;
+
+/** \class SkBounder
+
+ Base class for intercepting the device bounds of shapes before they are drawn.
+ Install a subclass of this in your canvas.
+*/
+class SkBounder : public SkRefCnt {
+public:
+ /* Call to perform a clip test before calling onIRect.
+ Returns the result from onIRect.
+ */
+ bool doIRect(const SkIRect&);
+
+protected:
+ /** Override in your subclass. This is called with the device bounds of an
+ object (text, geometry, image) just before it is drawn. If your method
+ returns false, the drawing for that shape is aborted. If your method
+ returns true, drawing continues. The bounds your method receives have already
+ been transformed in to device coordinates, and clipped to the current clip.
+ */
+ virtual bool onIRect(const SkIRect&) = 0;
+
+ /** Called after each shape has been drawn. The default implementation does
+ nothing, but your override could use this notification to signal itself
+ that the offscreen being rendered into needs to be updated to the screen.
+ */
+ virtual void commit();
+
+private:
+ bool doHairline(const SkPoint&, const SkPoint&, const SkPaint&);
+ bool doRect(const SkRect&, const SkPaint&);
+ bool doPath(const SkPath&, const SkPaint&, bool doFill);
+ void setClip(const SkRegion* clip) { fClip = clip; }
+
+ const SkRegion* fClip;
+ friend class SkAutoBounderCommit;
+ friend class SkDraw;
+ friend class SkDrawIter;
+ friend struct Draw1Glyph;
+ friend class SkMaskFilter;
+};
+
+#endif
+
diff --git a/include/core/SkBuffer.h b/include/core/SkBuffer.h
new file mode 100644
index 0000000000..bc11a1e70e
--- /dev/null
+++ b/include/core/SkBuffer.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkBuffer_DEFINED
+#define SkBuffer_DEFINED
+
+#include "SkScalar.h"
+
+/** \class SkRBuffer
+
+ Light weight class for reading data from a memory block.
+ The RBuffer is given the buffer to read from, with either a specified size
+ or no size (in which case no range checking is performed). It is iillegal
+ to attempt to read a value from an empty RBuffer (data == null).
+*/
+class SkRBuffer : SkNoncopyable {
+public:
+ SkRBuffer() : fData(0), fPos(0), fStop(0) {}
+ /** Initialize RBuffer with a data pointer, but no specified length.
+ This signals the RBuffer to not perform range checks during reading.
+ */
+ SkRBuffer(const void* data)
+ {
+ fData = (const char*)data;
+ fPos = (const char*)data;
+ fStop = 0; // no bounds checking
+ }
+ /** Initialize RBuffer with a data point and length.
+ */
+ SkRBuffer(const void* data, size_t size)
+ {
+ SkASSERT(data != 0 || size == 0);
+ fData = (const char*)data;
+ fPos = (const char*)data;
+ fStop = (const char*)data + size;
+ }
+
+ /** Return the number of bytes that have been read from the beginning
+ of the data pointer.
+ */
+ size_t pos() const { return fPos - fData; }
+ /** Return the total size of the data pointer. Only defined if the length was
+ specified in the constructor or in a call to reset().
+ */
+ size_t size() const { return fStop - fData; }
+ /** Return true if the buffer has read to the end of the data pointer.
+ Only defined if the length was specified in the constructor or in a call
+ to reset(). Always returns true if the length was not specified.
+ */
+ bool eof() const { return fPos >= fStop; }
+
+ /** Read the specified number of bytes from the data pointer. If buffer is not
+ null, copy those bytes into buffer.
+ */
+ void read(void* buffer, size_t size) { if (size) this->readNoSizeCheck(buffer, size); }
+ const void* skip(size_t size); // return start of skipped data
+ size_t skipToAlign4();
+
+ void* readPtr() { void* ptr; read(&ptr, sizeof(ptr)); return ptr; }
+ SkScalar readScalar() { SkScalar x; read(&x, 4); return x; }
+ uint32_t readU32() { uint32_t x; read(&x, 4); return x; }
+ int32_t readS32() { int32_t x; read(&x, 4); return x; }
+ uint16_t readU16() { uint16_t x; read(&x, 2); return x; }
+ int16_t readS16() { int16_t x; read(&x, 2); return x; }
+ uint8_t readU8() { uint8_t x; read(&x, 1); return x; }
+ bool readBool() { return this->readU8() != 0; }
+
+protected:
+ void readNoSizeCheck(void* buffer, size_t size);
+
+ const char* fData;
+ const char* fPos;
+ const char* fStop;
+};
+
+/** \class SkWBuffer
+
+ Light weight class for writing data to a memory block.
+ The WBuffer is given the buffer to write into, with either a specified size
+ or no size, in which case no range checking is performed. An empty WBuffer
+ is legal, in which case no data is ever written, but the relative pos()
+ is updated.
+*/
+class SkWBuffer : SkNoncopyable {
+public:
+ SkWBuffer() : fData(0), fPos(0), fStop(0) {}
+ SkWBuffer(void* data) { reset(data); }
+ SkWBuffer(void* data, size_t size) { reset(data, size); }
+
+ void reset(void* data)
+ {
+ fData = (char*)data;
+ fPos = (char*)data;
+ fStop = 0; // no bounds checking
+ }
+ void reset(void* data, size_t size)
+ {
+ SkASSERT(data != 0 || size == 0);
+ fData = (char*)data;
+ fPos = (char*)data;
+ fStop = (char*)data + size;
+ }
+
+ void* data() const { return fData; }
+ size_t pos() const { return fPos - fData; }
+ size_t size() const { return fStop - fData; }
+ bool eof() const { return fPos >= fStop; }
+ void* skip(size_t size); // return start of skipped data
+ void write(const void* buffer, size_t size) { if (size) this->writeNoSizeCheck(buffer, size); }
+ size_t padToAlign4();
+
+ void writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
+ void writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
+ void write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
+ void write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
+ void write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
+ void writeBool(bool x) { this->write8(x); }
+
+protected:
+ void writeNoSizeCheck(const void* buffer, size_t size);
+
+ char* fData;
+ char* fPos;
+ char* fStop;
+};
+
+#endif
+
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
new file mode 100644
index 0000000000..a19a5ae706
--- /dev/null
+++ b/include/core/SkCanvas.h
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkCanvas_DEFINED
+#define SkCanvas_DEFINED
+
+#include "SkTypes.h"
+#include "SkBitmap.h"
+#include "SkDeque.h"
+#include "SkPaint.h"
+#include "SkRefCnt.h"
+#include "SkPorterDuff.h"
+#include "SkPath.h"
+#include "SkRegion.h"
+#include "SkScalarCompare.h"
+
+class SkBounder;
+class SkDevice;
+class SkDraw;
+class SkDrawFilter;
+class SkPicture;
+
+/** \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 SkCanvas : public SkRefCnt {
+public:
+ /** 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);
+ /** Construct a canvas with the specified device to draw into.
+ @param device Specifies a device for the canvas to draw into. The
+ device may be null.
+ */
+ explicit SkCanvas(SkDevice* device = NULL);
+ virtual ~SkCanvas();
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** If this subclass of SkCanvas supports GL viewports, return true and set
+ size (if not null) to the size of the viewport. If it is not supported,
+ ignore vp and return false.
+ */
+ virtual bool getViewport(SkIPoint* size) const;
+
+ /** If this subclass of SkCanvas supports GL viewports, return true and set
+ the viewport to the specified x and y dimensions. If it is not
+ supported, ignore x and y and return false.
+ */
+ virtual bool setViewport(int x, int y);
+
+ /** 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.
+ */
+ SkDevice* getDevice() const;
+
+ /** 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.
+ */
+ SkDevice* setDevice(SkDevice* device);
+
+ /** Specify a bitmap for the canvas to draw into. This is a help method for
+ setDevice(), and it creates a device for the bitmap by calling
+ createDevice(). The structure of the bitmap is copied into the device.
+ */
+ virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ enum SaveFlags {
+ /** save the matrix state, restoring it on restore() */
+ kMatrix_SaveFlag = 0x01,
+ /** save the clip state, restoring it on restore() */
+ 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 */
+ kClipToLayer_SaveFlag = 0x10,
+
+ // helper masks for common choices
+ kMatrixClip_SaveFlag = 0x03,
+ kARGB_NoClipLayer_SaveFlag = 0x0F,
+ kARGB_ClipLayer_SaveFlag = 0x1F
+ };
+
+ /** This call saves the current matrix and clip information, and pushes a
+ copy onto a private stack. Subsequent calls to translate, scale,
+ rotate, skew, concat or clipRect, clipPath all operate on this copy.
+ When the balancing call to restore() is made, this copy is deleted and
+ the previous matrix/clip state is restored.
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
+
+ /** 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). Subsequent calls to translate,
+ scale, rotate, skew, concat or clipRect, clipPath all operate on this
+ copy. When the balancing call to restore() is made, this copy is deleted
+ and the previous matrix/clip state is restored.
+ @param bounds (may be null) the maximum size the offscreen bitmap needs
+ to be (in local coordinates)
+ @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()
+ */
+ virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
+ SaveFlags flags = kARGB_ClipLayer_SaveFlag);
+
+ /** 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). Subsequent calls to translate,
+ scale, rotate, skew, concat or clipRect, clipPath all operate on this
+ copy. When the balancing call to restore() is made, this copy is deleted
+ and the previous matrix/clip state is restored.
+ @param bounds (may be null) the maximum size the offscreen bitmap needs
+ to be (in local coordinates)
+ @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()
+ */
+ int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
+ SaveFlags flags = kARGB_ClipLayer_SaveFlag);
+
+ /** This call balances a previous call to save(), and is used to remove all
+ modifications to the matrix/clip state since the last save call. It is
+ an error to call restore() more times than save() was called.
+ */
+ virtual void restore();
+
+ /** Returns the number of matrix/clip states on the SkCanvas' private stack.
+ This will equal # save() calls - # restore() calls.
+ */
+ 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 less than
+ getSaveCount()
+ @param saveCount The number of save() levels to restore from
+ */
+ void restoreToCount(int saveCount);
+
+ /** Preconcat the current matrix with the specified translation
+ @param dx The distance to translate in X
+ @param dy The distance to translate in Y
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool 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
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool scale(SkScalar sx, SkScalar sy);
+
+ /** Preconcat the current matrix with the specified rotation.
+ @param degrees The amount to rotate, in degrees
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool 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
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool skew(SkScalar sx, SkScalar sy);
+
+ /** Preconcat the current matrix with the specified matrix.
+ @param matrix The matrix to preconcatenate with the current matrix
+ @return true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool concat(const SkMatrix& matrix);
+
+ /** Replace the current matrix with a copy of the specified matrix.
+ @param matrix The matrix that will be copied into the current matrix.
+ */
+ virtual void setMatrix(const SkMatrix& matrix);
+
+ /** Helper for setMatrix(identity). Sets the current matrix to identity.
+ */
+ void resetMatrix();
+
+ /** Modify the current clip with the specified rectangle.
+ @param rect The rect to intersect with the current clip
+ @param op The region op to apply to the current clip
+ @return true if the canvas' clip is non-empty
+ */
+ virtual bool clipRect(const SkRect& rect,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ /** Modify the current clip with the specified path.
+ @param path The path to apply to the current clip
+ @param op The region op to apply to the current clip
+ @return true if the canvas' new clip is non-empty
+ */
+ virtual bool clipPath(const SkPath& path,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ /** 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
+ @return true if the canvas' new clip is non-empty
+ */
+ virtual bool 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.
+ @return true if the new clip region is non-empty
+ */
+ bool setClipRegion(const SkRegion& deviceRgn) {
+ return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
+ }
+
+ /** Enum describing how to treat edges when performing quick-reject tests
+ of a geometry against the current clip. Treating them as antialiased
+ (kAA_EdgeType) will take into account the extra pixels that may be drawn
+ if the edge does not lie exactly on a device pixel boundary (after being
+ transformed by the current matrix).
+ */
+ enum EdgeType {
+ /** Treat the edges as B&W (not antialiased) for the purposes of testing
+ against the current clip
+ */
+ kBW_EdgeType,
+ /** Treat the edges as antialiased for the purposes of testing
+ against the current clip
+ */
+ kAA_EdgeType
+ };
+
+ /** 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
+ @param et specifies how to treat the edges (see EdgeType)
+ @return true if the rect (transformed by the canvas' matrix) does not
+ intersect with the canvas' clip
+ */
+ bool quickReject(const SkRect& rect, EdgeType et) 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
+ @param et specifies how to treat the edges (see EdgeType)
+ @return true if the path (transformed by the canvas' matrix) does not
+ intersect with the canvas' clip
+ */
+ bool quickReject(const SkPath& path, EdgeType et) 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, EdgeType et) const;
+
+ /** 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.
+ */
+ bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
+
+ /** Fill the entire canvas' bitmap (restricted to the current clip) with the
+ specified ARGB color, using the specified PorterDuff 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,
+ SkPorterDuff::Mode mode = SkPorterDuff::kSrcOver_Mode);
+
+ /** Fill the entire canvas' bitmap (restricted to the current clip) with the
+ specified color and porter-duff xfermode.
+ @param color the color to draw with
+ @param mode the mode to apply the color in (defaults to SrcOver)
+ */
+ void drawColor(SkColor color,
+ SkPorterDuff::Mode mode = SkPorterDuff::kSrcOver_Mode);
+
+ /** 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
+ */
+ void drawOval(const SkRect& oval, 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);
+
+ /** 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.
+ @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);
+
+ /** 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 drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, const SkPaint* paint = NULL);
+
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint = NULL);
+
+ /** Draw the specified bitmap, with its top/left corner at (x,y),
+ NOT transformed by the current matrix. Note: if the paint
+ contains a maskfilter that generates a mask which extends beyond the
+ 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)
+ */
+ 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)
+ */
+ 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)
+ */
+ 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
+ */
+ virtual void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint);
+
+ /** 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. This contrasts with
+ the more immediate method SkPicture::draw(), which does not bracket
+ the canvas with save/restore, thus the canvas may be left in a changed
+ state after the call.
+ @param picture The recorded drawing commands to playback into this
+ canvas.
+ */
+ virtual void drawPicture(SkPicture& picture);
+
+ enum VertexMode {
+ kTriangles_VertexMode,
+ kTriangleStrip_VertexMode,
+ kTriangleFan_VertexMode
+ };
+
+ /** Draw the array of vertices, interpreted as triangles (based on mode).
+ @param vmode How to interpret the array of vertices
+ @param vertexCount The number of points in the vertices array (and
+ 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 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
+ the porter-duff MULTIPLY 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);
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Get the current bounder object.
+ The bounder's reference count is unchaged.
+ @return the canva's bounder (or NULL).
+ */
+ SkBounder* getBounder() const { return fBounder; }
+
+ /** Set a new bounder (or NULL).
+ Pass NULL to clear any previous bounder.
+ As a convenience, the parameter passed is also returned.
+ If a previous bounder exists, its reference count is decremented.
+ If bounder is not NULL, its reference count is incremented.
+ @param bounder the new bounder (or NULL) to be installed in the canvas
+ @return the set bounder object
+ */
+ virtual SkBounder* setBounder(SkBounder* bounder);
+
+ /** Get the current filter object. The filter's reference count is not
+ affected. The filter is part of the state this is affected by
+ save/restore.
+ @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 part of the state this is affected
+ by save/restore.
+ @param filter the new filter (or NULL)
+ @return the new filter
+ */
+ virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /** 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 current device clip (concatenation of all clip calls).
+ This does not account for the translate in any of the devices.
+ @return the current device clip (concatenation of all clip calls).
+ */
+ const SkRegion& getTotalClip() const;
+
+ /** May be overridden by subclasses. This returns a compatible device
+ for this canvas, with the specified config/width/height. If isOpaque
+ is true, then the underlying bitmap is optimized to assume that every
+ pixel will be drawn to, and thus it does not need to clear the alpha
+ channel ahead of time (assuming the specified config supports per-pixel
+ alpha.) If isOpaque is false, then the bitmap should clear its alpha
+ channel.
+ */
+ virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
+ bool isOpaque, bool isForLayer);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** 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 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
+
+ SkDevice* 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[12];
+ class SkDrawIter* fImpl; // this points at fStorage
+ SkPaint fDefaultPaint;
+ bool fDone;
+ };
+
+protected:
+ // all of the drawBitmap variants call this guy
+ virtual void commonDrawBitmap(const SkBitmap&, const SkMatrix& m,
+ const SkPaint& paint);
+
+private:
+ class MCRec;
+
+ 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];
+
+ SkBounder* fBounder;
+
+ void prepareForDeviceDraw(SkDevice*);
+
+ bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
+ void updateDeviceCMCache();
+
+ friend class SkDrawIter; // needs setupDrawForLayerDevice()
+
+ SkDevice* init(SkDevice*);
+ void internalDrawBitmap(const SkBitmap&, const SkMatrix& m,
+ const SkPaint* paint);
+ void drawDevice(SkDevice*, int x, int y, const SkPaint*);
+ // shared by save() and saveLayer()
+ int internalSave(SaveFlags flags);
+ void internalRestore();
+
+ /* These maintain a cache of the clip bounds in local coordinates,
+ (converted to 2s-compliment if floats are slow).
+ */
+ mutable SkRectCompareType fLocalBoundsCompareType;
+ mutable bool fLocalBoundsCompareTypeDirty;
+
+ const SkRectCompareType& getLocalClipBoundsCompareType() const {
+ if (fLocalBoundsCompareTypeDirty) {
+ this->computeLocalClipBoundsCompareType();
+ fLocalBoundsCompareTypeDirty = false;
+ }
+ return fLocalBoundsCompareType;
+ }
+ void computeLocalClipBoundsCompareType() const;
+};
+
+/** 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) {
+ SkASSERT(canvas);
+ fSaveCount = canvas->getSaveCount();
+ if (doSave) {
+ canvas->save();
+ }
+ }
+ ~SkAutoCanvasRestore() {
+ fCanvas->restoreToCount(fSaveCount);
+ }
+
+private:
+ SkCanvas* fCanvas;
+ int fSaveCount;
+};
+
+#endif
+
diff --git a/include/core/SkChunkAlloc.h b/include/core/SkChunkAlloc.h
new file mode 100644
index 0000000000..0e9ad189cd
--- /dev/null
+++ b/include/core/SkChunkAlloc.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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();
+
+ /** Reuse all allocated blocks. This invalidates all returned
+ pointers (like reset) but doesn't necessarily free up all
+ of the privately allocated blocks. This is more efficient
+ if you plan to reuse the allocator multiple times.
+ */
+ void reuse();
+
+ enum AllocFailType {
+ kReturnNil_AllocFailType,
+ kThrow_AllocFailType
+ };
+
+ void* alloc(size_t bytes, AllocFailType);
+ void* allocThrow(size_t bytes) {
+ return this->alloc(bytes, kThrow_AllocFailType);
+ }
+
+ size_t totalCapacity() const { return fTotalCapacity; }
+
+private:
+ struct Block;
+ Block* fBlock;
+ size_t fMinSize;
+ Block* fPool;
+ size_t fTotalCapacity;
+
+ Block* newBlock(size_t bytes, AllocFailType ftype);
+};
+
+#endif
diff --git a/include/core/SkColor.h b/include/core/SkColor.h
new file mode 100644
index 0000000000..c97a8ec4d1
--- /dev/null
+++ b/include/core/SkColor.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 SkColorSetARGB(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);
+}
+
+/** 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_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.
+*/
+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
+*/
+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
+*/
+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.
+*/
+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/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
new file mode 100644
index 0000000000..a1b3171fdd
--- /dev/null
+++ b/include/core/SkColorFilter.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkColorFilter_DEFINED
+#define SkColorFilter_DEFINED
+
+#include "SkColor.h"
+#include "SkFlattenable.h"
+#include "SkPorterDuff.h"
+
+class SkColorFilter : public SkFlattenable {
+public:
+ /** 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[]) = 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[]);
+
+ 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() { return 0; }
+
+ /** Create a colorfilter that uses the specified color and porter-duff mode.
+ If porterDuffMode is DST, this function will return NULL (since that
+ mode will have no effect on the result).
+ @param srcColor The source color used with the specified mode
+ @param mode The porter-duff mode that is applied to each color in
+ the colorfilter's filterSpan[16,32] methods
+ @return colorfilter object that applies the src color and porter-duff
+ mode, or NULL if the mode will have no effect.
+ */
+ static SkColorFilter* CreatePorterDuffFilter(SkColor srcColor,
+ SkPorterDuff::Mode mode);
+
+ /** Create a colorfilter that calls through to the specified procs to
+ filter the colors. The SkXfermodeProc parameter must be non-null, but
+ the SkXfermodeProc16 is optional, and may be null.
+ */
+ static SkColorFilter* CreatXfermodeProcFilter(SkColor srcColor,
+ SkXfermodeProc proc,
+ SkXfermodeProc16 proc16 = NULL);
+
+ /** 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);
+
+protected:
+ SkColorFilter() {}
+ SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
+
+private:
+ typedef SkFlattenable INHERITED;
+};
+
+#include "SkShader.h"
+
+class SkFilterShader : public SkShader {
+public:
+ SkFilterShader(SkShader* shader, SkColorFilter* filter);
+ virtual ~SkFilterShader();
+
+ // override
+ virtual uint32_t getFlags();
+ virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix);
+ virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
+ virtual void shadeSpan16(int x, int y, uint16_t result[], int count);
+ virtual void beginSession();
+ virtual void endSession();
+
+protected:
+ SkFilterShader(SkFlattenableReadBuffer& );
+ virtual void flatten(SkFlattenableWriteBuffer& );
+ virtual Factory getFactory() { return CreateProc; }
+private:
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkFilterShader, (buffer)); }
+ SkShader* fShader;
+ SkColorFilter* fFilter;
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h
new file mode 100644
index 0000000000..041c0380a0
--- /dev/null
+++ b/include/core/SkColorPriv.h
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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"
+
+/** 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);
+ return alpha + (alpha >> 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)
+inline int SkAlphaBlend(int src, int dst, int scale256) {
+ SkASSERT((unsigned)scale256 <= 256);
+ return dst + SkAlphaMul(src - dst, scale256);
+}
+
+#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++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
+ } while (--count > 0);
+}
+
+#ifdef SK_DEBUG
+ static 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
+
+/* we check to see if the SHIFT value has already been defined (SkUserConfig.h)
+ 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
+
+#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
+ inline void SkPMColorAssert(SkPMColor c) {
+ unsigned a = SkGetPackedA32(c);
+ unsigned r = SkGetPackedR32(c);
+ unsigned g = SkGetPackedG32(c);
+ unsigned b = SkGetPackedB32(c);
+
+ SkA32Assert(a);
+ SkASSERT(r <= a);
+ SkASSERT(g <= a);
+ SkASSERT(b <= a);
+ }
+#else
+ #define SkPMColorAssert(c)
+#endif
+
+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);
+}
+
+extern const uint32_t gMask_00FF00FF;
+
+inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
+ uint32_t mask = gMask_00FF00FF;
+// uint32_t mask = 0xFF00FF;
+
+ uint32_t rb = ((c & mask) * scale) >> 8;
+ uint32_t ag = ((c >> 8) & mask) * scale;
+ return (rb & mask) | (ag & ~mask);
+}
+
+inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
+ return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
+}
+
+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
+ inline unsigned SkR32ToR16(unsigned r)
+ {
+ SkR32Assert(r);
+ return SkR32ToR16_MACRO(r);
+ }
+ inline unsigned SkG32ToG16(unsigned g)
+ {
+ SkG32Assert(g);
+ return SkG32ToG16_MACRO(g);
+ }
+ 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)
+
+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;
+}
+
+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)
+
+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);
+}
+
+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
+
+inline unsigned SkR16ToR32(unsigned r)
+{
+ return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
+}
+inline unsigned SkG16ToG32(unsigned g)
+{
+ return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
+}
+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))
+
+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);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+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 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));
+}
+
+extern const uint16_t gMask_0F0F;
+
+inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale)
+{
+ SkASSERT(scale <= 16);
+
+ const unsigned mask = 0xF0F; //gMask_0F0F;
+
+#if 0
+ unsigned rb = ((c & mask) * scale) >> 4;
+ unsigned ag = ((c >> 4) & mask) * scale;
+ return (rb & mask) | (ag & ~mask);
+#else
+ c = (c & mask) | ((c & (mask << 4)) << 12);
+ c = c * scale >> 4;
+ return (c & mask) | ((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. Used in conjunction with SkCompact_4444.
+*/
+inline uint32_t SkExpand_4444(U16CPU c)
+{
+ SkASSERT(c == (uint16_t)c);
+
+ const unsigned mask = 0xF0F; //gMask_0F0F;
+ return (c & mask) | ((c & ~mask) << 12);
+}
+
+/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16.
+ NOTE: this explicitly does not clean the top 16 bits (which may be garbage).
+ It does this for speed, since if it is being written directly to 16bits of
+ memory, the top 16bits will be ignored. Casting the result to uint16_t here
+ would add 2 more instructions, slow us down. It is up to the caller to
+ perform the cast if needed.
+*/
+static inline U16CPU SkCompact_4444(uint32_t c)
+{
+ const unsigned mask = 0xF0F; //gMask_0F0F;
+ return (c & mask) | ((c >> 12) & ~mask);
+}
+
+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 uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16)
+{
+ SkASSERT((unsigned)scale16 <= 16);
+
+ uint32_t src32 = SkExpand_4444(src) * scale16;
+ // the scaled srcAlpha is the bottom byte
+#ifdef SK_DEBUG
+ {
+ unsigned srcA = SkGetPackedA4444(src) * scale16;
+ SkASSERT(srcA == (src32 & 0xFF));
+ }
+#endif
+ unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4;
+ uint32_t dst32 = SkExpand_4444(dst) * dstScale;
+ return SkCompact_4444((src32 + dst32) >> 4);
+}
+
+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)
+{
+ a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4;
+ 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 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 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 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);
+
+#endif
+
diff --git a/include/core/SkColorShader.h b/include/core/SkColorShader.h
new file mode 100644
index 0000000000..f9c3dc33d2
--- /dev/null
+++ b/include/core/SkColorShader.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 SkColorShader : public SkShader {
+public:
+ /** Create a ColorShader that will inherit its color from the Paint
+ at draw time.
+ */
+ SkColorShader() : fInheritColor(true) {}
+ /** Create a ColorShader that ignores the color in the paint, and uses the
+ specified color. Note: like all shaders, at draw time the paint's alpha
+ will be respected, and is applied to the specified color.
+ */
+ SkColorShader(SkColor c) : fColor(c), fInheritColor(false) {}
+
+ virtual uint32_t getFlags();
+ virtual uint8_t getSpan16Alpha() const;
+ virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix);
+ virtual void shadeSpan(int x, int y, SkPMColor span[], int count);
+ virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
+ virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
+
+protected:
+ SkColorShader(SkFlattenableReadBuffer& );
+ virtual void flatten(SkFlattenableWriteBuffer& );
+ virtual Factory getFactory() { return CreateProc; }
+private:
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkColorShader, (buffer));
+ }
+ SkColor fColor; // ignored if fInheritColor is true
+ SkPMColor fPMColor; // cached after setContext()
+ uint16_t fColor16; // cached after setContext()
+ SkBool8 fInheritColor;
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/include/core/SkComposeShader.h b/include/core/SkComposeShader.h
new file mode 100644
index 0000000000..0b198f61da
--- /dev/null
+++ b/include/core/SkComposeShader.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkComposeShader_DEFINED
+#define SkComposeShader_DEFINED
+
+#include "SkShader.h"
+
+class SkXfermode;
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+/** \class SkComposeShader
+ This subclass of shader returns the coposition of two other shaders, combined by
+ a xfermode.
+*/
+class 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 of 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();
+
+ // override
+ virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix);
+ virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
+ virtual void beginSession();
+ virtual void endSession();
+
+protected:
+ SkComposeShader(SkFlattenableReadBuffer& );
+ virtual void flatten(SkFlattenableWriteBuffer& );
+ virtual Factory getFactory() { return CreateProc; }
+
+private:
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkComposeShader, (buffer)); }
+
+ SkShader* fShaderA;
+ SkShader* fShaderB;
+ SkXfermode* fMode;
+
+ typedef SkShader INHERITED;
+};
+
+#endif
diff --git a/include/core/SkDeque.h b/include/core/SkDeque.h
new file mode 100644
index 0000000000..cbed930088
--- /dev/null
+++ b/include/core/SkDeque.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDeque_DEFINED
+#define SkDeque_DEFINED
+
+#include "SkTypes.h"
+
+class SkDeque : SkNoncopyable {
+public:
+ explicit SkDeque(size_t elemSize);
+ SkDeque(size_t elemSize, void* storage, size_t storageSize);
+ ~SkDeque();
+
+ bool empty() const { return 0 == fCount; }
+ int count() const { return fCount; }
+ size_t elemSize() const { return fElemSize; }
+
+ const void* front() const;
+ const void* back() const;
+
+ void* front() {
+ return (void*)((const SkDeque*)this)->front();
+ }
+
+ void* back() {
+ return (void*)((const SkDeque*)this)->back();
+ }
+
+ void* push_front();
+ void* push_back();
+
+ void pop_front();
+ void pop_back();
+
+private:
+ struct Head;
+
+public:
+ class Iter {
+ public:
+ Iter(const SkDeque& d);
+ void* next();
+
+ private:
+ SkDeque::Head* fHead;
+ char* fPos;
+ size_t fElemSize;
+ };
+
+private:
+ Head* fFront;
+ Head* fBack;
+ size_t fElemSize;
+ void* fInitialStorage;
+ int fCount;
+
+ friend class Iter;
+};
+
+#endif
diff --git a/include/core/SkDescriptor.h b/include/core/SkDescriptor.h
new file mode 100644
index 0000000000..8074cff2b8
--- /dev/null
+++ b/include/core/SkDescriptor.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDescriptor_DEFINED
+#define SkDescriptor_DEFINED
+
+#include "SkTypes.h"
+
+class SkDescriptor : SkNoncopyable {
+public:
+ static size_t ComputeOverhead(int entryCount)
+ {
+ SkASSERT(entryCount >= 0);
+ return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
+ }
+
+ static SkDescriptor* Alloc(size_t length)
+ {
+ SkASSERT(SkAlign4(length) == length);
+ SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length);
+ return desc;
+ }
+
+ static void Free(SkDescriptor* desc)
+ {
+ sk_free(desc);
+ }
+
+ void init()
+ {
+ fLength = sizeof(SkDescriptor);
+ fCount = 0;
+ }
+
+ uint32_t getLength() const { return fLength; }
+
+ void* addEntry(uint32_t tag, uint32_t length, const void* data = NULL)
+ {
+ SkASSERT(tag);
+ SkASSERT(SkAlign4(length) == length);
+ SkASSERT(this->findEntry(tag, NULL) == NULL);
+
+ Entry* entry = (Entry*)((char*)this + fLength);
+ entry->fTag = tag;
+ entry->fLen = length;
+ if (data)
+ memcpy(entry + 1, data, length);
+
+ fCount += 1;
+ fLength += sizeof(Entry) + length;
+ return (entry + 1); // return its data
+ }
+
+ void computeChecksum()
+ {
+ fChecksum = SkDescriptor::ComputeChecksum(this);
+ }
+
+#ifdef SK_DEBUG
+ void assertChecksum() const
+ {
+ SkASSERT(fChecksum == SkDescriptor::ComputeChecksum(this));
+ }
+#endif
+
+ const void* findEntry(uint32_t tag, uint32_t* length) const
+ {
+ const Entry* entry = (const Entry*)(this + 1);
+ int count = fCount;
+
+ while (--count >= 0)
+ {
+ if (entry->fTag == tag)
+ {
+ if (length)
+ *length = entry->fLen;
+ return entry + 1;
+ }
+ entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
+ }
+ return NULL;
+ }
+
+ SkDescriptor* copy() const
+ {
+ SkDescriptor* desc = SkDescriptor::Alloc(fLength);
+ memcpy(desc, this, fLength);
+ return desc;
+ }
+
+ bool equals(const SkDescriptor& other) const
+ {
+ // probe to see if we have a good checksum algo
+// SkASSERT(a.fChecksum != b.fChecksum || memcmp(&a, &b, a.fLength) == 0);
+
+ // the first value we should look at is the checksum, so this loop
+ // should terminate early if they descriptors are different.
+ // NOTE: if we wrote a sentinel value at the end of each, we chould
+ // remove the aa < stop test in the loop...
+ const uint32_t* aa = (const uint32_t*)this;
+ const uint32_t* bb = (const uint32_t*)&other;
+ const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength);
+ do {
+ if (*aa++ != *bb++)
+ return false;
+ } while (aa < stop);
+ return true;
+ }
+
+ struct Entry {
+ uint32_t fTag;
+ uint32_t fLen;
+ };
+
+#ifdef SK_DEBUG
+ uint32_t getChecksum() const { return fChecksum; }
+ uint32_t getCount() const { return fCount; }
+#endif
+
+private:
+ uint32_t fChecksum; // must be first
+ uint32_t fLength; // must be second
+ uint32_t fCount;
+
+ static uint32_t ComputeChecksum(const SkDescriptor* desc)
+ {
+ const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field
+ const uint32_t* stop = (const uint32_t*)((const char*)desc + desc->fLength);
+ uint32_t sum = 0;
+
+ SkASSERT(ptr < stop);
+ do {
+ sum = (sum << 1) | (sum >> 31);
+ sum ^= *ptr++;
+ } while (ptr < stop);
+
+ return sum;
+ }
+
+ // private so no one can create one except our factories
+ SkDescriptor() {}
+};
+
+#include "SkScalerContext.h"
+
+class SkAutoDescriptor : SkNoncopyable {
+public:
+ SkAutoDescriptor(size_t size)
+ {
+ if (size <= sizeof(fStorage))
+ fDesc = (SkDescriptor*)(void*)fStorage;
+ else
+ fDesc = SkDescriptor::Alloc(size);
+ }
+ ~SkAutoDescriptor()
+ {
+ if (fDesc != (SkDescriptor*)(void*)fStorage)
+ SkDescriptor::Free(fDesc);
+ }
+ SkDescriptor* getDesc() const { return fDesc; }
+private:
+ enum {
+ kStorageSize = sizeof(SkDescriptor)
+ + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec) // for rec
+ + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface
+ + 32 // slop for occational small extras
+ };
+ SkDescriptor* fDesc;
+ uint32_t fStorage[(kStorageSize + 3) >> 2];
+};
+
+
+#endif
+
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
new file mode 100644
index 0000000000..4d678c6a40
--- /dev/null
+++ b/include/core/SkDevice.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDevice_DEFINED
+#define SkDevice_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkColor.h"
+
+class SkDraw;
+struct SkIRect;
+class SkMatrix;
+class SkRegion;
+
+class SkDevice : public SkRefCnt {
+public:
+ SkDevice();
+ /** Construct a new device, extracting the width/height/config/isOpaque values from
+ the bitmap. If transferPixelOwnership is true, and the bitmap claims to own its
+ own pixels (getOwnsPixels() == true), then transfer this responsibility to the
+ device, and call setOwnsPixels(false) on the bitmap.
+
+ Subclasses may override the destructor, which is virtual, even though this class
+ doesn't have one. SkRefCnt does.
+
+ @param bitmap A copy of this bitmap is made and stored in the device
+ */
+ SkDevice(const SkBitmap& bitmap);
+
+ /** Return the width of the device (in pixels).
+ */
+ int width() const { return fBitmap.width(); }
+ /** Return the height of the device (in pixels).
+ */
+ int height() const { return fBitmap.height(); }
+ /** Return the bitmap config of the device's pixels
+ */
+ SkBitmap::Config config() const { return fBitmap.getConfig(); }
+ /** Returns true if the device's bitmap's config treats every pixels as
+ implicitly opaque.
+ */
+ bool isOpaque() const { return fBitmap.isOpaque(); }
+
+ /** Return the bounds of the device
+ */
+ void getBounds(SkIRect* bounds) const;
+
+ /** Return true if the specified rectangle intersects the bounds of the
+ device. If sect is not NULL and there is an intersection, sect returns
+ the intersection.
+ */
+ bool intersects(const SkIRect& r, SkIRect* sect = NULL) const;
+
+ /** 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);
+
+ /** Helper to erase the entire device to the specified color (including
+ alpha).
+ */
+ void eraseColor(SkColor eraseColor);
+
+ /** Called when this device is installed into a Canvas. Balanaced by a call
+ to unlockPixels() when the device is removed from a Canvas.
+ */
+ virtual void lockPixels();
+ virtual void unlockPixels();
+
+ /** 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.
+ */
+ virtual void setMatrixClip(const SkMatrix&, const SkRegion&);
+
+ /** Called when this device gains focus (i.e becomes the current device
+ for drawing).
+ */
+ virtual void gainFocus(SkCanvas*) {}
+
+ /** 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);
+ virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+ const SkPoint[], const SkPaint& paint);
+ virtual void drawRect(const SkDraw&, const SkRect& r,
+ const SkPaint& paint);
+ virtual void drawPath(const SkDraw&, const SkPath& path,
+ const SkPaint& paint);
+ virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint& paint);
+ virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+ int x, int y, const SkPaint& paint);
+ virtual void drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint);
+ virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint& paint);
+ virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint);
+ 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);
+ virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
+ const SkPaint&);
+
+protected:
+ /** Update as needed the pixel value in the bitmap, so that the caller can access
+ the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
+ must remain unchanged.
+ */
+ virtual void onAccessBitmap(SkBitmap*);
+
+private:
+ SkBitmap fBitmap;
+};
+
+#endif
diff --git a/include/core/SkDither.h b/include/core/SkDither.h
new file mode 100644
index 0000000000..5b2552d1c1
--- /dev/null
+++ b/include/core/SkDither.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/core/SkDraw.h b/include/core/SkDraw.h
new file mode 100644
index 0000000000..2d775a4272
--- /dev/null
+++ b/include/core/SkDraw.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDraw_DEFINED
+#define SkDraw_DEFINED
+
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkMask.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkRect.h"
+#include "SkAutoKern.h"
+
+class SkBounder;
+class SkDevice;
+class SkPath;
+class SkRegion;
+struct SkDrawProcs;
+
+class SkDraw {
+public:
+ SkDraw() : fDevice(NULL), fBounder(NULL), fProcs(NULL) {}
+ SkDraw(const SkDraw& src);
+
+ void drawPaint(const SkPaint&) const;
+ void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[],
+ const SkPaint&) const;
+ void drawRect(const SkRect&, const SkPaint&) const;
+ /* To save on mallocs, we allow a flag that tells us that srcPath is
+ mutable, so that we don't have to make copies of it as we transform it.
+ */
+ void drawPath(const SkPath& srcPath, const SkPaint&,
+ const SkMatrix* prePathMatrix, bool pathIsMutable) const;
+ 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;
+
+ void drawPath(const SkPath& src, const SkPaint& paint) const {
+ this->drawPath(src, paint, NULL, false);
+ }
+
+ /** 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,
+ SkMaskFilter* filter, const SkMatrix* filterMatrix,
+ SkMask* mask, SkMask::CreateMode mode);
+
+private:
+ void drawText_asPaths(const char text[], size_t byteLength,
+ SkScalar x, SkScalar y, const SkPaint&) const;
+ void drawDevMask(const SkMask& mask, const SkPaint&) const;
+ void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
+
+public:
+ const SkBitmap* fBitmap; // required
+ const SkMatrix* fMatrix; // required
+ const SkRegion* fClip; // required
+ SkDevice* fDevice; // optional
+ SkBounder* fBounder; // optional
+ SkDrawProcs* fProcs; // optional
+
+#ifdef SK_DEBUG
+ void validate() const;
+#endif
+};
+
+#include "SkGlyphCache.h"
+
+class SkTextToPathIter {
+public:
+ SkTextToPathIter(const char text[], size_t length, const SkPaint&,
+ bool applyStrokeAndPathEffects, bool forceLinearTextOn);
+ ~SkTextToPathIter();
+
+ const SkPaint& getPaint() const { return fPaint; }
+ SkScalar getPathScale() const { return fScale; }
+
+ const SkPath* next(SkScalar* xpos); //!< returns nil when there are no more paths
+
+private:
+ SkGlyphCache* fCache;
+ SkPaint fPaint;
+ SkScalar fScale;
+ SkFixed fPrevAdvance;
+ const char* fText;
+ const char* fStop;
+ SkMeasureCacheProc fGlyphCacheProc;
+
+ const SkPath* fPath; // returned in next
+ SkScalar fXPos; // accumulated xpos, returned in next
+ SkAutoKern fAutoKern;
+};
+
+#endif
+
+
diff --git a/include/core/SkDrawFilter.h b/include/core/SkDrawFilter.h
new file mode 100644
index 0000000000..db5a685191
--- /dev/null
+++ b/include/core/SkDrawFilter.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDrawFilter_DEFINED
+#define SkDrawFilter_DEFINED
+
+#include "SkRefCnt.h"
+
+////////////////// EXPERIMENTAL //////////////////////////
+
+class SkCanvas;
+class SkPaint;
+
+/** Right before something is being draw, filter() is called with the
+ current canvas and paint. If it returns true, then drawing proceeds
+ with the (possibly modified) canvas/paint, and then restore() is called
+ to restore the canvas/paint to their state before filter() was called.
+ If filter returns false, canvas/paint should not have been changed, and
+ restore() will not be called.
+*/
+class SkDrawFilter : public SkRefCnt {
+public:
+ enum Type {
+ kPaint_Type,
+ kPoint_Type,
+ kLine_Type,
+ kBitmap_Type,
+ kRect_Type,
+ kPath_Type,
+ kText_Type
+ };
+
+ /** Return true to allow the draw to continue (with possibly modified
+ canvas/paint). If true is returned, then restore() will be called.
+ */
+ virtual bool filter(SkCanvas*, SkPaint*, Type) = 0;
+ /** If filter() returned true, then restore() will be called to restore the
+ canvas/paint to their previous states
+ */
+ virtual void restore(SkCanvas*, SkPaint*, Type) = 0;
+};
+
+#endif
diff --git a/include/core/SkDrawLooper.h b/include/core/SkDrawLooper.h
new file mode 100644
index 0000000000..333fb41105
--- /dev/null
+++ b/include/core/SkDrawLooper.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDrawLooper_DEFINED
+#define SkDrawLooper_DEFINED
+
+#include "SkFlattenable.h"
+
+////////////////// EXPERIMENTAL //////////////////////////
+
+class SkCanvas;
+class SkPaint;
+
+/** \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 SkDrawLooper : public SkFlattenable {
+public:
+ /** Called right before something is being drawn to the specified canvas
+ with the specified paint. Subclass that want to modify either parameter
+ can do so now.
+ */
+ virtual void init(SkCanvas*, SkPaint*) {}
+ /** Called in a loop (after init()). Each time true is returned, the object
+ is drawn (possibly with a modified canvas and/or paint). When false is
+ finally returned, drawing for the object stops.
+ */
+ virtual bool next() { return false; }
+ /** Called after the looper has finally returned false from next(), allowing
+ the looper to restore the canvas/paint to their original states.
+ is this required, since the subclass knows when it is done???
+ should we pass the canvas/paint here, and/or to the next call
+ so that subclasses don't need to retain pointers to them during the
+ loop?
+ */
+ virtual void restore() {}
+
+protected:
+ SkDrawLooper() {}
+ SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+private:
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/include/core/SkEndian.h b/include/core/SkEndian.h
new file mode 100644
index 0000000000..f08a9a990b
--- /dev/null
+++ b/include/core/SkEndian.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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
+*/
+inline uint16_t SkEndianSwap16(U16CPU value)
+{
+ SkASSERT(value == (uint16_t)value);
+ return (uint16_t)((value >> 8) | (value << 8));
+}
+
+/** Vector version of SkEndianSwap16(), which swaps the
+ low two bytes of each value in the array.
+*/
+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
+*/
+inline uint32_t SkEndianSwap32(uint32_t value)
+{
+ return ((value & 0xFF) << 24) |
+ ((value & 0xFF00) << 8) |
+ ((value & 0xFF0000) >> 8) |
+ (value >> 24);
+}
+
+/** Vector version of SkEndianSwap16(), which swaps the
+ bytes of each value in the array.
+*/
+inline void SkEndianSwap32s(uint32_t array[], int count)
+{
+ SkASSERT(count == 0 || array != NULL);
+
+ while (--count >= 0)
+ {
+ *array = SkEndianSwap32(*array);
+ array += 1;
+ }
+}
+
+#ifdef SK_CPU_LENDIAN
+ #define SkEndian_SwapBE16(n) SkEndianSwap16(n)
+ #define SkEndian_SwapBE32(n) SkEndianSwap32(n)
+ #define SkEndian_SwapLE16(n) (n)
+ #define SkEndian_SwapLE32(n) (n)
+#else // SK_CPU_BENDIAN
+ #define SkEndian_SwapBE16(n) (n)
+ #define SkEndian_SwapBE32(n) (n)
+ #define SkEndian_SwapLE16(n) SkEndianSwap16(n)
+ #define SkEndian_SwapLE32(n) SkEndianSwap32(n)
+#endif
+
+
+#endif
+
diff --git a/include/core/SkFDot6.h b/include/core/SkFDot6.h
new file mode 100644
index 0000000000..a4b9cf759b
--- /dev/null
+++ b/include/core/SkFDot6.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkFDot6_DEFINED
+#define SkFDot6_DEFINED
+
+#include "SkMath.h"
+
+typedef int32_t SkFDot6;
+
+#define SK_FDot61 (64)
+#define SK_FDot6Half (32)
+
+#ifdef SK_DEBUG
+ inline SkFDot6 SkIntToFDot6(S16CPU x)
+ {
+ SkASSERT(SkToS16(x) == x);
+ return x << 6;
+ }
+#else
+ #define SkIntToFDot6(x) ((x) << 6)
+#endif
+
+#define SkFDot6Floor(x) ((x) >> 6)
+#define SkFDot6Ceil(x) (((x) + 63) >> 6)
+#define SkFDot6Round(x) (((x) + 32) >> 6)
+
+#define SkFixedToFDot6(x) ((x) >> 10)
+
+inline SkFixed SkFDot6ToFixed(SkFDot6 x)
+{
+ SkASSERT((x << 10 >> 10) == x);
+
+ return x << 10;
+}
+
+#ifdef SK_SCALAR_IS_FLOAT
+ #define SkScalarToFDot6(x) (SkFDot6)((x) * 64)
+#else
+ #define SkScalarToFDot6(x) ((x) >> 10)
+#endif
+
+inline SkFixed SkFDot6Div(SkFDot6 a, SkFDot6 b)
+{
+ SkASSERT(b != 0);
+
+ if (a == (int16_t)a)
+ return (a << 16) / b;
+ else
+ return SkFixedDiv(a, b);
+}
+
+#endif
+
diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h
new file mode 100644
index 0000000000..be4bf99788
--- /dev/null
+++ b/include/core/SkFixed.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 (0x1)
+#define SK_FixedNaN ((int) 0x80000000)
+#define SK_FixedPI (0x3243F)
+#define SK_FixedSqrt2 (92682)
+#define SK_FixedTanPIOver8 (0x6A0A)
+#define SK_FixedRoot2Over2 (0xB505)
+
+#ifdef SK_CAN_USE_FLOAT
+ #define SkFixedToFloat(x) ((x) * 1.5258789e-5f)
+ #define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1))
+
+ #define SkFixedToDouble(x) ((x) * 1.5258789e-5)
+ #define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
+#endif
+
+/** 32 bit signed integer used to represent fractions values with 30 bits to the right of the decimal point
+*/
+typedef int32_t SkFract;
+#define SK_Fract1 (1 << 30)
+#define Sk_FracHalf (1 << 29)
+#define SK_FractPIOver180 (0x11DF46A)
+
+#ifdef SK_CAN_USE_FLOAT
+ #define SkFractToFloat(x) ((float)(x) * 0.00000000093132257f)
+ #define SkFloatToFract(x) ((SkFract)((x) * SK_Fract1))
+#endif
+
+/** 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
+
+/** Converts a SkFixed to a SkFract, asserting that the result does not overflow
+ a 32 bit signed integer
+*/
+#ifdef SK_DEBUG
+ inline SkFract SkFixedToFract(SkFixed x)
+ {
+ SkASSERT(x >= (-2 << 16) && x <= (2 << 16) - 1);
+ return x << 14;
+ }
+#else
+ #define SkFixedToFract(x) ((x) << 14)
+#endif
+
+/** Returns the signed fraction of a SkFixed
+*/
+inline SkFixed SkFixedFraction(SkFixed x)
+{
+ SkFixed mask = x >> 31 << 16;
+ return (x & 0xFFFF) | mask;
+}
+
+/** Converts a SkFract to a SkFixed
+*/
+#define SkFractToFixed(x) ((x) >> 14)
+/** Round a SkFixed to an integer
+*/
+#define SkFixedRound(x) (((x) + SK_FixedHalf) >> 16)
+#define SkFixedCeil(x) (((x) + SK_Fixed1 - 1) >> 16)
+#define SkFixedFloor(x) ((x) >> 16)
+#define SkFixedAbs(x) SkAbs32(x)
+#define SkFixedAve(a, b) (((a) + (b)) >> 1)
+
+SkFixed SkFixedMul_portable(SkFixed, SkFixed);
+SkFract SkFractMul_portable(SkFract, SkFract);
+inline SkFixed SkFixedSquare_portable(SkFixed value)
+{
+ uint32_t a = SkAbs32(value);
+ uint32_t ah = a >> 16;
+ uint32_t al = a & 0xFFFF;
+ return ah * a + al * ah + (al * al >> 16);
+}
+
+#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
+SkFixed SkFixedDivInt(int32_t numer, int32_t denom);
+SkFixed SkFixedMod(SkFixed numer, SkFixed denom);
+#define SkFixedInvert(n) SkDivBits(SK_Fixed1, n, 16)
+SkFixed SkFixedFastInvert(SkFixed n);
+#define SkFixedSqrt(n) SkSqrtBits(n, 23)
+SkFixed SkFixedMean(SkFixed a, SkFixed b); //*< returns sqrt(x*y)
+int SkFixedMulCommon(SkFixed, int , int bias); // internal used by SkFixedMulFloor, SkFixedMulCeil, SkFixedMulRound
+
+#define SkFractDiv(numer, denom) SkDivBits(numer, denom, 30)
+#define SkFractSqrt(n) SkSqrtBits(n, 30)
+
+SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull);
+#define SkFixedSin(radians) SkFixedSinCos(radians, NULL)
+inline SkFixed SkFixedCos(SkFixed radians)
+{
+ SkFixed cosValue;
+ (void)SkFixedSinCos(radians, &cosValue);
+ return cosValue;
+}
+SkFixed SkFixedTan(SkFixed radians);
+SkFixed SkFixedASin(SkFixed);
+SkFixed SkFixedACos(SkFixed);
+SkFixed SkFixedATan2(SkFixed y, SkFixed x);
+SkFixed SkFixedExp(SkFixed);
+SkFixed SkFixedLog(SkFixed);
+
+#define SK_FixedNearlyZero (SK_Fixed1 >> 12)
+
+inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero)
+{
+ SkASSERT(tolerance > 0);
+ return SkAbs32(x) < tolerance;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+// 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)((SkLONGLONG)a * b >> 16);
+ }
+ inline SkFract SkFractMul_longlong(SkFract a, SkFract b)
+ {
+ return (SkFixed)((SkLONGLONG)a * b >> 30);
+ }
+ inline SkFixed SkFixedSquare_longlong(SkFixed value)
+ {
+ return (SkFixed)((SkLONGLONG)value * value >> 16);
+ }
+ #define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
+ #define SkFractMul(a,b) SkFractMul_longlong(a,b)
+ #define SkFixedSquare(a) SkFixedSquare_longlong(a)
+#endif
+
+#if defined(__arm__) && !defined(__thumb__)
+ /* This guy does not handle NaN or other obscurities, but is faster than
+ than (int)(x*65536) when we only have software floats
+ */
+ inline SkFixed SkFloatToFixed_arm(float x)
+ {
+ register 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"
+ "rsbcs %1, %1, #0 \n"
+ : "=r"(x), "=&r"(y), "=&r"(z)
+ : "r"(x)
+ : "cc"
+ );
+ return y;
+ }
+ inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y)
+ {
+ register 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;
+ }
+ inline SkFixed SkFixedMulAdd_arm(SkFixed x, SkFixed y, SkFixed a)
+ {
+ register int32_t t;
+ asm("smull %0, %3, %1, %4 \n"
+ "add %0, %2, %0, lsr #16 \n"
+ "add %0, %0, %3, lsl #16 \n"
+ : "=r"(x), "=&r"(y), "=&r"(a), "=r"(t)
+ : "%r"(x), "1"(y), "2"(a)
+ :
+ );
+ return x;
+ }
+ inline SkFixed SkFractMul_arm(SkFixed x, SkFixed y)
+ {
+ register int32_t t;
+ asm("smull %0, %2, %1, %3 \n"
+ "mov %0, %0, lsr #30 \n"
+ "orr %0, %0, %2, lsl #2 \n"
+ : "=r"(x), "=&r"(y), "=r"(t)
+ : "r"(x), "1"(y)
+ :
+ );
+ return x;
+ }
+ #undef SkFixedMul
+ #undef SkFractMul
+ #define SkFixedMul(x, y) SkFixedMul_arm(x, y)
+ #define SkFractMul(x, y) SkFractMul_arm(x, y)
+ #define SkFixedMulAdd(x, y, a) SkFixedMulAdd_arm(x, y, a)
+
+ #undef SkFloatToFixed
+ #define SkFloatToFixed(x) SkFloatToFixed_arm(x)
+#endif
+
+/////////////////////// Now define our macros to the portable versions if they weren't overridden
+
+#ifndef SkFixedSquare
+ #define SkFixedSquare(x) SkFixedSquare_portable(x)
+#endif
+#ifndef SkFixedMul
+ #define SkFixedMul(x, y) SkFixedMul_portable(x, y)
+#endif
+#ifndef SkFractMul
+ #define SkFractMul(x, y) SkFractMul_portable(x, y)
+#endif
+#ifndef SkFixedMulAdd
+ #define SkFixedMulAdd(x, y, a) (SkFixedMul(x, y) + (a))
+#endif
+
+#endif
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h
new file mode 100644
index 0000000000..6958462033
--- /dev/null
+++ b/include/core/SkFlattenable.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkFlattenable_DEFINED
+#define SkFlattenable_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkBitmap.h"
+#include "SkReader32.h"
+#include "SkTDArray.h"
+#include "SkWriter32.h"
+
+class SkFlattenableReadBuffer;
+class SkFlattenableWriteBuffer;
+class SkString;
+
+/** \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 SkFlattenable : public SkRefCnt {
+public:
+ typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
+
+ 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() = 0;
+ /** Override this to write data specific to your subclass into the buffer,
+ being sure to call your super-class' version first. This data will later
+ be passed to your Factory function, returned by getFactory().
+ */
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+ /** Set the string to describe the sublass and return true. If this is not
+ overridden, ignore the string param and return false.
+ */
+ virtual bool toDumpString(SkString*) const;
+
+ static Factory NameToFactory(const char name[]);
+ static const char* FactoryToName(Factory);
+ static void Register(const char name[], Factory);
+
+ class Registrar {
+ public:
+ Registrar(const char name[], Factory factory) {
+ SkFlattenable::Register(name, factory);
+ }
+ };
+
+protected:
+ SkFlattenable(SkFlattenableReadBuffer&) {}
+};
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+class SkTypeface;
+
+class SkFlattenableReadBuffer : public SkReader32 {
+public:
+ SkFlattenableReadBuffer();
+ explicit SkFlattenableReadBuffer(const void* data);
+ SkFlattenableReadBuffer(const void* data, size_t size);
+
+ void setRefCntArray(SkRefCnt* array[], int count) {
+ fRCArray = array;
+ fRCCount = count;
+ }
+
+ void setTypefaceArray(SkTypeface* array[], int count) {
+ fTFArray = array;
+ fTFCount = count;
+ }
+
+ void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
+ fFactoryArray = array;
+ fFactoryCount = count;
+ }
+
+ SkTypeface* readTypeface();
+ SkRefCnt* readRefCnt();
+ void* readFunctionPtr();
+ SkFlattenable* readFlattenable();
+
+private:
+ SkRefCnt** fRCArray;
+ int fRCCount;
+
+ SkTypeface** fTFArray;
+ int fTFCount;
+
+ SkFlattenable::Factory* fFactoryArray;
+ int fFactoryCount;
+
+ typedef SkReader32 INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkPtrRecorder.h"
+
+class SkRefCntRecorder : public SkPtrRecorder {
+public:
+ virtual ~SkRefCntRecorder();
+
+ /** Add a refcnt object to the set and ref it if not already present,
+ or if it is already present, do nothing. Either way, returns 0 if obj
+ is null, or a base-1 index if obj is not null.
+ */
+ uint32_t record(SkRefCnt* ref) {
+ return this->recordPtr(ref);
+ }
+
+ // This does not change the owner counts on the objects
+ void get(SkRefCnt* array[]) const {
+ this->getPtrs((void**)array);
+ }
+
+protected:
+ // overrides
+ virtual void incPtr(void*);
+ virtual void decPtr(void*);
+
+private:
+ typedef SkPtrRecorder INHERITED;
+};
+
+class SkFactoryRecorder : public SkPtrRecorder {
+public:
+ /** Add a factory to the set. If it is null return 0, otherwise return a
+ base-1 index for the factory.
+ */
+ uint32_t record(SkFlattenable::Factory fact) {
+ return this->recordPtr((void*)fact);
+ }
+
+ void get(SkFlattenable::Factory array[]) const {
+ this->getPtrs((void**)array);
+ }
+
+private:
+ typedef SkPtrRecorder INHERITED;
+};
+
+class SkFlattenableWriteBuffer : public SkWriter32 {
+public:
+ SkFlattenableWriteBuffer(size_t minSize);
+ virtual ~SkFlattenableWriteBuffer();
+
+ void writeTypeface(SkTypeface*);
+ void writeRefCnt(SkRefCnt*);
+ void writeFunctionPtr(void*);
+ void writeFlattenable(SkFlattenable* flattenable);
+
+ SkRefCntRecorder* getTypefaceRecorder() const { return fTFRecorder; }
+ SkRefCntRecorder* setTypefaceRecorder(SkRefCntRecorder*);
+
+ SkRefCntRecorder* getRefCntRecorder() const { return fRCRecorder; }
+ SkRefCntRecorder* setRefCntRecorder(SkRefCntRecorder*);
+
+ SkFactoryRecorder* getFactoryRecorder() const { return fFactoryRecorder; }
+ SkFactoryRecorder* setFactoryRecorder(SkFactoryRecorder*);
+
+ enum Flags {
+ kCrossProcess_Flag = 0x01
+ };
+ Flags getFlags() const { return fFlags; }
+ void setFlags(Flags flags) { fFlags = flags; }
+
+ bool isCrossProcess() const { return (fFlags & kCrossProcess_Flag) != 0; }
+
+ bool persistBitmapPixels() const {
+ return (fFlags & kCrossProcess_Flag) != 0;
+ }
+
+ bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
+
+private:
+ Flags fFlags;
+ SkRefCntRecorder* fTFRecorder;
+ SkRefCntRecorder* fRCRecorder;
+ SkFactoryRecorder* fFactoryRecorder;
+
+ typedef SkWriter32 INHERITED;
+};
+
+#endif
+
diff --git a/include/core/SkFloatBits.h b/include/core/SkFloatBits.h
new file mode 100644
index 0000000000..1628f6e753
--- /dev/null
+++ b/include/core/SkFloatBits.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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
+ */
+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
+ */
+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
+ */
+int32_t SkFloatBits_toIntCeil(int32_t floatBits);
+
+
+#ifdef SK_CAN_USE_FLOAT
+
+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);
+float SkIntToFloatCast_NoOverflowCheck(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));
+}
+
+#endif
+
+// Scalar wrappers for float-bit routines
+
+#ifdef SK_SCALAR_IS_FLOAT
+ #define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x)
+ #define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x)
+#else
+ #define SkScalarAs2sCompliment(x) (x)
+ #define Sk2sComplimentAsScalar(x) (x)
+#endif
+
+#endif
+
diff --git a/include/core/SkFloatingPoint.h b/include/core/SkFloatingPoint.h
new file mode 100644
index 0000000000..d3a6fc5f80
--- /dev/null
+++ b/include/core/SkFloatingPoint.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkFloatingPoint_DEFINED
+#define SkFloatingPoint_DEFINED
+
+#include "SkTypes.h"
+
+#ifdef SK_CAN_USE_FLOAT
+
+#include <math.h>
+#include <float.h>
+#include "SkFloatBits.h"
+
+#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) acos(x)
+ #define sk_float_asin(x) 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)
+ #define sk_float_abs(x) fabsf(x)
+ #define sk_float_mod(x,y) fmodf(x,y)
+ #define sk_float_exp(x) expf(x)
+ #define sk_float_log(x) logf(x)
+ #define sk_float_isNaN(x) _isnan(x)
+#endif
+
+#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
+
+#endif
+#endif
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h
new file mode 100644
index 0000000000..ede40b7a31
--- /dev/null
+++ b/include/core/SkFontHost.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkFontHost_DEFINED
+#define SkFontHost_DEFINED
+
+#include "SkScalerContext.h"
+#include "SkTypeface.h"
+
+class SkDescriptor;
+class SkStream;
+class SkWStream;
+
+/** \class SkFontHost
+
+ This class is ported to each environment. It is responsible for bridging the gap
+ between SkTypeface and the resulting platform-specific instance of SkScalerContext.
+*/
+class SkFontHost {
+public:
+ /** Return the closest matching typeface given either an existing family
+ (specified by a typeface in that family) or by a familyName, and a
+ requested style.
+ 1) If familyFace is null, use famillyName.
+ 2) If famillyName is null, use familyFace.
+ 3) If both are null, return the default font that best matches style
+
+ NOTE: this does not return a new typeface, nor does it affect the
+ owner count of an existing one, so the caller is free to ignore the
+ return result, or just compare it against null.
+ */
+ static SkTypeface* FindTypeface(const SkTypeface* familyFace,
+ const char famillyName[],
+ SkTypeface::Style style);
+
+ /** Return the typeface associated with the uniqueID, or null if that ID
+ does not match any faces.
+
+ NOTE: this does not return a new typeface, nor does it affect the
+ owner count of an existing one, so the caller is free to ignore the
+ return result, or just compare it against null.
+ */
+ static SkTypeface* ResolveTypeface(uint32_t uniqueID);
+
+ /** Return a new stream to read the font data, or null if the uniqueID does
+ not match an existing typeface. The caller must call CloseStream() when
+ it is finished reading the stream.
+ */
+ static SkStream* OpenStream(uint32_t uniqueID);
+
+ /** Call this when finished reading from the stream returned by OpenStream.
+ The caller should NOT try to delete the stream.
+ */
+ static void CloseStream(uint32_t uniqueID, SkStream*);
+
+ /** Return a new typeface given the data buffer (owned by the caller).
+ If the data does not represent a valid font, return null. The caller is
+ responsible for unref-ing the returned typeface (if it is not null).
+ */
+ static SkTypeface* CreateTypeface(SkStream*);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** Write a unique identifier to the stream, so that the same typeface can
+ be retrieved with Deserialize().
+ */
+ static void Serialize(const SkTypeface*, SkWStream*);
+
+ /** Given a stream created by Serialize(), return the corresponding typeface
+ or null if no match is found.
+
+ NOTE: this does not return a new typeface, nor does it affect the
+ owner count of an existing one, so the caller is free to ignore the
+ return result, or just compare it against null.
+ */
+ static SkTypeface* Deserialize(SkStream*);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** Return a subclass of SkScalarContext
+ */
+ static SkScalerContext* CreateScalerContext(const SkDescriptor* desc);
+
+ /** Return a scalercontext using the "fallback" font. If there is no designated
+ fallback, return null.
+ */
+ static SkScalerContext* CreateFallbackScalerContext(const SkScalerContext::Rec&);
+
+ /** Return the number of bytes (approx) that should be purged from the font
+ cache. The input parameter is the cache's estimate of how much as been
+ allocated by the cache so far.
+ To purge (basically) everything, return the input parameter.
+ To purge nothing, return 0
+ */
+ static size_t ShouldPurgeFontCache(size_t sizeAllocatedSoFar);
+
+ /** Return SkScalerContext gamma flag, or 0, based on the paint that will be
+ used to draw something with antialiasing.
+ */
+ static int ComputeGammaFlag(const SkPaint& paint);
+
+ /** Return NULL or a pointer to 256 bytes for the black (table[0]) and
+ white (table[1]) gamma tables.
+ */
+ static void GetGammaTables(const uint8_t* tables[2]);
+};
+
+#endif
+
diff --git a/include/core/SkGlobals.h b/include/core/SkGlobals.h
new file mode 100644
index 0000000000..8e28290379
--- /dev/null
+++ b/include/core/SkGlobals.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkGlobals_DEFINED
+#define SkGlobals_DEFINED
+
+#include "SkThread.h"
+
+class SkGlobals {
+public:
+ class Rec {
+ public:
+ virtual ~Rec();
+ private:
+ Rec* fNext;
+ uint32_t fTag;
+
+ friend class SkGlobals;
+ };
+
+ /** Look for a matching Rec for the specified tag. If one is found, return it.
+ If one is not found, if create_proc is null, return null, else
+ call the proc, and if it returns a Rec, add it to the global list
+ and return it.
+
+ create_proc can NOT call back into SkGlobals::Find (it would deadlock)
+ */
+ static Rec* Find(uint32_t tag, Rec* (*create_proc)());
+ /** Helper for Find, when you want to assert that the Rec is already in the list
+ */
+ static Rec* Get(uint32_t tag)
+ {
+ Rec* rec = SkGlobals::Find(tag, NULL);
+ SkASSERT(rec);
+ return rec;
+ }
+
+ // used by porting layer
+ struct BootStrap {
+ SkMutex fMutex;
+ Rec* fHead;
+ };
+
+private:
+ static void Init();
+ static void Term();
+ friend class SkGraphics;
+
+ // This last function is implemented in the porting layer
+ static BootStrap& GetBootStrap();
+};
+
+#endif
+
diff --git a/include/core/SkGraphics.h b/include/core/SkGraphics.h
new file mode 100644
index 0000000000..cb06128306
--- /dev/null
+++ b/include/core/SkGraphics.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkGraphics_DEFINED
+#define SkGraphics_DEFINED
+
+#include "SkTypes.h"
+
+class SkGraphics {
+public:
+ static void Init(bool runUnitTests);
+ static void Term();
+
+ /** Return the (approximate) number of bytes used by the font cache.
+ */
+ static size_t GetFontCacheUsed();
+
+ /** Attempt to purge the font cache until <= the specified amount remains
+ in the cache. Specifying 0 will attempt to purge the entire cache.
+ Returns true if some amount was purged from the font cache.
+ */
+ static bool SetFontCacheUsed(size_t usageInBytes);
+
+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();
+};
+
+#endif
+
diff --git a/include/core/SkMMapStream.h b/include/core/SkMMapStream.h
new file mode 100644
index 0000000000..600c6212f7
--- /dev/null
+++ b/include/core/SkMMapStream.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkMMapStream_DEFINED
+#define SkMMapStream_DEFINED
+
+#include "SkStream.h"
+
+class SkMMAPStream : public SkMemoryStream {
+public:
+ SkMMAPStream(const char filename[]);
+ virtual ~SkMMAPStream();
+
+ virtual void setMemory(const void* data, size_t length);
+private:
+ int fFildes;
+ void* fAddr;
+ size_t fSize;
+
+ void closeMMap();
+
+ typedef SkMemoryStream INHERITED;
+};
+
+#endif
diff --git a/include/core/SkMallocPixelRef.h b/include/core/SkMallocPixelRef.h
new file mode 100644
index 0000000000..b6a013d787
--- /dev/null
+++ b/include/core/SkMallocPixelRef.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 SkMallocPixelRef : public SkPixelRef {
+public:
+ /** Allocate the specified buffer for pixels. The memory is freed when the
+ last owner of this pixelref is gone.
+ */
+ SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable);
+ virtual ~SkMallocPixelRef();
+
+ //! Return the allocation size for the pixels
+ size_t getSize() const { return fSize; }
+
+ // overrides from SkPixelRef
+ virtual void flatten(SkFlattenableWriteBuffer&) const;
+ virtual Factory getFactory() const {
+ return Create;
+ }
+ static SkPixelRef* Create(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkMallocPixelRef, (buffer));
+ }
+
+protected:
+ // overrides from SkPixelRef
+ virtual void* onLockPixels(SkColorTable**);
+ virtual void onUnlockPixels();
+
+ SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
+
+private:
+ void* fStorage;
+ size_t fSize;
+ SkColorTable* fCTable;
+
+ typedef SkPixelRef INHERITED;
+};
+
+#endif
diff --git a/include/core/SkMask.h b/include/core/SkMask.h
new file mode 100644
index 0000000000..764ead68e1
--- /dev/null
+++ b/include/core/SkMask.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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
+ kLCD_Format //!< 3 bytes/pixel: r/g/b
+ };
+
+ enum {
+ kCountMaskFormats = kLCD_Format + 1
+ };
+
+ uint8_t* fImage;
+ SkIRect fBounds;
+ uint16_t fRowBytes;
+ uint8_t fFormat; // Format
+
+ /** Return the byte size of the mask, assuming only 1 plane.
+ Does not account for k3D_Format. For that, use computeFormatImageSize()
+ */
+ size_t computeImageSize() const;
+ /** Return the byte size of the mask, taking into account
+ any extra planes (e.g. k3D_Format).
+ */
+ 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(fFormat == kBW_Format);
+ 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* getAddr(int x, int y) const
+ {
+ SkASSERT(fFormat != kBW_Format);
+ SkASSERT(fBounds.contains(x, y));
+ SkASSERT(fImage != NULL);
+ return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
+ }
+
+ 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
+ };
+};
+
+#endif
+
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
new file mode 100644
index 0000000000..749a73a651
--- /dev/null
+++ b/include/core/SkMaskFilter.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkMaskFilter_DEFINED
+#define SkMaskFilter_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkMask.h"
+
+class SkBlitter;
+class SkBounder;
+class SkMatrix;
+class SkPath;
+class SkRegion;
+
+/** \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 SkMaskFilter : public SkFlattenable {
+public:
+ SkMaskFilter() {}
+
+ /** Returns the format of the resulting mask that this subclass will return
+ when its filterMask() method is called.
+ */
+ virtual SkMask::Format getFormat() = 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);
+
+ /** 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& devMatrix,
+ const SkRegion& devClip, SkBounder*, SkBlitter* blitter);
+
+ virtual void flatten(SkFlattenableWriteBuffer& ) {}
+protected:
+ // empty for now, but lets get our subclass to remember to init us for the future
+ SkMaskFilter(SkFlattenableReadBuffer&) {}
+};
+
+/** \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 SkAutoMaskImage {
+public:
+ SkAutoMaskImage(SkMask* mask, bool alloc)
+ {
+ if (alloc)
+ mask->fImage = SkMask::AllocImage(mask->computeImageSize());
+ fImage = mask->fImage;
+ }
+ ~SkAutoMaskImage()
+ {
+ SkMask::FreeImage(fImage);
+ }
+private:
+ uint8_t* fImage;
+};
+
+#endif
+
diff --git a/include/core/SkMath.h b/include/core/SkMath.h
new file mode 100644
index 0000000000..5c2b475ef9
--- /dev/null
+++ b/include/core/SkMath.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkMath_DEFINED
+#define SkMath_DEFINED
+
+#include "SkTypes.h"
+
+//! Returns the number of leading zero bits (0...32)
+int SkCLZ_portable(uint32_t);
+
+/** Computes the 64bit product of a * b, and then shifts the answer down by
+ shift bits, returning the low 32bits. shift must be [0..63]
+ e.g. to perform a fixedmul, call SkMulShift(a, b, 16)
+*/
+int32_t SkMulShift(int32_t a, int32_t b, unsigned shift);
+
+/** 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.
+*/
+int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
+
+/** 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)
+
+/** Return the integer cube root of value, with a bias of bitBias
+ */
+int32_t SkCubeRootBits(int32_t value, int bitBias);
+
+/** Returns -1 if n < 0, else returns 0
+*/
+#define SkExtractSign(n) ((int32_t)(n) >> 31)
+
+/** If sign == -1, returns -n, else sign must be 0, and returns n.
+ Typically used in conjunction with SkExtractSign().
+*/
+static inline int32_t SkApplySign(int32_t n, int32_t sign) {
+ SkASSERT(sign == 0 || sign == -1);
+ return (n ^ sign) - sign;
+}
+
+/** 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.
+ Note: only works as long as max - value doesn't wrap around
+ @param value The value we want returned pinned between [0...max]
+ @param max The positive max value
+ @return 0 if value < 0, max if value > max, else value
+*/
+static inline int SkClampMax(int value, int max) {
+ // ensure that max is positive
+ SkASSERT(max >= 0);
+ // ensure that if value is negative, max - value doesn't wrap around
+ SkASSERT(value >= 0 || max - value > 0);
+
+#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
+ if (value < 0) {
+ value = 0;
+ }
+ if (value > max) {
+ value = max;
+ }
+ return value;
+#else
+
+ int diff = max - value;
+ // clear diff if diff is positive
+ diff &= diff >> 31;
+
+ // clear the result if value < 0
+ return (value + diff) & ~(value >> 31);
+#endif
+}
+
+/** Given a positive value and a positive max, return the value
+ pinned against max.
+ Note: only works as long as max - value doesn't wrap around
+ @return max if value >= max, else value
+*/
+static inline unsigned SkClampUMax(unsigned value, unsigned max) {
+#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
+ if (value > max) {
+ value = max;
+ }
+ return value;
+#else
+ int diff = max - value;
+ // clear diff if diff is positive
+ diff &= diff >> 31;
+
+ return value + diff;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(__arm__) && !defined(__thumb__)
+ #define SkCLZ(x) __builtin_clz(x)
+#endif
+
+#ifndef SkCLZ
+ #define SkCLZ(x) SkCLZ_portable(x)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** 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);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** 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.
+*/
+#if defined(__arm__) && !defined(__thumb__)
+ 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/255, truncating away any fractional bits. Only valid if both
+ a and b are 0..255
+*/
+static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
+ SkASSERT((uint8_t)a == a);
+ SkASSERT((uint8_t)b == b);
+ unsigned prod = SkMulS16(a, b) + 1;
+ return (prod + (prod >> 8)) >> 8;
+}
+
+/** Return a*b/255, rounding any fractional bits. Only valid if both
+ a and b are 0..255
+ */
+static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
+ SkASSERT((uint8_t)a == a);
+ SkASSERT((uint8_t)b == b);
+ unsigned prod = SkMulS16(a, b) + 128;
+ return (prod + (prod >> 8)) >> 8;
+}
+
+/** Return a*b/((1 << shift) - 1), rounding any fractional bits.
+ Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
+*/
+static inline unsigned SkMul16ShiftRound(unsigned a, unsigned 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;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_DEBUG
+ class SkMath {
+ public:
+ static void UnitTest();
+ };
+#endif
+
+#endif
+
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
new file mode 100644
index 0000000000..2b25dcada3
--- /dev/null
+++ b/include/core/SkMatrix.h
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkMatrix_DEFINED
+#define SkMatrix_DEFINED
+
+#include "SkRect.h"
+
+class SkString;
+
+/** \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 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 mask bitfield describing the types of transformations
+ that the matrix will perform. This information is used by routines
+ like mapPoints, to optimize its inner loops to only perform as much
+ arithmetic as is necessary.
+ */
+ 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;
+ }
+
+ /** 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;
+ }
+
+ enum {
+ kMScaleX,
+ kMSkewX,
+ kMTransX,
+ kMSkewY,
+ kMScaleY,
+ kMTransY,
+ kMPersp0,
+ kMPersp1,
+ kMPersp2
+ };
+
+ 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]; }
+ SkScalar getPerspX() const { return fMat[kMPersp0]; }
+ SkScalar getPerspY() const { return fMat[kMPersp1]; }
+
+ 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(SkScalar v) { this->set(kMPersp0, v); }
+ void setPerspY(SkScalar v) { this->set(kMPersp1, v); }
+
+ /** Set the matrix to identity
+ */
+ void reset();
+
+ /** Set the matrix to translate by (dx, dy).
+ */
+ void setTranslate(SkScalar dx, SkScalar dy);
+ /** 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 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,
+ returning true if the the result can be represented. Either of the
+ two matrices may also be the target matrix. *this = a * b;
+ */
+ bool setConcat(const SkMatrix& a, const SkMatrix& b);
+
+ /** Preconcats the matrix with the specified translation.
+ M' = M * T(dx, dy)
+ */
+ bool preTranslate(SkScalar dx, SkScalar dy);
+ /** Preconcats the matrix with the specified scale.
+ M' = M * S(sx, sy, px, py)
+ */
+ bool preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified scale.
+ M' = M * S(sx, sy)
+ */
+ bool preScale(SkScalar sx, SkScalar sy);
+ /** Preconcats the matrix with the specified rotation.
+ M' = M * R(degrees, px, py)
+ */
+ bool preRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified rotation.
+ M' = M * R(degrees)
+ */
+ bool preRotate(SkScalar degrees);
+ /** Preconcats the matrix with the specified skew.
+ M' = M * K(kx, ky, px, py)
+ */
+ bool preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Preconcats the matrix with the specified skew.
+ M' = M * K(kx, ky)
+ */
+ bool preSkew(SkScalar kx, SkScalar ky);
+ /** Preconcats the matrix with the specified matrix.
+ M' = M * other
+ */
+ bool preConcat(const SkMatrix& other);
+
+ /** Postconcats the matrix with the specified translation.
+ M' = T(dx, dy) * M
+ */
+ bool postTranslate(SkScalar dx, SkScalar dy);
+ /** Postconcats the matrix with the specified scale.
+ M' = S(sx, sy, px, py) * M
+ */
+ bool postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified scale.
+ M' = S(sx, sy) * M
+ */
+ bool 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
+ */
+ bool postRotate(SkScalar degrees, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified rotation.
+ M' = R(degrees) * M
+ */
+ bool postRotate(SkScalar degrees);
+ /** Postconcats the matrix with the specified skew.
+ M' = K(kx, ky, px, py) * M
+ */
+ bool postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
+ /** Postconcats the matrix with the specified skew.
+ M' = K(kx, ky) * M
+ */
+ bool postSkew(SkScalar kx, SkScalar ky);
+ /** Postconcats the matrix with the specified matrix.
+ M' = other * M
+ */
+ bool 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 invert(SkMatrix* inverse) 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);
+ }
+
+ 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);
+ }
+
+ /** 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;
+
+ friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
+ return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) == 0;
+ }
+
+ friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
+ return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
+ }
+
+ void dump() const;
+ void toDumpString(SkString*) const;
+
+#ifdef SK_DEBUG
+ /** @cond UNIT_TEST */
+
+ static void UnitTest();
+ /** @endcond */
+#endif
+
+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 is not set if the matrix is identity.
+
+ This bit will be set on identity matrices
+ */
+ kRectStaysRect_Mask = 0x10,
+
+ kUnknown_Mask = 0x80,
+
+ kAllMasks = kTranslate_Mask |
+ kScale_Mask |
+ kAffine_Mask |
+ kPerspective_Mask |
+ kRectStaysRect_Mask
+ };
+
+ SkScalar fMat[9];
+ mutable uint8_t fTypeMask;
+
+ uint8_t computeTypeMask() const;
+
+ void setTypeMask(int mask) {
+ // allow kUnknown or a valid mask
+ SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask);
+ fTypeMask = SkToU8(mask);
+ }
+
+ void clearTypeMask(int mask) {
+ // only allow a valid mask
+ SkASSERT((mask & kAllMasks) == mask);
+ fTypeMask &= ~mask;
+ }
+
+ 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/include/core/SkPackBits.h b/include/core/SkPackBits.h
new file mode 100644
index 0000000000..c11231bd48
--- /dev/null
+++ b/include/core/SkPackBits.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPackBits_DEFINED
+#define SkPackBits_DEFINED
+
+#include "SkTypes.h"
+
+class SkPackBits {
+public:
+ /** Given the number of 16bit values that will be passed to Pack16,
+ returns the worst-case size needed for the dst[] buffer.
+ */
+ static size_t ComputeMaxSize16(int count);
+
+ /** 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 16bit values
+ @param count Number of entries in src[]
+ @param dst Buffer (allocated by caller) to write the packed data
+ into
+ @return the number of bytes written to dst[]
+ */
+ static size_t Pack16(const uint16_t src[], int count, uint8_t dst[]);
+
+ /** 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 count Number of entries in src[]
+ @param dst Buffer (allocated by caller) to write the packed data
+ into
+ @return the number of bytes written to dst[]
+ */
+ static size_t Pack8(const uint8_t src[], int count, uint8_t dst[]);
+
+ /** Unpack the data in src[], and expand it into dst[]. The src[] data was
+ written by a previous call to Pack16.
+ @param src Input data to unpack, previously created by Pack16.
+ @param srcSize Number of bytes of src to unpack
+ @param dst Buffer (allocated by caller) to expand the src[] into.
+ @return the number of dst elements (not bytes) written into dst.
+ */
+ static int Unpack16(const uint8_t src[], size_t srcSize, uint16_t dst[]);
+
+ /** 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.
+ @return the number of bytes written into dst.
+ */
+ static int Unpack8(const uint8_t src[], size_t srcSize, uint8_t dst[]);
+
+ /** Unpack the data from src[], skip the first dstSkip bytes, then write
+ dstWrite bytes into dst[]. The src[] data was written by a previous
+ call to Pack8. Return the number of bytes actually writtten into dst[]
+ @param src Input data to unpack, previously created by Pack8.
+ @param dst Buffer (allocated by caller) to expand the src[] into.
+ @param dstSkip Number of bytes of unpacked src to skip before writing
+ into dst
+ @param dstWrite Number of bytes of unpacked src to write into dst (after
+ skipping dstSkip bytes)
+ */
+ static void Unpack8(uint8_t dst[], size_t dstSkip, size_t dstWrite,
+ const uint8_t src[]);
+};
+
+#endif
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
new file mode 100644
index 0000000000..fc390ab819
--- /dev/null
+++ b/include/core/SkPaint.h
@@ -0,0 +1,814 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPaint_DEFINED
+#define SkPaint_DEFINED
+
+#include "SkColor.h"
+#include "SkMath.h"
+#include "SkPorterDuff.h"
+
+class SkAutoGlyphCache;
+class SkColorFilter;
+class SkDescriptor;
+class SkFlattenableReadBuffer;
+class SkFlattenableWriteBuffer;
+struct SkGlyph;
+struct SkRect;
+class SkGlyphCache;
+class SkMaskFilter;
+class SkMatrix;
+class SkPath;
+class SkPathEffect;
+class SkRasterizer;
+class SkShader;
+class SkDrawLooper;
+class SkTypeface;
+class SkXfermode;
+
+typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
+ SkFixed x, SkFixed y);
+
+typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
+
+/** \class SkPaint
+
+ The SkPaint class holds the style and color information about how to draw
+ geometries, text and bitmaps.
+*/
+class SkPaint {
+public:
+ SkPaint();
+ SkPaint(const SkPaint& paint);
+ ~SkPaint();
+
+ SkPaint& operator=(const SkPaint&);
+
+ friend int operator==(const SkPaint& a, const SkPaint& b);
+ friend int operator!=(const SkPaint& a, const SkPaint& b)
+ {
+ return !(a == b);
+ }
+
+ void flatten(SkFlattenableWriteBuffer&) const;
+ void unflatten(SkFlattenableReadBuffer&);
+
+ /** Restores the paint to its initial settings.
+ */
+ void reset();
+
+ /** Specifies the bit values that are stored in the paint's flags.
+ */
+ enum Flags {
+ kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
+ kFilterBitmap_Flag = 0x02, //!< mask to enable bitmap filtering
+ 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
+ kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
+
+ kAllFlags = 0x1FF
+ };
+
+ /** 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 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 bit
+ @param subpixelText true to set the subpixelText bit in the paint's
+ flags, false to clear it.
+ */
+ void setSubpixelText(bool subpixelText);
+
+ /** 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);
+
+ bool isFilterBitmap() const
+ {
+ return SkToBool(this->getFlags() & kFilterBitmap_Flag);
+ }
+
+ void setFilterBitmap(bool filterBitmap);
+
+ /** Styles apply to rect, oval, path, and text.
+ Bitmaps are always drawn in "fill", and lines are always drawn in
+ "stroke".
+ */
+ enum Style {
+ kFill_Style, //!< fill with the paint's color
+ kStroke_Style, //!< stroke with the paint's color
+ kStrokeAndFill_Style, //!< fill and stroke with the paint's color
+
+ kStyleCount,
+ };
+
+ /** 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)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)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)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)
+ @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;
+
+ /** 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;
+
+ /** 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;
+
+ /** 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.
+ <p />
+ 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);
+
+ /** Helper for setXfermode, passing the corresponding xfermode object
+ returned from the PorterDuff factory.
+ @param mode The porter-duff mode used to create an xfermode for the
+ paint.
+ @return the resulting xfermode object (or NULL if the mode is
+ SrcOver)
+ */
+ SkXfermode* setPorterDuffXfermode(SkPorterDuff::Mode 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);
+
+ SkDrawLooper* getLooper() const { return fLooper; }
+ SkDrawLooper* setLooper(SkDrawLooper*);
+
+ enum Align {
+ kLeft_Align,
+ kCenter_Align,
+ kRight_Align,
+
+ kAlignCount
+ };
+ /** Return the paint's Align value for drawing text.
+ @return the paint's Align value for drawing text.
+ */
+ Align getTextAlign() const { return (Align)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
+ kGlyphID_TextEncoding //!< the text parameters are glyph indices
+ };
+
+ TextEncoding getTextEncoding() const
+ {
+ return (TextEncoding)fTextEncoding;
+ }
+
+ void setTextEncoding(TextEncoding encoding);
+
+ struct FontMetrics {
+ 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)
+ };
+
+ /** 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 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.
+ @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).
+ @param scale If not 0, return width as if the canvas were scaled
+ by this value
+ @return The advance width of the text
+ */
+ SkScalar measureText(const void* text, size_t length,
+ SkRect* bounds, SkScalar scale = 0) const;
+
+ /** Return the width of the text.
+ @param text Address of the text
+ @param length Number of bytes of text to measure
+ @return The width of the text
+ */
+ SkScalar measureText(const void* text, size_t length) const
+ {
+ return this->measureText(text, length, NULL, 0);
+ }
+
+ /** 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 width of the text.
+ @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 advance widths for the characters in the string.
+ @param text the text
+ @param byteLength number of bytes to of text
+ @param widths If not null, returns the array of advance widths of
+ 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;
+
+private:
+ SkTypeface* fTypeface;
+ SkScalar fTextSize;
+ SkScalar fTextScaleX;
+ SkScalar fTextSkewX;
+
+ SkPathEffect* fPathEffect;
+ SkShader* fShader;
+ SkXfermode* fXfermode;
+ SkMaskFilter* fMaskFilter;
+ SkColorFilter* fColorFilter;
+ SkRasterizer* fRasterizer;
+ SkDrawLooper* fLooper;
+
+ SkColor fColor;
+ SkScalar fWidth;
+ SkScalar fMiterLimit;
+ unsigned fFlags : 9;
+ unsigned fTextAlign : 2;
+ unsigned fCapType : 2;
+ unsigned fJoinType : 2;
+ unsigned fStyle : 2;
+ unsigned fTextEncoding : 2; // 3 values
+
+ 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 SkMatrix*) const;
+
+ void descriptorProc(const SkMatrix* deviceMatrix,
+ void (*proc)(const SkDescriptor*, void*),
+ void* context) const;
+
+ enum {
+ kCanonicalTextSizeForPaths = 64
+ };
+ friend class SkCanvas;
+ friend class SkDraw;
+ friend class SkAutoGlyphCache;
+ friend class SkTextToPathIter;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "SkPathEffect.h"
+
+/** \class SkStrokePathEffect
+
+ SkStrokePathEffect simulates stroking inside a patheffect, allowing the
+ caller to have explicit control of when to stroke a path. Typically this is
+ used if the caller wants to stroke before another patheffect is applied
+ (using SkComposePathEffect or SkSumPathEffect).
+*/
+class SkStrokePathEffect : public SkPathEffect {
+public:
+ SkStrokePathEffect(const SkPaint&);
+ SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
+ SkPaint::Cap, SkScalar miterLimit = -1);
+
+ // overrides
+ // This method is not exported to java.
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+ // overrides for SkFlattenable
+ // This method is not exported to java.
+ virtual void flatten(SkFlattenableWriteBuffer&);
+ // This method is not exported to java.
+ virtual Factory getFactory();
+
+private:
+ SkScalar fWidth, fMiter;
+ uint8_t fStyle, fJoin, fCap;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+ SkStrokePathEffect(SkFlattenableReadBuffer&);
+
+ typedef SkPathEffect INHERITED;
+
+ // illegal
+ SkStrokePathEffect(const SkStrokePathEffect&);
+ SkStrokePathEffect& operator=(const SkStrokePathEffect&);
+};
+
+#endif
+
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
new file mode 100644
index 0000000000..e2409ad6ba
--- /dev/null
+++ b/include/core/SkPath.h
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPath_DEFINED
+#define SkPath_DEFINED
+
+#include "SkMatrix.h"
+#include "SkTDArray.h"
+
+class SkFlattenableReadBuffer;
+class SkFlattenableWriteBuffer;
+class SkAutoPathBoundsUpdate;
+class SkString;
+
+/** \class SkPath
+
+ The SkPath class encapsulates compound (multiple contour) geometric paths
+ consisting of straight line segments, quadratic curves, and cubic curves.
+*/
+class SkPath {
+public:
+ SkPath();
+ SkPath(const SkPath&);
+ ~SkPath();
+
+ SkPath& operator=(const SkPath&);
+
+ 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 (fFillType & 2) != 0; }
+
+ /** Toggle between inverse and normal filltypes. This reverse the return
+ value of isInverseFillType()
+ */
+ void toggleInverseFillType() { fFillType ^= 2; }
+
+ /** Clear any lines and curves from the path, making it empty. This frees up
+ internal storage associated with those segments.
+ This does NOT change the fill-type setting.
+ */
+ 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.
+ This does NOT change the fill-type setting.
+ */
+ 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;
+
+ /** 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;
+
+ /** 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;
+
+ //! Swap contents of this and other. Guaranteed not to throw
+ void swap(SkPath& other);
+
+ enum BoundsType {
+ /** compute the bounds of the path's control points, may be larger than
+ with kExact_BoundsType, but may be faster to compute
+ */
+ kFast_BoundsType,
+ /** compute the exact bounds of the path, may be smaller than with
+ kFast_BoundsType, but may be slower to compute
+ */
+ kExact_BoundsType
+ };
+
+ /** Compute the bounds of the path, and write the answer into bounds. If the
+ path contains 0 or 1 points, the bounds is set to (0,0,0,0)
+
+ @param bounds Returns the computed bounds of the path
+ @param btype Specifies if the computed bounds should be exact
+ (slower) or approximate (faster)
+ */
+ void computeBounds(SkRect* bounds, BoundsType btype) const;
+
+ /** Calling this will, if the internal cache of the bounds is out of date,
+ update it so that subsequent calls to computeBounds will be instanteous.
+ This also means that any copies or simple transformations of the path
+ will inherit the cached bounds.
+ */
+ void updateBoundsCache() 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);
+
+ /** 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 {
+ /** clockwise direction for adding closed contours */
+ kCW_Direction,
+ /** counter-clockwise direction for adding closed contours */
+ kCCW_Direction
+ };
+
+ /** 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
+ */
+ 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
+ */
+ 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
+ */
+ 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
+ */
+ 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 round-rectangle's contour
+ */
+ 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 round-rectangle's contour
+ */
+ void addRoundRect(const SkRect& rect, const SkScalar radii[],
+ Direction dir = kCW_Direction);
+
+ /** 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);
+
+ /** Add a copy of src to the path
+ */
+ void addPath(const SkPath& src) {
+ SkMatrix m;
+ m.reset();
+ this->addPath(src, m);
+ }
+
+ /** Add a copy of src to the path, transformed by matrix
+ @param src The path to add as a new contour
+ */
+ void addPath(const SkPath& src, const SkMatrix& matrix);
+
+ /** 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.
+
+ @param lastPt The last point on the path is returned here
+ */
+ void 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 Verb {
+ kMove_Verb, //!< iter.next returns 1 point
+ kLine_Verb, //!< iter.next returns 2 points
+ kQuad_Verb, //!< iter.next returns 3 points
+ kCubic_Verb, //!< iter.next returns 4 points
+ kClose_Verb, //!< iter.next returns 1 point (the last point)
+ kDone_Verb //!< iter.next returns 0 points
+ };
+
+ /** Iterate through all of the segments (lines, quadratics, cubics) of
+ each contours in a path.
+ */
+ class 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
+ @return The verb for the current segment
+ */
+ Verb next(SkPoint pts[4]);
+
+ /** 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;
+ SkPoint fMoveTo;
+ SkPoint fLastPt;
+ SkBool8 fForceClose;
+ SkBool8 fNeedClose;
+ SkBool8 fNeedMoveTo;
+ SkBool8 fCloseLine;
+
+ bool cons_moveTo(SkPoint pts[1]);
+ Verb autoClose(SkPoint pts[2]);
+ };
+
+#ifdef SK_DEBUG
+ /** @cond UNIT_TEST */
+ void dump(bool forceClose, const char title[] = NULL) const;
+ static void UnitTest();
+ /** @endcond */
+#endif
+
+ void flatten(SkFlattenableWriteBuffer&) const;
+ void unflatten(SkFlattenableReadBuffer&);
+
+ /** Subdivide the path so that no segment is longer that dist.
+ If bendLines is true, then turn all line segments into curves.
+ If dst == null, then the original path itself is modified (not const!)
+ */
+ void subdivide(SkScalar dist, bool bendLines, SkPath* dst = NULL) const;
+
+ /** Return an SVG-compatible string of the path.
+ */
+ void toString(SkString*) const;
+
+ SkDEBUGCODE(void validate() const;)
+
+private:
+ SkTDArray<SkPoint> fPts;
+ SkTDArray<uint8_t> fVerbs;
+ mutable SkRect fFastBounds;
+ mutable uint8_t fFastBoundsIsDirty;
+ uint8_t fFillType;
+
+ friend class Iter;
+ void cons_moveto();
+
+ friend class SkPathStroker;
+ /* Append the first contour of path, ignoring path's initial point. If no
+ moveTo() call has been made for this contour, the first point is
+ automatically set to (0,0).
+ */
+ void pathTo(const SkPath& path);
+
+ /* 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&);
+
+ friend const SkPoint* sk_get_path_points(const SkPath&, int index);
+ friend class SkAutoPathBoundsUpdate;
+};
+
+#endif
+
diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h
new file mode 100644
index 0000000000..f97adb7904
--- /dev/null
+++ b/include/core/SkPathEffect.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPathEffect_DEFINED
+#define SkPathEffect_DEFINED
+
+#include "SkFlattenable.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 SkPathEffect : public SkFlattenable {
+public:
+ // This method is not exported to java.
+ SkPathEffect() {}
+
+ /** Given a src path and a width value, return true if the patheffect
+ has produced a new path (dst) and a new width value. If false is returned,
+ ignore dst and width.
+ On input, width >= 0 means the src should be stroked
+ On output, width >= 0 means the dst should be stroked
+ */
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) = 0;
+
+private:
+ // illegal
+ SkPathEffect(const SkPathEffect&);
+ SkPathEffect& operator=(const SkPathEffect&);
+};
+
+/** \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:
+ SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
+ virtual ~SkPairPathEffect();
+
+protected:
+ SkPairPathEffect(SkFlattenableReadBuffer&);
+ virtual void flatten(SkFlattenableWriteBuffer&);
+ // 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.
+ */
+ SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
+ : INHERITED(outer, inner) {}
+
+ // overrides
+
+ // This method is not exported to java.
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+protected:
+ virtual Factory getFactory() { return CreateProc; }
+
+private:
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkComposePathEffect, (buffer));
+ }
+ SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+ // 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.
+ */
+ SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
+ : INHERITED(first, second) {}
+
+ // overrides
+ // This method is not exported to java.
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+protected:
+ virtual Factory getFactory() { return CreateProc; }
+
+private:
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkSumPathEffect, (buffer));
+ }
+ SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+ // illegal
+ SkSumPathEffect(const SkSumPathEffect&);
+ SkSumPathEffect& operator=(const SkSumPathEffect&);
+
+ typedef SkPairPathEffect INHERITED;
+};
+
+#endif
+
diff --git a/include/core/SkPathMeasure.h b/include/core/SkPathMeasure.h
new file mode 100644
index 0000000000..5ab97cacfd
--- /dev/null
+++ b/include/core/SkPathMeasure.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPathMeasure_DEFINED
+#define SkPathMeasure_DEFINED
+
+#include "SkPath.h"
+#include "SkTDArray.h"
+
+class 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 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 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();
+ static void UnitTest();
+#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;
+ unsigned fTValue : 15;
+ unsigned fType : 2;
+
+ SkScalar getScalarT() const;
+ };
+ SkTDArray<Segment> fSegments;
+
+ 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/include/core/SkPerspIter.h b/include/core/SkPerspIter.h
new file mode 100644
index 0000000000..81ce7c8fac
--- /dev/null
+++ b/include/core/SkPerspIter.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPerspIter_DEFINED
+#define SkPerspIter_DEFINED
+
+#include "SkMatrix.h"
+
+class SkPerspIter {
+public:
+ /** Iterate a line through the matrix [x,y] ... [x+count-1, y].
+ @param m The matrix we will be iterating a line through
+ @param x The initial X coordinate to be mapped through the matrix
+ @param y The initial Y coordinate to be mapped through the matrix
+ @param count The number of points (x,y) (x+1,y) (x+2,y) ... we will eventually map
+ */
+ SkPerspIter(const SkMatrix& m, SkScalar x, SkScalar y, int count);
+
+ /** Return the buffer of [x,y] fixed point values we will be filling.
+ This always returns the same value, so it can be saved across calls to
+ next().
+ */
+ const SkFixed* getXY() const { return fStorage; }
+
+ /** Return the number of [x,y] pairs that have been filled in the getXY() buffer.
+ When this returns 0, the iterator is finished.
+ */
+ int next();
+
+private:
+ enum {
+ kShift = 4,
+ kCount = (1 << kShift)
+ };
+ const SkMatrix& fMatrix;
+ SkFixed fStorage[kCount * 2];
+ SkFixed fX, fY;
+ SkScalar fSX, fSY;
+ int fCount;
+};
+
+#endif
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
new file mode 100644
index 0000000000..fa614c9516
--- /dev/null
+++ b/include/core/SkPicture.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPicture_DEFINED
+#define SkPicture_DEFINED
+
+#include "SkRefCnt.h"
+
+class SkCanvas;
+class SkPicturePlayback;
+class SkPictureRecord;
+class SkStream;
+class SkWStream;
+
+/** \class SkPicture
+
+ The SkPicture class records the drawing commands made to a canvas, to
+ be played back at a later time.
+*/
+class SkPicture : public SkRefCnt {
+public:
+ /** The constructor prepares the picture to record.
+ @param width the width of the virtual device the picture records.
+ @param height the height of the virtual device the picture records.
+ */
+ SkPicture();
+ /** Make a copy of the contents of src. If src records more drawing after
+ this call, those elements will not appear in this picture.
+ */
+ SkPicture(const SkPicture& src);
+ explicit SkPicture(SkStream*);
+ virtual ~SkPicture();
+
+ /**
+ * Swap the contents of the two pictures. Guaranteed to succeed.
+ */
+ void swap(SkPicture& other);
+
+ /** Returns the canvas that records the drawing commands.
+ @return the picture canvas.
+ */
+ SkCanvas* beginRecording(int width, int height);
+ /** 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() const;
+ /** Signal that the caller is done recording. This invalidates the canvas
+ returned by beginRecording/getRecordingCanvas, and prepares the picture
+ for drawing. Note: this happens implicitly the first time the picture
+ is drawn.
+ */
+ void endRecording();
+
+ /** Replays the drawing commands on the specified canvas. This internally
+ calls endRecording() if that has not already been called.
+ @param surface the canvas receiving the drawing commands.
+ */
+ void draw(SkCanvas* surface);
+
+ /** Return the width of the picture's recording canvas. This
+ value reflects what was passed to setSize(), and does not necessarily
+ reflect the bounds of what has been recorded into the picture.
+ @return the width of the picture's recording canvas
+ */
+ int width() const { return fWidth; }
+
+ /** Return the height of the picture's recording canvas. This
+ value reflects what was passed to setSize(), and does not necessarily
+ reflect the bounds of what has been recorded into the picture.
+ @return the height of the picture's recording canvas
+ */
+ int height() const { return fHeight; }
+
+ void serialize(SkWStream*) const;
+
+ /** Signals that the caller is prematurely done replaying the drawing
+ commands. This can be called from a canvas virtual while the picture
+ is drawing. Has no effect if the picture is not drawing.
+ */
+ void abortPlayback();
+
+private:
+ int fWidth, fHeight;
+ SkPictureRecord* fRecord;
+ SkPicturePlayback* fPlayback;
+
+ friend class SkFlatPicture;
+ friend class SkPicturePlayback;
+};
+
+class SkAutoPictureRecord : SkNoncopyable {
+public:
+ SkAutoPictureRecord(SkPicture* pict, int width, int height) {
+ fPicture = pict;
+ fCanvas = pict->beginRecording(width, height);
+ }
+ ~SkAutoPictureRecord() {
+ fPicture->endRecording();
+ }
+
+ /** Return the canvas to draw into for recording into the picture.
+ */
+ SkCanvas* getRecordingCanvas() const { return fCanvas; }
+
+private:
+ SkPicture* fPicture;
+ SkCanvas* fCanvas;
+};
+
+
+#endif
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
new file mode 100644
index 0000000000..82e5ca7b5e
--- /dev/null
+++ b/include/core/SkPixelRef.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPixelRef_DEFINED
+#define SkPixelRef_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+class SkColorTable;
+class SkMutex;
+class SkFlattenableReadBuffer;
+class SkFlattenableWriteBuffer;
+
+/** \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 SkPixelRef : public SkRefCnt {
+public:
+ explicit SkPixelRef(SkMutex* mutex = NULL);
+
+ /** Return the pixel memory returned from lockPixels, or null if the
+ lockCount is 0.
+ */
+ void* pixels() const { return fPixels; }
+
+ /** Return the current colorTable (if any) if pixels are locked, or null.
+ */
+ SkColorTable* colorTable() const { return fColorTable; }
+
+ /** Return the current lockcount (defaults to 0)
+ */
+ int getLockCount() const { return fLockCount; }
+
+ /** Call to access the pixel memory, which is returned. Balance with a call
+ to unlockPixels().
+ */
+ void lockPixels();
+ /** 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();
+
+ /** 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();
+
+ /** 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; }
+
+ // serialization
+
+ typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
+
+ virtual Factory getFactory() const { return NULL; }
+ virtual void flatten(SkFlattenableWriteBuffer&) const;
+
+ static Factory NameToFactory(const char name[]);
+ static const char* FactoryToName(Factory);
+ static void Register(const char name[], Factory);
+
+ class Registrar {
+ public:
+ Registrar(const char name[], Factory factory) {
+ SkPixelRef::Register(name, factory);
+ }
+ };
+
+protected:
+ /** Called when the lockCount goes from 0 to 1. The caller will have already
+ acquire a mutex for thread safety, so this method need not do that.
+ */
+ virtual void* onLockPixels(SkColorTable**) = 0;
+ /** Called when the lock count goes from 1 to 0. The caller will have
+ already acquire a mutex for thread safety, so this method need not do
+ that.
+ */
+ virtual void onUnlockPixels() = 0;
+
+ /** Return the mutex associated with this pixelref. This value is assigned
+ in the constructor, and cannot change during the lifetime of the object.
+ */
+ SkMutex* mutex() const { return fMutex; }
+
+ SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
+
+private:
+ SkMutex* fMutex; // must remain in scope for the life of this object
+ void* fPixels;
+ SkColorTable* fColorTable; // we do not track ownership, subclass does
+ int fLockCount;
+
+ mutable uint32_t fGenerationID;
+
+ SkString fURI;
+
+ // can go from false to true, but never from true to false
+ bool fIsImmutable;
+};
+
+#endif
diff --git a/include/core/SkPoint.h b/include/core/SkPoint.h
new file mode 100644
index 0000000000..f038afb443
--- /dev/null
+++ b/include/core/SkPoint.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPoint_DEFINED
+#define SkPoint_DEFINED
+
+#include "SkMath.h"
+#include "SkScalar.h"
+
+/** \struct SkIPoint
+
+ SkIPoint holds two 32 bit integer coordinates
+*/
+struct SkIPoint {
+ int32_t fX, fY;
+
+ /** 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 SkPoint {
+ SkScalar fX, 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);
+ }
+
+ /** Return the euclidian distance from (0,0) to the point
+ */
+ SkScalar length() const { return SkPoint::Length(fX, fY); }
+
+ /** Set the point (vector) to be unit-length in the same direction as it
+ currently is, and return its old length. If the old length is
+ degenerately small (nearly zero), do nothing and return false, 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);
+
+ /** 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 scale) { this->scale(scale, 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 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;
+ }
+
+ /** 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);
+
+ /** 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 SkScalarMul(a.fX, b.fX) + SkScalarMul(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 SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX);
+ }
+};
+
+typedef SkPoint SkVector;
+
+#endif
+
diff --git a/include/core/SkPorterDuff.h b/include/core/SkPorterDuff.h
new file mode 100644
index 0000000000..f03e9cbb0e
--- /dev/null
+++ b/include/core/SkPorterDuff.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPorterDuff_DEFINED
+#define SkPorterDuff_DEFINED
+
+#include "SkColor.h"
+
+class SkXfermode;
+
+class 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)]
+ kMultiply_Mode, //!< [Sa * Da, Sc * Dc]
+ kScreen_Mode, //!< [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
+
+ 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);
+};
+
+#endif
+
diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h
new file mode 100644
index 0000000000..e32d6a10b2
--- /dev/null
+++ b/include/core/SkPostConfig.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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
+
+#if defined(SK_SCALAR_IS_FIXED) && defined(SK_SCALAR_IS_FLOAT)
+ #error "cannot define both SK_SCALAR_IS_FIXED and SK_SCALAR_IS_FLOAT"
+#elif !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
+ #ifdef SK_CAN_USE_FLOAT
+ #define SK_SCALAR_IS_FLOAT
+ #else
+ #define SK_SCALAR_IS_FIXED
+ #endif
+#endif
+
+#if defined(SK_SCALAR_IS_FLOAT) && !defined(SK_CAN_USE_FLOAT)
+ #define SK_CAN_USE_FLOAT
+ // we do nothing in the else case: fixed-scalars can have floats or not
+#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 these, 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
+
+///////////////////////////////////////////////////////////////////////////////
+
+#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 SkDELETE(obj) delete obj
+ #define SkDELETE_ARRAY(array) delete[] array
+#endif
+
+#ifndef SK_CRASH
+#if 1 // set to 0 for infinite loop, which can help connecting gdb
+ #define SK_CRASH() *(int *)(uintptr_t)0xbbadbeef = 0
+#else
+ #define SK_CRASH() do {} while (true)
+#endif
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(SK_SOFTWARE_FLOAT) && defined(SK_SCALAR_IS_FLOAT)
+ // if this is defined, we convert floats to 2scompliment ints for compares
+ #ifndef SK_SCALAR_SLOW_COMPARES
+ #define SK_SCALAR_SLOW_COMPARES
+ #endif
+#endif
+
+#ifdef SK_BUILD_FOR_WIN
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ #undef WIN32_LEAN_AND_MEAN
+
+ #ifndef SK_DEBUGBREAK
+ #define SK_DEBUGBREAK(cond) do { if (!(cond)) DebugBreak(); } while (false)
+ #endif
+
+ #ifdef SK_BUILD_FOR_WIN32
+ #define strcasecmp(a, b) stricmp(a, b)
+ #define strncasecmp(a, b, c) strnicmp(a, b, c)
+ #elif defined(SK_BUILD_FOR_WINCE)
+ #define strcasecmp(a, b) _stricmp(a, b)
+ #define strncasecmp(a, b, c) _strnicmp(a, b, c)
+ #endif
+#elif defined(SK_BUILD_FOR_MAC)
+ #ifndef SK_DEBUGBREAK
+ #define SK_DEBUGBREAK(cond) do { if (!(cond)) SK_CRASH(); } while (false)
+ #endif
+#else
+ #ifdef SK_DEBUG
+ #include <stdio.h>
+ #ifndef SK_DEBUGBREAK
+ #define SK_DEBUGBREAK(cond) do { if (cond) break; \
+ SkDebugf("%s:%d: failed assertion \"%s\"\n", \
+ __FILE__, __LINE__, #cond); SK_CRASH(); } while (false)
+ #endif
+ #endif
+#endif
+
+// stdlib macros
+
+#if 0
+#if !defined(strlen) && defined(SK_DEBUG)
+ extern size_t sk_strlen(const char*);
+ #define strlen(s) sk_strlen(s)
+#endif
+#ifndef sk_strcpy
+ #define sk_strcpy(dst, src) strcpy(dst, src)
+#endif
+#ifndef sk_strchr
+ #define sk_strchr(s, c) strchr(s, c)
+#endif
+#ifndef sk_strrchr
+ #define sk_strrchr(s, c) strrchr(s, c)
+#endif
+#ifndef sk_strcmp
+ #define sk_strcmp(s, t) strcmp(s, t)
+#endif
+#ifndef sk_strncmp
+ #define sk_strncmp(s, t, n) strncmp(s, t, n)
+#endif
+#ifndef sk_memcpy
+ #define sk_memcpy(dst, src, n) memcpy(dst, src, n)
+#endif
+#ifndef memmove
+ #define memmove(dst, src, n) memmove(dst, src, n)
+#endif
+#ifndef sk_memset
+ #define sk_memset(dst, val, n) memset(dst, val, n)
+#endif
+#ifndef sk_memcmp
+ #define sk_memcmp(s, t, n) memcmp(s, t, n)
+#endif
+
+#define sk_strequal(s, t) (!sk_strcmp(s, t))
+#define sk_strnequal(s, t, n) (!sk_strncmp(s, t, n))
+#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
+//#define _CRTDBG_MAP_ALLOC
+#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 // _DEBUG
+
+#endif
+
+#endif
+
diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h
new file mode 100644
index 0000000000..04f1987738
--- /dev/null
+++ b/include/core/SkPreConfig.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPreConfig_DEFINED
+#define SkPreConfig_DEFINED
+
+#ifdef ANDROID
+ #define SK_BUILD_FOR_UNIX
+ #define SkLONGLONG int64_t
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC)
+
+ #if 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(linux)
+ #define SK_BUILD_FOR_UNIX
+ #else
+ #define SK_BUILD_FOR_MAC
+ #endif
+
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
+ #ifdef NDEBUG
+ #define SK_RELEASE
+ #else
+ #define SK_DEBUG
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+// define to blank or change this in SkUserConfig.h as needed
+#define SK_RESTRICT __restrict__
+
+//////////////////////////////////////////////////////////////////////
+
+#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
+ #ifndef SK_CAN_USE_FLOAT
+ #define SK_CAN_USE_FLOAT
+ #endif
+ #if !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
+ #define SK_SCALAR_IS_FIXED
+ #endif
+
+ #ifndef SkLONGLONG
+ #ifdef SK_BUILD_FOR_WIN32
+ #define SkLONGLONG __int64
+ #else
+ #define SkLONGLONG long long
+ #endif
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
+ #if defined (__ppc__) || defined(__ppc64__)
+ #define SK_CPU_BENDIAN
+ #else
+ #define SK_CPU_LENDIAN
+ #endif
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+#if (defined(__arm__) && !defined(__thumb__)) || defined(SK_BUILD_FOR_BREW) || defined(SK_BUILD_FOR_WINCE) || (defined(SK_BUILD_FOR_SYMBIAN) && !defined(__MARM_THUMB__))
+ /* e.g. the ARM instructions have conditional execution, making tiny branches cheap */
+ #define SK_CPU_HAS_CONDITIONAL_INSTR
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Conditional features based on build target
+
+#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
+ #ifndef SK_BUILD_NO_IMAGE_ENCODE
+ #define SK_SUPPORT_IMAGE_ENCODE
+ #endif
+#endif
+
+#ifdef SK_BUILD_FOR_SYMBIAN
+ #define SK_USE_RUNTIME_GLOBALS
+#endif
+
+#endif
+
diff --git a/include/core/SkPtrRecorder.h b/include/core/SkPtrRecorder.h
new file mode 100644
index 0000000000..ff1e14dcb7
--- /dev/null
+++ b/include/core/SkPtrRecorder.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPtrRecorder_DEFINED
+#define SkPtrRecorder_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+class SkPtrRecorder : public SkRefCnt {
+public:
+ uint32_t recordPtr(void*);
+
+ int count() const { return fList.count(); }
+ void getPtrs(void* array[]) const;
+
+ void reset();
+
+protected:
+ virtual void incPtr(void* ptr) {}
+ virtual void decPtr(void* ptr) {}
+
+private:
+ struct Pair {
+ void* fPtr;
+ uint32_t fIndex;
+ };
+ SkTDArray<Pair> fList;
+
+ static int Cmp(const Pair& a, const Pair& b);
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/include/core/SkRandom.h b/include/core/SkRandom.h
new file mode 100644
index 0000000000..33b563af5e
--- /dev/null
+++ b/include/core/SkRandom.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkRandom_DEFINED
+#define SkRandom_DEFINED
+
+#include "Sk64.h"
+#include "SkScalar.h"
+
+/** \class SkRandom
+
+ 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 SkRandom {
+public:
+ SkRandom() : fSeed(0) {}
+ SkRandom(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; }
+
+ /** 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);
+ return min + this->nextU() % (max - min + 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 (-SK_Scalar1..SK_Scalar1).
+ */
+ SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
+
+ /** Return the next pseudo random number as a signed 64bit value.
+ */
+ void next64(Sk64* a) {
+ SkASSERT(a);
+ a->set(this->nextS(), this->nextU());
+ }
+
+ /** 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;
+};
+
+#endif
+
diff --git a/include/core/SkRasterizer.h b/include/core/SkRasterizer.h
new file mode 100644
index 0000000000..d81e613f0b
--- /dev/null
+++ b/include/core/SkRasterizer.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkRasterizer_DEFINED
+#define SkRasterizer_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkMask.h"
+
+class SkMaskFilter;
+class SkMatrix;
+class SkPath;
+struct SkIRect;
+
+class SkRasterizer : public SkFlattenable {
+public:
+ 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);
+
+ virtual void flatten(SkFlattenableWriteBuffer& ) {}
+protected:
+ SkRasterizer(SkFlattenableReadBuffer&);
+
+ virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
+ const SkIRect* clipBounds,
+ SkMask* mask, SkMask::CreateMode mode);
+
+private:
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
diff --git a/include/core/SkReader32.h b/include/core/SkReader32.h
new file mode 100644
index 0000000000..1c72a87eb7
--- /dev/null
+++ b/include/core/SkReader32.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkReader32_DEFINED
+#define SkReader32_DEFINED
+
+#include "SkTypes.h"
+
+#include "SkScalar.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+
+class SkReader32 : SkNoncopyable {
+public:
+ SkReader32() : fCurr(NULL), fStop(NULL), fBase(NULL) {}
+ SkReader32(const void* data, size_t size) {
+ this->setMemory(data, size);
+ }
+
+ void setMemory(const void* data, size_t size) {
+ SkASSERT(ptr_align_4(data));
+ SkASSERT(SkAlign4(size) == size);
+
+ fBase = fCurr = (const char*)data;
+ fStop = (const char*)data + size;
+ }
+
+ uint32_t size() const { return fStop - fBase; }
+ uint32_t offset() const { return fCurr - fBase; }
+ bool eof() const { return fCurr >= fStop; }
+ const void* base() const { return fBase; }
+ const void* peek() const { return fCurr; }
+ void rewind() { fCurr = fBase; }
+
+ void setOffset(size_t offset) {
+ SkASSERT(SkAlign4(offset) == offset);
+ SkASSERT(offset <= this->size());
+ fCurr = fBase + offset;
+ }
+
+ bool readBool() { return this->readInt() != 0; }
+
+ int32_t readInt() {
+ SkASSERT(ptr_align_4(fCurr));
+ int32_t value = *(const int32_t*)fCurr;
+ fCurr += sizeof(value);
+ SkASSERT(fCurr <= fStop);
+ return value;
+ }
+
+ SkScalar readScalar() {
+ SkASSERT(ptr_align_4(fCurr));
+ SkScalar value = *(const SkScalar*)fCurr;
+ fCurr += sizeof(value);
+ SkASSERT(fCurr <= fStop);
+ return value;
+ }
+
+ const SkPoint* skipPoint() {
+ return (const SkPoint*)this->skip(sizeof(SkPoint));
+ }
+
+ const SkRect* skipRect() {
+ return (const SkRect*)this->skip(sizeof(SkRect));
+ }
+
+ const void* skip(size_t size) {
+ SkASSERT(ptr_align_4(fCurr));
+ const void* addr = fCurr;
+ fCurr += SkAlign4(size);
+ SkASSERT(fCurr <= fStop);
+ return addr;
+ }
+
+ void read(void* dst, size_t size) {
+ SkASSERT(dst != NULL);
+ SkASSERT(ptr_align_4(fCurr));
+ memcpy(dst, fCurr, size);
+ fCurr += SkAlign4(size);
+ SkASSERT(fCurr <= fStop);
+ }
+
+ uint8_t readU8() { return (uint8_t)this->readInt(); }
+ uint16_t readU16() { return (uint16_t)this->readInt(); }
+ int32_t readS32() { return this->readInt(); }
+ uint32_t readU32() { return this->readInt(); }
+
+private:
+ // these are always 4-byte aligned
+ const char* fCurr; // current position within buffer
+ const char* fStop; // end of buffer
+ const char* fBase; // beginning of buffer
+
+#ifdef SK_DEBUG
+ static bool ptr_align_4(const void* ptr)
+ {
+ return (((const char*)ptr - (const char*)NULL) & 3) == 0;
+ }
+#endif
+};
+
+#endif
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
new file mode 100644
index 0000000000..a9f25aa9f5
--- /dev/null
+++ b/include/core/SkRect.h
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkRect_DEFINED
+#define SkRect_DEFINED
+
+#include "SkPoint.h"
+
+/** \struct SkIRect
+
+ SkIRect holds four 32 bit integer coordinates for a rectangle
+*/
+struct SkIRect {
+ int32_t fLeft, fTop, fRight, fBottom;
+
+ /** Return true if the rectangle's width or height are <= 0
+ */
+ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+
+ /** Returns the rectangle's width. This does not check for a valid rectangle (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 rectangle (i.e. top <= bottom)
+ so the result may be negative.
+ */
+ int height() const { return fBottom - fTop; }
+
+ friend int operator==(const SkIRect& a, const SkIRect& b)
+ {
+ return !memcmp(&a, &b, sizeof(a));
+ }
+ friend int operator!=(const SkIRect& a, const SkIRect& b)
+ {
+ return memcmp(&a, &b, sizeof(a));
+ }
+
+ /** 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;
+ }
+
+ /** 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;
+ }
+
+ /** 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 hods true for dy and the top and bottom.
+ */
+ void inset(int32_t dx, int32_t dy)
+ {
+ fLeft += dx;
+ fTop += dy;
+ fRight -= dx;
+ fBottom -= dy;
+ }
+ /** 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;
+ }
+
+ /** 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)
+ {
+ SkASSERT(&a && &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 && &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;
+ }
+
+ /** 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();
+};
+
+/** \struct SkRect
+*/
+struct SkRect {
+ SkScalar fLeft, fTop, fRight, fBottom;
+
+ /** Return true if the rectangle's width or height are <= 0
+ */
+ bool isEmpty() const { return fLeft >= fRight || fTop >= 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 int operator==(const SkRect& a, const SkRect& b)
+ {
+ return !memcmp(&a, &b, sizeof(a));
+ }
+ friend int operator!=(const SkRect& a, const SkRect& b)
+ {
+ return memcmp(&a, &b, sizeof(a));
+ }
+
+ /** return the 4 points that enclose the rectangle
+ */
+ 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;
+ }
+
+ /** 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 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);
+
+ /** 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;
+ }
+
+ /** 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 hods true for dy and the top and bottom.
+ */
+ void inset(SkScalar dx, SkScalar dy)
+ {
+ fLeft += dx;
+ fTop += dy;
+ fRight -= dx;
+ fBottom -= 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);
+
+ /** 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;
+ }
+
+ /** 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() && // check for empties
+ 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);
+ }
+
+ /** Returns true if (p.fX,p.fY) is inside the rectangle. The left and top coordinates of
+ the rectangle are considered to be inside, while the right and bottom coordinates
+ 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.
+ If this rectangle is empty, return false.
+ */
+ bool contains(const SkPoint& p) const
+ {
+ return !this->isEmpty() &&
+ fLeft <= p.fX && p.fX < fRight &&
+ fTop <= p.fY && p.fY < fBottom;
+ }
+
+ /** Returns true if (x,y) is inside the rectangle. The left and top coordinates of
+ the rectangle are considered to be inside, while the right and bottom coordinates
+ 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.
+ If this rectangle is empty, return false.
+ */
+ bool contains(SkScalar x, SkScalar y) const
+ {
+ return !this->isEmpty() &&
+ fLeft <= x && x < fRight &&
+ fTop <= y && y < fBottom;
+ }
+
+ /** Return true if this rectangle contains r.
+ If either rectangle is empty, return false.
+ */
+ bool contains(const SkRect& r) const
+ {
+ return !r.isEmpty() && !this->isEmpty() && // check for empties
+ fLeft <= r.fLeft && fTop <= r.fTop &&
+ fRight >= r.fRight && fBottom >= r.fBottom;
+ }
+
+ /** Set the dst integer rectangle by rounding this rectangle's coordinates
+ to their nearest integer values.
+ */
+ void round(SkIRect* dst) const
+ {
+ SkASSERT(dst);
+ dst->set(SkScalarRound(fLeft), SkScalarRound(fTop), SkScalarRound(fRight), SkScalarRound(fBottom));
+ }
+
+ /** Set the dst integer rectangle by rounding "out" this rectangle, choosing the floor of top and left,
+ and the ceiling of right and bototm.
+ */
+ void roundOut(SkIRect* dst) const
+ {
+ SkASSERT(dst);
+ dst->set(SkScalarFloor(fLeft), SkScalarFloor(fTop), SkScalarCeil(fRight), SkScalarCeil(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();
+};
+
+#endif
+
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
new file mode 100644
index 0000000000..adb59ddc18
--- /dev/null
+++ b/include/core/SkRefCnt.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkRefCnt_DEFINED
+#define SkRefCnt_DEFINED
+
+#include "SkThread.h"
+
+/** \class SkRefCnt
+
+ SkRefCnt is the base class for objects that may be shared by multiple
+ objects. When a new owner wants 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 SkRefCnt : SkNoncopyable {
+public:
+ /** Default construct, initializing the reference count to 1.
+ */
+ SkRefCnt() : fRefCnt(1) {}
+
+ /** Destruct, asserting that the reference count is 1.
+ */
+ virtual ~SkRefCnt() { SkASSERT(fRefCnt == 1); }
+
+ /** Return the reference count.
+ */
+ int32_t getRefCnt() const { return fRefCnt; }
+
+ /** Increment the reference count. Must be balanced by a call to unref().
+ */
+ void ref() const {
+ SkASSERT(fRefCnt > 0);
+ sk_atomic_inc(&fRefCnt);
+ }
+
+ /** Decrement the reference count. If the reference count is 1 before the
+ decrement, then call delete on the object. Note that if this is the
+ case, then the object needs to have been allocated via new, and not on
+ the stack.
+ */
+ void unref() const {
+ SkASSERT(fRefCnt > 0);
+ if (sk_atomic_dec(&fRefCnt) == 1) {
+ fRefCnt = 1; // so our destructor won't complain
+ SkDELETE(this);
+ }
+ }
+
+ /** Helper version of ref(), that first checks to see if this is not null.
+ If this is null, then do nothing.
+ */
+ void safeRef() const {
+ if (this) {
+ this->ref();
+ }
+ }
+
+ /** Helper version of unref(), that first checks to see if this is not null.
+ If this is null, then do nothing.
+ */
+ void safeUnref() const {
+ if (this) {
+ this->unref();
+ }
+ }
+
+private:
+ mutable int32_t fRefCnt;
+};
+
+/** \class SkAutoUnref
+
+ SkAutoUnref is a stack-helper class that will automatically call unref() on
+ the object it points to when the SkAutoUnref object goes out of scope.
+ If obj is null, do nothing.
+*/
+class SkAutoUnref : SkNoncopyable {
+public:
+ SkAutoUnref(SkRefCnt* obj) : fObj(obj) {}
+ ~SkAutoUnref();
+
+ SkRefCnt* get() const { return fObj; }
+
+ /** If the hosted object is null, do nothing and return false, else call
+ ref() on it and return true
+ */
+ bool ref();
+
+ /** If the hosted object is null, do nothing and return false, else call
+ unref() on it, set its reference to null, and return true
+ */
+ bool unref();
+
+ /** If the hosted object is null, do nothing and return NULL, else call
+ unref() on it, set its reference to null, and return the object
+ */
+ SkRefCnt* detach();
+
+private:
+ SkRefCnt* fObj;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** 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)
+
+#endif
+
diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h
new file mode 100644
index 0000000000..8b15a893c8
--- /dev/null
+++ b/include/core/SkRegion.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 SkRegion {
+public:
+ typedef int32_t RunType;
+ enum {
+ kRunTypeSentinel = 0x7FFFFFFF
+ };
+
+ SkRegion();
+ SkRegion(const SkRegion&);
+ explicit SkRegion(const SkIRect&);
+ ~SkRegion();
+
+ SkRegion& operator=(const SkRegion&);
+
+ friend int operator==(const SkRegion& a, const SkRegion& b);
+ friend int operator!=(const SkRegion& a, const SkRegion& b) {
+ return !(a == b);
+ }
+
+ /** Replace this region with the specified region, and return true if the
+ resulting region is non-empty.
+ */
+ 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 true if the region is non-empty, and if so, sets the specified
+ path to the boundary(s) of the region.
+ */
+ 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 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
+ };
+
+ /** 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);
+
+ /** Returns the sequence of rectangles, sorted in Y and X, that make up
+ this region.
+ */
+ class 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() { return fDone; }
+ void next();
+ const SkIRect& rect() const { return fRect; }
+
+ 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 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.
+ */
+ uint32_t flatten(void* buffer) const;
+ /** Initialized the region from the buffer, returning the number
+ of bytes actually read.
+ */
+ uint32_t unflatten(const void* buffer);
+
+ 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 {
+ kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S]
+ };
+
+ friend class android::Region; // needed for marshalling efficiently
+ void allocateRuns(int count); // allocate space for count runs
+
+ struct RunHead;
+
+ SkIRect fBounds;
+ RunHead* fRunHead;
+
+ void freeRuns();
+ const RunType* getRuns(RunType tmpStorage[], int* count) const;
+ bool setRuns(RunType runs[], int count);
+
+ int count_runtype_values(int* itop, int* ibot) const;
+
+ static void BuildRectRuns(const SkIRect& bounds,
+ RunType runs[kRectRegionRuns]);
+ // returns true if runs are just a rect
+ static bool ComputeRunBounds(const RunType runs[], int count,
+ SkIRect* bounds);
+
+ friend struct RunHead;
+ friend class Iterator;
+ friend class Spanerator;
+ friend class SkRgnBuilder;
+ friend class SkFlatRegion;
+};
+
+
+#endif
+
diff --git a/include/core/SkScalar.h b/include/core/SkScalar.h
new file mode 100644
index 0000000000..86341eb996
--- /dev/null
+++ b/include/core/SkScalar.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkScalar_DEFINED
+#define SkScalar_DEFINED
+
+#include "SkFixed.h"
+
+/** \file SkScalar.h
+
+ Types and macros for the data type SkScalar. This is the fractional numeric type
+ that, depending on the compile-time flag SK_SCALAR_IS_FLOAT, may be implemented
+ either as an IEEE float, or as a 16.16 SkFixed. The macros in this file are written
+ to allow the calling code to manipulate SkScalar values without knowing which representation
+ is in effect.
+*/
+
+#ifdef SK_SCALAR_IS_FLOAT
+ #include "SkFloatingPoint.h"
+
+ /** SkScalar is our type for fractional values and coordinates. Depending on
+ compile configurations, it is either represented as an IEEE float, or
+ as a 16.16 fixed point integer.
+ */
+ typedef float SkScalar;
+ extern const uint32_t gIEEENotANumber;
+ extern const uint32_t gIEEEInfinity;
+
+ /** 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 (*(const float*)&gIEEEInfinity)
+ /** SK_ScalarMax is defined to be the largest value representable as an SkScalar
+ */
+ #define SK_ScalarMax (3.4028235e+38f)
+ /** SK_ScalarMin is defined to be the smallest value representable as an SkScalar
+ */
+ #define SK_ScalarMin (1.1754944e-38f)
+ /** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar
+ */
+ #define SK_ScalarNaN (*(const float*)(const void*)&gIEEENotANumber)
+ /** SkScalarIsNaN(n) returns true if argument is not a number
+ */
+ static inline bool SkScalarIsNaN(float x) { return x != x; }
+ /** 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)
+ #define SkFloatToScalar(n) (n)
+
+ #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)
+ /** Rounds the SkScalar to the nearest integer value
+ */
+ #define SkScalarRound(x) sk_float_round2int(x)
+ /** Returns the smallest integer that is >= the specified SkScalar
+ */
+ #define SkScalarCeil(x) sk_float_ceil2int(x)
+ /** Returns the largest integer that is <= the specified SkScalar
+ */
+ #define SkScalarFloor(x) sk_float_floor2int(x)
+ /** Returns the absolute value of the specified SkScalar
+ */
+ #define SkScalarAbs(x) sk_float_abs(x)
+ /** 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 product of a SkScalar and an int rounded to the nearest integer value
+ */
+ #define SkScalarMulRound(a, b) SkScalarRound((float)(a) * (b))
+ /** Returns the product of a SkScalar and an int promoted to the next larger int
+ */
+ #define SkScalarMulCeil(a, b) SkScalarCeil((float)(a) * (b))
+ /** Returns the product of a SkScalar and an int truncated to the next smaller int
+ */
+ #define SkScalarMulFloor(a, b) SkScalarFloor((float)(a) * (b))
+ /** 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 the average of two SkScalars (a+b)/2
+ */
+ #define SkScalarAve(a, b) (((a) + (b)) * 0.5f)
+ /** Returns the geometric mean of two SkScalars
+ */
+ #define SkScalarMean(a, b) sk_float_sqrt((float)(a) * (b))
+ /** 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))
+ 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; }
+
+#else
+ typedef SkFixed SkScalar;
+
+ #define SK_Scalar1 SK_Fixed1
+ #define SK_ScalarHalf SK_FixedHalf
+ #define SK_ScalarInfinity SK_FixedMax
+ #define SK_ScalarMax SK_FixedMax
+ #define SK_ScalarMin SK_FixedMin
+ #define SK_ScalarNaN SK_FixedNaN
+ #define SkScalarIsNaN(x) ((x) == SK_FixedNaN)
+ #define SkIntToScalar(n) SkIntToFixed(n)
+ #define SkFixedToScalar(x) (x)
+ #define SkScalarToFixed(x) (x)
+ #ifdef SK_CAN_USE_FLOAT
+ #define SkScalarToFloat(n) SkFixedToFloat(n)
+ #define SkFloatToScalar(n) SkFloatToFixed(n)
+
+ #define SkScalarToDouble(n) SkFixedToDouble(n)
+ #define SkDoubleToScalar(n) SkDoubleToFixed(n)
+ #endif
+ #define SkScalarFraction(x) SkFixedFraction(x)
+ #define SkScalarRound(x) SkFixedRound(x)
+ #define SkScalarCeil(x) SkFixedCeil(x)
+ #define SkScalarFloor(x) SkFixedFloor(x)
+ #define SkScalarAbs(x) SkFixedAbs(x)
+ #define SkScalarClampMax(x, max) SkClampMax(x, max)
+ #define SkScalarPin(x, min, max) SkPin32(x, min, max)
+ #define SkScalarSquare(x) SkFixedSquare(x)
+ #define SkScalarMul(a, b) SkFixedMul(a, b)
+ #define SkScalarMulAdd(a, b, c) SkFixedMulAdd(a, b, c)
+ #define SkScalarMulRound(a, b) SkFixedMulCommon(a, b, SK_FixedHalf)
+ #define SkScalarMulCeil(a, b) SkFixedMulCommon(a, b, SK_Fixed1 - 1)
+ #define SkScalarMulFloor(a, b) SkFixedMulCommon(a, b, 0)
+ #define SkScalarDiv(a, b) SkFixedDiv(a, b)
+ #define SkScalarMod(a, b) SkFixedMod(a, b)
+ #define SkScalarMulDiv(a, b, c) SkMulDiv(a, b, c)
+ #define SkScalarInvert(x) SkFixedInvert(x)
+ #define SkScalarFastInvert(x) SkFixedFastInvert(x)
+ #define SkScalarSqrt(x) SkFixedSqrt(x)
+ #define SkScalarAve(a, b) SkFixedAve(a, b)
+ #define SkScalarMean(a, b) SkFixedMean(a, b)
+ #define SkScalarHalf(a) ((a) >> 1)
+
+ #define SK_ScalarSqrt2 SK_FixedSqrt2
+ #define SK_ScalarPI SK_FixedPI
+ #define SK_ScalarTanPIOver8 SK_FixedTanPIOver8
+ #define SK_ScalarRoot2Over2 SK_FixedRoot2Over2
+
+ #define SkDegreesToRadians(degrees) SkFractMul(degrees, SK_FractPIOver180)
+ #define SkScalarSinCos(radians, cosPtr) SkFixedSinCos(radians, cosPtr)
+ #define SkScalarSin(radians) SkFixedSin(radians)
+ #define SkScalarCos(radians) SkFixedCos(radians)
+ #define SkScalarTan(val) SkFixedTan(val)
+ #define SkScalarASin(val) SkFixedASin(val)
+ #define SkScalarACos(val) SkFixedACos(val)
+ #define SkScalarATan2(y, x) SkFixedATan2(y,x)
+ #define SkScalarExp(x) SkFixedExp(x)
+ #define SkScalarLog(x) SkFixedLog(x)
+
+ #define SkMaxScalar(a, b) SkMax32(a, b)
+ #define SkMinScalar(a, b) SkMin32(a, b)
+#endif
+
+#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
+
+/* <= is slower than < for floats, so we use < for our tolerance test
+*/
+
+inline bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance = SK_ScalarNearlyZero)
+{
+ SkASSERT(tolerance > 0);
+ return SkScalarAbs(x) < 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]
+*/
+inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t)
+{
+ SkASSERT(t >= 0 && t <= SK_Scalar1);
+ return A + SkScalarMul(B - A, t);
+}
+
+#endif
+
diff --git a/include/core/SkScalarCompare.h b/include/core/SkScalarCompare.h
new file mode 100644
index 0000000000..fee554cd2b
--- /dev/null
+++ b/include/core/SkScalarCompare.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkScalarCompare_DEFINED
+#define SkScalarCompare_DEFINED
+
+#include "SkFloatBits.h"
+#include "SkRect.h"
+
+#ifdef SK_SCALAR_SLOW_COMPARES
+ typedef int32_t SkScalarCompareType;
+ typedef SkIRect SkRectCompareType;
+ #define SkScalarToCompareType(x) SkScalarAs2sCompliment(x)
+#else
+ typedef SkScalar SkScalarCompareType;
+ typedef SkRect SkRectCompareType;
+ #define SkScalarToCompareType(x) (x)
+#endif
+
+#endif
+
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h
new file mode 100644
index 0000000000..ec2cd0db44
--- /dev/null
+++ b/include/core/SkScalerContext.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkScalerContext_DEFINED
+#define SkScalerContext_DEFINED
+
+#include "SkMask.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+
+class SkDescriptor;
+class SkMaskFilter;
+class SkPathEffect;
+class SkRasterizer;
+
+// needs to be != to any valid SkMask::Format
+#define MASK_FORMAT_JUST_ADVANCE (0xFF)
+
+struct SkGlyph {
+ void* fImage;
+ SkPath* fPath;
+ SkFixed fAdvanceX, fAdvanceY;
+
+ uint32_t fID;
+ uint16_t fWidth, fHeight;
+ int16_t fTop, fLeft;
+
+ uint8_t fMaskFormat;
+ int8_t fRsbDelta, fLsbDelta; // used by auto-kerning
+
+ unsigned rowBytes() const {
+ unsigned rb = fWidth;
+ if (SkMask::kBW_Format == fMaskFormat) {
+ rb = (rb + 7) >> 3;
+ } else {
+ rb = SkAlign4(rb);
+ }
+ return rb;
+ }
+
+ bool isJustAdvance() const {
+ return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
+ }
+
+ bool isFullMetrics() const {
+ return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
+ }
+
+ uint16_t getGlyphID() const {
+ return ID2Code(fID);
+ }
+
+ unsigned getGlyphID(unsigned baseGlyphCount) const {
+ unsigned code = ID2Code(fID);
+ SkASSERT(code >= baseGlyphCount);
+ return code - baseGlyphCount;
+ }
+
+ unsigned getSubX() const {
+ return ID2SubX(fID);
+ }
+
+ SkFixed getSubXFixed() const {
+ return SubToFixed(ID2SubX(fID));
+ }
+
+ SkFixed getSubYFixed() const {
+ return SubToFixed(ID2SubY(fID));
+ }
+
+ size_t computeImageSize() const;
+
+ enum {
+ kSubBits = 2,
+ kSubMask = ((1 << kSubBits) - 1),
+ kSubShift = 24, // must be large enough for glyphs and unichars
+ kCodeMask = ((1 << kSubShift) - 1),
+ // relative offsets for X and Y subpixel bits
+ kSubShiftX = kSubBits,
+ kSubShiftY = 0
+ };
+
+ static unsigned ID2Code(uint32_t id) {
+ return id & kCodeMask;
+ }
+
+ static unsigned ID2SubX(uint32_t id) {
+ return id >> (kSubShift + kSubShiftX);
+ }
+
+ static unsigned ID2SubY(uint32_t id) {
+ return (id >> (kSubShift + kSubShiftY)) & kSubMask;
+ }
+
+ static unsigned FixedToSub(SkFixed n) {
+ return (n >> (16 - kSubBits)) & kSubMask;
+ }
+
+ static SkFixed SubToFixed(unsigned sub) {
+ SkASSERT(sub <= kSubMask);
+ return sub << (16 - kSubBits);
+ }
+
+ static uint32_t MakeID(unsigned code) {
+ return code;
+ }
+
+ static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) {
+ SkASSERT(code <= kCodeMask);
+ x = FixedToSub(x);
+ y = FixedToSub(y);
+ return (x << (kSubShift + kSubShiftX)) |
+ (y << (kSubShift + kSubShiftY)) |
+ code;
+ }
+
+ void toMask(SkMask* mask) const;
+};
+
+class SkScalerContext {
+public:
+ enum Hints {
+ kNo_Hints,
+ kSubpixel_Hints,
+ kNormal_Hints
+ };
+ enum Flags {
+ kFrameAndFill_Flag = 0x01,
+ kDevKernText_Flag = 0x02,
+ kGammaForBlack_Flag = 0x04, // illegal to set both Gamma flags
+ kGammaForWhite_Flag = 0x08 // illegal to set both Gamma flags
+ };
+ struct Rec {
+ uint32_t fFontID;
+ SkScalar fTextSize, fPreScaleX, fPreSkewX;
+ SkScalar fPost2x2[2][2];
+ SkScalar fFrameWidth, fMiterLimit;
+ uint8_t fHints;
+ uint8_t fMaskFormat;
+ uint8_t fStrokeJoin;
+ uint8_t fFlags;
+
+ void getMatrixFrom2x2(SkMatrix*) const;
+ void getLocalMatrix(SkMatrix*) const;
+ void getSingleMatrix(SkMatrix*) const;
+ };
+
+ SkScalerContext(const SkDescriptor* desc);
+ virtual ~SkScalerContext();
+
+ void setBaseGlyphCount(unsigned baseGlyphCount) {
+ fBaseGlyphCount = baseGlyphCount;
+ }
+
+ uint16_t charToGlyphID(SkUnichar uni);
+
+ unsigned getGlyphCount() const { return this->generateGlyphCount(); }
+ void getAdvance(SkGlyph*);
+ void getMetrics(SkGlyph*);
+ void getImage(const SkGlyph&);
+ void getPath(const SkGlyph&, SkPath*);
+ void getFontMetrics(SkPaint::FontMetrics* mX,
+ SkPaint::FontMetrics* mY);
+
+ static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
+ static SkScalerContext* Create(const SkDescriptor*);
+
+protected:
+ Rec fRec;
+ unsigned fBaseGlyphCount;
+
+ virtual unsigned generateGlyphCount() const = 0;
+ virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
+ virtual void generateAdvance(SkGlyph*) = 0;
+ virtual void generateMetrics(SkGlyph*) = 0;
+ virtual void generateImage(const SkGlyph&) = 0;
+ virtual void generatePath(const SkGlyph&, SkPath*) = 0;
+ virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
+ SkPaint::FontMetrics* mY) = 0;
+
+private:
+ SkPathEffect* fPathEffect;
+ SkMaskFilter* fMaskFilter;
+ SkRasterizer* fRasterizer;
+ SkScalar fDevFrameWidth;
+
+ void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
+ SkPath* devPath, SkMatrix* fillToDevMatrix);
+
+ mutable SkScalerContext* fAuxScalerContext;
+
+ SkScalerContext* getGlyphContext(const SkGlyph& glyph) const;
+
+ // return loaded fAuxScalerContext or NULL
+ SkScalerContext* loadAuxContext() const;
+};
+
+#define kRec_SkDescriptorTag SkSetFourByteTag('s', 'r', 'e', 'c')
+#define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e')
+#define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f')
+#define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't')
+
+#endif
+
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
new file mode 100644
index 0000000000..7c13e3d3e8
--- /dev/null
+++ b/include/core/SkShader.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkShader_DEFINED
+#define SkShader_DEFINED
+
+#include "SkBitmap.h"
+#include "SkFlattenable.h"
+#include "SkMask.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+
+class SkPath;
+
+/** \class SkShader
+
+ SkShader is the based class for objects that return horizontal spans of colors during drawing.
+ A subclass of SkShader is installed in a SkPaint calling paint.setShader(shader). After that
+ any object (other than a bitmap) that is drawn with that paint will get its color(s) from the
+ shader.
+*/
+class SkShader : public SkFlattenable {
+public:
+ SkShader();
+ virtual ~SkShader();
+
+ /** Return true if the shader has a non-identity local matrix.
+ @param localM Optional: If not null, return the shader's local matrix
+ @return true if the shader has a non-identity local matrix.
+ */
+ bool getLocalMatrix(SkMatrix* localM) const;
+ /** Set the shader's local matrix.
+ @param localM The shader's new local matrix.
+ */
+ void setLocalMatrix(const SkMatrix& localM);
+ /** Reset the shader's local matrix to identity.
+ */
+ void resetLocalMatrix();
+
+ enum TileMode {
+ kClamp_TileMode, //!< replicate the edge color if the shader draws outside of its original bounds
+ kRepeat_TileMode, //!< repeat the shader's image horizontally and vertically
+ kMirror_TileMode, //!< repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam
+
+ 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
+ };
+
+ /** Called sometimes before drawing with this shader.
+ Return the type of alpha your shader will return.
+ The default implementation returns 0. Your subclass should override if it can
+ (even sometimes) report a non-zero value, since that will enable various blitters
+ to perform faster.
+ */
+ virtual uint32_t getFlags() { return 0; }
+
+ /** Return the alpha associated with the data returned by shadeSpan16(). If
+ kHasSpan16_Flag is not set, this value is meaningless.
+ */
+ virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
+
+ /** Called once before drawing, with the current paint and
+ device matrix. Return true if your shader supports these
+ parameters, or false if not. If false is returned, nothing
+ will be drawn.
+ */
+ virtual bool setContext( const SkBitmap& device,
+ const SkPaint& paint,
+ const SkMatrix& matrix);
+
+ /** Called for each span of the object being drawn. Your subclass
+ should set the appropriate colors (with premultiplied alpha) that
+ correspond to the specified device coordinates.
+ */
+ virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
+ /** 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());
+ }
+
+ /** Helper to check the flags to know if it is legal to call shadeSpan16()
+ */
+ static bool CanCallShadeSpan16(uint32_t flags) {
+ return (flags & kHasSpan16_Flag) != 0;
+ }
+
+ /** Called before a session using the shader begins. Some shaders override
+ this to defer some of their work (like calling bitmap.lockPixels()).
+ Must be balanced by a call to endSession.
+ */
+ virtual void beginSession();
+ virtual void endSession();
+
+ /** Optional methods for shaders that can pretend to be a bitmap/texture
+ to play along with opengl. Default just returns false and ignores
+ the out parameters.
+ */
+ virtual bool asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
+ TileMode xy[2]);
+
+ //////////////////////////////////////////////////////////////////////////
+ // Factory methods for stock shaders
+
+ /** Call this to create a new shader that will draw with the specified bitmap.
+ @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);
+
+ virtual void flatten(SkFlattenableWriteBuffer& );
+protected:
+ 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&);
+
+ // These can be called by your subclass after setContext() has been called
+ uint8_t getPaintAlpha() const { return fPaintAlpha; }
+ SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
+ const SkMatrix& getTotalInverse() const { return fTotalInverse; }
+ MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
+
+ SkShader(SkFlattenableReadBuffer& );
+private:
+ SkMatrix* fLocalMatrix;
+ SkMatrix fTotalInverse;
+ uint8_t fPaintAlpha;
+ uint8_t fDeviceConfig;
+ uint8_t fTotalInverseClass;
+ SkDEBUGCODE(SkBool8 fInSession;)
+
+ static SkShader* CreateBitmapShader(const SkBitmap& src,
+ TileMode, TileMode,
+ void* storage, size_t storageSize);
+ friend class SkAutoBitmapShaderInstall;
+ typedef SkFlattenable INHERITED;
+};
+
+#endif
+
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
new file mode 100644
index 0000000000..26ef43f624
--- /dev/null
+++ b/include/core/SkStream.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkStream_DEFINED
+#define SkStream_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+
+class SkStream : public SkRefCnt {
+public:
+ virtual ~SkStream();
+ /** Called to rewind to the beginning of the stream. If this cannot be
+ done, return false.
+ */
+ virtual bool rewind() = 0;
+ /** If this stream represents a file, this method returns the file's name.
+ If it does not, it returns NULL (the default behavior).
+ */
+ virtual const char* getFileName();
+ /** Called to read or skip size number of bytes.
+ If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped.
+ If buffer is NULL and size == 0, return the total length of the stream.
+ If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied.
+ @param buffer If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer
+ @param size The number of bytes to skip or copy
+ @return bytes read on success
+ */
+ virtual size_t read(void* buffer, size_t size) = 0;
+
+ /** Return the total length of the stream.
+ */
+ size_t getLength() { return this->read(NULL, 0); }
+
+ /** Skip the specified number of bytes, returning the actual number
+ of bytes that could be skipped.
+ */
+ size_t skip(size_t bytes);
+
+ /** If the stream is backed by RAM, this method returns the starting
+ address for the data. If not (i.e. it is backed by a file or other
+ structure), this method returns NULL.
+ The default implementation returns NULL.
+ */
+ virtual const void* getMemoryBase();
+
+ 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();
+
+ static void UnitTest();
+};
+
+class SkWStream : SkNoncopyable {
+public:
+ 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();
+
+ // helpers
+
+ bool write8(U8CPU);
+ bool write16(U16CPU);
+ bool write32(uint32_t);
+
+ bool writeText(const char text[]);
+ bool writeDecAsText(int32_t);
+ 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);
+
+ static void UnitTest();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkString.h"
+
+struct SkFILE;
+
+/** A stream that reads from a FILE*, which is opened in the constructor and
+ closed in the destructor
+ */
+class SkFILEStream : public SkStream {
+public:
+ /** Initialize the stream by calling fopen on the specified path. Will be
+ closed in the destructor.
+ */
+ explicit SkFILEStream(const char path[] = NULL);
+ 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 bool rewind();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const char* getFileName();
+
+private:
+ SkFILE* fFILE;
+ SkString fName;
+};
+
+/** A stream that reads from a file descriptor
+ */
+class SkFDStream : public SkStream {
+public:
+ /** Initialize the stream with a dup() of the specified file descriptor.
+ If closeWhenDone is true, then the descriptor will be closed in the
+ destructor.
+ */
+ SkFDStream(int fileDesc, bool closeWhenDone);
+ virtual ~SkFDStream();
+
+ /** Returns true if the current path could be opened.
+ */
+ bool isValid() const { return fFD >= 0; }
+
+ virtual bool rewind();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const char* getFileName() { return NULL; }
+
+private:
+ int fFD;
+ bool fCloseWhenDone;
+};
+
+class SkMemoryStream : public SkStream {
+public:
+ 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);
+ 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);
+ void skipToAlign4();
+ virtual bool rewind();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const void* getMemoryBase();
+ const void* getAtPos();
+ size_t seek(size_t offset);
+ size_t peek() const { return fOffset; }
+
+private:
+ const void* fSrc;
+ size_t fSize, fOffset;
+ SkBool8 fWeOwnTheData;
+};
+
+/** \class SkBufferStream
+ This is a wrapper class that adds buffering to another stream.
+ The caller can provide the buffer, or ask SkBufferStream to allocated/free
+ it automatically.
+*/
+class SkBufferStream : public SkStream {
+public:
+ /** Provide the stream to be buffered (proxy), and the size of the buffer that
+ should be used. This will be allocated and freed automatically. If bufferSize is 0,
+ a default buffer size will be used.
+ The proxy stream is referenced, and will be unreferenced in when the
+ bufferstream is destroyed.
+ */
+ SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
+ /** Provide the stream to be buffered (proxy), and a buffer and size to be used.
+ This buffer is owned by the caller, and must be at least bufferSize bytes big.
+ Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
+ If buffer is not NULL, it is an error for bufferSize to be 0.
+ The proxy stream is referenced, and will be unreferenced in when the
+ bufferstream is destroyed.
+ */
+ SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
+ virtual ~SkBufferStream();
+
+ virtual bool rewind();
+ virtual const char* getFileName();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const void* getMemoryBase();
+
+private:
+ enum {
+ kDefaultBufferSize = 128
+ };
+ // illegal
+ SkBufferStream(const SkBufferStream&);
+ SkBufferStream& operator=(const SkBufferStream&);
+
+ SkStream* fProxy;
+ char* fBuffer;
+ size_t fOrigBufferSize, fBufferSize, fBufferOffset;
+ bool fWeOwnTheBuffer;
+
+ void init(void*, size_t);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkFILEWStream : public SkWStream {
+public:
+ 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);
+ virtual void flush();
+private:
+ SkFILE* fFILE;
+};
+
+class SkMemoryWStream : public SkWStream {
+public:
+ SkMemoryWStream(void* buffer, size_t size);
+ virtual bool write(const void* buffer, size_t size);
+
+private:
+ char* fBuffer;
+ size_t fMaxLength;
+ size_t fBytesWritten;
+};
+
+class SkDynamicMemoryWStream : public SkWStream {
+public:
+ SkDynamicMemoryWStream();
+ virtual ~SkDynamicMemoryWStream();
+ virtual bool write(const void* buffer, size_t size);
+ // 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() { return fBytesWritten; }
+
+ // copy what has been written to the stream into dst
+ void copyTo(void* dst) const;
+ /* return a cache of the flattened data returned by copyTo().
+ This copy is only valid until the next call to write().
+ The memory is managed by the stream class.
+ */
+ const char* getStream() const;
+
+ // same as getStream, but additionally detach the flattened datat
+ const char* detach();
+
+ // reset the stream to its original state
+ void reset();
+ void padToAlign4();
+private:
+ struct Block;
+ Block* fHead;
+ Block* fTail;
+ size_t fBytesWritten;
+ mutable char* fCopyToCache;
+};
+
+
+class SkDebugWStream : public SkWStream {
+public:
+ // overrides
+ virtual bool write(const void* buffer, size_t size);
+ virtual void newline();
+};
+
+// for now
+typedef SkFILEStream SkURLStream;
+
+#endif
+
diff --git a/include/core/SkString.h b/include/core/SkString.h
new file mode 100644
index 0000000000..743b093207
--- /dev/null
+++ b/include/core/SkString.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkString_DEFINED
+#define SkString_DEFINED
+
+#include "SkScalar.h"
+
+/* Some helper functions for C strings
+*/
+
+bool SkStrStartsWith(const char string[], const char prefix[]);
+bool SkStrEndsWith(const char string[], const char suffix[]);
+int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
+
+#define SkStrAppendS32_MaxSize 11
+char* SkStrAppendS32(char buffer[], int32_t);
+#define SkStrAppendScalar_MaxSize 11
+char* SkStrAppendScalar(char buffer[], SkScalar);
+
+/** \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 SkString {
+public:
+ SkString();
+ explicit SkString(size_t len);
+ explicit SkString(const char text[]);
+ SkString(const char text[], size_t len);
+ explicit SkString(const SkString&);
+ ~SkString();
+
+ bool isEmpty() const { return fRec->fLength == 0; }
+ size_t size() const { return (size_t) fRec->fLength; }
+ const char* c_str() const { return fRec->data(); }
+
+ bool equals(const SkString&) const;
+ bool equals(const char text[]) const;
+ bool equals(const char text[], size_t len) const;
+
+ bool startsWith(const char prefix[]) const
+ {
+ return SkStrStartsWith(fRec->data(), prefix);
+ }
+ bool endsWith(const char suffix[]) const
+ {
+ return SkStrEndsWith(fRec->data(), suffix);
+ }
+
+ friend int operator==(const SkString& a, const SkString& b)
+ {
+ return a.equals(b);
+ }
+ friend int operator!=(const SkString& a, const SkString& b)
+ {
+ return !a.equals(b);
+ }
+
+ // these methods edit the string
+
+ SkString& operator=(const SkString&);
+
+ char* writable_str();
+
+ 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 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 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 prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
+ void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
+
+ void printf(const char format[], ...);
+ void appendf(const char format[], ...);
+ void prependf(const char format[], ...);
+
+ void remove(size_t offset, size_t length);
+
+ /** Swap contents between this and other. This function is guaranteed
+ to never fail or throw.
+ */
+ void swap(SkString& other);
+
+ /** @cond UNIT_TEST */
+ SkDEBUGCODE(static void UnitTest();)
+ /** @endcond */
+
+private:
+ struct Rec {
+ public:
+ uint16_t fLength;
+ uint16_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[], U16CPU len);
+ static Rec* RefRec(Rec*);
+};
+
+class SkAutoUCS2 {
+public:
+ SkAutoUCS2(const char utf8[]);
+ ~SkAutoUCS2();
+
+ /** This returns the number of ucs2 characters
+ */
+ int count() const { return fCount; }
+ /** This returns a null terminated ucs2 string
+ */
+ const uint16_t* getUCS2() const { return fUCS2; }
+
+private:
+ int fCount;
+ uint16_t* fUCS2;
+};
+
+#endif
+
diff --git a/include/core/SkStroke.h b/include/core/SkStroke.h
new file mode 100644
index 0000000000..b593b69e8d
--- /dev/null
+++ b/include/core/SkStroke.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkStroke_DEFINED
+#define SkStroke_DEFINED
+
+#include "SkPoint.h"
+#include "SkPaint.h"
+
+struct SkRect;
+class SkPath;
+
+#define SK_DefaultStrokeWidth SK_Scalar1
+#define SK_DefaultMiterLimit SkIntToScalar(4)
+
+
+/** \class SkStroke
+ SkStroke is the utility class that constructs paths by stroking
+ geometries (lines, rects, ovals, roundrects, paths). This is
+ invoked when a geometry or text is drawn in a canvas with the
+ kStroke_Mask bit set in the paint.
+*/
+class SkStroke {
+public:
+ SkStroke();
+ SkStroke(const SkPaint&);
+ SkStroke(const SkPaint&, SkScalar width); // width overrides paint.getStrokeWidth()
+
+ SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
+ void setCap(SkPaint::Cap);
+
+ SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; }
+ void setJoin(SkPaint::Join);
+
+ void setMiterLimit(SkScalar);
+ void setWidth(SkScalar);
+
+ bool getDoFill() const { return SkToBool(fDoFill); }
+ void setDoFill(bool doFill) { fDoFill = SkToU8(doFill); }
+
+ void strokeLine(const SkPoint& start, const SkPoint& end, SkPath*) const;
+ void strokeRect(const SkRect& rect, SkPath*) const;
+ void strokeOval(const SkRect& oval, SkPath*) const;
+ void strokeRRect(const SkRect& rect, SkScalar rx, SkScalar ry, SkPath*) const;
+ void strokePath(const SkPath& path, SkPath*) const;
+
+ ////////////////////////////////////////////////////////////////
+
+private:
+ SkScalar fWidth, fMiterLimit;
+ uint8_t fCap, fJoin;
+ SkBool8 fDoFill;
+
+ friend class SkPaint;
+};
+
+#endif
+
diff --git a/include/core/SkTDArray.h b/include/core/SkTDArray.h
new file mode 100644
index 0000000000..4d2d7f7ed3
--- /dev/null
+++ b/include/core/SkTDArray.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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[], size_t 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 int 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)));
+ }
+
+ 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);
+ }
+
+ bool isEmpty() const { return fCount == 0; }
+ int count() const { return fCount; }
+ T* begin() const { return fArray; }
+ T* end() const { return fArray ? fArray + fCount : NULL; }
+ T& operator[](int index) const {
+ SkASSERT((unsigned)index < fCount);
+ return fArray[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;
+ }
+
+ void setCount(size_t count) {
+ if (count > fReserve) {
+ this->growBy(count - fCount);
+ } else {
+ fCount = count;
+ }
+ }
+
+ void setReserve(size_t reserve) {
+ if (reserve > fReserve) {
+ SkASSERT(reserve > fCount);
+ size_t count = fCount;
+ this->growBy(reserve - fCount);
+ fCount = count;
+ }
+ }
+
+ T* prepend() {
+ this->growBy(1);
+ memmove(fArray + 1, fArray, (fCount - 1) * sizeof(T));
+ return fArray;
+ }
+
+ T* append() {
+ return this->append(1, NULL);
+ }
+ T* append(size_t count, const T* src = NULL) {
+ unsigned oldCount = fCount;
+ if (count) {
+ SkASSERT(src == NULL || fArray == NULL ||
+ src + count <= fArray || fArray + oldCount <= src);
+
+ this->growBy(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(size_t index) {
+ return this->insert(index, 1, NULL);
+ }
+ T* insert(size_t index, size_t count, const T* src = NULL) {
+ SkASSERT(count);
+ SkASSERT(index <= fCount);
+ int oldCount = fCount;
+ this->growBy(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(size_t index, size_t count = 1) {
+ SkASSERT(index + count <= fCount);
+ fCount = fCount - count;
+ memmove(fArray + index, fArray + index + count, sizeof(T) * (fCount - index));
+ }
+
+ void removeShuffle(size_t index) {
+ SkASSERT(index < fCount);
+ unsigned 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 iter - stop;
+ }
+ }
+ return -1;
+ }
+
+ // 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) { if (elem) *elem = (*this)[fCount - 1]; --fCount; }
+ void pop() { --fCount; }
+
+ void deleteAll() {
+ T* iter = fArray;
+ T* stop = fArray + fCount;
+ while (iter < stop) {
+ delete (*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();
+ }
+
+#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;
+ size_t fReserve, fCount;
+
+ void growBy(size_t extra) {
+ SkASSERT(extra);
+
+ if (fCount + extra > fReserve) {
+ size_t size = fCount + extra + 4;
+ size += size >> 2;
+
+ fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T));
+#ifdef SK_DEBUG
+ fData = (ArrayT*)fArray;
+#endif
+ fReserve = size;
+ }
+ fCount += extra;
+ }
+};
+
+#endif
+
diff --git a/include/core/SkTDStack.h b/include/core/SkTDStack.h
new file mode 100644
index 0000000000..5bc10ee9cb
--- /dev/null
+++ b/include/core/SkTDStack.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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; }
+
+ 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/include/core/SkTDict.h b/include/core/SkTDict.h
new file mode 100644
index 0000000000..0b92779ce3
--- /dev/null
+++ b/include/core/SkTDict.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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
+ {
+ Pair* end = fArray.end();
+ for (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:
+ Pair* fIter;
+ 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/include/core/SkTSearch.h b/include/core/SkTSearch.h
new file mode 100644
index 0000000000..f29e6f5e77
--- /dev/null
+++ b/include/core/SkTSearch.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkTSearch_DEFINED
+#define SkTSearch_DEFINED
+
+#include "SkTypes.h"
+
+template <typename T>
+int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
+{
+ 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 (*elem < target)
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ const T* elem = (const T*)((const char*)base + hi * elemSize);
+ if (*elem != target)
+ {
+ if (*elem < target)
+ hi += 1;
+ hi = ~hi;
+ }
+ return hi;
+}
+
+template <typename T>
+int SkTSearch(const T* base, int count, const T& target, size_t elemSize,
+ int (*compare)(const T&, const T&))
+{
+ 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 ((*compare)(*elem, target) < 0)
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ const T* elem = (const T*)((const char*)base + hi * elemSize);
+ int pred = (*compare)(*elem, target);
+ if (pred != 0) {
+ if (pred < 0)
+ hi += 1;
+ hi = ~hi;
+ }
+ return hi;
+}
+
+template <typename T>
+int SkTSearch(const T** base, int count, const T* target, size_t elemSize,
+ int (*compare)(const T*, const T*))
+{
+ 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 ((*compare)(elem, target) < 0)
+ lo = mid + 1;
+ else
+ hi = mid;
+ }
+
+ const T* elem = *(const T**)((const char*)base + hi * elemSize);
+ int pred = (*compare)(elem, target);
+ if (pred != 0)
+ {
+ if (pred < 0)
+ hi += 1;
+ hi = ~hi;
+ }
+ return hi;
+}
+
+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];
+};
+
+extern "C" {
+ typedef int (*SkQSortCompareProc)(const void*, const void*);
+ void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc);
+}
+
+SkDEBUGCODE(void SkQSort_UnitTest();)
+
+#endif
+
diff --git a/include/core/SkTemplates.h b/include/core/SkTemplates.h
new file mode 100644
index 0000000000..27ebd416df
--- /dev/null
+++ b/include/core/SkTemplates.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkTemplates_DEFINED
+#define SkTemplates_DEFINED
+
+#include "SkTypes.h"
+
+/** \file SkTemplates.h
+
+ This file contains light-weight template classes for type-safe and exception-safe
+ resource management.
+*/
+
+/** \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); }
+ T* detach() { T* obj = fObj; fObj = NULL; return 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;
+};
+
+template <typename T> class SkAutoTDelete : SkNoncopyable {
+public:
+ SkAutoTDelete(T* obj) : fObj(obj) {}
+ ~SkAutoTDelete() { delete fObj; }
+
+ T* get() const { return fObj; }
+ void free() { delete fObj; fObj = NULL; }
+ T* detach() { T* obj = fObj; fObj = NULL; return obj; }
+
+private:
+ T* fObj;
+};
+
+template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
+public:
+ SkAutoTDeleteArray(T array[]) : fArray(array) {}
+ ~SkAutoTDeleteArray() { delete[] fArray; }
+
+ T* get() const { return fArray; }
+ void free() { delete[] fArray; fArray = NULL; }
+ T* detach() { T* array = fArray; fArray = NULL; return array; }
+
+private:
+ T* fArray;
+};
+
+/** Allocate an array of T elements, and free the array in the destructor
+ */
+template <typename T> class SkAutoTArray : SkNoncopyable {
+public:
+ /** Allocate count number of T elements
+ */
+ SkAutoTArray(size_t count) {
+ fArray = NULL;
+ if (count) {
+ fArray = new T[count];
+ }
+ SkDEBUGCODE(fCount = count;)
+ }
+
+ ~SkAutoTArray() {
+ delete[] 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 < fCount);
+ return fArray[index];
+ }
+
+private:
+ T* fArray;
+ SkDEBUGCODE(size_t fCount;)
+};
+
+/** Wraps SkAutoTArray, with room for up to N elements preallocated
+ */
+template <size_t N, typename T> class SkAutoSTArray : SkNoncopyable {
+public:
+ /** Allocate count number of T elements
+ */
+ SkAutoSTArray(size_t count) {
+ if (count > N) {
+ fArray = new T[count];
+ } else if (count) {
+ fArray = new (fStorage) T[count];
+ } else {
+ fArray = NULL;
+ }
+ fCount = count;
+ }
+
+ ~SkAutoSTArray() {
+ if (fCount > N) {
+ delete[] fArray;
+ } else {
+ T* start = fArray;
+ T* iter = start + fCount;
+ while (iter > start) {
+ (--iter)->~T();
+ }
+ }
+ }
+
+ /** Return the number of T elements in the array
+ */
+ size_t 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((unsigned)index < fCount);
+ return fArray[index];
+ }
+
+private:
+ size_t fCount;
+ T* fArray;
+ // since we come right after fArray, fStorage should be properly aligned
+ char fStorage[N * sizeof(T)];
+};
+
+/** Allocate a temp array on the stack/heap.
+ Does NOT call any constructors/destructors on T (i.e. T must be POD)
+*/
+template <typename T> class SkAutoTMalloc : SkNoncopyable {
+public:
+ SkAutoTMalloc(size_t count)
+ {
+ fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
+ }
+ ~SkAutoTMalloc()
+ {
+ sk_free(fPtr);
+ }
+ T* get() const { return fPtr; }
+
+private:
+ T* fPtr;
+};
+
+template <size_t N, typename T> class SkAutoSTMalloc : SkNoncopyable {
+public:
+ SkAutoSTMalloc(size_t count)
+ {
+ if (count <= N)
+ fPtr = fTStorage;
+ else
+ fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
+ }
+ ~SkAutoSTMalloc()
+ {
+ if (fPtr != fTStorage)
+ sk_free(fPtr);
+ }
+ T* get() const { return fPtr; }
+
+private:
+ T* fPtr;
+ union {
+ uint32_t fStorage32[(N*sizeof(T) + 3) >> 2];
+ T fTStorage[1]; // do NOT want to invoke T::T()
+ };
+};
+
+#endif
+
diff --git a/include/core/SkThread.h b/include/core/SkThread.h
new file mode 100644
index 0000000000..637492dc43
--- /dev/null
+++ b/include/core/SkThread.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkThread_DEFINED
+#define SkThread_DEFINED
+
+#include "SkTypes.h"
+#include "SkThread_platform.h"
+
+/****** SkThread_platform needs to define the following...
+
+int32_t sk_atomic_inc(int32_t*);
+int32_t sk_atomic_dec(int32_t*);
+
+class SkMutex {
+public:
+ SkMutex();
+ ~SkMutex();
+
+ void acquire();
+ void release();
+};
+
+****************/
+
+class SkAutoMutexAcquire : SkNoncopyable {
+public:
+ explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(&mutex)
+ {
+ SkASSERT(fMutex != NULL);
+ mutex.acquire();
+ }
+ /** If the mutex has not been release, release it now.
+ */
+ ~SkAutoMutexAcquire()
+ {
+ if (fMutex)
+ fMutex->release();
+ }
+ /** If the mutex has not been release, release it now.
+ */
+ void release()
+ {
+ if (fMutex)
+ {
+ fMutex->release();
+ fMutex = NULL;
+ }
+ }
+
+private:
+ SkMutex* fMutex;
+};
+
+#endif
diff --git a/include/core/SkThread_platform.h b/include/core/SkThread_platform.h
new file mode 100644
index 0000000000..825b737554
--- /dev/null
+++ b/include/core/SkThread_platform.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkThread_platform_DEFINED
+#define SkThread_platform_DEFINED
+
+#ifdef ANDROID
+
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+
+#define sk_atomic_inc(addr) android_atomic_inc(addr)
+#define sk_atomic_dec(addr) android_atomic_dec(addr)
+
+class SkMutex : android::Mutex {
+public:
+ // if isGlobal is true, then ignore any errors in the platform-specific
+ // destructor
+ SkMutex(bool isGlobal = true) {}
+ ~SkMutex() {}
+
+ void acquire() { this->lock(); }
+ void release() { this->unlock(); }
+};
+
+#else
+
+/** Implemented by the porting layer, this function adds 1 to the int specified
+ by the address (in a thread-safe manner), and returns the previous value.
+*/
+int32_t sk_atomic_inc(int32_t* addr);
+/** Implemented by the porting layer, this function subtracts 1 to the int
+ specified by the address (in a thread-safe manner), and returns the previous
+ value.
+*/
+int32_t sk_atomic_dec(int32_t* addr);
+
+class SkMutex {
+public:
+ // if isGlobal is true, then ignore any errors in the platform-specific
+ // destructor
+ SkMutex(bool isGlobal = true);
+ ~SkMutex();
+
+ void acquire();
+ void release();
+
+private:
+ bool fIsGlobal;
+ enum {
+ kStorageIntCount = 12
+ };
+ uint32_t fStorage[kStorageIntCount];
+};
+
+#endif
+
+#endif
diff --git a/include/core/SkTime.h b/include/core/SkTime.h
new file mode 100644
index 0000000000..9ee7110029
--- /dev/null
+++ b/include/core/SkTime.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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;
+};
+
+#endif
+
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
new file mode 100644
index 0000000000..546edcaae8
--- /dev/null
+++ b/include/core/SkTypeface.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkTypeface_DEFINED
+#define SkTypeface_DEFINED
+
+#include "SkRefCnt.h"
+
+class SkStream;
+class SkWStream;
+
+/** \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 shred between threads.
+ To enable this, Typeface inherits from the thread-safe version of SkRefCnt.
+*/
+class SkTypeface : public SkRefCnt {
+public:
+ /** 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; }
+
+ /** DEPRECATED */
+ Style getStyle() const { return this->style(); }
+
+ /** 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; }
+
+ uint32_t 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.
+ */
+ static uint32_t UniqueID(const SkTypeface* face);
+
+ /** 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* Create(const char familyName[], Style style = kNormal);
+
+ /** 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);
+
+ /** Returns true if the two typefaces reference the same underlying font,
+ even if one is null (which maps to the default font).
+ */
+ static bool Equal(const SkTypeface* facea, const SkTypeface* faceb);
+
+ /** Returns a 32bit hash value for the typeface. Takes care of mapping null
+ to the default typeface.
+ */
+ static uint32_t Hash(const SkTypeface* face);
+
+ /** 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[]);
+
+ /** 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);
+
+ // Serialization
+ void serialize(SkWStream*) const;
+ static SkTypeface* Deserialize(SkStream*);
+
+protected:
+ /** uniqueID must be unique (please!) and non-zero
+ */
+ SkTypeface(Style style, uint32_t uniqueID)
+ : fUniqueID(uniqueID), fStyle(style) {}
+
+private:
+ uint32_t fUniqueID;
+ Style fStyle;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
new file mode 100644
index 0000000000..0554c73d12
--- /dev/null
+++ b/include/core/SkTypes.h
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkTypes_DEFINED
+#define SkTypes_DEFINED
+
+#include "SkPreConfig.h"
+#include "SkUserConfig.h"
+#include "SkPostConfig.h"
+
+#ifndef SK_IGNORE_STDINT_DOT_H
+ #include <stdint.h>
+#endif
+
+#include <stdio.h>
+
+/** \file SkTypes.h
+*/
+
+/*
+ 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.
+*/
+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.
+*/
+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 call sk_throw()
+ (if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free().
+*/
+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
+*/
+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.
+*/
+extern void* sk_realloc_throw(void* buffer, size_t size);
+/** Free memory returned by sk_malloc(). It is safe to pass null.
+*/
+extern void sk_free(void*);
+
+///////////////////////////////////////////////////////////////////////
+
+#define SK_INIT_TO_AVOID_WARNING = 0
+
+#ifndef SkDebugf
+ void SkDebugf(const char format[], ...);
+#endif
+
+#ifdef SK_DEBUG
+ #define SkASSERT(cond) SK_DEBUGBREAK(cond)
+ #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 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
+
+///////////////////////////////////////////////////////////////////////
+
+/** Fast type for signed 8 bits. Use for parameter passing and local variables, not for storage
+*/
+typedef int S8CPU;
+/** Fast type for unsigned 8 bits. Use for parameter passing and local variables, not for storage
+*/
+typedef int S16CPU;
+/** Fast type for signed 16 bits. Use for parameter passing and local variables, not for storage
+*/
+typedef unsigned U8CPU;
+/** Fast type for unsigned 16 bits. Use for parameter passing and local variables, not for storage
+*/
+typedef unsigned U16CPU;
+
+/** Meant to be faster than bool (doesn't promise to be 0 or 1, just 0 or non-zero
+*/
+typedef int SkBool;
+/** Meant to be a small version of bool, for storage purposes. Will be 0 or 1
+*/
+typedef uint8_t SkBool8;
+
+#ifdef SK_DEBUG
+ int8_t SkToS8(long);
+ uint8_t SkToU8(size_t);
+ int16_t SkToS16(long);
+ uint16_t SkToU16(size_t);
+ int32_t SkToS32(long);
+ uint32_t SkToU32(size_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))
+#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 0x80000001
+#define SK_MaxU32 0xFFFFFFFF
+#define SK_MinU32 0
+#define SK_NaN32 0x80000000
+
+#ifndef SK_OFFSETOF
+ #define SK_OFFSETOF(type, field) ((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]))
+
+/** Returns x rounded up to a multiple of 2
+*/
+#define SkAlign2(x) (((x) + 1) >> 1 << 1)
+/** Returns x rounded up to a multiple of 4
+*/
+#define SkAlign4(x) (((x) + 3) >> 2 << 2)
+
+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 rest of these only build with C++
+*/
+#ifdef __cplusplus
+
+/** Faster than SkToBool for integral conditions. Returns 0 or 1
+*/
+inline int Sk32ToBool(uint32_t n)
+{
+ return (n | (0-n)) >> 31;
+}
+
+template <typename T> inline void SkTSwap(T& a, T& b)
+{
+ T c(a);
+ a = b;
+ b = c;
+}
+
+inline int32_t SkAbs32(int32_t value)
+{
+#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
+ if (value < 0)
+ value = -value;
+ return value;
+#else
+ int32_t mask = value >> 31;
+ return (value ^ mask) - mask;
+#endif
+}
+
+inline int32_t SkMax32(int32_t a, int32_t b)
+{
+ if (a < b)
+ a = b;
+ return a;
+}
+
+inline int32_t SkMin32(int32_t a, int32_t b)
+{
+ if (a > b)
+ a = b;
+ return a;
+}
+
+inline int32_t SkSign32(int32_t a)
+{
+ return (a >> 31) | ((unsigned) -a >> 31);
+}
+
+inline int32_t SkFastMin32(int32_t value, int32_t max)
+{
+#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
+ if (value > max)
+ value = max;
+ return value;
+#else
+ int diff = max - value;
+ // clear diff if it is negative (clear if value > max)
+ diff &= (diff >> 31);
+ return value + diff;
+#endif
+}
+
+/** Returns signed 32 bit value pinned between min and max, inclusively
+*/
+inline int32_t SkPin32(int32_t value, int32_t min, int32_t max)
+{
+#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
+ if (value < min)
+ value = min;
+ if (value > max)
+ value = max;
+#else
+ if (value < min)
+ value = min;
+ else if (value > max)
+ value = max;
+#endif
+ return value;
+}
+
+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);
+}
+
+inline uint32_t SkSetClearMask(uint32_t bits, bool cond, uint32_t mask)
+{
+ return cond ? bits | mask : bits & ~mask;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/** \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 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&);
+};
+
+class SkAutoMalloc : public SkAutoFree {
+public:
+ explicit SkAutoMalloc(size_t size)
+ : SkAutoFree(sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP)) {}
+
+ SkAutoMalloc(size_t size, unsigned flags)
+ : SkAutoFree(sk_malloc_flags(size, flags)) {}
+ SkAutoMalloc() {}
+
+ void* alloc(size_t size,
+ unsigned flags = (SK_MALLOC_THROW | SK_MALLOC_TEMP)) {
+ sk_free(set(sk_malloc_flags(size, flags)));
+ return get();
+ }
+};
+
+template <size_t kSize> class SkAutoSMalloc : SkNoncopyable {
+public:
+ explicit SkAutoSMalloc(size_t size)
+ {
+ if (size <= kSize)
+ fPtr = fStorage;
+ else
+ fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
+ }
+ ~SkAutoSMalloc()
+ {
+ if (fPtr != (void*)fStorage)
+ sk_free(fPtr);
+ }
+ void* get() const { return fPtr; }
+private:
+ void* fPtr;
+ uint32_t fStorage[(kSize + 3) >> 2];
+ // illegal
+ SkAutoSMalloc(const SkAutoSMalloc&);
+ SkAutoSMalloc& operator=(const SkAutoSMalloc&);
+};
+
+#endif /* C++ */
+
+#endif
+
diff --git a/include/core/SkUnPreMultiply.h b/include/core/SkUnPreMultiply.h
new file mode 100644
index 0000000000..4bdb9802e0
--- /dev/null
+++ b/include/core/SkUnPreMultiply.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+
+#ifndef SkUnPreMultiply_DEFINED
+#define SkUnPreMultiply_DEFINED
+
+#include "SkColor.h"
+
+class 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);
+
+private:
+ static const uint32_t gTable[256];
+};
+
+#endif
diff --git a/include/core/SkUnitMapper.h b/include/core/SkUnitMapper.h
new file mode 100644
index 0000000000..5d1ea35882
--- /dev/null
+++ b/include/core/SkUnitMapper.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkUnitMapper_DEFINED
+#define SkUnitMapper_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+
+#include "SkFlattenable.h"
+
+class SkUnitMapper : public SkFlattenable {
+public:
+ SkUnitMapper() {}
+
+ /** Given a value in [0..0xFFFF], return a value in the same range.
+ */
+ virtual uint16_t mapUnit16(uint16_t x) = 0;
+
+protected:
+ SkUnitMapper(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}
+};
+
+#endif
+
diff --git a/include/core/SkUserConfig.h b/include/core/SkUserConfig.h
new file mode 100644
index 0000000000..85cda1cb58
--- /dev/null
+++ b/include/core/SkUserConfig.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkUserConfig_DEFINED
+#define SkUserConfig_DEFINED
+
+// for floats
+#ifdef SK_SCALAR_IS_FIXED
+#undef SK_SCALAR_IS_FIXED
+#endif
+#define SK_SCALAR_IS_FLOAT
+
+// remove the x if you want to force us into SK_DEBUG mode
+#ifdef SK_RELEASE
+ #undef SK_RELEASE
+ #define SK_DEBUG
+#endif
+
+// remove the x if you want to force us into SK_RELEASE mode
+#ifdef SK_DEBUGx
+ #undef SK_DEBUG
+ #define SK_RELEASE
+#endif
+
+#ifdef ANDROID
+ #include <utils/misc.h>
+ #include <assert.h>
+
+ #define SK_CRASH() *(int *)(uintptr_t)0 = 0
+// #define SK_CRASH() assert(0)
+
+#if 0
+ // force fixed
+ #define SK_SCALAR_IS_FIXED
+ #undef SK_SCALAR_IS_FLOAT
+#else
+ // force floats
+ #ifdef SK_SCALAR_IS_FIXED
+ #undef SK_SCALAR_IS_FIXED
+ #endif
+ #define SK_SCALAR_IS_FLOAT
+#endif
+
+ #define SK_CAN_USE_FLOAT
+ #define SK_SOFTWARE_FLOAT
+ #define SkLONGLONG int64_t
+
+ // replace some sw float routines (floor, ceil, etc.)
+ #define SK_USE_FLOATBITS
+
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ #define SK_CPU_BENDIAN
+ #undef SK_CPU_LENDIAN
+ #else
+ #define SK_CPU_LENDIAN
+ #undef SK_CPU_BENDIAN
+ #endif
+
+ // define SkDebugf to record file/line
+ #define SkDebugf(...) Android_SkDebugf(__FILE__, __LINE__, \
+ __FUNCTION__, __VA_ARGS__)
+ void Android_SkDebugf(const char* file, int line,
+ const char* function, const char* format, ...);
+#endif
+
+/* This file is included before all other headers, except for SkPreConfig.h.
+ That file uses various heuristics to make a "best guess" at settings for
+ the following build defines.
+
+ However, in this file you can override any of those decisions by either
+ defining new symbols, or #undef symbols that were already set.
+*/
+
+// experimental for now
+#define SK_SUPPORT_MIPMAP
+
+#ifdef SK_DEBUG
+ #define SK_SUPPORT_UNITTEST
+ /* Define SK_SIMULATE_FAILED_MALLOC to have
+ * sk_malloc throw an exception. Use this to
+ * detect unhandled memory leaks. */
+ //#define SK_SIMULATE_FAILED_MALLOC
+ //#define SK_FIND_MEMORY_LEAKS
+#endif
+
+#ifdef SK_BUILD_FOR_BREW
+ #include "SkBrewUserConfig.h"
+#endif
+
+#endif
+
diff --git a/include/core/SkUtils.h b/include/core/SkUtils.h
new file mode 100644
index 0000000000..f3e33417f1
--- /dev/null
+++ b/include/core/SkUtils.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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_portable(uint16_t dst[], uint16_t value, int count);
+
+/** 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_portable(uint32_t dst[], uint32_t value, int count);
+
+#ifdef ANDROID
+ #include "cutils/memory.h"
+
+ #define sk_memset16(dst, value, count) android_memset16(dst, value, (count) << 1)
+ #define sk_memset32(dst, value, count) android_memset32(dst, value, (count) << 2)
+#endif
+
+#ifndef sk_memset16
+ #define sk_memset16(dst, value, count) sk_memset16_portable(dst, value, count)
+#endif
+
+#ifndef sk_memset32
+ #define sk_memset32(dst, value, count) sk_memset32_portable(dst, value, count)
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////
+
+#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);
+
+class SkUtils {
+public:
+#ifdef SK_DEBUG
+ static void UnitTest();
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+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;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkAutoMemoryUsageProbe {
+public:
+ /** Record memory usage in constructor, and dump the result
+ (delta and current total) in the destructor, with the optional
+ label. NOTE: label contents are not copied, just the ptr is
+ retained, so DON'T DELETE IT.
+ */
+ SkAutoMemoryUsageProbe(const char label[]);
+ ~SkAutoMemoryUsageProbe();
+private:
+ const char* fLabel;
+ size_t fBytesAllocated;
+};
+
+#endif
+
diff --git a/include/core/SkWriter32.h b/include/core/SkWriter32.h
new file mode 100644
index 0000000000..aeeb37de4b
--- /dev/null
+++ b/include/core/SkWriter32.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkWriter32_DEFINED
+#define SkWriter32_DEFINED
+
+#include "SkTypes.h"
+
+#include "SkScalar.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+
+class SkStream;
+class SkWStream;
+
+class SkWriter32 : SkNoncopyable {
+public:
+ SkWriter32(size_t minSize) {
+ fMinSize = minSize;
+ fSize = 0;
+ fHead = fTail = NULL;
+ }
+ ~SkWriter32();
+
+ bool writeBool(bool value) {
+ this->writeInt(value);
+ return value;
+ }
+
+ void writeInt(int32_t value) {
+ *(int32_t*)this->reserve(sizeof(value)) = 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 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;
+ }
+
+ // write count bytes (must be a multiple of 4)
+ void writeMul4(const void* values, size_t size) {
+ SkASSERT(SkAlign4(size) == size);
+ // if we could query how much is avail in the current block, we might
+ // copy that much, and then alloc the rest. That would reduce the waste
+ // in the current block
+ memcpy(this->reserve(size), values, size);
+ }
+
+ void writePad(const void* src, size_t size);
+
+ // return the current offset (will always be a multiple of 4)
+ uint32_t size() const { return fSize; }
+ void reset();
+ uint32_t* reserve(size_t size); // size MUST be multiple of 4
+
+ // return the address of the 4byte int at the specified offset (which must
+ // be a multiple of 4. This does not allocate any new space, so the returned
+ // address is only valid for 1 int.
+ uint32_t* peek32(size_t offset);
+
+ // copy into a single buffer (allocated by caller). Must be at least size()
+ void flatten(void* dst) const;
+
+ // read from the stream, and write up to length bytes. Return the actual
+ // number of bytes written.
+ size_t readFromStream(SkStream*, size_t length);
+
+ bool writeToStream(SkWStream*);
+
+private:
+ size_t fMinSize;
+ uint32_t fSize;
+
+ struct Block;
+ Block* fHead;
+ Block* fTail;
+
+ Block* newBlock(size_t bytes);
+};
+
+#endif
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
new file mode 100644
index 0000000000..f7e6510f83
--- /dev/null
+++ b/include/core/SkXfermode.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkXfermode_DEFINED
+#define SkXfermode_DEFINED
+
+#include "SkFlattenable.h"
+#include "SkColor.h"
+
+/** \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.
+*/
+class SkXfermode : public SkFlattenable {
+public:
+ SkXfermode() {}
+
+ virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+
+ enum Coeff {
+ kZero_Coeff,
+ kOne_Coeff,
+ kSC_Coeff,
+ kISC_Coeff,
+ kDC_Coeff,
+ kIDC_Coeff,
+ kSA_Coeff,
+ kISA_Coeff,
+ kDA_Coeff,
+ kIDA_Coeff,
+
+ kCoeffCount
+ };
+ virtual bool asCoeff(Coeff* src, Coeff* dst);
+
+protected:
+ SkXfermode(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}
+
+ /** 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);
+
+private:
+ typedef SkFlattenable INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/** \class SkProcXfermode
+
+ SkProcXfermode is a xfermode that applies the specified proc to its colors.
+ This class is not exported to java.
+*/
+class SkProcXfermode : public SkXfermode {
+public:
+ SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {}
+
+ // overrides from SkXfermode
+ virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+
+ // overrides from SkFlattenable
+ virtual Factory getFactory() { return CreateProc; }
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkProcXfermode(SkFlattenableReadBuffer&);
+
+private:
+ SkXfermodeProc fProc;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkProcXfermode, (buffer)); }
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif
+
diff --git a/include/effects/Sk1DPathEffect.h b/include/effects/Sk1DPathEffect.h
new file mode 100644
index 0000000000..db01055735
--- /dev/null
+++ b/include/effects/Sk1DPathEffect.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef Sk1DPathEffect_DEFINED
+#define Sk1DPathEffect_DEFINED
+
+#include "SkPathEffect.h"
+#include "SkPath.h"
+
+class SkPathMeasure;
+
+// This class is not exported to java.
+class Sk1DPathEffect : public SkPathEffect {
+public:
+ // override from SkPathEffect
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+protected:
+ /** Called at the start of each contour, returns the initial offset
+ into that contour.
+ */
+ virtual SkScalar begin(SkScalar contourLength) = 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 distance, SkPathMeasure&) = 0;
+
+private:
+ typedef SkPathEffect INHERITED;
+};
+
+class 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)
+ */
+ SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
+
+ // override from SkPathEffect
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+protected:
+ SkPath1DPathEffect(SkFlattenableReadBuffer& buffer);
+
+ // overrides from Sk1DPathEffect
+ virtual SkScalar begin(SkScalar contourLength);
+ virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&);
+ // overrides from SkFlattenable
+ virtual void flatten(SkFlattenableWriteBuffer& );
+ virtual Factory getFactory() { return CreateProc; }
+
+private:
+ SkPath fPath; // copied from constructor
+ SkScalar fAdvance; // copied from constructor
+ SkScalar fInitialOffset; // computed from phase
+ Style fStyle; // copied from constructor
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkPath1DPathEffect, (buffer));
+ }
+
+ typedef Sk1DPathEffect INHERITED;
+};
+
+
+#endif
diff --git a/include/effects/Sk2DPathEffect.h b/include/effects/Sk2DPathEffect.h
new file mode 100644
index 0000000000..6e54d0aa19
--- /dev/null
+++ b/include/effects/Sk2DPathEffect.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef Sk2DPathEffect_DEFINED
+#define Sk2DPathEffect_DEFINED
+
+#include "SkPathEffect.h"
+#include "SkMatrix.h"
+
+// This class is not exported to java.
+class Sk2DPathEffect : public SkPathEffect {
+public:
+ Sk2DPathEffect(const SkMatrix& mat);
+
+ // overrides
+ // This method is not exported to java.
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+ // overrides from SkFlattenable
+ // This method is not exported to java.
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+ // This method is not exported to java.
+ virtual Factory getFactory();
+
+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);
+ virtual void next(const SkPoint& loc, int u, int v, SkPath* dst);
+ virtual void end(SkPath* dst);
+
+ /** 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 SkMatrix& getMatrix() const { return fMatrix; }
+
+ // protected so that subclasses can call this during unflattening
+ Sk2DPathEffect(SkFlattenableReadBuffer&);
+
+private:
+ SkMatrix fMatrix, fInverse;
+ // illegal
+ Sk2DPathEffect(const Sk2DPathEffect&);
+ Sk2DPathEffect& operator=(const Sk2DPathEffect&);
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ friend class Sk2DPathEffectBlitter;
+ typedef SkPathEffect INHERITED;
+};
+
+#endif
diff --git a/include/effects/SkAvoidXfermode.h b/include/effects/SkAvoidXfermode.h
new file mode 100644
index 0000000000..32bc049492
--- /dev/null
+++ b/include/effects/SkAvoidXfermode.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 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 will draw the src everywhere except on top of the opColor
+ or, depending on the Mode, draw only on top of the opColor.
+ @param opColor the color to avoid (or to target depending on Mode).
+ note: the alpha in opColor is ignored
+ @param tolerance How closely we compare a pixel to the opColor.
+ 0 - only operate if exact match
+ 255 - maximum gradation (blending) based on how
+ similar the pixel is to our opColor (max tolerance)
+ @param mode If we should avoid or target the opColor
+ */
+ SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
+
+ // overrides from SkXfermode
+ virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+ virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]);
+
+ // overrides from SkFlattenable
+ virtual Factory getFactory();
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkAvoidXfermode(SkFlattenableReadBuffer&);
+
+private:
+ SkColor fOpColor;
+ uint32_t fDistMul; // x.14
+ Mode fMode;
+
+ static SkFlattenable* Create(SkFlattenableReadBuffer&);
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif
diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h
new file mode 100644
index 0000000000..028b2ebc8b
--- /dev/null
+++ b/include/effects/SkBlurDrawLooper.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkBlurDrawLooper_DEFINED
+#define SkBlurDrawLooper_DEFINED
+
+#include "SkDrawLooper.h"
+#include "SkColor.h"
+
+class SkMaskFilter;
+
+/** \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 SkBlurDrawLooper : public SkDrawLooper {
+public:
+ SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color);
+ virtual ~SkBlurDrawLooper();
+
+ // overrides from SkDrawLooper
+ virtual void init(SkCanvas*, SkPaint*);
+ virtual bool next();
+ virtual void restore();
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
+ }
+
+protected:
+ SkBlurDrawLooper(SkFlattenableReadBuffer&);
+ // overrides from SkFlattenable
+ virtual void flatten(SkFlattenableWriteBuffer& );
+ virtual Factory getFactory() { return CreateProc; }
+
+private:
+ SkCanvas* fCanvas;
+ SkPaint* fPaint;
+ SkMaskFilter* fBlur;
+ SkScalar fDx, fDy;
+ SkColor fBlurColor;
+ SkColor fSavedColor; // remember the original
+ int fSaveCount;
+
+ enum State {
+ kBeforeEdge,
+ kAfterEdge,
+ kDone
+ };
+ State fState;
+
+ typedef SkDrawLooper INHERITED;
+};
+
+#endif
diff --git a/include/effects/SkBlurMaskFilter.h b/include/effects/SkBlurMaskFilter.h
new file mode 100644
index 0000000000..b90ea5e49e
--- /dev/null
+++ b/include/effects/SkBlurMaskFilter.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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"
+
+class SkBlurMaskFilter {
+public:
+ enum BlurStyle {
+ kNormal_BlurStyle, //!< fuzzy inside and outside
+ kSolid_BlurStyle, //!< solid inside, fuzzy outside
+ kOuter_BlurStyle, //!< nothing inside, fuzzy outside
+ kInner_BlurStyle, //!< fuzzy inside, nothing outside
+
+ kBlurStyleCount
+ };
+
+ /** Create a blur maskfilter.
+ @param radius The radius to extend the blur from the original mask. Must be > 0.
+ @param style The BlurStyle to use
+ @return The new blur maskfilter
+ */
+ static SkMaskFilter* Create(SkScalar radius, BlurStyle style);
+
+ /** Create an emboss maskfilter
+ @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)
+ @param blurRadius amount to blur before applying lighting (e.g. 3)
+ @return the emboss maskfilter
+ */
+ static SkMaskFilter* CreateEmboss( const SkScalar direction[3],
+ SkScalar ambient, SkScalar specular,
+ SkScalar blurRadius);
+
+private:
+ SkBlurMaskFilter(); // can't be instantiated
+};
+
+#endif
+
diff --git a/include/effects/SkColorMatrix.h b/include/effects/SkColorMatrix.h
new file mode 100644
index 0000000000..cee5d6e2d6
--- /dev/null
+++ b/include/effects/SkColorMatrix.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkColorMatrix_DEFINED
+#define SkColorMatrix_DEFINED
+
+#include "SkScalar.h"
+
+class SkColorMatrix {
+public:
+ SkScalar fMat[20];
+
+ 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);
+
+ 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();
+};
+
+#endif
diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h
new file mode 100644
index 0000000000..f9194df6db
--- /dev/null
+++ b/include/effects/SkColorMatrixFilter.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkColorMatrixFilter_DEFINED
+#define SkColorMatrixFilter_DEFINED
+
+#include "SkColorFilter.h"
+#include "SkColorMatrix.h"
+
+class SkColorMatrixFilter : public SkColorFilter {
+public:
+ SkColorMatrixFilter();
+ explicit SkColorMatrixFilter(const SkColorMatrix&);
+ SkColorMatrixFilter(const SkScalar array[20]);
+
+ void setMatrix(const SkColorMatrix&);
+ void setArray(const SkScalar array[20]);
+
+ // overrides from SkColorFilter
+ virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]);
+ virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]);
+ virtual uint32_t getFlags();
+
+ // overrides for SkFlattenable
+ virtual void flatten(SkFlattenableWriteBuffer& buffer);
+
+ struct State {
+ int32_t fArray[20];
+ int fShift;
+ int32_t fResult[4];
+ };
+
+protected:
+ // overrides for SkFlattenable
+ virtual Factory getFactory();
+
+ SkColorMatrixFilter(SkFlattenableReadBuffer& buffer);
+
+private:
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer);
+
+ typedef void (*Proc)(State*, unsigned r, unsigned g, unsigned b,
+ unsigned a);
+
+ Proc fProc;
+ State fState;
+ uint32_t fFlags;
+
+ void setup(const SkScalar array[20]);
+
+ typedef SkColorFilter INHERITED;
+};
+
+#endif
diff --git a/include/effects/SkCornerPathEffect.h b/include/effects/SkCornerPathEffect.h
new file mode 100644
index 0000000000..a459478cd9
--- /dev/null
+++ b/include/effects/SkCornerPathEffect.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 SkCornerPathEffect : public SkPathEffect {
+public:
+ /** radius must be > 0 to have an effect. It specifies the distance from each corner
+ that should be "rounded".
+ */
+ SkCornerPathEffect(SkScalar radius);
+ virtual ~SkCornerPathEffect();
+
+ // overrides for SkPathEffect
+ // This method is not exported to java.
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+ // overrides for SkFlattenable
+ // This method is not exported to java.
+ virtual Factory getFactory();
+ // This method is not exported to java.
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkCornerPathEffect(SkFlattenableReadBuffer&);
+
+private:
+ SkScalar fRadius;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ // illegal
+ SkCornerPathEffect(const SkCornerPathEffect&);
+ SkCornerPathEffect& operator=(const SkCornerPathEffect&);
+
+ typedef SkPathEffect INHERITED;
+};
+
+#endif
+
diff --git a/include/effects/SkDashPathEffect.h b/include/effects/SkDashPathEffect.h
new file mode 100644
index 0000000000..cc414e305e
--- /dev/null
+++ b/include/effects/SkDashPathEffect.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDashPathEffect_DEFINED
+#define SkDashPathEffect_DEFINED
+
+#include "SkPathEffect.h"
+
+/** \class SkDashPathEffect
+
+ SkDashPathEffect is a subclass of SkPathEffect that implements dashing
+*/
+class SkDashPathEffect : public SkPathEffect {
+public:
+ /** The intervals array must contain an even number of entries (>=2), with the even
+ indices specifying the "on" intervals, and the odd indices specifying the "off"
+ intervals. phase is an offset into the intervals array (mod the sum of all of the
+ intervals).
+ Note: only affects framed paths
+ */
+ SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase, bool scaleToFit = false);
+ virtual ~SkDashPathEffect();
+
+ // overrides for SkPathEffect
+ // This method is not exported to java.
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+ // overrides for SkFlattenable
+ // This method is not exported to java.
+ virtual Factory getFactory();
+ // This method is not exported to java.
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkDashPathEffect(SkFlattenableReadBuffer&);
+
+private:
+ SkScalar* fIntervals;
+ int32_t fCount;
+ // computed from phase
+ SkScalar fInitialDashLength;
+ int32_t fInitialDashIndex;
+ SkScalar fIntervalLength;
+ bool fScaleToFit;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ typedef SkPathEffect INHERITED;
+};
+
+#endif
+
diff --git a/include/effects/SkDiscretePathEffect.h b/include/effects/SkDiscretePathEffect.h
new file mode 100644
index 0000000000..2950950aad
--- /dev/null
+++ b/include/effects/SkDiscretePathEffect.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDiscretePathEffect_DEFINED
+#define SkDiscretePathEffect_DEFINED
+
+#include "SkPathEffect.h"
+
+/** \class SkDiscretePathEffect
+
+ This path effect chops a path into discrete segments, and randomly displaces them.
+*/
+class 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
+ */
+ SkDiscretePathEffect(SkScalar segLength, SkScalar deviation);
+
+ // overrides for SkPathEffect
+ // This method is not exported to java.
+ virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
+
+ // overrides for SkFlattenable
+ // This method is not exported to java.
+ virtual Factory getFactory();
+ // This method is not exported to java.
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkDiscretePathEffect(SkFlattenableReadBuffer&);
+
+private:
+ SkScalar fSegLength, fPerterb;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ typedef SkPathEffect INHERITED;
+};
+
+#endif
+
diff --git a/include/effects/SkDrawExtraPathEffect.h b/include/effects/SkDrawExtraPathEffect.h
new file mode 100644
index 0000000000..65e255aab1
--- /dev/null
+++ b/include/effects/SkDrawExtraPathEffect.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SK_DRAW_EXTRA_PATH_EFFECT_H
+#define SK_DRAW_EXTRA_PATH_EFFECT_H
+class SkAnimator;
+void InitializeSkExtraPathEffects(SkAnimator* animator);
+#endif
+
diff --git a/include/effects/SkEmbossMaskFilter.h b/include/effects/SkEmbossMaskFilter.h
new file mode 100644
index 0000000000..042a2a6b66
--- /dev/null
+++ b/include/effects/SkEmbossMaskFilter.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 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
+ };
+
+ SkEmbossMaskFilter(const Light& light, SkScalar blurRadius);
+
+ // overrides from SkMaskFilter
+ // This method is not exported to java.
+ virtual SkMask::Format getFormat();
+ // This method is not exported to java.
+ virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin);
+
+ // overrides from SkFlattenable
+
+ // This method is not exported to java.
+ virtual Factory getFactory();
+ // This method is not exported to java.
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkEmbossMaskFilter(SkFlattenableReadBuffer&);
+
+private:
+ Light fLight;
+ SkScalar fBlurRadius;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ typedef SkMaskFilter INHERITED;
+};
+
+#endif
+
diff --git a/include/effects/SkGradientShader.h b/include/effects/SkGradientShader.h
new file mode 100644
index 0000000000..9a8696c5b3
--- /dev/null
+++ b/include/effects/SkGradientShader.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkGradientShader_DEFINED
+#define SkGradientShader_DEFINED
+
+#include "SkShader.h"
+
+class SkUnitMapper;
+
+/** \class SkGradientShader
+
+ SkGradientShader hosts factories for creating subclasses of SkShader that
+ render linear and radial gradients.
+*/
+class SkGradientShader {
+public:
+ /** 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
+ @param mapper May be NULL. Callback to modify the spread of the colors.
+ */
+ static SkShader* CreateLinear( const SkPoint pts[2],
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode,
+ SkUnitMapper* mapper = NULL);
+
+ /** 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
+ @param mapper May be NULL. Callback to modify the spread of the colors.
+ */
+ static SkShader* CreateRadial( const SkPoint& center, SkScalar radius,
+ const SkColor colors[], const SkScalar pos[], int count,
+ SkShader::TileMode mode,
+ SkUnitMapper* mapper = NULL);
+
+ /** Returns a shader that generates a sweep gradient given a center.
+ <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.
+ @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
+ @param mapper May be NULL. Callback to modify the spread of the colors.
+ */
+ static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
+ const SkColor colors[], const SkScalar pos[],
+ int count, SkUnitMapper* mapper = NULL);
+};
+
+#endif
+
diff --git a/include/effects/SkKernel33MaskFilter.h b/include/effects/SkKernel33MaskFilter.h
new file mode 100644
index 0000000000..84136e205c
--- /dev/null
+++ b/include/effects/SkKernel33MaskFilter.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkKernel33MaskFilter_DEFINED
+#define SkKernel33MaskFilter_DEFINED
+
+#include "SkMaskFilter.h"
+
+class SkKernel33ProcMaskFilter : public SkMaskFilter {
+public:
+ SkKernel33ProcMaskFilter(unsigned percent256 = 256)
+ : fPercent256(percent256) {}
+
+ virtual uint8_t computeValue(uint8_t* const* srcRows) = 0;
+
+ // overrides from SkMaskFilter
+ virtual SkMask::Format getFormat();
+ virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&, SkIPoint*);
+
+ // overrides from SkFlattenable
+ virtual void flatten(SkFlattenableWriteBuffer& wb);
+
+protected:
+ SkKernel33ProcMaskFilter(SkFlattenableReadBuffer& rb);
+
+private:
+ int fPercent256;
+
+ typedef SkMaskFilter INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkKernel33MaskFilter : public SkKernel33ProcMaskFilter {
+public:
+ SkKernel33MaskFilter(const int coeff[3][3], int shift, int percent256 = 256)
+ : SkKernel33ProcMaskFilter(percent256)
+ {
+ memcpy(fKernel, coeff, 9 * sizeof(int));
+ fShift = shift;
+ }
+
+ // override from SkKernel33ProcMaskFilter
+ virtual uint8_t computeValue(uint8_t* const* srcRows);
+
+ // overrides from SkFlattenable
+ virtual void flatten(SkFlattenableWriteBuffer& wb);
+ virtual Factory getFactory();
+
+private:
+ int fKernel[3][3];
+ int fShift;
+
+ SkKernel33MaskFilter(SkFlattenableReadBuffer& rb);
+ static SkFlattenable* Create(SkFlattenableReadBuffer& rb);
+
+ typedef SkKernel33ProcMaskFilter INHERITED;
+};
+
+#endif
diff --git a/include/effects/SkLayerDrawLooper.h b/include/effects/SkLayerDrawLooper.h
new file mode 100644
index 0000000000..670ac23d87
--- /dev/null
+++ b/include/effects/SkLayerDrawLooper.h
@@ -0,0 +1,70 @@
+#ifndef SkLayerDrawLooper_DEFINED
+#define SkLayerDrawLooper_DEFINED
+
+#include "SkDrawLooper.h"
+
+struct SkPoint;
+
+class SkLayerDrawLooper : public SkDrawLooper {
+public:
+ SkLayerDrawLooper();
+ virtual ~SkLayerDrawLooper();
+
+ /** Call for each layer you want to add (from top to bottom).
+ This returns a paint you can modify, but that ptr is only valid until
+ the next call made to this object.
+ */
+ SkPaint* addLayer(SkScalar dx, SkScalar dy);
+
+ /** Helper for addLayer() which passes (0, 0) for the offset parameters
+ */
+ SkPaint* addLayer() {
+ return this->addLayer(0, 0);
+ }
+
+ // overrides from SkDrawLooper
+ virtual void init(SkCanvas*, SkPaint*);
+ virtual bool next();
+ virtual void restore();
+
+ // must be public for Registrar :(
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
+ }
+
+protected:
+ SkLayerDrawLooper(SkFlattenableReadBuffer&);
+
+ // overrides from SkFlattenable
+ virtual void flatten(SkFlattenableWriteBuffer& );
+ virtual Factory getFactory() { return CreateProc; }
+
+private:
+ struct Rec {
+ Rec* fNext;
+ SkPaint fPaint;
+ SkPoint fOffset;
+
+ static Rec* Reverse(Rec*);
+ };
+ Rec* fRecs;
+ int fCount;
+
+ struct Iter {
+ SkPaint fSavedPaint;
+ SkPaint* fPaint;
+ SkCanvas* fCanvas;
+ Rec* fRec;
+ };
+ Iter fIter;
+
+ class MyRegistrar : public SkFlattenable::Registrar {
+ public:
+ MyRegistrar();
+ };
+
+ typedef SkDrawLooper INHERITED;
+};
+
+
+#endif
diff --git a/include/effects/SkLayerRasterizer.h b/include/effects/SkLayerRasterizer.h
new file mode 100644
index 0000000000..820f6fca66
--- /dev/null
+++ b/include/effects/SkLayerRasterizer.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkLayerRasterizer_DEFINED
+#define SkLayerRasterizer_DEFINED
+
+#include "SkRasterizer.h"
+#include "SkDeque.h"
+#include "SkScalar.h"
+
+class SkPaint;
+
+class SkLayerRasterizer : public SkRasterizer {
+public:
+ SkLayerRasterizer();
+ virtual ~SkLayerRasterizer();
+
+ 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);
+
+ // overrides from SkFlattenable
+ virtual Factory getFactory();
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkLayerRasterizer(SkFlattenableReadBuffer&);
+
+ // override from SkRasterizer
+ virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
+ const SkIRect* clipBounds,
+ SkMask* mask, SkMask::CreateMode mode);
+
+private:
+ SkDeque fLayers;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ typedef SkRasterizer INHERITED;
+};
+
+#endif
diff --git a/include/effects/SkPaintFlagsDrawFilter.h b/include/effects/SkPaintFlagsDrawFilter.h
new file mode 100644
index 0000000000..941be245aa
--- /dev/null
+++ b/include/effects/SkPaintFlagsDrawFilter.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPaintFlagsDrawFilter_DEFINED
+#define SkPaintFlagsDrawFilter_DEFINED
+
+#include "SkDrawFilter.h"
+
+class SkPaintFlagsDrawFilter : public SkDrawFilter {
+public:
+ SkPaintFlagsDrawFilter(uint32_t clearFlags, uint32_t setFlags);
+
+ // overrides
+ virtual bool filter(SkCanvas*, SkPaint*, Type);
+ virtual void restore(SkCanvas*, SkPaint*, Type);
+
+private:
+ uint32_t fPrevFlags; // local cache for filter/restore
+ uint16_t fClearFlags; // user specified
+ uint16_t fSetFlags; // user specified
+};
+
+#endif
+
diff --git a/include/effects/SkPixelXorXfermode.h b/include/effects/SkPixelXorXfermode.h
new file mode 100644
index 0000000000..369e0e5444
--- /dev/null
+++ b/include/effects/SkPixelXorXfermode.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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 SkPixelXorXfermode : public SkXfermode {
+public:
+ SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {}
+
+ // override from SkFlattenable
+ virtual Factory getFactory();
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ // override from SkXfermode
+ virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst);
+
+private:
+ SkColor fOpColor;
+
+ SkPixelXorXfermode(SkFlattenableReadBuffer& rb);
+ // our private factory
+ static SkFlattenable* Create(SkFlattenableReadBuffer&);
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif
+
diff --git a/include/effects/SkTransparentShader.h b/include/effects/SkTransparentShader.h
new file mode 100644
index 0000000000..8bc60ff81b
--- /dev/null
+++ b/include/effects/SkTransparentShader.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkTransparentShader_DEFINED
+#define SkTransparentShader_DEFINED
+
+#include "SkShader.h"
+
+class SkTransparentShader : public SkShader {
+public:
+ SkTransparentShader() {}
+ virtual uint32_t getFlags();
+ virtual bool setContext( const SkBitmap& device,
+ const SkPaint& paint,
+ const SkMatrix& matrix);
+ virtual void shadeSpan(int x, int y, SkPMColor[], int count);
+ virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
+
+ // overrides for SkFlattenable
+ virtual Factory getFactory() { return Create; }
+ virtual void flatten(SkFlattenableWriteBuffer& buffer)
+ {
+ this->INHERITED::flatten(buffer);
+ }
+
+private:
+ // these are a cache from the call to setContext()
+ const SkBitmap* fDevice;
+ uint8_t fAlpha;
+
+ SkTransparentShader(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
+
+ static SkFlattenable* Create(SkFlattenableReadBuffer& buffer)
+ {
+ return SkNEW_ARGS(SkTransparentShader, (buffer));
+ }
+
+ typedef SkShader INHERITED;
+};
+
+#endif
+
diff --git a/include/images/SkFlipPixelRef.h b/include/images/SkFlipPixelRef.h
new file mode 100644
index 0000000000..3b4e97a8ef
--- /dev/null
+++ b/include/images/SkFlipPixelRef.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkFlipPixelRef_DEFINED
+#define SkFlipPixelRef_DEFINED
+
+#include "SkBitmap.h"
+#include "SkPageFlipper.h"
+#include "SkPixelRef.h"
+#include "SkThread.h"
+
+class SkRegion;
+
+class SkFlipPixelRef : public SkPixelRef {
+public:
+ SkFlipPixelRef(SkBitmap::Config, int width, int height);
+ virtual ~SkFlipPixelRef();
+
+ bool isDirty() const { return fFlipper.isDirty(); }
+ const SkRegion& dirtyRgn() const { return fFlipper.dirtyRgn(); }
+
+ void inval() { fFlipper.inval(); }
+ void inval(const SkIRect& rect) { fFlipper.inval(rect); }
+ void inval(const SkRegion& rgn) { fFlipper.inval(rgn); }
+ void inval(const SkRect& r, bool doAA) { fFlipper.inval(r, doAA); }
+
+ const SkRegion& beginUpdate(SkBitmap* device);
+ void endUpdate();
+
+private:
+ void getFrontBack(const void** front, void** back) const {
+ if (front) {
+ *front = fPage0;
+ }
+ if (back) {
+ *back = fPage1;
+ }
+ }
+
+ void swapPages();
+
+ // Helper to copy pixels from srcAddr to the dst bitmap, clipped to clip.
+ // srcAddr points to memory with the same config as dst.
+ static void CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip,
+ const void* srcAddr);
+
+ // serialization
+
+public:
+ virtual Factory getFactory() const { return Create; }
+ virtual void flatten(SkFlattenableWriteBuffer&) const;
+ static SkPixelRef* Create(SkFlattenableReadBuffer& buffer);
+
+protected:
+ virtual void* onLockPixels(SkColorTable**);
+ virtual void onUnlockPixels();
+
+ SkFlipPixelRef(SkFlattenableReadBuffer&);
+
+private:
+ SkMutex fMutex;
+ SkPageFlipper fFlipper;
+
+ void* fStorage;
+ void* fPage0; // points into fStorage;
+ void* fPage1; // points into fStorage;
+ size_t fSize; // size of 1 page. fStorage holds 2 pages
+ SkBitmap::Config fConfig;
+
+ typedef SkPixelRef INHERITED;
+};
+
+class SkAutoFlipUpdate : SkNoncopyable {
+public:
+ SkAutoFlipUpdate(SkFlipPixelRef* ref) : fRef(ref) {
+ fDirty = &ref->beginUpdate(&fBitmap);
+ }
+ ~SkAutoFlipUpdate() {
+ if (fRef) {
+ fRef->endUpdate();
+ }
+ }
+
+ const SkBitmap& bitmap() const { return fBitmap; }
+ const SkRegion& dirty() const { return *fDirty; }
+
+ // optional. This gets automatically called in the destructor (only once)
+ void endUpdate() {
+ if (fRef) {
+ fRef->endUpdate();
+ fRef = NULL;
+ }
+ }
+
+private:
+ SkFlipPixelRef* fRef;
+ SkBitmap fBitmap;
+ const SkRegion* fDirty;
+};
+
+#endif
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h
new file mode 100644
index 0000000000..4a18cab594
--- /dev/null
+++ b/include/images/SkImageDecoder.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkImageDecoder_DEFINED
+#define SkImageDecoder_DEFINED
+
+#include "SkBitmap.h"
+#include "SkRefCnt.h"
+
+class SkStream;
+
+/** \class SkImageDecoder
+
+ Base class for decoding compressed images into a SkBitmap
+*/
+class SkImageDecoder {
+public:
+ virtual ~SkImageDecoder();
+
+ enum Format {
+ kUnknown_Format,
+ kBMP_Format,
+ kGIF_Format,
+ kICO_Format,
+ kJPEG_Format,
+ kPNG_Format,
+ kWBMP_Format,
+
+ kLastKnownFormat = kWBMP_Format
+ };
+
+ /** Return the compressed data's format (see Format enum)
+ */
+ virtual Format getFormat() const;
+
+ /** 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; }
+
+ /** \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:
+ /** 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;
+ };
+
+ Peeker* getPeeker() const { return fPeeker; }
+ Peeker* setPeeker(Peeker*);
+
+ /** \class Peeker
+
+ Base class for optional callbacks to retrieve meta/chunk data out of
+ an image as it is being decoded.
+ */
+ class Chooser : public SkRefCnt {
+ public:
+ 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;
+ };
+
+ Chooser* getChooser() const { return fChooser; }
+ Chooser* setChooser(Chooser*);
+
+ 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 width/height/config need be set. If kDecodePixels_Mode
+ is passed, then the bitmap must have pixels or a pixelRef.
+ */
+ enum Mode {
+ kDecodeBounds_Mode, //!< only return width/height/config 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.setConfig(),
+ 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.
+
+ note: document use of Allocator, Peeker and Chooser
+ */
+ bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
+
+ /** Given a stream, this will try to find an appropriate decoder object.
+ If none is found, the method returns NULL.
+ */
+ static SkImageDecoder* Factory(SkStream*);
+
+ /** Decode the image stored in the specified file, and store the result
+ in bitmap. Return true for success or false on failure.
+
+ If pref is kNo_Config, then the decoder is free to choose the most natural
+ config given the image data. If pref something other than kNo_Config,
+ the decoder will attempt to decode the image into that format, unless
+ there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
+ config does not support that), in which case the decoder will choose a
+ closest match configuration.
+ */
+ static bool DecodeFile(const char file[], SkBitmap* bitmap,
+ SkBitmap::Config prefConfig, Mode);
+ static bool DecodeFile(const char file[], SkBitmap* bitmap)
+ {
+ return DecodeFile(file, bitmap, SkBitmap::kNo_Config, kDecodePixels_Mode);
+ }
+ /** Decode the image stored in the specified memory buffer, and store the
+ result in bitmap. Return true for success or false on failure.
+
+ If pref is kNo_Config, then the decoder is free to choose the most natural
+ config given the image data. If pref something other than kNo_Config,
+ the decoder will attempt to decode the image into that format, unless
+ there is a conflict (e.g. the image has per-pixel alpha and the bitmap's
+ config does not support that), in which case the decoder will choose a
+ closest match configuration.
+ */
+ static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap,
+ SkBitmap::Config prefConfig, Mode);
+ static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap)
+ {
+ return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config,
+ kDecodePixels_Mode);
+ }
+ /** Decode the image stored in the specified SkStream, and store the result
+ in bitmap. Return true for success or false on failure.
+
+ If pref is kNo_Config, then the decoder is free to choose the most
+ natural config given the image data. If pref something other than
+ kNo_Config, the decoder will attempt to decode the image into that
+ format, unless there is a conflict (e.g. the image has per-pixel alpha
+ and the bitmap's config does not support that), in which case the
+ decoder will choose a closest match configuration.
+ */
+ static bool DecodeStream(SkStream* stream, SkBitmap* bitmap,
+ SkBitmap::Config prefConfig, Mode);
+ static bool DecodeStream(SkStream* stream, SkBitmap* bitmap)
+ {
+ return DecodeStream(stream, bitmap, SkBitmap::kNo_Config,
+ kDecodePixels_Mode);
+ }
+
+ /* Given a format, return true if there is a currently installed decoder
+ for that format. Since a given build may not include all codecs (to save
+ code-size), this may return false.
+ */
+ static bool SupportsFormat(Format);
+
+ /** Return the default config for the running device.
+ Currently this used as a suggestion to image decoders that need to guess
+ what config they should decode into.
+ Default is kNo_Config, but this can be changed with SetDeviceConfig()
+ */
+ static SkBitmap::Config GetDeviceConfig();
+ /** Set the default config for the running device.
+ Currently this used as a suggestion to image decoders that need to guess
+ what config they should decode into.
+ Default is kNo_Config.
+ This can be queried with GetDeviceConfig()
+ */
+ static void SetDeviceConfig(SkBitmap::Config);
+
+ /** @cond UNIT_TEST */
+ SkDEBUGCODE(static void UnitTest();)
+ /** @endcond */
+
+protected:
+ // must be overridden in subclasses. This guy is called by decode(...)
+ virtual bool onDecode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref,
+ Mode) = 0;
+
+ /** 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();
+
+ // helper function for decoders to handle the (common) case where there is only
+ // once choice available in the image file.
+ bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const;
+
+ /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's
+ width/height/rowbytes/config. Returns true on success. This method handles checking
+ for an optional Allocator.
+ */
+ bool allocPixelRef(SkBitmap*, SkColorTable*) const;
+
+private:
+ Peeker* fPeeker;
+ Chooser* fChooser;
+ SkBitmap::Allocator* fAllocator;
+ int fSampleSize;
+ bool fDitherImage;
+ mutable bool fShouldCancelDecode;
+
+ // illegal
+ SkImageDecoder(const SkImageDecoder&);
+ SkImageDecoder& operator=(const SkImageDecoder&);
+};
+
+#ifdef SK_SUPPORT_IMAGE_ENCODE
+
+class SkWStream;
+
+class SkImageEncoder {
+public:
+ enum Type {
+ kJPEG_Type,
+ kPNG_Type
+ };
+ static SkImageEncoder* Create(Type);
+
+ virtual ~SkImageEncoder();
+
+ /* Quality ranges from 0..100 */
+
+ bool encodeFile(const char file[], const SkBitmap&, int quality = 80);
+ bool encodeStream(SkWStream*, const SkBitmap&, int quality = 80);
+
+ static bool EncodeFile(const char file[], const SkBitmap&, Type,
+ int quality = 80);
+ static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
+ int quality = 80);
+
+protected:
+ virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0;
+};
+
+#endif /* SK_SUPPORT_IMAGE_ENCODE */
+
+///////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/include/images/SkImageRef.h b/include/images/SkImageRef.h
new file mode 100644
index 0000000000..e94b7d4e99
--- /dev/null
+++ b/include/images/SkImageRef.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkImageRef_DEFINED
+#define SkImageRef_DEFINED
+
+#include "SkPixelRef.h"
+#include "SkBitmap.h"
+#include "SkImageDecoder.h"
+#include "SkString.h"
+
+class SkImageRefPool;
+class SkStream;
+
+// define this to enable dumping whenever we add/remove/purge an imageref
+//#define DUMP_IMAGEREF_LIFECYCLE
+
+class SkImageRef : public SkPixelRef {
+public:
+ /** Create a new imageref from a stream. NOTE: the stream is not copied, but
+ since it may be accessed from another thread, the caller must ensure
+ that this imageref is the only owner of the stream. i.e. - sole
+ ownership of the stream object is transferred to this imageref object.
+
+ @param stream The stream containing the encoded image data. Ownership
+ of this stream is transferred to the imageref, and
+ therefore the stream's ownercount must be 1.
+ @param config The preferred config of the decoded bitmap.
+ @param sampleSize Requested sampleSize for decoding. Defaults to 1.
+ */
+ SkImageRef(SkStream*, SkBitmap::Config config, int sampleSize = 1);
+ virtual ~SkImageRef();
+
+ /** Return true if the image can be decoded. If so, and bitmap is non-null,
+ call its setConfig() with the corresponding values, but explicitly will
+ not set its pixels or colortable. Use SkPixelRef::lockPixels() for that.
+
+ If there has been an error decoding the bitmap, this will return false
+ and ignore the bitmap parameter.
+ */
+ bool getInfo(SkBitmap* bm);
+
+ // overrides
+ virtual void flatten(SkFlattenableWriteBuffer&) const;
+
+protected:
+ /** Override if you want to install a custom allocator.
+ When this is called we will have already acquired the mutex!
+ */
+ virtual bool onDecode(SkImageDecoder* codec, SkStream*, SkBitmap*,
+ SkBitmap::Config, SkImageDecoder::Mode);
+
+ /* Overrides from SkPixelRef
+ When these are called, we will have already acquired the mutex!
+ */
+
+ virtual void* onLockPixels(SkColorTable**);
+ // override this in your subclass to clean up when we're unlocking pixels
+ virtual void onUnlockPixels();
+
+ SkImageRef(SkFlattenableReadBuffer&);
+
+ SkBitmap fBitmap;
+
+private:
+ SkStream* setStream(SkStream*);
+ // called with mutex already held. returns true if the bitmap is in the
+ // requested state (or further, i.e. has pixels)
+ bool prepareBitmap(SkImageDecoder::Mode);
+
+ SkStream* fStream;
+ SkBitmap::Config fConfig;
+ int fSampleSize;
+ bool fErrorInDecoding;
+
+ friend class SkImageRefPool;
+
+ SkImageRef* fPrev, *fNext;
+ size_t ramUsed() const;
+
+ typedef SkPixelRef INHERITED;
+};
+
+#endif
diff --git a/include/images/SkImageRef_GlobalPool.h b/include/images/SkImageRef_GlobalPool.h
new file mode 100644
index 0000000000..a9d4dcec38
--- /dev/null
+++ b/include/images/SkImageRef_GlobalPool.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkImageRef_GlobalPool_DEFINED
+#define SkImageRef_GlobalPool_DEFINED
+
+#include "SkImageRef.h"
+
+class SkImageRef_GlobalPool : public SkImageRef {
+public:
+ // if pool is null, use the global pool
+ SkImageRef_GlobalPool(SkStream*, SkBitmap::Config, int sampleSize = 1);
+ virtual ~SkImageRef_GlobalPool();
+
+ // overrides
+ virtual Factory getFactory() const {
+ return Create;
+ }
+ static SkPixelRef* Create(SkFlattenableReadBuffer&);
+
+ // API to control the global pool
+
+ /** Return the amount specified as the budget for the cache (in bytes).
+ */
+ static size_t GetRAMBudget();
+
+ /** Set a new budget value for the cache.
+ */
+ static void SetRAMBudget(size_t);
+
+ /** Return how much ram is currently in use by the global cache.
+ */
+ static size_t GetRAMUsed();
+
+ /** Free up (approximately) enough such that the amount used by the cache
+ is <= the specified amount. Since some images may be "in use", the
+ amount actually freed may not always result in a ram usage value <=
+ to the requested amount. In addition, because of the
+ chunky nature of the cache, the resulting usage may be < the requested
+ amount.
+ */
+ static void SetRAMUsed(size_t usageInBytes);
+
+ static void DumpPool();
+
+protected:
+ virtual bool onDecode(SkImageDecoder* codec, SkStream* stream,
+ SkBitmap* bitmap, SkBitmap::Config config,
+ SkImageDecoder::Mode mode);
+
+ virtual void onUnlockPixels();
+
+ SkImageRef_GlobalPool(SkFlattenableReadBuffer&);
+
+private:
+ typedef SkImageRef INHERITED;
+};
+
+#endif
diff --git a/include/images/SkMovie.h b/include/images/SkMovie.h
new file mode 100644
index 0000000000..45962a5e6b
--- /dev/null
+++ b/include/images/SkMovie.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkMovie_DEFINED
+#define SkMovie_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkCanvas.h"
+
+class SkStream;
+
+class SkMovie : public SkRefCnt {
+public:
+ /** Try to create a movie from the stream. If the stream format is not
+ supported, return NULL.
+ */
+ static SkMovie* DecodeStream(SkStream*);
+ /** 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();
+};
+
+#endif
diff --git a/include/images/SkPageFlipper.h b/include/images/SkPageFlipper.h
new file mode 100644
index 0000000000..0d791ee9a0
--- /dev/null
+++ b/include/images/SkPageFlipper.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/ports/SkOSFile.h b/include/ports/SkOSFile.h
new file mode 100644
index 0000000000..de8090c5ec
--- /dev/null
+++ b/include/ports/SkOSFile.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+#ifndef SkOSFile_DEFINED
+#define SkOSFile_DEFINED
+
+#include "SkString.h"
+
+#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
+ #include <dirent.h>
+#endif
+
+struct SkFILE;
+
+enum SkFILE_Flags {
+ kRead_SkFILE_Flag = 0x01,
+ kWrite_SkFILE_Flag = 0x02
+};
+
+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*);
+void sk_fflush(SkFILE*);
+
+int sk_fseek( SkFILE*, size_t, int );
+size_t sk_ftell( SkFILE* );
+
+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);
+ bool next(SkString* name, bool getDir = false);
+
+ private:
+#ifdef SK_BUILD_FOR_WIN
+ HANDLE fHandle;
+ uint16_t* fPath16;
+#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
+ DIR* fDIR;
+ SkString fPath, fSuffix;
+#endif
+ };
+};
+
+class SkUTF16_Str {
+public:
+ SkUTF16_Str(const char src[]);
+ ~SkUTF16_Str()
+ {
+ sk_free(fStr);
+ }
+ const uint16_t* get() const { return fStr; }
+
+private:
+ uint16_t* fStr;
+};
+
+#endif
+
diff --git a/include/ports/SkStream_Win.h b/include/ports/SkStream_Win.h
new file mode 100644
index 0000000000..1b17450580
--- /dev/null
+++ b/include/ports/SkStream_Win.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkStream_Win_DEFINED
+#define SkStream_Win_DEFINED
+
+#ifndef SK_BUILD_FOR_WIN
+#error "only valid for windows and wince builds"
+#endif
+
+#ifndef SkStream_DEFINED
+#include "SkStream.h"
+#endif
+#include "SkString.h"
+#include "Wininet.h"
+
+/** \cond ZERO */
+class SkURLStream : public SkStream {
+public:
+ SkURLStream(const char url[] = NULL);
+ virtual ~SkURLStream();
+
+ /** Close the current URL, and open a new URL.
+ If URL is null, just close the current URL.
+ */
+ void setURL(const char url[]);
+
+ // overrides
+ virtual bool rewind();
+ virtual size_t read(void* buffer, size_t size);
+
+private:
+ SkString fURL;
+ HINTERNET fConnection;
+ HINTERNET fURLStream;
+};
+
+/** \endcond */
+#endif // SkStream_Win_DEFINED
+
diff --git a/include/svg/SkSVGAttribute.h b/include/svg/SkSVGAttribute.h
new file mode 100644
index 0000000000..810d11c68e
--- /dev/null
+++ b/include/svg/SkSVGAttribute.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/svg/SkSVGBase.h b/include/svg/SkSVGBase.h
new file mode 100644
index 0000000000..4d24aed4ab
--- /dev/null
+++ b/include/svg/SkSVGBase.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/svg/SkSVGPaintState.h b/include/svg/SkSVGPaintState.h
new file mode 100644
index 0000000000..f3f74e1753
--- /dev/null
+++ b/include/svg/SkSVGPaintState.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/svg/SkSVGParser.h b/include/svg/SkSVGParser.h
new file mode 100644
index 0000000000..86ae4c28d9
--- /dev/null
+++ b/include/svg/SkSVGParser.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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();
+ 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/include/svg/SkSVGTypes.h b/include/svg/SkSVGTypes.h
new file mode 100644
index 0000000000..38d63cec1c
--- /dev/null
+++ b/include/svg/SkSVGTypes.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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_Use
+};
+
+#endif // SkSVGTypes_DEFINED
diff --git a/include/utils/SkCamera.h b/include/utils/SkCamera.h
new file mode 100644
index 0000000000..8bbcabf478
--- /dev/null
+++ b/include/utils/SkCamera.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+// Inspired by Rob Johnson's most excellent QuickDraw GX sample code
+
+#ifndef SkCamera_DEFINED
+#define SkCamera_DEFINED
+
+#include "Sk64.h"
+#include "SkMatrix.h"
+
+class SkCanvas;
+
+#ifdef SK_SCALAR_IS_FIXED
+ typedef SkFract SkUnitScalar;
+ #define SK_UnitScalar1 SK_Fract1
+ #define SkUnitScalarMul(a, b) SkFractMul(a, b)
+ #define SkUnitScalarDiv(a, b) SkFractDiv(a, b)
+#else
+ typedef float SkUnitScalar;
+ #define SK_UnitScalar1 SK_Scalar1
+ #define SkUnitScalarMul(a, b) SkScalarMul(a, b)
+ #define SkUnitScalarDiv(a, b) SkScalarDiv(a, b)
+#endif
+
+struct SkUnit3D {
+ SkUnitScalar fX, fY, fZ;
+
+ void set(SkUnitScalar x, SkUnitScalar y, SkUnitScalar z)
+ {
+ fX = x; fY = y; fZ = z;
+ }
+ static SkUnitScalar 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);
+ }
+
+ // depreicated, 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);
+
+ 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/include/utils/SkCullPoints.h b/include/utils/SkCullPoints.h
new file mode 100644
index 0000000000..cee64e2ac2
--- /dev/null
+++ b/include/utils/SkCullPoints.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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;
+};
+
+#endif
diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h
new file mode 100644
index 0000000000..b91962793b
--- /dev/null
+++ b/include/utils/SkDumpCanvas.h
@@ -0,0 +1,139 @@
+#ifndef SkDumpCanvas_DEFINED
+#define SkDumpCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+/** 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,
+ kDrawRect_Verb,
+ kDrawPath_Verb,
+ kDrawBitmap_Verb,
+ kDrawText_Verb,
+ kDrawPicture_Verb,
+ kDrawVertices_Verb
+ };
+
+ /** Subclasses of this are installed on the DumpCanvas, and then called for
+ each drawing command.
+ */
+ class Dumper : public SkRefCnt {
+ public:
+ virtual void dump(SkDumpCanvas*, SkDumpCanvas::Verb, const char str[],
+ const SkPaint*) = 0;
+ };
+
+ Dumper* getDumper() const { return fDumper; }
+ void setDumper(Dumper*);
+
+ // overrides from SkCanvas
+
+ virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
+ virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
+ SaveFlags flags = kARGB_ClipLayer_SaveFlag);
+ virtual void restore();
+
+ virtual bool translate(SkScalar dx, SkScalar dy);
+ virtual bool scale(SkScalar sx, SkScalar sy);
+ virtual bool rotate(SkScalar degrees);
+ virtual bool skew(SkScalar sx, SkScalar sy);
+ virtual bool concat(const SkMatrix& matrix);
+ virtual void setMatrix(const SkMatrix& matrix);
+
+ virtual bool clipRect(const SkRect& rect,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+ virtual bool clipPath(const SkPath& path,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+ virtual bool clipRegion(const SkRegion& deviceRgn,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ virtual void drawPaint(const SkPaint& paint);
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint);
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint);
+ virtual void drawPath(const SkPath& path, const SkPaint& paint);
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint = NULL);
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, const SkPaint* paint = NULL);
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint = NULL);
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint = NULL);
+ virtual void drawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint);
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint);
+ virtual void drawPosTextH(const void* text, size_t byteLength,
+ const SkScalar xpos[], SkScalar constY,
+ const SkPaint& paint);
+ virtual void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint);
+ virtual void drawPicture(SkPicture& picture);
+ 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);
+
+private:
+ Dumper* fDumper;
+
+ 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*);
+
+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
diff --git a/include/utils/SkGLCanvas.h b/include/utils/SkGLCanvas.h
new file mode 100644
index 0000000000..40fc52d556
--- /dev/null
+++ b/include/utils/SkGLCanvas.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkGLCanvas_DEFINED
+#define SkGLCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+#ifdef SK_BUILD_FOR_MAC
+ #include <OpenGL/gl.h>
+#elif defined(ANDROID)
+ #include <GLES/gl.h>
+#endif
+
+class SkGLDevice;
+class SkGLClipIter;
+
+class SkGLCanvas : public SkCanvas {
+public:
+ // notice, we do NOT allow the SkCanvas(bitmap) constructor, since that
+ // does not create a SkGLDevice, which we require
+ SkGLCanvas();
+ virtual ~SkGLCanvas();
+
+ // overrides from SkCanvas
+
+ virtual bool getViewport(SkIPoint*) const;
+ virtual bool setViewport(int width, int height);
+
+ virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
+ bool isOpaque, bool isForLayer);
+
+ // settings for the global texture cache
+
+ static size_t GetTextureCacheMaxCount();
+ static void SetTextureCacheMaxCount(size_t count);
+
+ static size_t GetTextureCacheMaxSize();
+ static void SetTextureCacheMaxSize(size_t size);
+
+ /** Call glDeleteTextures for all textures (including those for text)
+ This should be called while the gl-context is still valid. Its purpose
+ is to free up gl resources. Note that if a bitmap or text is drawn after
+ this call, new caches will be created.
+ */
+ static void DeleteAllTextures();
+
+ /** Forget all textures without calling delete (including those for text).
+ This should be called if the gl-context has changed, and the texture
+ IDs that have been cached are no longer valid.
+ */
+ static void AbandonAllTextures();
+
+private:
+ SkIPoint fViewportSize;
+
+ // need to disallow this guy
+ virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap) {
+ sk_throw();
+ return NULL;
+ }
+
+ typedef SkCanvas INHERITED;
+};
+
+#endif
+
diff --git a/include/utils/SkInterpolator.h b/include/utils/SkInterpolator.h
new file mode 100644
index 0000000000..c03eb23090
--- /dev/null
+++ b/include/utils/SkInterpolator.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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;
+
+ SkDEBUGCODE(static void UnitTest();)
+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/include/utils/SkNinePatch.h b/include/utils/SkNinePatch.h
new file mode 100644
index 0000000000..a655621d49
--- /dev/null
+++ b/include/utils/SkNinePatch.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/utils/SkParse.h b/include/utils/SkParse.h
new file mode 100644
index 0000000000..57d040ce5a
--- /dev/null
+++ b/include/utils/SkParse.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkParse_DEFINED
+#define SkParse_DEFINED
+
+#include "SkColor.h"
+#include "SkMath.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/include/utils/SkParsePaint.h b/include/utils/SkParsePaint.h
new file mode 100644
index 0000000000..d23cd92040
--- /dev/null
+++ b/include/utils/SkParsePaint.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/utils/SkProxyCanvas.h b/include/utils/SkProxyCanvas.h
new file mode 100644
index 0000000000..1bc411a5d4
--- /dev/null
+++ b/include/utils/SkProxyCanvas.h
@@ -0,0 +1,90 @@
+#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 SkProxyCanvas : public SkCanvas {
+public:
+ SkProxyCanvas() : fProxy(NULL) {}
+ SkProxyCanvas(SkCanvas* proxy);
+ virtual ~SkProxyCanvas();
+
+ SkCanvas* getProxy() const { return fProxy; }
+ void setProxy(SkCanvas* proxy);
+
+ // overrides from SkCanvas
+
+ virtual bool getViewport(SkIPoint* size) const;
+ virtual bool setViewport(int x, int y);
+
+ virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap);
+
+ virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
+ virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
+ SaveFlags flags = kARGB_ClipLayer_SaveFlag);
+ virtual void restore();
+
+ virtual bool translate(SkScalar dx, SkScalar dy);
+ virtual bool scale(SkScalar sx, SkScalar sy);
+ virtual bool rotate(SkScalar degrees);
+ virtual bool skew(SkScalar sx, SkScalar sy);
+ virtual bool concat(const SkMatrix& matrix);
+ virtual void setMatrix(const SkMatrix& matrix);
+
+ virtual bool clipRect(const SkRect& rect,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+ virtual bool clipPath(const SkPath& path,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+ virtual bool clipRegion(const SkRegion& deviceRgn,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ virtual void drawPaint(const SkPaint& paint);
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint);
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint);
+ virtual void drawPath(const SkPath& path, const SkPaint& paint);
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint = NULL);
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, const SkPaint* paint = NULL);
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint = NULL);
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint = NULL);
+ virtual void drawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint);
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint);
+ virtual void drawPosTextH(const void* text, size_t byteLength,
+ const SkScalar xpos[], SkScalar constY,
+ const SkPaint& paint);
+ virtual void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint);
+ virtual void drawPicture(SkPicture& picture);
+ 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);
+
+ virtual SkBounder* setBounder(SkBounder* bounder);
+ virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
+
+ virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
+ bool isOpaque, bool isForLayer);
+
+private:
+ SkCanvas* fProxy;
+
+ typedef SkCanvas INHERITED;
+};
+
+#endif
diff --git a/include/utils/SkTextBox.h b/include/utils/SkTextBox.h
new file mode 100644
index 0000000000..2c34448977
--- /dev/null
+++ b/include/utils/SkTextBox.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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&);
+
+private:
+ SkRect fBox;
+ SkScalar fSpacingMul, fSpacingAdd;
+ uint8_t fMode, fSpacingAlign;
+};
+
+class SkTextLineBreaker {
+public:
+ static int CountLines(const char text[], size_t len, const SkPaint&, SkScalar width);
+};
+
+#endif
+
diff --git a/include/utils/SkUnitMappers.h b/include/utils/SkUnitMappers.h
new file mode 100644
index 0000000000..51708b63fc
--- /dev/null
+++ b/include/utils/SkUnitMappers.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkUnitMappers_DEFINED
+#define SkUnitMappers_DEFINED
+
+#include "SkUnitMapper.h"
+
+/** This discretizes the range [0...1) into N discret values.
+*/
+class SkDiscreteMapper : public SkUnitMapper {
+public:
+ SkDiscreteMapper(int segments);
+ // override from SkUnitMapper
+ virtual uint16_t mapUnit16(uint16_t x);
+
+protected:
+ SkDiscreteMapper(SkFlattenableReadBuffer& );
+ // overrides from SkFlattenable
+ virtual void flatten(SkFlattenableWriteBuffer& );
+ virtual Factory getFactory();
+private:
+ int fSegments;
+ SkFract fScale; // computed from fSegments
+
+ static SkFlattenable* Create(SkFlattenableReadBuffer& buffer);
+
+ typedef SkUnitMapper INHERITED;
+};
+
+/** This returns cos(x), to simulate lighting a sphere, where 0 maps to the
+ center of the sphere, and 1 maps to the edge.
+*/
+class SkCosineMapper : public SkUnitMapper {
+public:
+ SkCosineMapper() {}
+ // override from SkUnitMapper
+ virtual uint16_t mapUnit16(uint16_t x);
+
+protected:
+ SkCosineMapper(SkFlattenableReadBuffer&);
+ // overrides from SkFlattenable
+ virtual Factory getFactory();
+
+private:
+ static SkFlattenable* Create(SkFlattenableReadBuffer&);
+
+ typedef SkUnitMapper INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkApplication.h b/include/views/SkApplication.h
new file mode 100644
index 0000000000..4c4a4fb0d1
--- /dev/null
+++ b/include/views/SkApplication.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkApplication_DEFINED
+#define SkApplication_DEFINED
+
+class SkOSWindow;
+
+extern SkOSWindow* create_sk_window(void* hwnd);
+extern void application_init();
+extern void application_term();
+
+#endif // SkApplication_DEFINED
diff --git a/include/views/SkBGViewArtist.h b/include/views/SkBGViewArtist.h
new file mode 100644
index 0000000000..1bca42fa52
--- /dev/null
+++ b/include/views/SkBGViewArtist.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/views/SkBorderView.h b/include/views/SkBorderView.h
new file mode 100644
index 0000000000..94ccc1f0a5
--- /dev/null
+++ b/include/views/SkBorderView.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/views/SkEvent.h b/include/views/SkEvent.h
new file mode 100644
index 0000000000..2b43f34f5b
--- /dev/null
+++ b/include/views/SkEvent.h
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkEvent_DEFINED
+#define SkEvent_DEFINED
+
+#include "SkDOM.h"
+#include "SkMetaData.h"
+#include "SkString.h"
+
+//class SkOSWindow;
+
+/** Unique 32bit id used to identify an instance of SkEventSink. When events are
+ posted, they are posted to a specific sinkID. When it is time to dispatch the
+ event, the sinkID is used to find the specific SkEventSink object. If it is found,
+ its doEvent() method is called with the event.
+*/
+typedef uint32_t SkEventSinkID;
+
+/** \class SkEvent
+
+ SkEvents are used to communicate type-safe information to SkEventSinks.
+ SkEventSinks (including SkViews) each have a unique ID, which is stored
+ in an event. This ID is used to target the event once it has been "posted".
+*/
+class SkEvent {
+public:
+ /** Default construct, creating an empty event.
+ */
+ SkEvent();
+ /** Construct a new event with the specified type.
+ */
+ explicit SkEvent(const SkString& type);
+ /** Construct a new event with the specified type.
+ */
+ explicit SkEvent(const char type[]);
+ /** Construct a new event by copying the fields from the src event.
+ */
+ SkEvent(const SkEvent& src);
+ ~SkEvent();
+
+// /** Return the event's type (will never be null) */
+// const char* getType() const;
+ /** 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.
+ In XML, use the "type" attribute.
+ */
+ void setType(const SkString&);
+ /** Set the event's type to the specified string.
+ In XML, use the "type" attribute.
+ */
+ void setType(const char type[], size_t len = 0);
+
+ /** Return the event's unnamed 32bit field. Default value is 0 */
+ uint32_t getFast32() const { return f32; }
+ /** Set the event's unnamed 32bit field. In XML, use
+ the subelement <data fast32=... />
+ */
+ 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); }
+
+ /** 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); }
+
+ /** 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); }
+
+ /** Return the underlying metadata object */
+ SkMetaData& getMetaData() { return fMeta; }
+ /** Return the underlying metadata object */
+ const SkMetaData& getMetaData() const { return fMeta; }
+
+ void tron() { SkDEBUGCODE(fDebugTrace = true;) }
+ void troff() { SkDEBUGCODE(fDebugTrace = false;) }
+ bool isDebugTrace() const
+ {
+#ifdef SK_DEBUG
+ return fDebugTrace;
+#else
+ return false;
+#endif
+ }
+
+ /** 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 the specified event to the event queue, targeting the specified eventsink, with an optional
+ delay. The event must be dynamically allocated for this. It cannot be a global or on the stack.
+ After this call, ownership is transfered to the system, so the caller must not retain
+ the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
+ */
+ static bool Post(SkEvent* evt, SkEventSinkID targetID, SkMSec delay = 0);
+ /** Post the specified event to the event queue, targeting the specified eventsink, to be delivered on/after the
+ specified millisecond time. The event must be dynamically allocated for this. It cannot be a global or on the stack.
+ After this call, ownership is transfered to the system, so the caller must not retain
+ the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
+ */
+ static bool PostTime(SkEvent* evt, SkEventSinkID targetID, SkMSec time);
+
+ /** Helper method for calling SkEvent::PostTime(this, ...), where the caller specifies a delay.
+ The real "time" will be computed automatically by sampling the clock and adding its value
+ to delay.
+ */
+ bool post(SkEventSinkID sinkID, SkMSec delay = 0)
+ {
+ return SkEvent::Post(this, sinkID, delay);
+ }
+
+ void postTime(SkEventSinkID sinkID, SkMSec time)
+ {
+ SkEvent::PostTime(this, sinkID, 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();
+
+ ////////////////////////////////////////////////////
+ /** 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);
+
+#ifndef SK_USE_WXWIDGETS
+#ifdef SK_BUILD_FOR_WIN
+ static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+#elif defined(SK_BUILD_FOR_UNIXx)
+ static uint32_t HandleTimer(uint32_t, void*);
+ static bool WndProc(Display*, Window, XEvent&);
+#endif
+#else
+ // Don't know yet what this will be
+ //static bool CustomEvent();
+#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;
+ SkDEBUGCODE(bool fDebugTrace;)
+
+ // these are for our implementation of the event queue
+ SkEventSinkID fTargetID;
+ SkMSec fTime;
+ SkEvent* fNextEvent; // either in the delay or normal event queue
+ void initialize(const char* type, size_t typeLen);
+
+ static bool Enqueue(SkEvent* evt);
+ static SkMSec EnqueueTime(SkEvent* evt, SkMSec time);
+ static SkEvent* Dequeue(SkEventSinkID* targetID);
+ static bool QHasEvents();
+};
+
+#endif
+
diff --git a/include/views/SkEventSink.h b/include/views/SkEventSink.h
new file mode 100644
index 0000000000..27a67437c3
--- /dev/null
+++ b/include/views/SkEventSink.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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:
+ 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.
+ */
+ 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 searching for an eventsink object that matches the targetID.
+ If one is found, it calls the sink's doEvent method, returning
+ either kHandled_EventResult or kNotHandled_EventResult. If no matching
+ eventsink is found, kSinkNotFound_EventResult is returned.
+ */
+ static EventResult DoEvent(const SkEvent&, SkEventSinkID targetID);
+
+ /** 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;
+};
+
+#endif
+
diff --git a/include/views/SkImageView.h b/include/views/SkImageView.h
new file mode 100644
index 0000000000..157abb180e
--- /dev/null
+++ b/include/views/SkImageView.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkImageView_DEFINED
+#define SkImageView_DEFINED
+
+#include "SkView.h"
+#include "SkString.h"
+
+class SkAnimator;
+class SkBitmap;
+struct 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/include/views/SkKey.h b/include/views/SkKey.h
new file mode 100644
index 0000000000..3fd5114346
--- /dev/null
+++ b/include/views/SkKey.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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
+};
+
+#endif
+
diff --git a/include/views/SkMetaData.h b/include/views/SkMetaData.h
new file mode 100644
index 0000000000..21739fef4c
--- /dev/null
+++ b/include/views/SkMetaData.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkMetaData_DEFINED
+#define SkMetaData_DEFINED
+
+#include "SkScalar.h"
+
+class SkMetaData {
+public:
+ 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) const;
+ bool findBool(const char name[], bool* value = 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;
+ }
+
+ 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);
+ void setBool(const char name[], bool value);
+
+ 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[]);
+
+ SkDEBUGCODE(static void UnitTest();)
+
+ enum Type {
+ kS32_Type,
+ kScalar_Type,
+ kString_Type,
+ kPtr_Type,
+ kBool_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
+#ifdef SK_DEBUG
+ Type fType;
+#else
+ uint8_t fType;
+#endif
+
+#ifdef SK_DEBUG
+ const char* fName;
+ union {
+ int32_t fS32;
+ SkScalar fScalar;
+ const char* fString;
+ void* fPtr;
+ bool fBool;
+ } fData;
+#endif
+
+ const void* data() const { return (this + 1); }
+ void* data() { return (this + 1); }
+ const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
+ char* name() { return (char*)this->data() + fDataLen * fDataCount; }
+
+ static Rec* Alloc(size_t);
+ static void Free(Rec*);
+ };
+ Rec* fRec;
+
+ const Rec* find(const char name[], Type) const;
+ void* set(const char name[], const void* data, size_t len, Type, int count);
+ bool remove(const char name[], Type);
+};
+
+#endif
+
diff --git a/include/views/SkOSMenu.h b/include/views/SkOSMenu.h
new file mode 100644
index 0000000000..433a60155c
--- /dev/null
+++ b/include/views/SkOSMenu.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSMenu_DEFINED
+#define SkOSMenu_DEFINED
+
+#include "SkEvent.h"
+#include "SkTDArray.h"
+
+class SkOSMenu {
+public:
+ explicit SkOSMenu(const char title[]);
+ ~SkOSMenu();
+
+ const char* getTitle() const { return fTitle; }
+
+ void appendItem(const char title[], const char eventType[], int32_t eventData);
+
+ // called by SkOSWindow when it receives an OS menu event
+ int countItems() const;
+ const char* getItem(int index, uint32_t* cmdID) const;
+
+ SkEvent* createEvent(uint32_t os_cmd);
+
+private:
+ const char* fTitle;
+
+ struct Item {
+ const char* fTitle;
+ const char* fEventType;
+ uint32_t fEventData;
+ uint32_t fOSCmd; // internal
+ };
+ SkTDArray<Item> fItems;
+
+ // illegal
+ SkOSMenu(const SkOSMenu&);
+ SkOSMenu& operator=(const SkOSMenu&);
+};
+
+#endif
+
diff --git a/include/views/SkOSSound.h b/include/views/SkOSSound.h
new file mode 100644
index 0000000000..5d77955eda
--- /dev/null
+++ b/include/views/SkOSSound.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSSound_DEFINED
+#define SkOSSound_DEFINED
+
+#include "SkTypes.h"
+
+class SkOSSound {
+public:
+ static void Play(const char path[]);
+ static void Pause();
+ static void Resume();
+ static bool TogglePause(); // returns true if we are now playing, or false if we're now paused
+ static void Stop();
+
+ // volume runs from 0 (silent) to 0xFF (max-volume)
+ static uint8_t GetVolume();
+ static void SetVolume(U8CPU volume);
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_Mac.h b/include/views/SkOSWindow_Mac.h
new file mode 100644
index 0000000000..1f6a1fa9b2
--- /dev/null
+++ b/include/views/SkOSWindow_Mac.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_Mac_DEFINED
+#define SkOSWindow_Mac_DEFINED
+
+#include "SkWindow.h"
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void* hwnd);
+
+ void* getHWND() const { return fHWND; }
+ void updateSize();
+
+ static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+ static pascal OSStatus SkOSWindow::EventHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* userData );
+
+protected:
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+ virtual void onSetTitle(const char[]);
+
+private:
+ void* fHWND;
+
+ void doPaint(void* ctx);
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_Unix.h b/include/views/SkOSWindow_Unix.h
new file mode 100644
index 0000000000..26f51be162
--- /dev/null
+++ b/include/views/SkOSWindow_Unix.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_Unix_DEFINED
+#define SkOSWindow_Unix_DEFINED
+
+#include "SkWindow.h"
+#include <X11/Xlib.h>
+
+struct SkUnixWindow {
+ Display* fDisplay;
+ Window fWin;
+ size_t fOSWin;
+};
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(Display* display, Window win);
+
+ void* getHWND() const { return (void*)fUnixWindow.fWin; }
+ void* getDisplay() const { return (void*)fUnixWindow.fDisplay; }
+ void* getUnixWindow() const { return (void*)&fUnixWindow; }
+ void setSize(int width, int height);
+ void updateSize();
+
+ static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+ static bool WndProc(SkUnixWindow* w, XEvent &e);
+
+protected:
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+
+private:
+ SkUnixWindow fUnixWindow;
+
+ void doPaint();
+
+ void* fMBar;
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_Win.h b/include/views/SkOSWindow_Win.h
new file mode 100644
index 0000000000..6d821dbb46
--- /dev/null
+++ b/include/views/SkOSWindow_Win.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_Win_DEFINED
+#define SkOSWindow_Win_DEFINED
+
+#include "SkWindow.h"
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void* hwnd);
+
+ void* getHWND() const { return fHWND; }
+ void setSize(int width, int height);
+ void updateSize();
+
+ static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+ static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static bool SkOSWindow::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*);
+
+private:
+ void* fHWND;
+
+ void doPaint(void* ctx);
+
+ HMENU fMBar;
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_wxwidgets.h b/include/views/SkOSWindow_wxwidgets.h
new file mode 100644
index 0000000000..c5dfc7c45a
--- /dev/null
+++ b/include/views/SkOSWindow_wxwidgets.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * SkOSWindow_wxwidgets.h
+ * wxwidgets
+ *
+ * Copyright 2005 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef SkOSWindow_wxwidgets_DEFINED
+#define SkOSWindow_wxwidgets_DEFINED
+
+#include "SkWindow.h"
+#include "wx/frame.h"
+
+class SkOSWindow: public SkWindow
+{
+public:
+ SkOSWindow();
+ SkOSWindow(const wxString& title, int x, int y, int width, int height);
+ ~SkOSWindow();
+
+ wxFrame* getWXFrame() const { return fFrame; }
+
+ void updateSize();
+
+protected:
+ virtual void onHandleInval(const SkIRect&);
+ virtual void onAddMenu(const SkOSMenu*);
+
+private:
+ wxFrame* fFrame;
+ typedef SkWindow INHERITED;
+
+};
+
+#endifpedef SkWindow INHERITED;
diff --git a/include/views/SkProgressBarView.h b/include/views/SkProgressBarView.h
new file mode 100644
index 0000000000..6341fcb051
--- /dev/null
+++ b/include/views/SkProgressBarView.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/views/SkScrollBarView.h b/include/views/SkScrollBarView.h
new file mode 100644
index 0000000000..b8a5209ddb
--- /dev/null
+++ b/include/views/SkScrollBarView.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/views/SkStackViewLayout.h b/include/views/SkStackViewLayout.h
new file mode 100644
index 0000000000..8000319fcb
--- /dev/null
+++ b/include/views/SkStackViewLayout.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/views/SkSystemEventTypes.h b/include/views/SkSystemEventTypes.h
new file mode 100644
index 0000000000..8dfe8bec07
--- /dev/null
+++ b/include/views/SkSystemEventTypes.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/views/SkView.h b/include/views/SkView.h
new file mode 100644
index 0000000000..d5d89dfeed
--- /dev/null
+++ b/include/views/SkView.h
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkView_DEFINED
+#define SkView_DEFINED
+
+#include "SkEventSink.h"
+#include "SkRect.h"
+#include "SkDOM.h"
+#include "SkTDict.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,
+
+ 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
+
+ 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; }
+ /** Helper to set/clear the view's kVisible_Mask flag */
+ void setVisibleP(bool);
+ void setEnabledP(bool);
+ void setFocusableP(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;
+
+ /** 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); }
+ /** 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. */
+ 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;
+ private:
+ SkEventSinkID fTargetID;
+ char* fType;
+ bool fWeOwnTheType;
+
+ void resetType();
+
+ friend class SkView;
+ };
+ Click* findClickHandler(SkScalar x, SkScalar y);
+
+ static void DoClickDown(Click*, int x, int y);
+ static void DoClickMoved(Click*, int x, int y);
+ static void DoClickUp(Click*, int x, int y);
+
+ /** 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&);
+ /** Depricated helper function. Just call event->post(sinkID, delay);
+ */
+ bool postEvent(SkEvent* evt, SkEventSinkID sinkID, SkMSec delay) { return evt->post(sinkID, delay); }
+
+ // 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
+ */
+ void globalToLocal(SkPoint* pt) const { if (pt) this->globalToLocal(pt->fX, pt->fY, pt); }
+ /** Convert the specified x,y from global coordinates into view-local coordinates, returning
+ the answer in the local parameter.
+ */
+ void 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:
+ 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*);
+ };
+ /** 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:
+ 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*);
+ };
+
+ /** 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&);
+ virtual SkCanvas* beforeChildren(SkCanvas* c) { return c; }
+ virtual void afterChildren(SkCanvas* orig) {}
+ /** Override this if you might handle the click
+ */
+ virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
+ /** 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:
+ // 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;
+ 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();
+};
+
+#endif
+
diff --git a/include/views/SkViewInflate.h b/include/views/SkViewInflate.h
new file mode 100644
index 0000000000..3ec65a6f77
--- /dev/null
+++ b/include/views/SkViewInflate.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/views/SkWidget.h b/include/views/SkWidget.h
new file mode 100644
index 0000000000..db85f01ff4
--- /dev/null
+++ b/include/views/SkWidget.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkWidget_DEFINED
+#define SkWidget_DEFINED
+
+#include "SkView.h"
+#include "SkBitmap.h"
+#include "SkDOM.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkTDArray.h"
+
+//////////////////////////////////////////////////////////////////////////////
+
+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);
+ 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;
+};
+
+#include "SkTextBox.h"
+
+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 SkShader;
+class SkInterpolator;
+
+class SkWidgetView : public SkView {
+public:
+ SkWidgetView(uint32_t flags = 0);
+ virtual ~SkWidgetView();
+
+ static const char* GetEventType();
+};
+
+class SkSliderView : public SkWidgetView {
+public:
+ SkSliderView(uint32_t flags = 0);
+
+ 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 Click* onFindClickHandler(SkScalar x, SkScalar y);
+ virtual bool onClick(Click*);
+
+private:
+ uint16_t fValue, fMax;
+
+ typedef SkWidgetView 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 SkTextView : public SkView {
+public:
+ SkTextView(uint32_t flags = 0);
+ virtual ~SkTextView();
+
+ enum AnimaDir {
+ kNeutral_AnimDir,
+ kForward_AnimDir,
+ kBackward_AnimDir,
+ kAnimDirCount
+ };
+
+ void getText(SkString*) const;
+ void setText(const SkString&, AnimaDir dir = kNeutral_AnimDir);
+ void setText(const char text[], AnimaDir dir = kNeutral_AnimDir);
+ void setText(const char text[], size_t len, AnimaDir dir = kNeutral_AnimDir);
+
+ void getMargin(SkPoint* margin) const;
+ void setMargin(const SkPoint&);
+
+ SkPaint& paint() { return fPaint; }
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkString fText;
+ SkPaint fPaint;
+ SkPoint fMargin;
+
+ class Interp;
+ Interp* fInterp;
+ bool fDoInterp;
+ // called by the other setText methods. This guy does not check for !=
+ // before doing the assign, so the caller must check for us
+ void privSetText(const SkString&, AnimaDir dir);
+
+ typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////
+
+class SkEvent;
+
+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 SkWidgetView {
+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 SkWidgetView INHERITED;
+};
+
+//////////////////////////////////////////////////////////
+
+class SkGridView : public SkWidgetView {
+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 SkWidgetView INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkWidgetViews.h b/include/views/SkWidgetViews.h
new file mode 100644
index 0000000000..4dd88669f8
--- /dev/null
+++ b/include/views/SkWidgetViews.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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&);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+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:
+ 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[]);
+};
+
+#endif
diff --git a/include/views/SkWindow.h b/include/views/SkWindow.h
new file mode 100644
index 0000000000..96262eecf1
--- /dev/null
+++ b/include/views/SkWindow.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkWindow_DEFINED
+#define SkWindow_DEFINED
+
+#include "SkView.h"
+#include "SkBitmap.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 SkOSMenu;
+
+class SkWindow : public SkView {
+public:
+ SkWindow();
+ virtual ~SkWindow();
+
+ const SkBitmap& getBitmap() const { return fBitmap; }
+
+ void setConfig(SkBitmap::Config);
+ void resize(int width, int height, SkBitmap::Config config = SkBitmap::kNo_Config);
+ void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
+ void eraseRGB(U8CPU r, U8CPU g, U8CPU b);
+
+ bool isDirty() const { return !fDirtyRgn.isEmpty(); }
+ bool update(SkIRect* updateArea);
+ bool handleClick(int x, int y, Click::State);
+ bool handleChar(SkUnichar);
+ bool handleKey(SkKey);
+ bool handleKeyUp(SkKey);
+ bool handleMenu(uint32_t os_cmd);
+
+ void addMenu(SkOSMenu*);
+ void setTitle(const char title[]);
+
+protected:
+ virtual bool onEvent(const SkEvent&);
+
+ // 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 onSetTitle(const char title[]) {}
+
+ // overrides from SkView
+ virtual bool handleInval(const SkRect&);
+ virtual bool onGetFocusView(SkView** focus) const;
+ virtual bool onSetFocusView(SkView* focus);
+
+private:
+ SkBitmap::Config fConfig;
+ SkBitmap fBitmap;
+ SkRegion fDirtyRgn;
+ Click* fClick; // to track clicks
+
+ SkTDArray<SkOSMenu*> fMenus;
+
+ SkView* fFocusView;
+ bool fWaitingOnInval;
+
+ typedef SkView INHERITED;
+};
+
+///////////////////////////////////////////////////////////
+
+#ifndef SK_USE_WXWIDGETS
+#ifdef SK_BUILD_FOR_MAC
+ #include "SkOSWindow_Mac.h"
+#elif defined(SK_BUILD_FOR_WIN)
+ #include "SkOSWindow_Win.h"
+#elif defined(SK_BUILD_FOR_UNIXx)
+ #include "SkOSWindow_Unix.h"
+#endif
+#else
+ #include "SkOSWindow_wxwidgets.h"
+#endif
+
+#endif
+
diff --git a/include/xml/SkBML_WXMLParser.h b/include/xml/SkBML_WXMLParser.h
new file mode 100644
index 0000000000..faa127dce7
--- /dev/null
+++ b/include/xml/SkBML_WXMLParser.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/xml/SkBML_XMLParser.h b/include/xml/SkBML_XMLParser.h
new file mode 100644
index 0000000000..f056bca438
--- /dev/null
+++ b/include/xml/SkBML_XMLParser.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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/include/xml/SkDOM.h b/include/xml/SkDOM.h
new file mode 100644
index 0000000000..74e2492953
--- /dev/null
+++ b/include/xml/SkDOM.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkDOM_DEFINED
+#define SkDOM_DEFINED
+
+#include "SkChunkAlloc.h"
+#include "SkMath.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/include/xml/SkJS.h b/include/xml/SkJS.h
new file mode 100644
index 0000000000..fe76352e34
--- /dev/null
+++ b/include/xml/SkJS.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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/include/xml/SkXMLParser.h b/include/xml/SkXMLParser.h
new file mode 100644
index 0000000000..ddad2732d8
--- /dev/null
+++ b/include/xml/SkXMLParser.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkXMLParser_DEFINED
+#define SkXMLParser_DEFINED
+
+#include "SkMath.h"
+#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);
+};
+
+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
diff --git a/include/xml/SkXMLWriter.h b/include/xml/SkXMLWriter.h
new file mode 100644
index 0000000000..742e7f1ccc
--- /dev/null
+++ b/include/xml/SkXMLWriter.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef 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
+