зеркало из https://github.com/mozilla/gecko-dev.git
Bug 777614 - Update Skia to r5539.
This commit is contained in:
Родитель
56efc718a2
Коммит
2c79accd09
|
@ -22,23 +22,31 @@ DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SHIFT=16 -DSK_G32_SHIFT=8 -DSK_B32_SHIFT=0
|
|||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/include/core \
|
||||
-I$(srcdir)/include/config \
|
||||
-I$(srcdir)/include/gpu \
|
||||
-I$(srcdir)/include/pipe \
|
||||
-I$(srcdir)/include/ports \
|
||||
-I$(srcdir)/src/core \
|
||||
-I$(srcdir)/include/images \
|
||||
-I$(srcdir)/include/utils \
|
||||
-I$(srcdir)/include/utils/mac \
|
||||
-I$(srcdir)/include/utils/win \
|
||||
-I$(srcdir)/include/views \
|
||||
-I$(srcdir)/include/effects \
|
||||
-I$(srcdir)/src/core \
|
||||
-I$(srcdir)/src/image \
|
||||
-I$(srcdir)/src/gpu \
|
||||
-I$(srcdir)/src/utils \
|
||||
-I$(srcdir)/src/sfnt \
|
||||
$(NULL)
|
||||
|
||||
VPATH += \
|
||||
$(srcdir)/src/core \
|
||||
$(srcdir)/src/image \
|
||||
$(srcdir)/src/images \
|
||||
$(srcdir)/src/pipe \
|
||||
$(srcdir)/src/ports \
|
||||
$(srcdir)/src/opts \
|
||||
$(srcdir)/src/effects \
|
||||
$(srcdir)/src/effects/gradients \
|
||||
$(srcdir)/src/utils \
|
||||
$(srcdir)/src/utils/mac \
|
||||
$(srcdir)/src/sfnt \
|
||||
|
@ -47,12 +55,9 @@ VPATH += \
|
|||
EXPORTS_skia = \
|
||||
include/core/Sk64.h \
|
||||
include/core/SkAdvancedTypefaceMetrics.h \
|
||||
include/core/SkAutoKern.h \
|
||||
include/core/SkBitmap.h \
|
||||
include/core/SkBlitRow.h \
|
||||
include/core/SkBlitter.h \
|
||||
include/core/SkBounder.h \
|
||||
include/core/SkBuffer.h \
|
||||
include/core/SkCanvas.h \
|
||||
include/core/SkChunkAlloc.h \
|
||||
include/core/SkClipStack.h \
|
||||
|
@ -60,28 +65,25 @@ EXPORTS_skia = \
|
|||
include/core/SkColorFilter.h \
|
||||
include/core/SkColorPriv.h \
|
||||
include/core/SkColorShader.h \
|
||||
include/core/SkColorTable.h \
|
||||
include/core/SkComposeShader.h \
|
||||
include/core/SkData.h \
|
||||
include/core/SkDeque.h \
|
||||
include/core/SkDescriptor.h \
|
||||
include/core/SkDevice.h \
|
||||
include/core/SkDeviceProfile.h \
|
||||
include/core/SkDither.h \
|
||||
include/core/SkDraw.h \
|
||||
include/core/SkDrawFilter.h \
|
||||
include/core/SkDrawLooper.h \
|
||||
include/core/SkEdgeClipper.h \
|
||||
include/core/SkEmptyShader.h \
|
||||
include/core/SkEndian.h \
|
||||
include/core/SkFDot6.h \
|
||||
include/core/SkFixed.h \
|
||||
include/core/SkFlattenable.h \
|
||||
include/core/SkFloatBits.h \
|
||||
include/core/SkFloatingPoint.h \
|
||||
include/core/SkFontHost.h \
|
||||
include/core/SkGeometry.h \
|
||||
include/core/SkGlobals.h \
|
||||
include/core/SkGraphics.h \
|
||||
include/core/SkInstCnt.h \
|
||||
include/core/SkLineClipper.h \
|
||||
include/core/SkMMapStream.h \
|
||||
include/core/SkMallocPixelRef.h \
|
||||
|
@ -91,38 +93,28 @@ EXPORTS_skia = \
|
|||
include/core/SkMatrix.h \
|
||||
include/core/SkMetaData.h \
|
||||
include/core/SkOSFile.h \
|
||||
include/core/SkOrderedReadBuffer.h \
|
||||
include/core/SkOrderedWriteBuffer.h \
|
||||
include/core/SkPackBits.h \
|
||||
include/core/SkPaint.h \
|
||||
include/core/SkPath.h \
|
||||
include/core/SkPathEffect.h \
|
||||
include/core/SkPathMeasure.h \
|
||||
include/core/SkPerspIter.h \
|
||||
include/core/SkPicture.h \
|
||||
include/core/SkPixelRef.h \
|
||||
include/core/SkPoint.h \
|
||||
include/core/SkPostConfig.h \
|
||||
include/core/SkPreConfig.h \
|
||||
include/core/SkPtrRecorder.h \
|
||||
include/core/SkRandom.h \
|
||||
include/core/SkRasterizer.h \
|
||||
include/core/SkReader32.h \
|
||||
include/core/SkRect.h \
|
||||
include/core/SkRefCnt.h \
|
||||
include/core/SkRefDict.h \
|
||||
include/core/SkRegion.h \
|
||||
include/core/SkRelay.h \
|
||||
include/core/SkScalar.h \
|
||||
include/core/SkScalarCompare.h \
|
||||
include/core/SkScalerContext.h \
|
||||
include/core/SkScan.h \
|
||||
include/core/SkShader.h \
|
||||
include/core/SkShape.h \
|
||||
include/core/SkSize.h \
|
||||
include/core/SkStream.h \
|
||||
include/core/SkString.h \
|
||||
include/core/SkStroke.h \
|
||||
include/core/SkTDArray.h \
|
||||
include/core/SkTDStack.h \
|
||||
include/core/SkTDict.h \
|
||||
|
@ -162,10 +154,13 @@ CPPSRCS = \
|
|||
SkAAClip.cpp \
|
||||
SkAdvancedTypefaceMetrics.cpp \
|
||||
SkAlphaRuns.cpp \
|
||||
SkBBoxRecord.cpp \
|
||||
SkBBoxHierarchyRecord.cpp \
|
||||
SkBase64.cpp \
|
||||
SkBitSet.cpp \
|
||||
SkBitmap.cpp \
|
||||
SkBitmapCache.cpp \
|
||||
SkBitmapHeap.cpp \
|
||||
SkBitmapProcShader.cpp \
|
||||
SkBitmapProcState.cpp \
|
||||
SkBitmapProcState_matrixProcs.cpp \
|
||||
|
@ -188,13 +183,13 @@ CPPSRCS = \
|
|||
SkBuffer.cpp \
|
||||
SkCanvas.cpp \
|
||||
SkChunkAlloc.cpp \
|
||||
SkClampRange.cpp \
|
||||
SkClipStack.cpp \
|
||||
SkColor.cpp \
|
||||
SkColorFilter.cpp \
|
||||
SkColorFilters.cpp \
|
||||
SkColorMatrix.cpp \
|
||||
SkColorTable.cpp \
|
||||
SkClampRange.cpp \
|
||||
SkComposeShader.cpp \
|
||||
SkConcaveToTriangles.cpp \
|
||||
SkConfig8888.cpp \
|
||||
|
@ -202,6 +197,7 @@ CPPSRCS = \
|
|||
SkCubicClipper.cpp \
|
||||
SkDashPathEffect.cpp \
|
||||
SkData.cpp \
|
||||
SkDataPixelRef.cpp \
|
||||
SkDebug.cpp \
|
||||
SkDeferredCanvas.cpp \
|
||||
SkDeque.cpp \
|
||||
|
@ -214,26 +210,37 @@ CPPSRCS = \
|
|||
SkEdgeClipper.cpp \
|
||||
SkFilterProc.cpp \
|
||||
SkFlattenable.cpp \
|
||||
SkFlattenableBuffers.cpp \
|
||||
SkFloat.cpp \
|
||||
SkFloatBits.cpp \
|
||||
SkFontDescriptor.cpp \
|
||||
SkFontHost.cpp \
|
||||
SkGeometry.cpp \
|
||||
SkGlobals.cpp \
|
||||
SkGlobals_global.cpp \
|
||||
SkGlyphCache.cpp \
|
||||
SkGradientShader.cpp \
|
||||
SkGraphics.cpp \
|
||||
SkGPipeRead.cpp \
|
||||
SkGPipeWrite.cpp \
|
||||
SkImage.cpp \
|
||||
SkImage_Codec.cpp \
|
||||
SkImage_Picture.cpp \
|
||||
SkImage_Raster.cpp \
|
||||
SkImageDecoder.cpp \
|
||||
SkImageDecoder_Factory.cpp \
|
||||
SkImageFilter.cpp \
|
||||
SkImagePriv.cpp \
|
||||
SkLayerDrawLooper.cpp \
|
||||
SkLayerRasterizer.cpp \
|
||||
SkLinearGradient.cpp \
|
||||
SkLineClipper.cpp \
|
||||
SkMallocPixelRef.cpp \
|
||||
SkMask.cpp \
|
||||
SkMaskFilter.cpp \
|
||||
SkMaskGamma.cpp \
|
||||
SkMath.cpp \
|
||||
SkMatrix.cpp \
|
||||
SkMemory_mozalloc.cpp \
|
||||
SkMemory_malloc.cpp \
|
||||
SkMetaData.cpp \
|
||||
SkMorphologyImageFilter.cpp \
|
||||
SkOrderedReadBuffer.cpp \
|
||||
SkOrderedWriteBuffer.cpp \
|
||||
SkOSFile_stdio.cpp \
|
||||
|
@ -248,11 +255,14 @@ CPPSRCS = \
|
|||
SkPictureFlat.cpp \
|
||||
SkPicturePlayback.cpp \
|
||||
SkPictureRecord.cpp \
|
||||
SkPictureStateTree.cpp \
|
||||
SkPixelRef.cpp \
|
||||
SkPoint.cpp \
|
||||
SkProcSpriteBlitter.cpp \
|
||||
SkPtrRecorder.cpp \
|
||||
SkQuadClipper.cpp \
|
||||
SkRTree.cpp \
|
||||
SkRadialGradient.cpp \
|
||||
SkRasterClip.cpp \
|
||||
SkRasterizer.cpp \
|
||||
SkRect.cpp \
|
||||
|
@ -268,15 +278,20 @@ CPPSRCS = \
|
|||
SkScan_Hairline.cpp \
|
||||
SkScan_Path.cpp \
|
||||
SkShader.cpp \
|
||||
SkShape.cpp \
|
||||
SkSpriteBlitter_ARGB32.cpp \
|
||||
SkSpriteBlitter_RGB16.cpp \
|
||||
SkStream.cpp \
|
||||
SkString.cpp \
|
||||
SkStroke.cpp \
|
||||
SkStrokerPriv.cpp \
|
||||
SkSurface.cpp \
|
||||
SkSurface_Raster.cpp \
|
||||
SkSurface_Picture.cpp \
|
||||
SkSweepGradient.cpp \
|
||||
SkTLS.cpp \
|
||||
SkTSearch.cpp \
|
||||
SkTwoPointConicalGradient.cpp \
|
||||
SkTwoPointRadialGradient.cpp \
|
||||
SkTypeface.cpp \
|
||||
SkTypefaceCache.cpp \
|
||||
SkUnPreMultiply.cpp \
|
||||
|
@ -300,8 +315,8 @@ ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
|||
CPPSRCS += \
|
||||
SkDebug_android.cpp \
|
||||
SkFontHost_android_old.cpp \
|
||||
SkFontHost_gamma.cpp \
|
||||
SkFontHost_FreeType.cpp \
|
||||
SkFontHost_FreeType_common.cpp \
|
||||
SkFontHost_tables.cpp \
|
||||
SkMMapStream.cpp \
|
||||
SkTime_Unix.cpp \
|
||||
|
@ -320,7 +335,7 @@ endif
|
|||
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += \
|
||||
SkFontHost_FreeType.cpp \
|
||||
SkFontHost_gamma_none.cpp \
|
||||
SkFontHost_FreeType_common.cpp \
|
||||
SkFontHost_linux.cpp \
|
||||
SkFontHost_tables.cpp \
|
||||
SkTime_Unix.cpp \
|
||||
|
@ -334,7 +349,7 @@ endif
|
|||
ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += \
|
||||
SkFontHost_FreeType.cpp \
|
||||
SkFontHost_gamma_none.cpp \
|
||||
SkFontHost_FreeType_common.cpp \
|
||||
SkFontHost_tables.cpp \
|
||||
SkMMapStream.cpp \
|
||||
SkOSFile.cpp \
|
||||
|
@ -360,6 +375,9 @@ CPPSRCS += \
|
|||
SkFontHost_sandbox_none.cpp \
|
||||
SkTime_win.cpp \
|
||||
$(NULL)
|
||||
ifdef _MSC_VER
|
||||
HAVE_COMPILER_FLAG_MSSSE3=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(INTEL_ARCHITECTURE))
|
||||
|
@ -407,3 +425,10 @@ ifdef GNU_CC
|
|||
CXXFLAGS := $(filter-out -pedantic,$(CXXFLAGS))
|
||||
CFLAGS := $(filter-out -pedantic,$(CFLAGS))
|
||||
endif
|
||||
|
||||
ifeq ($(CPU_ARCH)_$(GNU_CC),arm_1)
|
||||
# The assembly uses the frame pointer register (r7 in Thumb/r11 in
|
||||
# ARM), the compiler doesn't like that.
|
||||
CXXFLAGS := $(filter-out -fno-omit-frame-pointer,$(CXXFLAGS)) -fomit-frame-pointer
|
||||
CFLAGS := $(filter-out -fno-omit-frame-pointer,$(CFLAGS)) -fomit-frame-pointer
|
||||
endif
|
||||
|
|
|
@ -2,4 +2,4 @@ The source from this directory was copied from the skia subversion trunk
|
|||
using the update.sh script. The changes made were those applied by update.sh,
|
||||
the addition/update of Makefile.in files for the Mozilla build system.
|
||||
|
||||
The subversion revision used was r4037.
|
||||
The subversion revision used was r5539.
|
||||
|
|
|
@ -42,15 +42,15 @@ enum SkFieldType {
|
|||
/** \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
|
||||
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 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
|
||||
|
@ -84,7 +84,7 @@ public:
|
|||
SkAnimator();
|
||||
virtual ~SkAnimator();
|
||||
|
||||
/** Add a drawable extension to the graphics engine. Experimental.
|
||||
/** 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);
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
*/
|
||||
bool appendStream(SkStream* stream);
|
||||
|
||||
/** Read in XML from memory. Returns true if the file can be
|
||||
/** 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.
|
||||
|
@ -106,7 +106,7 @@ public:
|
|||
*/
|
||||
bool decodeMemory(const void* buffer, size_t size);
|
||||
|
||||
/** Read in XML from a stream. Returns true if the file can be
|
||||
/** 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.
|
||||
|
@ -114,14 +114,14 @@ public:
|
|||
*/
|
||||
virtual bool decodeStream(SkStream* stream);
|
||||
|
||||
/** Parse the DOM tree starting at the specified node. Returns true if it can be
|
||||
/** 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 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).
|
||||
|
@ -131,14 +131,14 @@ public:
|
|||
|
||||
/** 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"
|
||||
@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
|
||||
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
|
||||
|
@ -151,48 +151,48 @@ public:
|
|||
|
||||
/** 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"
|
||||
@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
|
||||
|
||||
/** 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.
|
||||
/** 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
|
||||
/** 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
|
||||
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
|
||||
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
|
||||
kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
|
||||
redraw area.
|
||||
*/
|
||||
DifferenceType draw(SkCanvas* canvas, SkMSec time);
|
||||
|
@ -203,7 +203,7 @@ public:
|
|||
@param y ignored
|
||||
@return true if a mouseDown event handler is enabled.
|
||||
*/
|
||||
bool findClickEvent(SkScalar x, SkScalar y);
|
||||
bool findClickEvent(SkScalar x, SkScalar y);
|
||||
|
||||
|
||||
/** Get the nested animator associated with this element, if any.
|
||||
|
@ -223,7 +223,7 @@ public:
|
|||
|
||||
/** 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 fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the integer value to retrieve, or SK_NaN32 if unsuccessful
|
||||
*/
|
||||
|
@ -239,7 +239,7 @@ public:
|
|||
|
||||
/** 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 fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
|
||||
*/
|
||||
|
@ -247,7 +247,7 @@ public:
|
|||
|
||||
/** 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 field is a value returned by getField
|
||||
@param index the array entry
|
||||
@return the string value to retrieve, or null if unsuccessful
|
||||
*/
|
||||
|
@ -255,55 +255,55 @@ public:
|
|||
|
||||
/** 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 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
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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);
|
||||
|
@ -315,54 +315,54 @@ public:
|
|||
|
||||
/** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
|
||||
kIsPartiallyDifferent to do a mimimal inval(). */
|
||||
void getInvalBounds(SkRect* inval);
|
||||
void getInvalBounds(SkRect* inval);
|
||||
|
||||
/** Returns the details of any error encountered while parsing the XML.
|
||||
/** 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.
|
||||
|
||||
/** 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
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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);
|
||||
|
@ -373,31 +373,31 @@ public:
|
|||
/** 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
|
||||
/** 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 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 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 fieldName specifies the name of the attribute
|
||||
@param data the integer value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
|
@ -405,7 +405,7 @@ public:
|
|||
|
||||
/** 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 fieldName specifies the name of the attribute
|
||||
@param data the scalar value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
|
@ -413,14 +413,14 @@ public:
|
|||
|
||||
/** 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 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
|
||||
/** Sets the file default directory of the URL base path
|
||||
@param path the directory path
|
||||
*/
|
||||
void setURIBase(const char* path);
|
||||
|
||||
|
@ -442,7 +442,7 @@ public:
|
|||
virtual SkMSec getMSecs() const = 0;
|
||||
};
|
||||
|
||||
/** Sets a user class to return the current time to the animator.
|
||||
/** 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
|
||||
*/
|
||||
|
@ -450,28 +450,28 @@ public:
|
|||
|
||||
static void Init(bool runUnitTests);
|
||||
static void Term();
|
||||
|
||||
/** The event sink events generated by the animation are posted to.
|
||||
|
||||
/** 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
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void onSetHostHandler(Handler handler);
|
||||
virtual void onEventPost(SkEvent*, SkEventSinkID);
|
||||
|
@ -484,7 +484,7 @@ private:
|
|||
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;
|
||||
|
|
|
@ -35,16 +35,6 @@
|
|||
commented out, so including it will have no effect.
|
||||
*/
|
||||
|
||||
/*
|
||||
Override new/delete with Mozilla's allocator, mozalloc
|
||||
|
||||
Ideally we shouldn't need to do this here, but until
|
||||
http://code.google.com/p/skia/issues/detail?id=598 is fixed
|
||||
we need to include this here to override operator new and delete
|
||||
*/
|
||||
|
||||
#include "mozilla/mozalloc.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Scalars (the fractional value type in skia) can be implemented either as
|
||||
|
@ -55,13 +45,6 @@
|
|||
//#define SK_SCALAR_IS_FIXED
|
||||
|
||||
|
||||
/* Somewhat independent of how SkScalar is implemented, Skia also wants to know
|
||||
if it can use floats at all. Naturally, if SK_SCALAR_IS_FLOAT is defined,
|
||||
SK_CAN_USE_FLOAT must be too; but if scalars are fixed, SK_CAN_USE_FLOAT
|
||||
can go either way.
|
||||
*/
|
||||
//#define SK_CAN_USE_FLOAT
|
||||
|
||||
/* For some performance-critical scalar operations, skia will optionally work
|
||||
around the standard float operators if it knows that the CPU does not have
|
||||
native support for floats. If your environment uses software floating point,
|
||||
|
@ -82,6 +65,12 @@
|
|||
//#define SK_DEBUG
|
||||
//#define SK_RELEASE
|
||||
|
||||
/* To assist debugging, Skia provides an instance counting utility in
|
||||
include/core/SkInstCount.h. This flag turns on and off that utility to
|
||||
allow instance count tracking in either debug or release builds. By
|
||||
default it is enabled in debug but disabled in release.
|
||||
*/
|
||||
//#define SK_ENABLE_INST_COUNT
|
||||
|
||||
/* If, in debugging mode, Skia needs to stop (presumably to invoke a debugger)
|
||||
it will call SK_CRASH(). If this is not defined it, it is defined in
|
||||
|
@ -149,7 +138,7 @@
|
|||
/* Define this to remove dimension checks on bitmaps. Not all blits will be
|
||||
correct yet, so this is mostly for debugging the implementation.
|
||||
*/
|
||||
//#define SK_ALLOW_OVER_32K_BITMAPS
|
||||
#define SK_ALLOW_OVER_32K_BITMAPS
|
||||
|
||||
/* Define this to set the upper limit for text to support LCD. Values that
|
||||
are very large increase the cost in the font cache and draw slower, without
|
||||
|
@ -166,10 +155,6 @@
|
|||
//#define SK_SUPPORT_UNITTEST
|
||||
#endif
|
||||
|
||||
/* Don't dither 32bit gradients, to match what the canvas test suite expects.
|
||||
*/
|
||||
#define SK_DISABLE_DITHER_32BIT_GRADIENT
|
||||
|
||||
/* If your system embeds skia and has complex event logging, define this
|
||||
symbol to name a file that maps the following macros to your system's
|
||||
equivalents:
|
||||
|
@ -191,10 +176,13 @@
|
|||
#define SK_A32_SHIFT 24
|
||||
#endif
|
||||
|
||||
/* Don't include stdint.h on windows as it conflicts with our build system.
|
||||
*/
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define SK_IGNORE_STDINT_DOT_H
|
||||
#endif
|
||||
|
||||
/* Determines whether to build code that supports the GPU backend. Some classes
|
||||
that are not GPU-specific, such as SkShader subclasses, have optional code
|
||||
that is used allows them to interact with the GPU backend. If you'd like to
|
||||
omit this code set SK_SUPPORT_GPU to 0. This also allows you to omit the gpu
|
||||
directories from your include search path when you're not building the GPU
|
||||
backend. Defaults to 1 (build the GPU code).
|
||||
*/
|
||||
//#define SK_SUPPORT_GPU 1
|
||||
#endif
|
||||
|
|
|
@ -134,7 +134,7 @@ struct SK_API Sk64 {
|
|||
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;
|
||||
|
@ -142,18 +142,18 @@ struct SK_API Sk64 {
|
|||
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);
|
||||
|
@ -162,7 +162,7 @@ struct SK_API Sk64 {
|
|||
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).
|
||||
*/
|
||||
|
@ -205,19 +205,19 @@ struct SK_API Sk64 {
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
class SkAdvancedTypefaceMetrics : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkAdvancedTypefaceMetrics)
|
||||
|
||||
SkString fFontName;
|
||||
|
||||
enum FontType {
|
||||
|
@ -112,6 +114,9 @@ public:
|
|||
// The mapping from glyph to Unicode, only populated if
|
||||
// kToUnicode_PerGlyphInfo is passed to GetAdvancedTypefaceMetrics.
|
||||
SkTDArray<SkUnichar> fGlyphToUnicode;
|
||||
|
||||
private:
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
namespace skia_advanced_typeface_metrics_utils {
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAnnotation_DEFINED
|
||||
#define SkAnnotation_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkData;
|
||||
class SkDataSet;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
/**
|
||||
* Experimental class for annotating draws. Do not use directly yet.
|
||||
* Use helper functions at the bottom of this file for now.
|
||||
*/
|
||||
class SkAnnotation : public SkFlattenable {
|
||||
public:
|
||||
enum Flags {
|
||||
// If set, the associated drawing primitive should not be drawn
|
||||
kNoDraw_Flag = 1 << 0,
|
||||
};
|
||||
|
||||
SkAnnotation(SkDataSet*, uint32_t flags);
|
||||
virtual ~SkAnnotation();
|
||||
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
SkDataSet* getDataSet() const { return fDataSet; }
|
||||
|
||||
bool isNoDraw() const { return SkToBool(fFlags & kNoDraw_Flag); }
|
||||
|
||||
/**
|
||||
* Helper for search the annotation's dataset.
|
||||
*/
|
||||
SkData* find(const char name[]) const;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAnnotation)
|
||||
|
||||
protected:
|
||||
SkAnnotation(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkDataSet* fDataSet;
|
||||
uint32_t fFlags;
|
||||
|
||||
void writeToStream(SkWStream*) const;
|
||||
void readFromStream(SkStream*);
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* Experimental collection of predefined Keys into the Annotation dictionary
|
||||
*/
|
||||
class SkAnnotationKeys {
|
||||
public:
|
||||
/**
|
||||
* Returns the canonical key whose payload is a URL
|
||||
*/
|
||||
static const char* URL_Key();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Experimental helper functions to use Annotations
|
||||
//
|
||||
|
||||
struct SkRect;
|
||||
class SkCanvas;
|
||||
|
||||
/**
|
||||
* Experimental!
|
||||
*
|
||||
* Annotate the canvas by associating the specified URL with the
|
||||
* specified rectangle (in local coordinates, just like drawRect). If the
|
||||
* backend of this canvas does not support annotations, this call is
|
||||
* safely ignored.
|
||||
*
|
||||
* The caller is responsible for managing its ownership of the SkData.
|
||||
*/
|
||||
SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
|
||||
|
||||
#endif
|
|
@ -12,17 +12,15 @@
|
|||
|
||||
#include "Sk64.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkColorTable.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
struct SkIRect;
|
||||
struct SkRect;
|
||||
class SkColorTable;
|
||||
class SkPaint;
|
||||
class SkPixelRef;
|
||||
class SkRegion;
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
|
||||
// This is an opaque class, not interpreted by skia
|
||||
class SkGpuTexture;
|
||||
|
@ -94,10 +92,10 @@ public:
|
|||
*/
|
||||
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()).
|
||||
/** Return true iff the bitmap has no 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; }
|
||||
bool isNull() const { return NULL == fPixelRef; }
|
||||
|
||||
/** Return the config for the bitmap.
|
||||
*/
|
||||
|
@ -171,7 +169,7 @@ public:
|
|||
|
||||
/** Marks this bitmap as immutable, meaning that the contents of its
|
||||
pixels will not change for the lifetime of the bitmap and of the
|
||||
underlying pixelref. This state can be set, but it cannot be
|
||||
underlying pixelref. This state can be set, but it cannot be
|
||||
cleared once it is set. This state propagates to all other bitmaps
|
||||
that share the same pixelref.
|
||||
*/
|
||||
|
@ -190,11 +188,11 @@ public:
|
|||
*/
|
||||
bool isVolatile() const;
|
||||
|
||||
/** Specify whether this bitmap is volatile. Bitmaps are not volatile by
|
||||
/** Specify whether this bitmap is volatile. Bitmaps are not volatile by
|
||||
default. Temporary bitmaps that are discarded after use should be
|
||||
marked as volatile. This provides a hint to the device that the bitmap
|
||||
should not be cached. Providing this hint when appropriate can
|
||||
improve performance by avoiding unnecessary overhead and resource
|
||||
should not be cached. Providing this hint when appropriate can
|
||||
improve performance by avoiding unnecessary overhead and resource
|
||||
consumption on the device.
|
||||
*/
|
||||
void setIsVolatile(bool);
|
||||
|
@ -361,9 +359,9 @@ public:
|
|||
SkColorTable* getColorTable() const { return fColorTable; }
|
||||
|
||||
/** Returns a non-zero, unique value corresponding to the pixels in our
|
||||
pixelref (or raw pixels set via setPixels). Each time the pixels are
|
||||
changed (and notifyPixelsChanged is called), a different generation ID
|
||||
will be returned.
|
||||
pixelref. Each time the pixels are changed (and notifyPixelsChanged
|
||||
is called), a different generation ID will be returned. Finally, if
|
||||
their is no pixelRef then zero is returned.
|
||||
*/
|
||||
uint32_t getGenerationID() const;
|
||||
|
||||
|
@ -397,7 +395,8 @@ public:
|
|||
|
||||
/** 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).
|
||||
still update the inval region (if present). If the bitmap is immutable,
|
||||
do nothing and return false.
|
||||
|
||||
@param subset The subset of the bitmap to scroll/move. To scroll the
|
||||
entire contents, specify [0, 0, width, height] or just
|
||||
|
@ -425,7 +424,7 @@ public:
|
|||
* does not have any pixels (or has not be locked with lockPixels()).
|
||||
*/
|
||||
SkColor getColor(int x, int y) const;
|
||||
|
||||
|
||||
/** Returns the address of the specified pixel. This performs a runtime
|
||||
check to know the size of the pixels, and will return the same answer
|
||||
as the corresponding size-specific method (e.g. getAddr16). Since the
|
||||
|
@ -550,6 +549,13 @@ public:
|
|||
bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
|
||||
SkIPoint* offset) const;
|
||||
|
||||
/** The following two functions provide the means to both flatten and
|
||||
unflatten the bitmap AND its pixels into the provided buffer.
|
||||
It is recommended that you do not call these functions directly,
|
||||
but instead call the write/readBitmap functions on the respective
|
||||
buffers as they can optimize the recording process and avoid recording
|
||||
duplicate bitmaps and pixelRefs.
|
||||
*/
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
void unflatten(SkFlattenableReadBuffer&);
|
||||
|
||||
|
@ -557,6 +563,8 @@ public:
|
|||
|
||||
class Allocator : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(Allocator)
|
||||
|
||||
/** 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
|
||||
|
@ -565,6 +573,8 @@ public:
|
|||
colortable should be left unchanged.
|
||||
*/
|
||||
virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
|
||||
private:
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
/** Subclass of Allocator that returns a pixelref that allocates its pixel
|
||||
|
@ -608,10 +618,6 @@ private:
|
|||
// or a cache of the returned value from fPixelRef->lockPixels()
|
||||
mutable void* fPixels;
|
||||
mutable SkColorTable* fColorTable; // only meaningful for kIndex8
|
||||
// When there is no pixel ref (setPixels was called) we still need a
|
||||
// gen id for SkDevice implementations that may cache a copy of the
|
||||
// pixels (e.g. as a gpu texture)
|
||||
mutable int fRawPixelGenerationID;
|
||||
|
||||
enum Flags {
|
||||
kImageIsOpaque_Flag = 0x01,
|
||||
|
@ -645,95 +651,6 @@ private:
|
|||
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:
|
||||
/** Makes a deep copy of colors.
|
||||
*/
|
||||
SkColorTable(const SkColorTable& src);
|
||||
/** Preallocates the colortable to have 'count' colors, which
|
||||
* are initially set to 0.
|
||||
*/
|
||||
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);
|
||||
|
||||
bool isOpaque() const { return (fFlags & kColorsAreOpaque_Flag) != 0; }
|
||||
void setIsOpaque(bool isOpaque);
|
||||
|
||||
/** 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 SkNoncopyable {
|
||||
public:
|
||||
SkAutoLockPixels(const SkBitmap& bm, bool doLock = true) : fBitmap(bm) {
|
||||
|
|
|
@ -29,9 +29,11 @@ class SkRegion;
|
|||
*/
|
||||
class SkBounder : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkBounder)
|
||||
|
||||
SkBounder();
|
||||
|
||||
/* Call to perform a clip test before calling onIRect.
|
||||
/* Call to perform a clip test before calling onIRect.
|
||||
Returns the result from onIRect.
|
||||
*/
|
||||
bool doIRect(const SkIRect&);
|
||||
|
@ -84,6 +86,8 @@ private:
|
|||
friend class SkDrawIter;
|
||||
friend struct Draw1Glyph;
|
||||
friend class SkMaskFilter;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,7 @@ class SkDevice;
|
|||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
class SkPicture;
|
||||
class SkSurface_Base;
|
||||
|
||||
/** \class SkCanvas
|
||||
|
||||
|
@ -44,6 +45,8 @@ class SkPicture;
|
|||
*/
|
||||
class SK_API SkCanvas : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkCanvas)
|
||||
|
||||
SkCanvas();
|
||||
|
||||
/** Construct a canvas with the specified device to draw into.
|
||||
|
@ -384,33 +387,15 @@ public:
|
|||
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;
|
||||
bool quickReject(const SkRect& rect) const;
|
||||
|
||||
/** Return true if the specified path, after being transformed by the
|
||||
current matrix, would lie completely outside of the current clip. Call
|
||||
|
@ -419,11 +404,10 @@ public:
|
|||
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;
|
||||
bool quickReject(const SkPath& path) const;
|
||||
|
||||
/** Return true if the horizontal band specified by top and bottom is
|
||||
completely clipped out. This is a conservative calculation, meaning
|
||||
|
@ -435,9 +419,9 @@ public:
|
|||
@return true if the horizontal band is completely clipped out (i.e. does
|
||||
not intersect the current clip)
|
||||
*/
|
||||
bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const {
|
||||
bool quickRejectY(SkScalar top, SkScalar bottom) const {
|
||||
SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom));
|
||||
const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(et);
|
||||
const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType();
|
||||
// In the case where the clip is empty and we are provided with a
|
||||
// negative top and positive bottom parameter then this test will return
|
||||
// false even though it will be clipped. We have chosen to exclude that
|
||||
|
@ -451,7 +435,7 @@ public:
|
|||
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;
|
||||
bool getClipBounds(SkRect* bounds) const;
|
||||
|
||||
/** Return the bounds of the current clip, in device coordinates; returns
|
||||
true if non-empty. Maybe faster than getting the clip explicitly and
|
||||
|
@ -886,10 +870,20 @@ public:
|
|||
*/
|
||||
const SkRegion& getTotalClip() const;
|
||||
|
||||
/** Return the clip stack. The clip stack stores all the individual
|
||||
* clips organized by the save/restore frame in which they were
|
||||
* added.
|
||||
* @return the current clip stack ("list" of individual clip elements)
|
||||
*/
|
||||
const SkClipStack* getClipStack() const {
|
||||
return &fClipStack;
|
||||
}
|
||||
|
||||
void setExternalMatrix(const SkMatrix* = NULL);
|
||||
|
||||
class ClipVisitor {
|
||||
public:
|
||||
virtual ~ClipVisitor();
|
||||
virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
|
||||
virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
|
||||
};
|
||||
|
@ -957,6 +951,10 @@ protected:
|
|||
bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
|
||||
SkIRect* intersection);
|
||||
|
||||
// notify our surface (if we have one) that we are about to draw, so it
|
||||
// can perform copy-on-write or invalidate any cached images
|
||||
void predrawNotify();
|
||||
|
||||
private:
|
||||
class MCRec;
|
||||
|
||||
|
@ -971,8 +969,14 @@ private:
|
|||
SkDevice* fLastDeviceToGainFocus;
|
||||
int fSaveLayerCount; // number of successful saveLayer calls
|
||||
|
||||
void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
|
||||
const SkClipStack& clipStack);
|
||||
SkSurface_Base* fSurfaceBase;
|
||||
SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
|
||||
void setSurfaceBase(SkSurface_Base* sb) {
|
||||
fSurfaceBase = sb;
|
||||
}
|
||||
friend class SkSurface_Base;
|
||||
|
||||
void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&);
|
||||
|
||||
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
|
||||
void updateDeviceCMCache();
|
||||
|
@ -1013,31 +1017,14 @@ private:
|
|||
mutable SkRectCompareType fLocalBoundsCompareType;
|
||||
mutable bool fLocalBoundsCompareTypeDirty;
|
||||
|
||||
mutable SkRectCompareType fLocalBoundsCompareTypeBW;
|
||||
mutable bool fLocalBoundsCompareTypeDirtyBW;
|
||||
|
||||
/* Get the local clip bounds with an anti-aliased edge.
|
||||
*/
|
||||
const SkRectCompareType& getLocalClipBoundsCompareType() const {
|
||||
return getLocalClipBoundsCompareType(kAA_EdgeType);
|
||||
}
|
||||
|
||||
const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const {
|
||||
if (et == kAA_EdgeType) {
|
||||
if (fLocalBoundsCompareTypeDirty) {
|
||||
this->computeLocalClipBoundsCompareType(et);
|
||||
fLocalBoundsCompareTypeDirty = false;
|
||||
}
|
||||
return fLocalBoundsCompareType;
|
||||
} else {
|
||||
if (fLocalBoundsCompareTypeDirtyBW) {
|
||||
this->computeLocalClipBoundsCompareType(et);
|
||||
fLocalBoundsCompareTypeDirtyBW = false;
|
||||
}
|
||||
return fLocalBoundsCompareTypeBW;
|
||||
if (fLocalBoundsCompareTypeDirty) {
|
||||
this->computeLocalClipBoundsCompareType();
|
||||
fLocalBoundsCompareTypeDirty = false;
|
||||
}
|
||||
return fLocalBoundsCompareType;
|
||||
}
|
||||
void computeLocalClipBoundsCompareType(EdgeType et) const;
|
||||
void computeLocalClipBoundsCompareType() const;
|
||||
|
||||
SkMatrix fExternalMatrix, fExternalInverse;
|
||||
bool fUseExternalMatrix;
|
||||
|
@ -1058,6 +1045,8 @@ private:
|
|||
#else
|
||||
void validateClip() const {}
|
||||
#endif
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
/** Stack helper class to automatically call restoreToCount() on the canvas
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkChecksum_DEFINED
|
||||
#define SkChecksum_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkChecksum : SkNoncopyable {
|
||||
private:
|
||||
/*
|
||||
* Our Rotate and Mash helpers are meant to automatically do the right
|
||||
* thing depending if sizeof(uintptr_t) is 4 or 8.
|
||||
*/
|
||||
enum {
|
||||
ROTR = 17,
|
||||
ROTL = sizeof(uintptr_t) * 8 - ROTR,
|
||||
HALFBITS = sizeof(uintptr_t) * 4
|
||||
};
|
||||
|
||||
static inline uintptr_t Mash(uintptr_t total, uintptr_t value) {
|
||||
return ((total >> ROTR) | (total << ROTL)) ^ value;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Compute a 32-bit checksum for a given data block
|
||||
*
|
||||
* @param data Memory address of the data block to be processed. Must be
|
||||
* 32-bit aligned.
|
||||
* @param size Size of the data block in bytes. Must be a multiple of 4.
|
||||
* @return checksum result
|
||||
*/
|
||||
static uint32_t Compute(const uint32_t* data, size_t size) {
|
||||
SkASSERT(SkIsAlign4(size));
|
||||
|
||||
/*
|
||||
* We want to let the compiler use 32bit or 64bit addressing and math
|
||||
* so we use uintptr_t as our magic type. This makes the code a little
|
||||
* more obscure (we can't hard-code 32 or 64 anywhere, but have to use
|
||||
* sizeof()).
|
||||
*/
|
||||
uintptr_t result = 0;
|
||||
const uintptr_t* ptr = reinterpret_cast<const uintptr_t*>(data);
|
||||
|
||||
/*
|
||||
* count the number of quad element chunks. This takes into account
|
||||
* if we're on a 32bit or 64bit arch, since we use sizeof(uintptr_t)
|
||||
* to compute how much to shift-down the size.
|
||||
*/
|
||||
size_t n4 = size / (sizeof(uintptr_t) << 2);
|
||||
for (size_t i = 0; i < n4; ++i) {
|
||||
result = Mash(result, *ptr++);
|
||||
result = Mash(result, *ptr++);
|
||||
result = Mash(result, *ptr++);
|
||||
result = Mash(result, *ptr++);
|
||||
}
|
||||
size &= ((sizeof(uintptr_t) << 2) - 1);
|
||||
|
||||
data = reinterpret_cast<const uint32_t*>(ptr);
|
||||
const uint32_t* stop = data + (size >> 2);
|
||||
while (data < stop) {
|
||||
result = Mash(result, *data++);
|
||||
}
|
||||
|
||||
/*
|
||||
* smash us down to 32bits if we were 64. Note that when uintptr_t is
|
||||
* 32bits, this code-path should go away, but I still got a warning
|
||||
* when I wrote
|
||||
* result ^= result >> 32;
|
||||
* since >>32 is undefined for 32bit ints, hence the wacky HALFBITS
|
||||
* define.
|
||||
*/
|
||||
if (8 == sizeof(result)) {
|
||||
result ^= result >> HALFBITS;
|
||||
}
|
||||
return static_cast<uint32_t>(result);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -27,12 +27,12 @@ public:
|
|||
kReturnNil_AllocFailType,
|
||||
kThrow_AllocFailType
|
||||
};
|
||||
|
||||
|
||||
void* alloc(size_t bytes, AllocFailType);
|
||||
void* allocThrow(size_t bytes) {
|
||||
return this->alloc(bytes, kThrow_AllocFailType);
|
||||
}
|
||||
|
||||
|
||||
/** Call this to unalloc the most-recently allocated ptr by alloc(). On
|
||||
success, the number of bytes freed is returned, or 0 if the block could
|
||||
not be unallocated. This is a hint to the underlying allocator that
|
||||
|
@ -40,7 +40,7 @@ public:
|
|||
to ignore this call (and return 0).
|
||||
*/
|
||||
size_t unalloc(void* ptr);
|
||||
|
||||
|
||||
size_t totalCapacity() const { return fTotalCapacity; }
|
||||
int blockCount() const { return fBlockCount; }
|
||||
|
||||
|
|
|
@ -10,14 +10,23 @@
|
|||
|
||||
#include "SkDeque.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
struct SkRect;
|
||||
class SkPath;
|
||||
|
||||
// Because a single save/restore state can have multiple clips, this class
|
||||
// stores the stack depth (fSaveCount) and clips (fDeque) separately.
|
||||
// Each clip in fDeque stores the stack state to which it belongs
|
||||
// (i.e., the fSaveCount in force when it was added). Restores are thus
|
||||
// implemented by removing clips from fDeque that have an fSaveCount larger
|
||||
// then the freshly decremented count.
|
||||
class SK_API SkClipStack {
|
||||
public:
|
||||
SkClipStack();
|
||||
SkClipStack(const SkClipStack& b);
|
||||
explicit SkClipStack(const SkRect& r);
|
||||
explicit SkClipStack(const SkIRect& r);
|
||||
~SkClipStack();
|
||||
|
||||
SkClipStack& operator=(const SkClipStack& b);
|
||||
|
@ -30,6 +39,30 @@ public:
|
|||
void save();
|
||||
void restore();
|
||||
|
||||
enum BoundsType {
|
||||
// The bounding box contains all the pixels that can be written to
|
||||
kNormal_BoundsType,
|
||||
// The bounding box contains all the pixels that cannot be written to.
|
||||
// The real bound extends out to infinity and all the pixels outside
|
||||
// of the bound can be written to. Note that some of the pixels inside
|
||||
// the bound may also be writeable but all pixels that cannot be
|
||||
// written to are guaranteed to be inside.
|
||||
kInsideOut_BoundsType
|
||||
};
|
||||
|
||||
/**
|
||||
* getBounds places the current finite bound in its first parameter. In its
|
||||
* second, it indicates which kind of bound is being returned. If
|
||||
* 'canvFiniteBound' is a normal bounding box then it encloses all writeable
|
||||
* pixels. If 'canvFiniteBound' is an inside out bounding box then it
|
||||
* encloses all the un-writeable pixels and the true/normal bound is the
|
||||
* infinite plane. isIntersectionOfRects is an optional parameter
|
||||
* that is true if 'canvFiniteBound' resulted from an intersection of rects.
|
||||
*/
|
||||
void getBounds(SkRect* canvFiniteBound,
|
||||
BoundsType* boundType,
|
||||
bool* isIntersectionOfRects = NULL) const;
|
||||
|
||||
void clipDevRect(const SkIRect& ir, SkRegion::Op op) {
|
||||
SkRect r;
|
||||
r.set(ir);
|
||||
|
@ -37,18 +70,60 @@ public:
|
|||
}
|
||||
void clipDevRect(const SkRect&, SkRegion::Op, bool doAA);
|
||||
void clipDevPath(const SkPath&, SkRegion::Op, bool doAA);
|
||||
// An optimized version of clipDevRect(emptyRect, kIntersect, ...)
|
||||
void clipEmpty();
|
||||
|
||||
class B2FIter {
|
||||
/**
|
||||
* isWideOpen returns true if the clip state corresponds to the infinite
|
||||
* plane (i.e., draws are not limited at all)
|
||||
*/
|
||||
bool isWideOpen() const;
|
||||
|
||||
/**
|
||||
* Add a callback function that will be called whenever a clip state
|
||||
* is no longer viable. This will occur whenever restore
|
||||
* is called or when a clipDevRect or clipDevPath call updates the
|
||||
* clip within an existing save/restore state. Each clip state is
|
||||
* represented by a unique generation ID.
|
||||
*/
|
||||
typedef void (*PFPurgeClipCB)(int genID, void* data);
|
||||
void addPurgeClipCallback(PFPurgeClipCB callback, void* data) const;
|
||||
|
||||
/**
|
||||
* Remove a callback added earlier via addPurgeClipCallback
|
||||
*/
|
||||
void removePurgeClipCallback(PFPurgeClipCB callback, void* data) const;
|
||||
|
||||
/**
|
||||
* The generation ID has three reserved values to indicate special
|
||||
* (potentially ignoreable) cases
|
||||
*/
|
||||
static const int32_t kInvalidGenID = 0;
|
||||
static const int32_t kEmptyGenID = 1; // no pixels writeable
|
||||
static const int32_t kWideOpenGenID = 2; // all pixels writeable
|
||||
|
||||
int32_t getTopmostGenID() const;
|
||||
|
||||
private:
|
||||
struct Rec;
|
||||
|
||||
public:
|
||||
class Iter {
|
||||
public:
|
||||
enum IterStart {
|
||||
kBottom_IterStart = SkDeque::Iter::kFront_IterStart,
|
||||
kTop_IterStart = SkDeque::Iter::kBack_IterStart
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an uninitialized iterator. Must be reset()
|
||||
*/
|
||||
B2FIter();
|
||||
Iter();
|
||||
|
||||
B2FIter(const SkClipStack& stack);
|
||||
Iter(const SkClipStack& stack, IterStart startLoc);
|
||||
|
||||
struct Clip {
|
||||
Clip() : fRect(NULL), fPath(NULL), fOp(SkRegion::kIntersect_Op),
|
||||
Clip() : fRect(NULL), fPath(NULL), fOp(SkRegion::kIntersect_Op),
|
||||
fDoAA(false) {}
|
||||
friend bool operator==(const Clip& a, const Clip& b);
|
||||
friend bool operator!=(const Clip& a, const Clip& b);
|
||||
|
@ -56,6 +131,7 @@ public:
|
|||
const SkPath* fPath; // if non-null, this is a path clip
|
||||
SkRegion::Op fOp;
|
||||
bool fDoAA;
|
||||
int32_t fGenID;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -68,23 +144,116 @@ public:
|
|||
* fRect==NULL fPath==NULL empty clip
|
||||
*/
|
||||
const Clip* next();
|
||||
const Clip* prev();
|
||||
|
||||
/**
|
||||
* Moves the iterator to the topmost clip with the specified RegionOp
|
||||
* and returns that clip. If no clip with that op is found,
|
||||
* returns NULL.
|
||||
*/
|
||||
const Clip* skipToTopmost(SkRegion::Op op);
|
||||
|
||||
/**
|
||||
* Restarts the iterator on a clip stack.
|
||||
*/
|
||||
void reset(const SkClipStack& stack);
|
||||
void reset(const SkClipStack& stack, IterStart startLoc);
|
||||
|
||||
private:
|
||||
Clip fClip;
|
||||
SkDeque::F2BIter fIter;
|
||||
const SkClipStack* fStack;
|
||||
Clip fClip;
|
||||
SkDeque::Iter fIter;
|
||||
|
||||
/**
|
||||
* updateClip updates fClip to the current state of fIter. It unifies
|
||||
* functionality needed by both next() and prev().
|
||||
*/
|
||||
const Clip* updateClip(const SkClipStack::Rec* rec);
|
||||
};
|
||||
|
||||
/**
|
||||
* The B2TIter iterates from the bottom of the stack to the top.
|
||||
* It inherits privately from Iter to prevent access to reverse iteration.
|
||||
*/
|
||||
class B2TIter : private Iter {
|
||||
public:
|
||||
B2TIter() {}
|
||||
|
||||
/**
|
||||
* Wrap Iter's 2 parameter ctor to force initialization to the
|
||||
* beginning of the deque/bottom of the stack
|
||||
*/
|
||||
B2TIter(const SkClipStack& stack)
|
||||
: INHERITED(stack, kBottom_IterStart) {
|
||||
}
|
||||
|
||||
using Iter::Clip;
|
||||
using Iter::next;
|
||||
|
||||
/**
|
||||
* Wrap Iter::reset to force initialization to the
|
||||
* beginning of the deque/bottom of the stack
|
||||
*/
|
||||
void reset(const SkClipStack& stack) {
|
||||
this->INHERITED::reset(stack, kBottom_IterStart);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Iter INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetConservativeBounds returns a conservative bound of the current clip.
|
||||
* Since this could be the infinite plane (if inverse fills were involved) the
|
||||
* maxWidth and maxHeight parameters can be used to limit the returned bound
|
||||
* to the expected drawing area. Similarly, the offsetX and offsetY parameters
|
||||
* allow the caller to offset the returned bound to account for translated
|
||||
* drawing areas (i.e., those resulting from a saveLayer). For finite bounds,
|
||||
* the translation (+offsetX, +offsetY) is applied before the clamp to the
|
||||
* maximum rectangle: [0,maxWidth) x [0,maxHeight).
|
||||
* isIntersectionOfRects is an optional parameter that is true when
|
||||
* 'devBounds' is the result of an intersection of rects. In this case
|
||||
* 'devBounds' is the exact answer/clip.
|
||||
*/
|
||||
void getConservativeBounds(int offsetX,
|
||||
int offsetY,
|
||||
int maxWidth,
|
||||
int maxHeight,
|
||||
SkRect* devBounds,
|
||||
bool* isIntersectionOfRects = NULL) const;
|
||||
|
||||
private:
|
||||
friend class B2FIter;
|
||||
struct Rec;
|
||||
friend class Iter;
|
||||
|
||||
SkDeque fDeque;
|
||||
int fSaveCount;
|
||||
|
||||
// Generation ID for the clip stack. This is incremented for each
|
||||
// clipDevRect and clipDevPath call. 0 is reserved to indicate an
|
||||
// invalid ID.
|
||||
static int32_t gGenID;
|
||||
|
||||
struct ClipCallbackData {
|
||||
PFPurgeClipCB fCallback;
|
||||
void* fData;
|
||||
|
||||
friend bool operator==(const ClipCallbackData& a,
|
||||
const ClipCallbackData& b) {
|
||||
return a.fCallback == b.fCallback && a.fData == b.fData;
|
||||
}
|
||||
};
|
||||
|
||||
mutable SkTDArray<ClipCallbackData> fCallbackData;
|
||||
|
||||
/**
|
||||
* Invoke all the purge callbacks passing in rec's generation ID.
|
||||
*/
|
||||
void purgeClip(Rec* rec);
|
||||
|
||||
/**
|
||||
* Return the next unique generation ID.
|
||||
*/
|
||||
static int32_t GetNextGenID();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,8 +14,12 @@
|
|||
#include "SkFlattenable.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class SkBitmap;
|
||||
|
||||
class SK_API SkColorFilter : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkColorFilter)
|
||||
|
||||
/**
|
||||
* If the filter can be represented by a source color plus Mode, this
|
||||
* returns true, and sets (if not NULL) the color and mode appropriately.
|
||||
|
@ -91,7 +95,6 @@ public:
|
|||
*/
|
||||
SkColor filterColor(SkColor);
|
||||
|
||||
|
||||
/** Create a colorfilter that uses the specified color and mode.
|
||||
If the Mode is DST, this function will return NULL (since that
|
||||
mode will have no effect on the result).
|
||||
|
@ -103,21 +106,13 @@ public:
|
|||
*/
|
||||
static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::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* CreateProcFilter(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);
|
||||
|
||||
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
protected:
|
||||
SkColorFilter() {}
|
||||
|
@ -127,33 +122,4 @@ 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();
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkFilterShader)
|
||||
|
||||
protected:
|
||||
SkFilterShader(SkFlattenableReadBuffer& );
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkShader* fShader;
|
||||
SkColorFilter* fFilter;
|
||||
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,30 @@
|
|||
#include "SkColor.h"
|
||||
#include "SkMath.h"
|
||||
|
||||
///@{
|
||||
/** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/
|
||||
#define SK_ITU_BT709_LUM_COEFF_R (0.2126f)
|
||||
#define SK_ITU_BT709_LUM_COEFF_G (0.7152f)
|
||||
#define SK_ITU_BT709_LUM_COEFF_B (0.0722f)
|
||||
///@}
|
||||
|
||||
///@{
|
||||
/** A float value which specifies this channel's contribution to luminance. */
|
||||
#define SK_LUM_COEFF_R SK_ITU_BT709_LUM_COEFF_R
|
||||
#define SK_LUM_COEFF_G SK_ITU_BT709_LUM_COEFF_G
|
||||
#define SK_LUM_COEFF_B SK_ITU_BT709_LUM_COEFF_B
|
||||
///@}
|
||||
|
||||
/** Computes the luminance from the given r, g, and b in accordance with
|
||||
SK_LUM_COEFF_X. For correct results, r, g, and b should be in linear space.
|
||||
*/
|
||||
static inline U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b) {
|
||||
//The following is
|
||||
//r * SK_LUM_COEFF_R + g * SK_LUM_COEFF_G + b * SK_LUM_COEFF_B
|
||||
//with SK_LUM_COEFF_X in 1.8 fixed point (rounding adjusted to sum to 256).
|
||||
return (r * 54 + g * 183 + b * 19) >> 8;
|
||||
}
|
||||
|
||||
/** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a
|
||||
byte into a scale value, so that we can say scale * value >> 8 instead of
|
||||
alpha * value / 255.
|
||||
|
@ -53,7 +77,7 @@ static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) {
|
|||
SkASSERT((int16_t)src == src);
|
||||
SkASSERT((int16_t)dst == dst);
|
||||
SkASSERT((uint8_t)alpha == alpha);
|
||||
|
||||
|
||||
int prod = SkMulS16(src - dst, alpha) + 128;
|
||||
prod = (prod + (prod >> 8)) >> 8;
|
||||
return dst + prod;
|
||||
|
@ -228,7 +252,7 @@ static inline SkPMColor SkFourByteInterp256(SkPMColor src, SkPMColor dst,
|
|||
unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
|
||||
unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
|
||||
unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
|
||||
|
||||
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
|
||||
|
@ -740,32 +764,32 @@ static inline int SkBlend32(int src, int dst, int scale) {
|
|||
}
|
||||
|
||||
static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB,
|
||||
SkPMColor dst, uint16_t mask) {
|
||||
SkPMColor dst, uint16_t mask) {
|
||||
if (mask == 0) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/* We want all of these in 5bits, hence the shifts in case one of them
|
||||
* (green) is 6bits.
|
||||
*/
|
||||
int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
|
||||
int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
|
||||
int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
|
||||
|
||||
|
||||
// Now upscale them to 0..32, so we can use blend32
|
||||
maskR = SkUpscale31To32(maskR);
|
||||
maskG = SkUpscale31To32(maskG);
|
||||
maskB = SkUpscale31To32(maskB);
|
||||
|
||||
|
||||
// srcA has been upscaled to 256 before passed into this function
|
||||
maskR = maskR * srcA >> 8;
|
||||
maskG = maskG * srcA >> 8;
|
||||
maskB = maskB * srcA >> 8;
|
||||
|
||||
|
||||
int dstR = SkGetPackedR32(dst);
|
||||
int dstG = SkGetPackedG32(dst);
|
||||
int dstB = SkGetPackedB32(dst);
|
||||
|
||||
|
||||
// LCD blitting is only supported if the dst is known/required
|
||||
// to be opaque
|
||||
return SkPackARGB32(0xFF,
|
||||
|
@ -776,7 +800,7 @@ static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB,
|
|||
|
||||
static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB,
|
||||
SkPMColor dst, uint16_t mask,
|
||||
SkPMColor opaqueDst) {
|
||||
SkPMColor opaqueDst) {
|
||||
if (mask == 0) {
|
||||
return dst;
|
||||
}
|
||||
|
@ -784,23 +808,23 @@ static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB,
|
|||
if (0xFFFF == mask) {
|
||||
return opaqueDst;
|
||||
}
|
||||
|
||||
|
||||
/* We want all of these in 5bits, hence the shifts in case one of them
|
||||
* (green) is 6bits.
|
||||
*/
|
||||
int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
|
||||
int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
|
||||
int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
|
||||
|
||||
|
||||
// Now upscale them to 0..32, so we can use blend32
|
||||
maskR = SkUpscale31To32(maskR);
|
||||
maskG = SkUpscale31To32(maskG);
|
||||
maskB = SkUpscale31To32(maskB);
|
||||
|
||||
|
||||
int dstR = SkGetPackedR32(dst);
|
||||
int dstG = SkGetPackedG32(dst);
|
||||
int dstB = SkGetPackedB32(dst);
|
||||
|
||||
|
||||
// LCD blitting is only supported if the dst is known/required
|
||||
// to be opaque
|
||||
return SkPackARGB32(0xFF,
|
||||
|
@ -815,24 +839,24 @@ static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t src[],
|
|||
int srcR = SkColorGetR(color);
|
||||
int srcG = SkColorGetG(color);
|
||||
int srcB = SkColorGetB(color);
|
||||
|
||||
|
||||
srcA = SkAlpha255To256(srcA);
|
||||
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t src[],
|
||||
SkColor color, int width,
|
||||
SkColor color, int width,
|
||||
SkPMColor opaqueDst) {
|
||||
int srcR = SkColorGetR(color);
|
||||
int srcG = SkColorGetG(color);
|
||||
int srcB = SkColorGetB(color);
|
||||
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], src[i],
|
||||
opaqueDst);
|
||||
opaqueDst);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,7 @@ public:
|
|||
// we return false for this, use asAGradient
|
||||
virtual BitmapType asABitmap(SkBitmap* outTexture,
|
||||
SkMatrix* outMatrix,
|
||||
TileMode xy[2],
|
||||
SkScalar* twoPointRadialParams) const SK_OVERRIDE;
|
||||
TileMode xy[2]) const SK_OVERRIDE;
|
||||
|
||||
virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
|
||||
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkColorTable_DEFINED
|
||||
#define SkColorTable_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
/** \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 SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkColorTable)
|
||||
|
||||
/** Makes a deep copy of colors.
|
||||
*/
|
||||
SkColorTable(const SkColorTable& src);
|
||||
/** Preallocates the colortable to have 'count' colors, which
|
||||
* are initially set to 0.
|
||||
*/
|
||||
explicit SkColorTable(int count);
|
||||
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);
|
||||
|
||||
bool isOpaque() const { return (fFlags & kColorsAreOpaque_Flag) != 0; }
|
||||
void setIsOpaque(bool isOpaque);
|
||||
|
||||
/** 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(sk_atomic_inc(&fColorLockCount);)
|
||||
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);
|
||||
}
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorTable)
|
||||
|
||||
protected:
|
||||
explicit SkColorTable(SkFlattenableReadBuffer&);
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
|
||||
private:
|
||||
SkPMColor* fColors;
|
||||
uint16_t* f16BitCache;
|
||||
uint16_t fCount;
|
||||
uint8_t fFlags;
|
||||
SkDEBUGCODE(int fColorLockCount;)
|
||||
SkDEBUGCODE(int f16BitCacheLockCount;)
|
||||
|
||||
void inval16BitCache();
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -33,7 +33,7 @@ public:
|
|||
*/
|
||||
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);
|
||||
|
|
|
@ -11,20 +11,24 @@
|
|||
#ifndef SkData_DEFINED
|
||||
#define SkData_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
/**
|
||||
* SkData holds an immutable data buffer. Not only is the data immutable,
|
||||
* but the actual ptr that is returned (by data() or bytes()) is guaranteed
|
||||
* to always be the same for the life of this instance.
|
||||
*/
|
||||
class SkData : public SkRefCnt {
|
||||
class SK_API SkData : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkData)
|
||||
|
||||
/**
|
||||
* Returns the number of bytes stored.
|
||||
*/
|
||||
size_t size() const { return fSize; }
|
||||
|
||||
bool isEmpty() const { return 0 == fSize; }
|
||||
|
||||
/**
|
||||
* Returns the ptr to the data.
|
||||
*/
|
||||
|
@ -46,17 +50,31 @@ public:
|
|||
*/
|
||||
size_t copyRange(size_t offset, size_t length, void* buffer) const;
|
||||
|
||||
/**
|
||||
* Returns true if these two objects have the same length and contents,
|
||||
* effectively returning 0 == memcmp(...)
|
||||
*/
|
||||
bool equals(const SkData* other) const;
|
||||
|
||||
/**
|
||||
* Function that, if provided, will be called when the SkData goes out
|
||||
* of scope, allowing for custom allocation/freeing of the data.
|
||||
*/
|
||||
typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new dataref by copying the specified data
|
||||
*/
|
||||
static SkData* NewWithCopy(const void* data, size_t length);
|
||||
|
||||
/**
|
||||
* Create a new dataref by copying the specified c-string
|
||||
* (a null-terminated array of bytes). The returned SkData will have size()
|
||||
* equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
|
||||
* as "".
|
||||
*/
|
||||
static SkData* NewWithCString(const char cstr[]);
|
||||
|
||||
/**
|
||||
* Create a new dataref, taking the data ptr as is, and using the
|
||||
* releaseproc to free it. The proc may be NULL.
|
||||
|
@ -82,6 +100,12 @@ public:
|
|||
*/
|
||||
static SkData* NewEmpty();
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkData)
|
||||
|
||||
protected:
|
||||
SkData(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
ReleaseProc fReleaseProc;
|
||||
void* fReleaseProcContext;
|
||||
|
@ -90,7 +114,16 @@ private:
|
|||
size_t fSize;
|
||||
|
||||
SkData(const void* ptr, size_t size, ReleaseProc, void* context);
|
||||
~SkData();
|
||||
virtual ~SkData();
|
||||
|
||||
// This is here because SkAutoTUnref creates an internal helper class
|
||||
// that derives from SkData (i.e., BlockRef) to prevent refs\unrefs.
|
||||
// This helper class generates a compiler warning on Windows since the
|
||||
// SkData's destructor is private. This friending gives the helper class
|
||||
// access to the destructor.
|
||||
friend class SkAutoTUnref<SkData>::BlockRef<SkData>;
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -99,39 +132,25 @@ private:
|
|||
*/
|
||||
class SkAutoDataUnref : SkNoncopyable {
|
||||
public:
|
||||
SkAutoDataUnref(SkData* data) : fRef(data) {
|
||||
if (data) {
|
||||
fData = data->data();
|
||||
fSize = data->size();
|
||||
} else {
|
||||
fData = NULL;
|
||||
fSize = 0;
|
||||
}
|
||||
}
|
||||
SkAutoDataUnref(SkData* data) : fRef(data) {}
|
||||
~SkAutoDataUnref() {
|
||||
SkSafeUnref(fRef);
|
||||
}
|
||||
|
||||
const void* data() const { return fData; }
|
||||
const uint8_t* bytes() const {
|
||||
return reinterpret_cast<const uint8_t*> (fData);
|
||||
}
|
||||
size_t size() const { return fSize; }
|
||||
SkData* get() const { return fRef; }
|
||||
|
||||
void release() {
|
||||
if (fRef) {
|
||||
fRef->unref();
|
||||
fRef = NULL;
|
||||
fData = NULL;
|
||||
fSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SkData *operator->() const { return fRef; }
|
||||
operator SkData*() { return fRef; }
|
||||
|
||||
private:
|
||||
SkData* fRef;
|
||||
const void* fData;
|
||||
size_t fSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDataSet_DEFINED
|
||||
#define SkDataSet_DEFINED
|
||||
|
||||
#include "SkData.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
class SkDataSet : public SkFlattenable {
|
||||
public:
|
||||
/**
|
||||
* Returns a new empty dataset. Note: since SkDataSet is immutable, this
|
||||
* "new" set may be the same one that was returned before, but each
|
||||
* returned object must have its reference-count balanced regardless.
|
||||
*
|
||||
* SkDataSet* empty = SkDataSet::NewEmpty();
|
||||
* ...
|
||||
* empty->unref();
|
||||
*/
|
||||
static SkDataSet* NewEmpty();
|
||||
|
||||
struct Pair {
|
||||
const char* fKey;
|
||||
SkData* fValue;
|
||||
};
|
||||
|
||||
SkDataSet(const char key[], SkData* value);
|
||||
SkDataSet(const Pair[], int count);
|
||||
virtual ~SkDataSet();
|
||||
|
||||
bool isEmpty() const { return 0 == fCount; }
|
||||
int count() const { return fCount; }
|
||||
SkData* find(const char name[]) const;
|
||||
|
||||
class Iter {
|
||||
public:
|
||||
Iter(const SkDataSet& ds) {
|
||||
fPair = ds.fPairs;
|
||||
fStop = ds.fPairs + ds.fCount;
|
||||
}
|
||||
|
||||
const char* key() const {
|
||||
SkASSERT(!this->done());
|
||||
return fPair->fKey;
|
||||
}
|
||||
|
||||
SkData* value() const {
|
||||
SkASSERT(!this->done());
|
||||
return fPair->fValue;
|
||||
}
|
||||
|
||||
bool done() const { return fPair >= fStop; }
|
||||
void next() {
|
||||
SkASSERT(!this->done());
|
||||
fPair += 1;
|
||||
}
|
||||
|
||||
private:
|
||||
const SkDataSet::Pair* fPair;
|
||||
const SkDataSet::Pair* fStop;
|
||||
};
|
||||
|
||||
explicit SkDataSet(SkStream*);
|
||||
void writeToStream(SkWStream*) const;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDataSet)
|
||||
|
||||
protected:
|
||||
SkDataSet(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
int32_t fCount;
|
||||
uint32_t fKeySize;
|
||||
Pair* fPairs;
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -12,18 +12,33 @@
|
|||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/*
|
||||
* The deque class works by blindly creating memory space of a specified element
|
||||
* size. It manages the memory as a doubly linked list of blocks each of which
|
||||
* can contain multiple elements. Pushes and pops add/remove blocks from the
|
||||
* beginning/end of the list as necessary while each block tracks the used
|
||||
* portion of its memory.
|
||||
* One behavior to be aware of is that the pops do not immediately remove an
|
||||
* empty block from the beginning/end of the list (Presumably so push/pop pairs
|
||||
* on the block boundaries don't cause thrashing). This can result in the first/
|
||||
* last element not residing in the first/last block.
|
||||
*/
|
||||
class SK_API SkDeque : SkNoncopyable {
|
||||
public:
|
||||
explicit SkDeque(size_t elemSize);
|
||||
SkDeque(size_t elemSize, void* storage, size_t storageSize);
|
||||
/**
|
||||
* elemSize specifies the size of each individual element in the deque
|
||||
* allocCount specifies how many elements are to be allocated as a block
|
||||
*/
|
||||
explicit SkDeque(size_t elemSize, int allocCount = 1);
|
||||
SkDeque(size_t elemSize, void* storage, size_t storageSize, int allocCount = 1);
|
||||
~SkDeque();
|
||||
|
||||
bool empty() const { return 0 == fCount; }
|
||||
int count() const { return fCount; }
|
||||
size_t elemSize() const { return fElemSize; }
|
||||
|
||||
const void* front() const;
|
||||
const void* back() const;
|
||||
const void* front() const { return fFront; }
|
||||
const void* back() const { return fBack; }
|
||||
|
||||
void* front() {
|
||||
return (void*)((const SkDeque*)this)->front();
|
||||
|
@ -33,6 +48,10 @@ public:
|
|||
return (void*)((const SkDeque*)this)->back();
|
||||
}
|
||||
|
||||
/**
|
||||
* push_front and push_back return a pointer to the memory space
|
||||
* for the new element
|
||||
*/
|
||||
void* push_front();
|
||||
void* push_back();
|
||||
|
||||
|
@ -40,35 +59,80 @@ public:
|
|||
void pop_back();
|
||||
|
||||
private:
|
||||
struct Head;
|
||||
struct Block;
|
||||
|
||||
public:
|
||||
class F2BIter {
|
||||
class Iter {
|
||||
public:
|
||||
enum IterStart {
|
||||
kFront_IterStart,
|
||||
kBack_IterStart
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an uninitialized iterator. Must be reset()
|
||||
*/
|
||||
F2BIter();
|
||||
Iter();
|
||||
|
||||
F2BIter(const SkDeque& d);
|
||||
Iter(const SkDeque& d, IterStart startLoc);
|
||||
void* next();
|
||||
void* prev();
|
||||
|
||||
void reset(const SkDeque& d);
|
||||
void reset(const SkDeque& d, IterStart startLoc);
|
||||
|
||||
private:
|
||||
SkDeque::Head* fHead;
|
||||
SkDeque::Block* fCurBlock;
|
||||
char* fPos;
|
||||
size_t fElemSize;
|
||||
};
|
||||
|
||||
// Inherit privately from Iter to prevent access to reverse iteration
|
||||
class F2BIter : private Iter {
|
||||
public:
|
||||
F2BIter() {}
|
||||
|
||||
/**
|
||||
* Wrap Iter's 2 parameter ctor to force initialization to the
|
||||
* beginning of the deque
|
||||
*/
|
||||
F2BIter(const SkDeque& d) : INHERITED(d, kFront_IterStart) {}
|
||||
|
||||
using Iter::next;
|
||||
|
||||
/**
|
||||
* Wrap Iter::reset to force initialization to the beginning of the
|
||||
* deque
|
||||
*/
|
||||
void reset(const SkDeque& d) {
|
||||
this->INHERITED::reset(d, kFront_IterStart);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef Iter INHERITED;
|
||||
};
|
||||
|
||||
private:
|
||||
Head* fFront;
|
||||
Head* fBack;
|
||||
// allow unit test to call numBlocksAllocated
|
||||
friend class DequeUnitTestHelper;
|
||||
|
||||
void* fFront;
|
||||
void* fBack;
|
||||
|
||||
Block* fFrontBlock;
|
||||
Block* fBackBlock;
|
||||
size_t fElemSize;
|
||||
void* fInitialStorage;
|
||||
int fCount;
|
||||
int fCount; // number of elements in the deque
|
||||
int fAllocCount; // number of elements to allocate per block
|
||||
|
||||
friend class Iter;
|
||||
Block* allocateBlock(int allocCount);
|
||||
void freeBlock(Block* block);
|
||||
|
||||
/**
|
||||
* This returns the number of chunk blocks allocated by the deque. It
|
||||
* can be used to gauge the effectiveness of the selected allocCount.
|
||||
*/
|
||||
int numBlocksAllocated() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,8 @@ class SkGpuRenderTarget;
|
|||
|
||||
class SK_API SkDevice : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDevice)
|
||||
|
||||
/**
|
||||
* Construct a new device with the specified bitmap as its backend. It is
|
||||
* valid for the bitmap to have no pixels associated with it. In that case,
|
||||
|
@ -136,6 +138,34 @@ public:
|
|||
*/
|
||||
const SkIPoint& getOrigin() const { return fOrigin; }
|
||||
|
||||
/**
|
||||
* onAttachToCanvas is invoked whenever a device is installed in a canvas
|
||||
* (i.e., setDevice, saveLayer (for the new device created by the save),
|
||||
* and SkCanvas' SkDevice & SkBitmap -taking ctors). It allows the
|
||||
* devices to prepare for drawing (e.g., locking their pixels, etc.)
|
||||
*/
|
||||
virtual void onAttachToCanvas(SkCanvas* canvas) {
|
||||
SkASSERT(!fAttachedToCanvas);
|
||||
this->lockPixels();
|
||||
#ifdef SK_DEBUG
|
||||
fAttachedToCanvas = true;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* onDetachFromCanvas notifies a device that it will no longer be drawn to.
|
||||
* It gives the device a chance to clean up (e.g., unlock its pixels). It
|
||||
* is invoked from setDevice (for the displaced device), restore and
|
||||
* possibly from SkCanvas' dtor.
|
||||
*/
|
||||
virtual void onDetachFromCanvas() {
|
||||
SkASSERT(fAttachedToCanvas);
|
||||
this->unlockPixels();
|
||||
#ifdef SK_DEBUG
|
||||
fAttachedToCanvas = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
enum Usage {
|
||||
kGeneral_Usage,
|
||||
|
@ -175,8 +205,9 @@ protected:
|
|||
/** Called when this device gains focus (i.e becomes the current device
|
||||
for drawing).
|
||||
*/
|
||||
virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
|
||||
const SkClipStack&) {}
|
||||
virtual void gainFocus(const SkMatrix&, const SkRegion&) {
|
||||
SkASSERT(fAttachedToCanvas);
|
||||
}
|
||||
|
||||
/** Clears the entire device to the specified color (including alpha).
|
||||
* Ignores the clip.
|
||||
|
@ -283,7 +314,7 @@ protected:
|
|||
access the pixels directly. Note: only the pixels field should be
|
||||
altered. The config/width/height/rowbytes must remain unchanged.
|
||||
@param bitmap The device's bitmap
|
||||
@return Echo the bitmap parameter, or an alternate (shadow) bitmap
|
||||
@return Echo the bitmap parameter, or an alternate (shadow) bitmap
|
||||
maintained by the subclass.
|
||||
*/
|
||||
virtual const SkBitmap& onAccessBitmap(SkBitmap*);
|
||||
|
@ -351,19 +382,11 @@ private:
|
|||
friend class SkDeviceFilteredPaint;
|
||||
friend class DeviceImageFilterProxy;
|
||||
|
||||
/**
|
||||
* postSave is called by SkCanvas to inform the device that it has
|
||||
* just completed a save operation. This allows derived
|
||||
* classes to initialize their state-dependent caches.
|
||||
*/
|
||||
virtual void postSave() {};
|
||||
|
||||
/**
|
||||
* preRestore is called by SkCanvas right before it executes a restore
|
||||
* operation. As the partner of postSave, it allows
|
||||
* derived classes to clear their state-dependent caches.
|
||||
*/
|
||||
virtual void preRestore() {};
|
||||
friend class SkSurface_Raster;
|
||||
// used to change the backend's pixels (and possibly config/rowbytes)
|
||||
// but cannot change the width/height, so there should be no change to
|
||||
// any clip information.
|
||||
void replaceBitmapBackendForRasterSurface(const SkBitmap&);
|
||||
|
||||
// just called by SkCanvas when built as a layer
|
||||
void setOrigin(int x, int y) { fOrigin.set(x, y); }
|
||||
|
@ -387,6 +410,12 @@ private:
|
|||
SkBitmap fBitmap;
|
||||
SkIPoint fOrigin;
|
||||
SkMetaData* fMetaData;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
bool fAttachedToCanvas;
|
||||
#endif
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
static inline SkPMColor SkDitherARGB32For565(SkPMColor c, unsigned dither)
|
||||
{
|
||||
SkASSERT(dither <= SK_DitherValueMax565);
|
||||
|
||||
|
||||
unsigned sa = SkGetPackedA32(c);
|
||||
dither = SkAlphaMul(dither, SkAlpha255To256(sa));
|
||||
|
||||
|
@ -81,21 +81,21 @@ static inline SkPMColor SkDitherARGB32For565(SkPMColor c, unsigned dither)
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -112,29 +112,29 @@ static inline uint16_t SkDitherRGBTo565(U8CPU r, U8CPU g, U8CPU 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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, U8CPU g,
|
|||
r = SkDITHER_R32To4444(r, dither);
|
||||
g = SkDITHER_G32To4444(g, dither);
|
||||
b = SkDITHER_B32To4444(b, dither);
|
||||
|
||||
|
||||
return SkPackARGB4444(a, r, g, b);
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ static inline SkPMColor16 SkDitherARGB32To4444(SkPMColor c, unsigned dither)
|
|||
r = SkDITHER_R32To4444(r, dither);
|
||||
g = SkDITHER_G32To4444(g, dither);
|
||||
b = SkDITHER_B32To4444(b, dither);
|
||||
|
||||
|
||||
return SkPackARGB4444(a, r, g, b);
|
||||
}
|
||||
|
||||
|
|
|
@ -125,35 +125,6 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
class SkGlyphCache;
|
||||
|
||||
class SkTextToPathIter {
|
||||
public:
|
||||
SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
|
||||
bool applyStrokeAndPathEffects, bool useCanonicalTextSize = true);
|
||||
~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
|
||||
bool nextWithWhitespace(const SkPath** path, SkScalar* xpos); //!< returns false 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;
|
||||
int fXYIndex; // cache for horizontal -vs- vertical text
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ class SkPaint;
|
|||
*/
|
||||
class SkDrawFilter : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDrawFilter)
|
||||
|
||||
enum Type {
|
||||
kPaint_Type,
|
||||
kPoint_Type,
|
||||
|
@ -38,6 +40,9 @@ public:
|
|||
* The implementation may modify the paint as they wish.
|
||||
*/
|
||||
virtual void filter(SkPaint*, Type) = 0;
|
||||
|
||||
private:
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
struct SkRect;
|
||||
|
||||
/** \class SkDrawLooper
|
||||
Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
|
||||
|
@ -25,6 +26,8 @@ class SkPaint;
|
|||
*/
|
||||
class SK_API SkDrawLooper : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDrawLooper)
|
||||
|
||||
/**
|
||||
* Called right before something is being drawn. This will be followed by
|
||||
* calls to next() until next() returns false.
|
||||
|
@ -44,7 +47,7 @@ public:
|
|||
* init() was first called.
|
||||
*/
|
||||
virtual bool next(SkCanvas*, SkPaint* paint) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The fast bounds functions are used to enable the paint to be culled early
|
||||
* in the drawing pipeline. If a subclass can support this feature it must
|
||||
|
|
|
@ -30,8 +30,7 @@ typedef int32_t SkFixed;
|
|||
#define SK_FixedTanPIOver8 (0x6A0A)
|
||||
#define SK_FixedRoot2Over2 (0xB505)
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SkFixedToFloat(x) ((x) * 1.5258789e-5f)
|
||||
#define SkFixedToFloat(x) ((x) * 1.5258789e-5f)
|
||||
#if 1
|
||||
#define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
#else
|
||||
|
@ -42,10 +41,20 @@ typedef int32_t SkFixed;
|
|||
}
|
||||
#endif
|
||||
|
||||
#define SkFixedToDouble(x) ((x) * 1.5258789e-5)
|
||||
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
#ifdef SK_DEBUG
|
||||
static inline SkFixed SkFloatToFixed_Check(float x) {
|
||||
int64_t n64 = (int64_t)(x * SK_Fixed1);
|
||||
SkFixed n32 = (SkFixed)n64;
|
||||
SkASSERT(n64 == n32);
|
||||
return n32;
|
||||
}
|
||||
#else
|
||||
#define SkFloatToFixed_Check(x) SkFloatToFixed(x)
|
||||
#endif
|
||||
|
||||
#define SkFixedToDouble(x) ((x) * 1.5258789e-5)
|
||||
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
|
||||
/** 32 bit signed integer used to represent fractions values with 30 bits to the right of the decimal point
|
||||
*/
|
||||
typedef int32_t SkFract;
|
||||
|
@ -53,10 +62,8 @@ typedef int32_t SkFract;
|
|||
#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
|
||||
#define SkFractToFloat(x) ((float)(x) * 0.00000000093132257f)
|
||||
#define SkFloatToFract(x) ((SkFract)((x) * SK_Fract1))
|
||||
|
||||
/** Converts an integer to a SkFixed, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
|
|
|
@ -30,19 +30,19 @@ public:
|
|||
* putting the result into dst. Returns false if an error occurs.
|
||||
*/
|
||||
static bool Deflate(SkStream* src, SkWStream* dst);
|
||||
|
||||
|
||||
/**
|
||||
* Use the flate compression algorithm to compress the data in src,
|
||||
* putting the result into dst. Returns false if an error occurs.
|
||||
*/
|
||||
static bool Deflate(const void* src, size_t len, SkWStream* dst);
|
||||
|
||||
|
||||
/**
|
||||
* Use the flate compression algorithm to compress the data,
|
||||
* putting the result into dst. Returns false if an error occurs.
|
||||
*/
|
||||
static bool Deflate(const SkData*, SkWStream* dst);
|
||||
|
||||
|
||||
/** Use the flate compression algorithm to decompress the data in src,
|
||||
putting the result into dst. Returns false if an error occurs.
|
||||
*/
|
||||
|
|
|
@ -11,16 +11,9 @@
|
|||
#define SkFlattenable_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkReader32.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkWriter32.h"
|
||||
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
class SkString;
|
||||
|
||||
#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
|
||||
|
||||
|
@ -55,29 +48,31 @@ class SkString;
|
|||
virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \
|
||||
|
||||
#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
|
||||
virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }; \
|
||||
virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } \
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \
|
||||
return SkNEW_ARGS(flattenable, (buffer)); \
|
||||
}
|
||||
|
||||
/** \class SkFlattenable
|
||||
|
||||
|
||||
SkFlattenable is the base class for objects that need to be flattened
|
||||
into a data stream for either transport or as part of the key to the
|
||||
font cache.
|
||||
*/
|
||||
class SK_API SkFlattenable : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkFlattenable)
|
||||
|
||||
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;
|
||||
|
||||
|
||||
static Factory NameToFactory(const char name[]);
|
||||
static const char* FactoryToName(Factory);
|
||||
static void Register(const char name[], Factory);
|
||||
|
@ -104,205 +99,8 @@ private:
|
|||
|
||||
friend class SkGraphics;
|
||||
friend class SkFlattenableWriteBuffer;
|
||||
};
|
||||
|
||||
// helpers for matrix and region
|
||||
|
||||
class SkMatrix;
|
||||
extern void SkReadMatrix(SkReader32*, SkMatrix*);
|
||||
extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
|
||||
|
||||
class SkRegion;
|
||||
extern void SkReadRegion(SkReader32*, SkRegion*);
|
||||
extern void SkWriteRegion(SkWriter32*, const SkRegion&);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkTypeface;
|
||||
|
||||
class SkFlattenableReadBuffer {
|
||||
public:
|
||||
SkFlattenableReadBuffer();
|
||||
virtual ~SkFlattenableReadBuffer() {}
|
||||
|
||||
|
||||
virtual uint8_t readU8() = 0;
|
||||
virtual uint16_t readU16() = 0;
|
||||
virtual uint32_t readU32() = 0;
|
||||
virtual void read(void* dst, size_t size) = 0;
|
||||
virtual bool readBool() = 0;
|
||||
virtual int32_t readInt() = 0;
|
||||
virtual SkScalar readScalar() = 0;
|
||||
virtual const void* skip(size_t size) = 0;
|
||||
|
||||
virtual int32_t readS32() { return readInt(); }
|
||||
template <typename T> const T& skipT() {
|
||||
SkASSERT(SkAlign4(sizeof(T)) == sizeof(T));
|
||||
return *(const T*)this->skip(sizeof(T));
|
||||
}
|
||||
|
||||
virtual void readMatrix(SkMatrix*) = 0;
|
||||
virtual void readPath(SkPath*) = 0;
|
||||
virtual void readPoint(SkPoint*) = 0;
|
||||
|
||||
// helper function for classes with const SkPoint members
|
||||
SkPoint readPoint() {
|
||||
SkPoint point;
|
||||
this->readPoint(&point);
|
||||
return point;
|
||||
}
|
||||
|
||||
void setRefCntArray(SkRefCnt* array[], int count) {
|
||||
fRCArray = array;
|
||||
fRCCount = count;
|
||||
}
|
||||
|
||||
void setTypefaceArray(SkTypeface* array[], int count) {
|
||||
fTFArray = array;
|
||||
fTFCount = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this with a pre-loaded array of Factories, in the same order as
|
||||
* were created/written by the writer. SkPicture uses this.
|
||||
*/
|
||||
void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
|
||||
fFactoryTDArray = NULL;
|
||||
fFactoryArray = array;
|
||||
fFactoryCount = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this with an initially empty array, so the reader can cache each
|
||||
* factory it sees by name. Used by the pipe code in conjunction with
|
||||
* the writer's kInlineFactoryNames_Flag.
|
||||
*/
|
||||
void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) {
|
||||
fFactoryTDArray = array;
|
||||
fFactoryArray = NULL;
|
||||
fFactoryCount = 0;
|
||||
}
|
||||
|
||||
virtual SkTypeface* readTypeface() = 0;
|
||||
virtual SkRefCnt* readRefCnt() = 0;
|
||||
virtual void* readFunctionPtr() = 0;
|
||||
virtual SkFlattenable* readFlattenable() = 0;
|
||||
|
||||
protected:
|
||||
SkRefCnt** fRCArray;
|
||||
int fRCCount;
|
||||
|
||||
SkTypeface** fTFArray;
|
||||
int fTFCount;
|
||||
|
||||
SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
|
||||
SkFlattenable::Factory* fFactoryArray;
|
||||
int fFactoryCount;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkPtrRecorder.h"
|
||||
|
||||
/**
|
||||
* Subclass of SkTPtrSet specialed to call ref() and unref() when the
|
||||
* base class's incPtr() and decPtr() are called. This makes it a valid owner
|
||||
* of each ptr, which is released when the set is reset or destroyed.
|
||||
*/
|
||||
class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
|
||||
public:
|
||||
virtual ~SkRefCntSet();
|
||||
|
||||
protected:
|
||||
// overrides
|
||||
virtual void incPtr(void*);
|
||||
virtual void decPtr(void*);
|
||||
};
|
||||
|
||||
class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
|
||||
|
||||
class SkFlattenableWriteBuffer {
|
||||
public:
|
||||
SkFlattenableWriteBuffer();
|
||||
virtual ~SkFlattenableWriteBuffer();
|
||||
|
||||
// deprecated naming convention that will be removed after callers are updated
|
||||
virtual bool writeBool(bool value) = 0;
|
||||
virtual void writeInt(int32_t value) = 0;
|
||||
virtual void write8(int32_t value) = 0;
|
||||
virtual void write16(int32_t value) = 0;
|
||||
virtual void write32(int32_t value) = 0;
|
||||
virtual void writeScalar(SkScalar value) = 0;
|
||||
virtual void writeMul4(const void* values, size_t size) = 0;
|
||||
|
||||
virtual void writePad(const void* src, size_t size) = 0;
|
||||
virtual void writeString(const char* str, size_t len = (size_t)-1) = 0;
|
||||
virtual uint32_t* reserve(size_t size) = 0;
|
||||
virtual void flatten(void* dst) = 0;
|
||||
virtual uint32_t size() = 0;
|
||||
virtual void write(const void* values, size_t size) = 0;
|
||||
virtual void writeRect(const SkRect& rect) = 0;
|
||||
virtual size_t readFromStream(SkStream*, size_t length) = 0;
|
||||
|
||||
virtual void writeMatrix(const SkMatrix& matrix) = 0;
|
||||
virtual void writePath(const SkPath& path) = 0;
|
||||
virtual void writePoint(const SkPoint& point) = 0;
|
||||
|
||||
virtual bool writeToStream(SkWStream*) = 0;
|
||||
|
||||
virtual void writeFunctionPtr(void*)= 0;
|
||||
virtual void writeFlattenable(SkFlattenable* flattenable)= 0;
|
||||
|
||||
void writeTypeface(SkTypeface*);
|
||||
void writeRefCnt(SkRefCnt* obj);
|
||||
|
||||
SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
|
||||
SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
|
||||
|
||||
SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
|
||||
SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
|
||||
|
||||
SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
|
||||
SkFactorySet* setFactoryRecorder(SkFactorySet*);
|
||||
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 0x01,
|
||||
/**
|
||||
* Instructs the writer to inline Factory names as there are seen the
|
||||
* first time (after that we store an index). The pipe code uses this.
|
||||
*/
|
||||
kInlineFactoryNames_Flag = 0x02
|
||||
};
|
||||
Flags getFlags() const { return (Flags)fFlags; }
|
||||
void setFlags(Flags flags) { fFlags = flags; }
|
||||
|
||||
bool isCrossProcess() const {
|
||||
return SkToBool(fFlags & kCrossProcess_Flag);
|
||||
}
|
||||
bool inlineFactoryNames() const {
|
||||
return SkToBool(fFlags & kInlineFactoryNames_Flag);
|
||||
}
|
||||
|
||||
bool persistBitmapPixels() const {
|
||||
return (fFlags & kCrossProcess_Flag) != 0;
|
||||
}
|
||||
|
||||
bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
|
||||
|
||||
protected:
|
||||
|
||||
// A helper function so that each subclass does not have to be a friend of
|
||||
// SkFlattenable.
|
||||
void flattenObject(SkFlattenable* obj, SkFlattenableWriteBuffer& buffer) {
|
||||
obj->flatten(buffer);
|
||||
}
|
||||
|
||||
uint32_t fFlags;
|
||||
SkRefCntSet* fTFSet;
|
||||
SkRefCntSet* fRCSet;
|
||||
SkFactorySet* fFactorySet;
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFlattenableBuffers_DEFINED
|
||||
#define SkFlattenableBuffers_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkFlattenable;
|
||||
struct SkIRect;
|
||||
class SkMatrix;
|
||||
class SkOrderedReadBuffer;
|
||||
class SkOrderedWriteBuffer;
|
||||
class SkPath;
|
||||
class SkPixelRef;
|
||||
struct SkRect;
|
||||
class SkRefCnt;
|
||||
class SkRegion;
|
||||
class SkStream;
|
||||
class SkString;
|
||||
class SkTypeface;
|
||||
class SkWStream;
|
||||
|
||||
class SkFlattenableReadBuffer {
|
||||
public:
|
||||
SkFlattenableReadBuffer();
|
||||
virtual ~SkFlattenableReadBuffer();
|
||||
|
||||
bool isOrderedBinaryBuffer() { return NULL != getOrderedBinaryBuffer(); }
|
||||
virtual SkOrderedReadBuffer* getOrderedBinaryBuffer() { return NULL; }
|
||||
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 1 << 0,
|
||||
kScalarIsFloat_Flag = 1 << 1,
|
||||
kPtrIs64Bit_Flag = 1 << 2,
|
||||
};
|
||||
|
||||
void setFlags(uint32_t flags) { fFlags = flags; }
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
|
||||
bool isCrossProcess() const { return SkToBool(fFlags & kCrossProcess_Flag); }
|
||||
bool isScalarFloat() const { return SkToBool(fFlags & kScalarIsFloat_Flag); }
|
||||
bool isPtr64Bit() const { return SkToBool(fFlags & kPtrIs64Bit_Flag); }
|
||||
|
||||
// primitives
|
||||
virtual bool readBool() = 0;
|
||||
virtual SkColor readColor() = 0;
|
||||
virtual SkFixed readFixed() = 0;
|
||||
virtual int32_t readInt() = 0;
|
||||
virtual SkScalar readScalar() = 0;
|
||||
virtual uint32_t readUInt() = 0;
|
||||
virtual int32_t read32() = 0;
|
||||
|
||||
// strings -- the caller is responsible for freeing the string contents
|
||||
virtual char* readString() = 0;
|
||||
virtual void* readEncodedString(size_t* length, SkPaint::TextEncoding encoding) = 0;
|
||||
|
||||
// common data structures
|
||||
virtual SkFlattenable* readFlattenable() = 0;
|
||||
virtual void readPoint(SkPoint* point) = 0;
|
||||
virtual void readMatrix(SkMatrix* matrix) = 0;
|
||||
virtual void readIRect(SkIRect* rect) = 0;
|
||||
virtual void readRect(SkRect* rect) = 0;
|
||||
virtual void readRegion(SkRegion* region) = 0;
|
||||
virtual void readPath(SkPath* path) = 0;
|
||||
|
||||
// binary data and arrays
|
||||
virtual uint32_t readByteArray(void* value) = 0;
|
||||
virtual uint32_t readColorArray(SkColor* colors) = 0;
|
||||
virtual uint32_t readIntArray(int32_t* values) = 0;
|
||||
virtual uint32_t readPointArray(SkPoint* points) = 0;
|
||||
virtual uint32_t readScalarArray(SkScalar* values) = 0;
|
||||
|
||||
/** This helper peeks into the buffer and reports back the length of the next array in
|
||||
* the buffer but does not change the state of the buffer.
|
||||
*/
|
||||
virtual uint32_t getArrayCount() = 0;
|
||||
|
||||
// helper functions
|
||||
virtual void* readFunctionPtr();
|
||||
virtual void readPaint(SkPaint* paint);
|
||||
|
||||
virtual void readBitmap(SkBitmap* bitmap) = 0;
|
||||
virtual SkTypeface* readTypeface() = 0;
|
||||
|
||||
// helper function for classes with const SkPoint members
|
||||
SkPoint readPoint() {
|
||||
SkPoint point;
|
||||
this->readPoint(&point);
|
||||
return point;
|
||||
}
|
||||
|
||||
template <typename T> T* readFlattenableT() {
|
||||
return static_cast<T*>(this->readFlattenable());
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t fFlags;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkFlattenableWriteBuffer {
|
||||
public:
|
||||
SkFlattenableWriteBuffer();
|
||||
virtual ~SkFlattenableWriteBuffer();
|
||||
|
||||
virtual bool isOrderedBinaryBuffer() { return false; }
|
||||
virtual SkOrderedWriteBuffer* getOrderedBinaryBuffer() { sk_throw(); return NULL; }
|
||||
|
||||
// primitives
|
||||
virtual void writeByteArray(const void* data, size_t size) = 0;
|
||||
virtual void writeBool(bool value) = 0;
|
||||
virtual void writeFixed(SkFixed value) = 0;
|
||||
virtual void writeScalar(SkScalar value) = 0;
|
||||
virtual void writeScalarArray(const SkScalar* value, uint32_t count) = 0;
|
||||
virtual void writeInt(int32_t value) = 0;
|
||||
virtual void writeIntArray(const int32_t* value, uint32_t count) = 0;
|
||||
virtual void writeUInt(uint32_t value) = 0;
|
||||
virtual void write32(int32_t value) = 0; // printf in hex
|
||||
virtual void writeString(const char* value) = 0;
|
||||
virtual void writeEncodedString(const void* value, size_t byteLength,
|
||||
SkPaint::TextEncoding encoding) = 0;
|
||||
|
||||
// common data structures
|
||||
virtual void writeFlattenable(SkFlattenable* flattenable) = 0;
|
||||
virtual void writeColor(const SkColor& color) = 0;
|
||||
virtual void writeColorArray(const SkColor* color, uint32_t count) = 0;
|
||||
virtual void writePoint(const SkPoint& point) = 0;
|
||||
virtual void writePointArray(const SkPoint* points, uint32_t count) = 0;
|
||||
virtual void writeMatrix(const SkMatrix& matrix) = 0;
|
||||
virtual void writeIRect(const SkIRect& rect) = 0;
|
||||
virtual void writeRect(const SkRect& rect) = 0;
|
||||
virtual void writeRegion(const SkRegion& region) = 0;
|
||||
virtual void writePath(const SkPath& path) = 0;
|
||||
virtual size_t writeStream(SkStream* stream, size_t length) = 0;
|
||||
|
||||
// helper functions
|
||||
virtual void writeFunctionPtr(void* ptr);
|
||||
virtual void writePaint(const SkPaint& paint);
|
||||
|
||||
virtual void writeBitmap(const SkBitmap& bitmap) = 0;
|
||||
virtual void writeTypeface(SkTypeface* typeface) = 0;
|
||||
|
||||
virtual bool writeToStream(SkWStream*) = 0;
|
||||
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 0x01,
|
||||
|
||||
/**
|
||||
* Instructs the writer to always serialize bitmap pixel data.
|
||||
*/
|
||||
kForceFlattenBitmapPixels_Flag = 0x04,
|
||||
};
|
||||
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
void setFlags(uint32_t flags) { fFlags = flags; }
|
||||
|
||||
bool isCrossProcess() const {
|
||||
return SkToBool(fFlags & kCrossProcess_Flag);
|
||||
}
|
||||
|
||||
bool persistBitmapPixels() const {
|
||||
return (fFlags & (kCrossProcess_Flag | kForceFlattenBitmapPixels_Flag)) != 0;
|
||||
}
|
||||
|
||||
bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
|
||||
|
||||
protected:
|
||||
// A helper function so that each subclass does not have to be a friend of SkFlattenable
|
||||
void flattenObject(SkFlattenable* obj, SkFlattenableWriteBuffer& buffer);
|
||||
|
||||
uint32_t fFlags;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -57,8 +57,6 @@ SK_API int32_t SkFloatBits_toIntRound(int32_t floatBits);
|
|||
SK_API int32_t SkFloatBits_toIntCeil(int32_t floatBits);
|
||||
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
|
||||
union SkFloatIntUnion {
|
||||
float fFloat;
|
||||
int32_t fSignBitInt;
|
||||
|
@ -127,8 +125,6 @@ static inline int32_t SkFloatToIntCeil(float x) {
|
|||
return SkFloatBits_toIntCeil(SkFloat2Bits(x));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Scalar wrappers for float-bit routines
|
||||
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
|
|
|
@ -12,16 +12,15 @@
|
|||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include "SkFloatBits.h"
|
||||
|
||||
// If math.h had powf(float, float), I could remove this wrapper
|
||||
// C++98 cmath std::pow seems to be the earliest portable way to get float pow.
|
||||
// However, on Linux including cmath undefines isfinite.
|
||||
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14608
|
||||
static inline float sk_float_pow(float base, float exp) {
|
||||
return static_cast<float>(pow(static_cast<double>(base),
|
||||
static_cast<double>(exp)));
|
||||
return powf(base, exp);
|
||||
}
|
||||
|
||||
static inline float sk_float_copysign(float x, float y) {
|
||||
|
@ -89,4 +88,3 @@ static inline float sk_float_copysign(float x, float y) {
|
|||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
#ifndef SkFontHost_DEFINED
|
||||
#define SkFontHost_DEFINED
|
||||
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
class SkDescriptor;
|
||||
class SkScalerContext;
|
||||
struct SkScalerContextRec;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
|
@ -118,12 +119,17 @@ public:
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Write a unique identifier to the stream, so that the same typeface can
|
||||
be retrieved with Deserialize().
|
||||
be retrieved with Deserialize(). The standard format is to serialize
|
||||
a SkFontDescriptor followed by a uint32_t length value. If the length
|
||||
is non-zero then the following bytes (of that length) represent a
|
||||
serialized copy of the font which can be recreated from a stream.
|
||||
*/
|
||||
static void Serialize(const SkTypeface*, SkWStream*);
|
||||
|
||||
/** Given a stream created by Serialize(), return a new typeface (like
|
||||
CreateTypeface) or return NULL if no match is found.
|
||||
CreateTypeface) which is either an exact match to the one serialized
|
||||
or the best available typeface based on the data in the deserialized
|
||||
SkFontDescriptor.
|
||||
*/
|
||||
static SkTypeface* Deserialize(SkStream*);
|
||||
|
||||
|
@ -162,7 +168,7 @@ public:
|
|||
|
||||
A lazy (but valid) fonthost can do nothing in its FilterRec routine.
|
||||
*/
|
||||
static void FilterRec(SkScalerContext::Rec* rec);
|
||||
static void FilterRec(SkScalerContextRec* rec);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -222,15 +228,6 @@ public:
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** DEPRECATED -- only called by SkFontHost_FreeType internally
|
||||
|
||||
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]);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** LCDs either have their color elements arranged horizontally or
|
||||
vertically. When rendering subpixel glyphs we need to know which way
|
||||
round they are.
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef 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
|
||||
|
|
@ -16,7 +16,7 @@ class SK_API SkGraphics {
|
|||
public:
|
||||
/**
|
||||
* Call this at process initialization time if your environment does not
|
||||
* permit static global initializers that execute code. Note that
|
||||
* permit static global initializers that execute code. Note that
|
||||
* Init() is not thread-safe.
|
||||
*/
|
||||
static void Init();
|
||||
|
@ -38,7 +38,7 @@ public:
|
|||
* This max can be changed by calling SetFontCacheLimit().
|
||||
*/
|
||||
static size_t GetFontCacheLimit();
|
||||
|
||||
|
||||
/**
|
||||
* Specify the max number of bytes that should be used by the font cache.
|
||||
* If the cache needs to allocate more, it will purge previous entries.
|
||||
|
@ -48,13 +48,18 @@ public:
|
|||
*/
|
||||
static size_t SetFontCacheLimit(size_t bytes);
|
||||
|
||||
/**
|
||||
* Return the number of bytes currently used by the font cache.
|
||||
*/
|
||||
static size_t GetFontCacheUsed();
|
||||
|
||||
/**
|
||||
* For debugging purposes, this will attempt to purge the font cache. It
|
||||
* does not change the limit, but will cause subsequent font measures and
|
||||
* draws to be recreated, since they will no longer be in the cache.
|
||||
*/
|
||||
static void PurgeFontCache();
|
||||
|
||||
|
||||
/**
|
||||
* Applications with command line options may pass optional state, such
|
||||
* as cache sizes, here, for instance:
|
||||
|
@ -64,7 +69,7 @@ public:
|
|||
* This format is subject to change.
|
||||
*/
|
||||
static void SetFlags(const char* flags);
|
||||
|
||||
|
||||
/**
|
||||
* Return the max number of bytes that should be used by the thread-local
|
||||
* font cache.
|
||||
|
@ -77,14 +82,14 @@ public:
|
|||
* GetFontCacheLimit.
|
||||
*/
|
||||
static size_t GetTLSFontCacheLimit();
|
||||
|
||||
|
||||
/**
|
||||
* Specify the max number of bytes that should be used by the thread-local
|
||||
* font cache. If this value is 0, then this thread will use the shared
|
||||
* global font cache.
|
||||
*/
|
||||
static void SetTLSFontCacheLimit(size_t bytes);
|
||||
|
||||
|
||||
private:
|
||||
/** This is automatically called by SkGraphics::Init(), and must be
|
||||
implemented by the host OS. This allows the host OS to register a callback
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkImage_DEFINED
|
||||
#define SkImage_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkData;
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
class SkShader;
|
||||
class GrContext;
|
||||
struct GrPlatformTextureDesc;
|
||||
|
||||
// need for TileMode
|
||||
#include "SkShader.h"
|
||||
|
||||
////// EXPERIMENTAL
|
||||
|
||||
class SkColorSpace;
|
||||
|
||||
/**
|
||||
* SkImage is an abstraction for drawing a rectagle of pixels, though the
|
||||
* particular type of image could be actually storing its data on the GPU, or
|
||||
* as drawing commands (picture or PDF or otherwise), ready to be played back
|
||||
* into another canvas.
|
||||
*
|
||||
* The content of SkImage is always immutable, though the actual storage may
|
||||
* change, if for example that image can be re-created via encoded data or
|
||||
* other means.
|
||||
*/
|
||||
class SkImage : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkImage)
|
||||
|
||||
enum ColorType {
|
||||
kAlpha_8_ColorType,
|
||||
kRGB_565_ColorType,
|
||||
kRGBA_8888_ColorType,
|
||||
kBGRA_8888_ColorType,
|
||||
kPMColor_ColorType,
|
||||
|
||||
kLastEnum_ColorType = kPMColor_ColorType
|
||||
};
|
||||
|
||||
enum AlphaType {
|
||||
kIgnore_AlphaType,
|
||||
kOpaque_AlphaType,
|
||||
kPremul_AlphaType,
|
||||
kUnpremul_AlphaType,
|
||||
|
||||
kLastEnum_AlphaType = kUnpremul_AlphaType
|
||||
};
|
||||
|
||||
struct Info {
|
||||
int fWidth;
|
||||
int fHeight;
|
||||
ColorType fColorType;
|
||||
AlphaType fAlphaType;
|
||||
|
||||
};
|
||||
|
||||
static SkImage* NewRasterCopy(const Info&, SkColorSpace*, const void* pixels, size_t rowBytes);
|
||||
static SkImage* NewRasterData(const Info&, SkColorSpace*, SkData* pixels, size_t rowBytes);
|
||||
static SkImage* NewEncodedData(SkData*);
|
||||
static SkImage* NewTexture(GrContext*, const GrPlatformTextureDesc&);
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
|
||||
SkShader* newShaderClamp() const;
|
||||
SkShader* newShader(SkShader::TileMode, SkShader::TileMode) const;
|
||||
|
||||
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
|
||||
|
||||
protected:
|
||||
SkImage(int width, int height) :
|
||||
fWidth(width),
|
||||
fHeight(height),
|
||||
fUniqueID(NextUniqueID()) {
|
||||
|
||||
SkASSERT(width >= 0);
|
||||
SkASSERT(height >= 0);
|
||||
}
|
||||
|
||||
private:
|
||||
const int fWidth;
|
||||
const int fHeight;
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
static uint32_t NextUniqueID();
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -13,7 +13,11 @@
|
|||
class SkBitmap;
|
||||
class SkDevice;
|
||||
class SkMatrix;
|
||||
struct SkPoint;
|
||||
struct SkIPoint;
|
||||
struct SkIRect;
|
||||
struct SkRect;
|
||||
class GrCustomStage;
|
||||
class GrTexture;
|
||||
|
||||
/**
|
||||
* Experimental.
|
||||
|
@ -38,6 +42,8 @@ struct SkPoint;
|
|||
*/
|
||||
class SK_API SkImageFilter : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkImageFilter)
|
||||
|
||||
class Proxy {
|
||||
public:
|
||||
virtual ~Proxy() {};
|
||||
|
@ -60,7 +66,7 @@ public:
|
|||
* The matrix is the current matrix on the canvas.
|
||||
*
|
||||
* Offset is the amount to translate the resulting image relative to the
|
||||
* src when it is drawn.
|
||||
* src when it is drawn.
|
||||
*
|
||||
* If the result image cannot be created, return false, in which case both
|
||||
* the result and offset parameters will be ignored by the caller.
|
||||
|
@ -75,28 +81,32 @@ public:
|
|||
bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst);
|
||||
|
||||
/**
|
||||
* Experimental.
|
||||
* Returns true if the filter can be expressed a single-pass
|
||||
* GrCustomStage, used to process this filter on the GPU, or false if
|
||||
* not.
|
||||
*
|
||||
* If the filter can be expressed as a gaussian-blur, return true and
|
||||
* set the sigma to the values for horizontal and vertical.
|
||||
* If stage is non-NULL, a new GrCustomStage instance is stored
|
||||
* in it. The caller assumes ownership of the stage, and it is up to the
|
||||
* caller to unref it.
|
||||
*/
|
||||
virtual bool asABlur(SkSize* sigma) const;
|
||||
virtual bool asNewCustomStage(GrCustomStage** stage, GrTexture*) const;
|
||||
|
||||
/**
|
||||
* Experimental.
|
||||
*
|
||||
* If the filter can be expressed as an erode, return true and
|
||||
* set the radius in X and Y.
|
||||
* Returns true if the filter can be processed on the GPU. This is most
|
||||
* often used for multi-pass effects, where intermediate results must be
|
||||
* rendered to textures. For single-pass effects, use asNewCustomStage().
|
||||
* The default implementation returns false.
|
||||
*/
|
||||
virtual bool asAnErode(SkISize* radius) const;
|
||||
virtual bool canFilterImageGPU() const;
|
||||
|
||||
/**
|
||||
* Experimental.
|
||||
*
|
||||
* If the filter can be expressed as a dilation, return true and
|
||||
* set the radius in X and Y.
|
||||
* Process this image filter on the GPU. texture is the source texture
|
||||
* for processing, and rect is the effect region to process. The
|
||||
* function must allocate a new texture of at least rect width/height
|
||||
* size, and return it to the caller. The default implementation returns
|
||||
* NULL.
|
||||
*/
|
||||
virtual bool asADilate(SkISize* radius) const;
|
||||
virtual GrTexture* onFilterImageGPU(GrTexture* texture, const SkRect& rect);
|
||||
|
||||
protected:
|
||||
SkImageFilter() {}
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkInstCnt_DEFINED
|
||||
#define SkInstCnt_DEFINED
|
||||
|
||||
/*
|
||||
* The instance counting system consists of three macros that create the
|
||||
* instance counting machinery. A class is added to the system by adding:
|
||||
* SK_DECLARE_INST_COUNT at the top of its declaration for derived classes
|
||||
* SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class
|
||||
* SK_DEFINE_INST_COUNT at the top of its .cpp file (for both kinds).
|
||||
* At the end of an application a call to all the "root" objects'
|
||||
* CheckInstanceCount methods should be made
|
||||
*/
|
||||
#ifdef SK_ENABLE_INST_COUNT
|
||||
#include <stdlib.h>
|
||||
#include "SkTArray.h"
|
||||
#include "SkThread_platform.h"
|
||||
|
||||
extern bool gPrintInstCount;
|
||||
|
||||
// The non-root classes just register themselves with their parent
|
||||
#define SK_DECLARE_INST_COUNT(className) \
|
||||
SK_DECLARE_INST_COUNT_INTERNAL(className, \
|
||||
INHERITED::AddInstChild(CheckInstanceCount);,\
|
||||
/**/)
|
||||
|
||||
#define SK_DECLARE_INST_COUNT_TEMPLATE(className) \
|
||||
SK_DECLARE_INST_COUNT_INTERNAL(className, \
|
||||
INHERITED::AddInstChild(CheckInstanceCount);, \
|
||||
typename)
|
||||
|
||||
// The root classes registers a function to print out the memory stats when
|
||||
// the app ends
|
||||
#define SK_DECLARE_INST_COUNT_ROOT(className) \
|
||||
SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);, /**/)
|
||||
|
||||
#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep, templateType) \
|
||||
class SkInstanceCountHelper { \
|
||||
public: \
|
||||
typedef int (*PFCheckInstCnt)(int level, bool cleanUp); \
|
||||
SkInstanceCountHelper() { \
|
||||
if (!gInited) { \
|
||||
initStep \
|
||||
gChildren = new SkTArray<PFCheckInstCnt>; \
|
||||
gInited = true; \
|
||||
} \
|
||||
sk_atomic_inc(&gInstanceCount); \
|
||||
} \
|
||||
\
|
||||
SkInstanceCountHelper(const SkInstanceCountHelper& other) { \
|
||||
sk_atomic_inc(&gInstanceCount); \
|
||||
} \
|
||||
\
|
||||
~SkInstanceCountHelper() { \
|
||||
sk_atomic_dec(&gInstanceCount); \
|
||||
} \
|
||||
\
|
||||
static int32_t gInstanceCount; \
|
||||
static bool gInited; \
|
||||
static SkTArray<PFCheckInstCnt>* gChildren; \
|
||||
} fInstanceCountHelper; \
|
||||
\
|
||||
static int32_t GetInstanceCount() { \
|
||||
return SkInstanceCountHelper::gInstanceCount; \
|
||||
} \
|
||||
\
|
||||
static void exitPrint() { \
|
||||
CheckInstanceCount(0, true); \
|
||||
} \
|
||||
\
|
||||
static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \
|
||||
if (gPrintInstCount && 0 != SkInstanceCountHelper::gInstanceCount) {\
|
||||
SkDebugf("%*c Leaked %s: %d\n", \
|
||||
4*level, ' ', #className, \
|
||||
SkInstanceCountHelper::gInstanceCount); \
|
||||
} \
|
||||
if (NULL == SkInstanceCountHelper::gChildren) { \
|
||||
return SkInstanceCountHelper::gInstanceCount; \
|
||||
} \
|
||||
int childCount = SkInstanceCountHelper::gChildren->count(); \
|
||||
int count = SkInstanceCountHelper::gInstanceCount; \
|
||||
for (int i = 0; i < childCount; ++i) { \
|
||||
count -= (*(*SkInstanceCountHelper::gChildren)[i])(level+1, cleanUp); \
|
||||
} \
|
||||
SkASSERT(count >= 0); \
|
||||
if (gPrintInstCount && childCount > 0 && count > 0) { \
|
||||
SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \
|
||||
} \
|
||||
if (cleanUp) { \
|
||||
delete SkInstanceCountHelper::gChildren; \
|
||||
SkInstanceCountHelper::gChildren = NULL; \
|
||||
} \
|
||||
return SkInstanceCountHelper::gInstanceCount; \
|
||||
} \
|
||||
\
|
||||
static void AddInstChild(templateType SkInstanceCountHelper::PFCheckInstCnt \
|
||||
childCheckInstCnt) { \
|
||||
if (CheckInstanceCount != childCheckInstCnt && \
|
||||
NULL != SkInstanceCountHelper::gChildren) { \
|
||||
SkInstanceCountHelper::gChildren->push_back(childCheckInstCnt); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SK_DEFINE_INST_COUNT(className) \
|
||||
int32_t className::SkInstanceCountHelper::gInstanceCount = 0; \
|
||||
bool className::SkInstanceCountHelper::gInited = false; \
|
||||
SkTArray<className::SkInstanceCountHelper::PFCheckInstCnt>* \
|
||||
className::SkInstanceCountHelper::gChildren = NULL;
|
||||
|
||||
#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) \
|
||||
templateInfo int32_t className::SkInstanceCountHelper::gInstanceCount = 0;\
|
||||
templateInfo bool className::SkInstanceCountHelper::gInited = false; \
|
||||
templateInfo \
|
||||
SkTArray<typename className::SkInstanceCountHelper::PFCheckInstCnt>*\
|
||||
className::SkInstanceCountHelper::gChildren = NULL;
|
||||
|
||||
#else
|
||||
#define SK_DECLARE_INST_COUNT(className)
|
||||
#define SK_DECLARE_INST_COUNT_TEMPLATE(className)
|
||||
#define SK_DECLARE_INST_COUNT_ROOT(className)
|
||||
#define SK_DEFINE_INST_COUNT(className)
|
||||
#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className)
|
||||
#endif
|
||||
|
||||
#endif // SkInstCnt_DEFINED
|
|
@ -14,14 +14,15 @@
|
|||
class SkLineClipper {
|
||||
public:
|
||||
enum {
|
||||
kMaxPoints = 4
|
||||
kMaxPoints = 4,
|
||||
kMaxClippedLineSegments = kMaxPoints - 1
|
||||
};
|
||||
|
||||
/* Clip the line pts[0]...pts[1] against clip, ignoring segments that
|
||||
lie completely above or below the clip. For portions to the left or
|
||||
right, turn those into vertical line segments that are aligned to the
|
||||
edge of the clip.
|
||||
|
||||
|
||||
Return the number of line segments that result, and store the end-points
|
||||
of those segments sequentially in lines as follows:
|
||||
1st segment: lines[0]..lines[1]
|
||||
|
@ -34,7 +35,7 @@ public:
|
|||
/* Intersect the line segment against the rect. If there is a non-empty
|
||||
resulting segment, return true and set dst[] to that segment. If not,
|
||||
return false and ignore dst[].
|
||||
|
||||
|
||||
ClipLine is specialized for scan-conversion, as it adds vertical
|
||||
segments on the sides to show where the line extended beyond the
|
||||
left or right sides. IntersectLine does not.
|
||||
|
|
|
@ -21,9 +21,9 @@ public:
|
|||
private:
|
||||
void* fAddr;
|
||||
size_t fSize;
|
||||
|
||||
|
||||
void closeMMap();
|
||||
|
||||
|
||||
typedef SkMemoryStream INHERITED;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,9 +21,9 @@ public:
|
|||
last owner of this pixelref is gone. If addr is NULL, sk_malloc_throw()
|
||||
is called to allocate it.
|
||||
*/
|
||||
SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable);
|
||||
SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable, bool ownPixels = true);
|
||||
virtual ~SkMallocPixelRef();
|
||||
|
||||
|
||||
//! Return the allocation size for the pixels
|
||||
size_t getSize() const { return fSize; }
|
||||
void* getAddr() const { return fStorage; }
|
||||
|
@ -42,6 +42,7 @@ private:
|
|||
void* fStorage;
|
||||
size_t fSize;
|
||||
SkColorTable* fCTable;
|
||||
bool fOwnPixels;
|
||||
|
||||
typedef SkPixelRef INHERITED;
|
||||
};
|
||||
|
|
|
@ -136,7 +136,7 @@ public:
|
|||
SkAutoMaskFreeImage(uint8_t* maskImage) {
|
||||
fImage = maskImage;
|
||||
}
|
||||
|
||||
|
||||
~SkAutoMaskFreeImage() {
|
||||
SkMask::FreeImage(fImage);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ class SkRasterClip;
|
|||
*/
|
||||
class SkMaskFilter : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkMaskFilter)
|
||||
|
||||
SkMaskFilter() {}
|
||||
|
||||
/** Returns the format of the resulting mask that this subclass will return
|
||||
|
|
|
@ -12,68 +12,55 @@
|
|||
|
||||
#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.
|
||||
*/
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
/**
|
||||
* 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
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Returns the number of leading zero bits (0...32)
|
||||
int SkCLZ_portable(uint32_t);
|
||||
|
||||
#if defined(__arm__)
|
||||
#define SkCLZ(x) __builtin_clz(x)
|
||||
#endif
|
||||
|
||||
#ifndef SkCLZ
|
||||
#define SkCLZ(x) SkCLZ_portable(x)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/** Return x with the sign of y */
|
||||
static inline int32_t SkCopySign32(int32_t x, int32_t y) {
|
||||
return SkApplySign(x, SkExtractSign(x ^ y));
|
||||
}
|
||||
|
||||
/** Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
|
||||
*/
|
||||
static inline int SkClampPos(int value) {
|
||||
return value & ~(value >> 31);
|
||||
}
|
||||
|
||||
/** Given an integer and a positive (max) integer, return the value
|
||||
pinned against 0 and max, inclusive.
|
||||
@param value The value we want returned pinned between [0...max]
|
||||
@param max The positive max value
|
||||
@return 0 if value < 0, max if value > max, else value
|
||||
*/
|
||||
* pinned against 0 and max, inclusive.
|
||||
* @param value The value we want returned pinned between [0...max]
|
||||
* @param max The positive max value
|
||||
* @return 0 if value < 0, max if value > max, else value
|
||||
*/
|
||||
static inline int SkClampMax(int value, int max) {
|
||||
// ensure that max is positive
|
||||
SkASSERT(max >= 0);
|
||||
|
@ -86,62 +73,33 @@ static inline int SkClampMax(int value, int max) {
|
|||
return value;
|
||||
}
|
||||
|
||||
/** 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__)
|
||||
#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.
|
||||
*/
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
/**
|
||||
* Returns the log2 of the specified value, were that value to be rounded up
|
||||
* to the next power of 2. It is undefined to pass 0. Examples:
|
||||
* SkNextLog2(1) -> 0
|
||||
* SkNextLog2(2) -> 1
|
||||
* SkNextLog2(3) -> 2
|
||||
* SkNextLog2(4) -> 2
|
||||
* SkNextLog2(5) -> 3
|
||||
*/
|
||||
static inline int SkNextLog2(uint32_t value) {
|
||||
SkASSERT(value != 0);
|
||||
return 32 - SkCLZ(value - 1);
|
||||
}
|
||||
|
||||
/** Returns true if value is a power of 2. Does not explicitly check for
|
||||
value <= 0.
|
||||
/**
|
||||
* Returns true if value is a power of 2. Does not explicitly check for
|
||||
* value <= 0.
|
||||
*/
|
||||
static inline bool SkIsPow2(int value) {
|
||||
return (value & (value - 1)) == 0;
|
||||
|
@ -149,10 +107,11 @@ static inline bool SkIsPow2(int value) {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
/**
|
||||
* SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
|
||||
* With this requirement, we can generate faster instructions on some
|
||||
* architectures.
|
||||
*/
|
||||
#ifdef SK_ARM_HAS_EDSP
|
||||
static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
|
||||
SkASSERT((int16_t)x == x);
|
||||
|
@ -176,39 +135,10 @@ static inline bool SkIsPow2(int value) {
|
|||
#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
|
||||
/**
|
||||
* 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 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)/255, taking the ceiling of any fractional bits. Only valid if
|
||||
both a and b are 0..255. The expected result equals (a * b + 254) / 255.
|
||||
*/
|
||||
static inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) {
|
||||
SkASSERT((uint8_t)a == a);
|
||||
SkASSERT((uint8_t)b == b);
|
||||
unsigned prod = SkMulS16(a, b) + 255;
|
||||
return (prod + (prod >> 8)) >> 8;
|
||||
}
|
||||
|
||||
/** Return a*b/((1 << shift) - 1), rounding any fractional bits.
|
||||
Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
|
||||
*/
|
||||
static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
|
||||
SkASSERT(a <= 32767);
|
||||
SkASSERT(b <= 32767);
|
||||
|
@ -217,10 +147,14 @@ static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
|
|||
return (prod + (prod >> shift)) >> shift;
|
||||
}
|
||||
|
||||
/** Just the rounding step in SkDiv255Round: round(value / 255)
|
||||
/**
|
||||
* Return a*b/255, rounding any fractional bits. Only valid if both
|
||||
* a and b are 0..255
|
||||
*/
|
||||
static inline unsigned SkDiv255Round(unsigned prod) {
|
||||
prod += 128;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,11 +44,12 @@ public:
|
|||
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.
|
||||
*/
|
||||
/** Returns a bitfield describing the transformations the matrix may
|
||||
perform. The bitfield is computed conservatively, so it may include
|
||||
false positives. For example, when kPerspective_Mask is true, all
|
||||
other bits may be set to true even in the case of a pure perspective
|
||||
transform.
|
||||
*/
|
||||
TypeMask getType() const {
|
||||
if (fTypeMask & kUnknown_Mask) {
|
||||
fTypeMask = this->computeTypeMask();
|
||||
|
@ -95,7 +96,7 @@ public:
|
|||
kMPersp1,
|
||||
kMPersp2
|
||||
};
|
||||
|
||||
|
||||
/** Affine arrays are in column major order
|
||||
because that's how PDF and XPS like it.
|
||||
*/
|
||||
|
@ -112,12 +113,12 @@ public:
|
|||
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]; }
|
||||
|
@ -162,7 +163,7 @@ public:
|
|||
fMat[kMPersp2] = persp2;
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
}
|
||||
|
||||
|
||||
/** Set the matrix to identity
|
||||
*/
|
||||
void reset();
|
||||
|
@ -322,7 +323,7 @@ public:
|
|||
@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
|
||||
|
@ -374,7 +375,7 @@ public:
|
|||
void mapPoints(SkPoint pts[], int count) const {
|
||||
this->mapPoints(pts, pts, count);
|
||||
}
|
||||
|
||||
|
||||
/** Like mapPoints but with custom byte stride between the points. Stride
|
||||
* should be a multiple of sizeof(SkScalar).
|
||||
*/
|
||||
|
@ -460,7 +461,7 @@ public:
|
|||
SkASSERT((mask & ~kAllMasks) == 0);
|
||||
return gMapXYProcs[mask & kAllMasks];
|
||||
}
|
||||
|
||||
|
||||
MapXYProc getMapXYProc() const {
|
||||
return GetMapXYProc(this->getType());
|
||||
}
|
||||
|
@ -472,7 +473,7 @@ public:
|
|||
SkASSERT((mask & ~kAllMasks) == 0);
|
||||
return gMapPtsProcs[mask & kAllMasks];
|
||||
}
|
||||
|
||||
|
||||
MapPtsProc getMapPtsProc() const {
|
||||
return GetMapPtsProc(this->getType());
|
||||
}
|
||||
|
@ -507,14 +508,14 @@ public:
|
|||
}
|
||||
|
||||
enum {
|
||||
// flatten/unflatten will never return a value larger than this
|
||||
// writeTo/readFromMemory will never return a value larger than this
|
||||
kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
|
||||
};
|
||||
// return the number of bytes written, whether or not buffer is null
|
||||
uint32_t flatten(void* buffer) const;
|
||||
uint32_t writeToMemory(void* buffer) const;
|
||||
// return the number of bytes read
|
||||
uint32_t unflatten(const void* buffer);
|
||||
|
||||
uint32_t readFromMemory(const void* buffer);
|
||||
|
||||
void dump() const;
|
||||
void toDumpString(SkString*) const;
|
||||
|
||||
|
@ -550,7 +551,7 @@ private:
|
|||
/** Set if the matrix will map a rectangle to another rectangle. This
|
||||
can be true if the matrix is scale-only, or rotates a multiple of
|
||||
90 degrees.
|
||||
|
||||
|
||||
This bit will be set on identity matrices
|
||||
*/
|
||||
kRectStaysRect_Mask = 0x10,
|
||||
|
@ -583,8 +584,8 @@ private:
|
|||
void setTypeMask(int mask) {
|
||||
// allow kUnknown or a valid mask
|
||||
SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
|
||||
((kUnknown_Mask | kOnlyPerspectiveValid_Mask | kPerspective_Mask) & mask)
|
||||
== mask);
|
||||
((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask)
|
||||
== (kUnknown_Mask | kOnlyPerspectiveValid_Mask));
|
||||
fTypeMask = SkToU8(mask);
|
||||
}
|
||||
|
||||
|
@ -616,7 +617,7 @@ private:
|
|||
}
|
||||
return ((fTypeMask & 0xF) == 0);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
@ -628,9 +629,9 @@ private:
|
|||
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);
|
||||
|
@ -640,7 +641,7 @@ private:
|
|||
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;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
#ifndef SkOSFile_DEFINED
|
||||
#define SkOSFile_DEFINED
|
||||
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkOrderedReadBuffer_DEFINED
|
||||
#define SkOrderedReadBuffer_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkWriter32.h"
|
||||
#include "SkPath.h"
|
||||
|
||||
class SkOrderedReadBuffer : public SkFlattenableReadBuffer {
|
||||
public:
|
||||
SkOrderedReadBuffer() : INHERITED() {}
|
||||
SkOrderedReadBuffer(const void* data, size_t size);
|
||||
|
||||
void setMemory(const void* data, size_t size) { fReader.setMemory(data, size); }
|
||||
uint32_t size() { return fReader.size(); }
|
||||
const void* base() { return fReader.base(); }
|
||||
uint32_t offset() { return fReader.offset(); }
|
||||
bool eof() { return fReader.eof(); }
|
||||
void rewind() { fReader.rewind(); }
|
||||
void setOffset(size_t offset) { fReader.setOffset(offset); }
|
||||
|
||||
SkReader32* getReader32() { return &fReader; }
|
||||
|
||||
virtual uint8_t readU8() { return fReader.readU8(); }
|
||||
virtual uint16_t readU16() { return fReader.readU16(); }
|
||||
virtual uint32_t readU32() { return fReader.readU32(); }
|
||||
virtual void read(void* dst, size_t size) { return fReader.read(dst, size); }
|
||||
virtual bool readBool() { return fReader.readBool(); }
|
||||
virtual int32_t readInt() { return fReader.readInt(); }
|
||||
virtual SkScalar readScalar() { return fReader.readScalar(); }
|
||||
virtual const void* skip(size_t size) { return fReader.skip(size); }
|
||||
|
||||
virtual void readMatrix(SkMatrix* m) { fReader.readMatrix(m); }
|
||||
virtual void readPath(SkPath* p) { p->unflatten(fReader); }
|
||||
virtual void readPoint(SkPoint* p) {
|
||||
p->fX = fReader.readScalar();
|
||||
p->fY = fReader.readScalar();
|
||||
}
|
||||
|
||||
virtual SkTypeface* readTypeface();
|
||||
virtual SkRefCnt* readRefCnt();
|
||||
virtual void* readFunctionPtr();
|
||||
virtual SkFlattenable* readFlattenable();
|
||||
|
||||
private:
|
||||
SkReader32 fReader;
|
||||
|
||||
typedef SkFlattenableReadBuffer INHERITED;
|
||||
};
|
||||
|
||||
#endif // SkOrderedReadBuffer_DEFINED
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkOrderedWriteBuffer_DEFINED
|
||||
#define SkOrderedWriteBuffer_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkWriter32.h"
|
||||
#include "SkPath.h"
|
||||
|
||||
class SkOrderedWriteBuffer : public SkFlattenableWriteBuffer {
|
||||
public:
|
||||
SkOrderedWriteBuffer(size_t minSize);
|
||||
SkOrderedWriteBuffer(size_t minSize, void* initialStorage,
|
||||
size_t storageSize);
|
||||
virtual ~SkOrderedWriteBuffer() {}
|
||||
|
||||
// deprecated naming convention that will be removed after callers are updated
|
||||
virtual bool writeBool(bool value) { return fWriter.writeBool(value); }
|
||||
virtual void writeInt(int32_t value) { fWriter.writeInt(value); }
|
||||
virtual void write8(int32_t value) { fWriter.write8(value); }
|
||||
virtual void write16(int32_t value) { fWriter.write16(value); }
|
||||
virtual void write32(int32_t value) { fWriter.write32(value); }
|
||||
virtual void writeScalar(SkScalar value) { fWriter.writeScalar(value); }
|
||||
virtual void writeMul4(const void* values, size_t size) { fWriter.writeMul4(values, size); }
|
||||
|
||||
virtual void writePad(const void* src, size_t size) { fWriter.writePad(src, size); }
|
||||
virtual void writeString(const char* str, size_t len = (size_t)-1) { fWriter.writeString(str, len); }
|
||||
virtual bool writeToStream(SkWStream* stream) { return fWriter.writeToStream(stream); }
|
||||
virtual void write(const void* values, size_t size) { fWriter.write(values, size); }
|
||||
virtual void writeRect(const SkRect& rect) { fWriter.writeRect(rect); }
|
||||
virtual size_t readFromStream(SkStream* s, size_t length) { return fWriter.readFromStream(s, length); }
|
||||
|
||||
virtual void writeMatrix(const SkMatrix& matrix) { fWriter.writeMatrix(matrix); }
|
||||
virtual void writePath(const SkPath& path) { path.flatten(fWriter); };
|
||||
virtual void writePoint(const SkPoint& point) {
|
||||
fWriter.writeScalar(point.fX);
|
||||
fWriter.writeScalar(point.fY);
|
||||
}
|
||||
|
||||
virtual uint32_t* reserve(size_t size) { return fWriter.reserve(size); }
|
||||
virtual void flatten(void* dst) { fWriter.flatten(dst); }
|
||||
virtual uint32_t size() { return fWriter.size(); }
|
||||
|
||||
virtual void writeFunctionPtr(void*);
|
||||
virtual void writeFlattenable(SkFlattenable* flattenable);
|
||||
|
||||
private:
|
||||
SkWriter32 fWriter;
|
||||
typedef SkFlattenableWriteBuffer INHERITED;
|
||||
};
|
||||
|
||||
#endif // SkOrderedWriteBuffer_DEFINED
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
#include "SkDrawLooper.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class SkAnnotation;
|
||||
class SkAutoGlyphCache;
|
||||
class SkColorFilter;
|
||||
class SkDescriptor;
|
||||
|
@ -28,6 +29,7 @@ class SkMaskFilter;
|
|||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkPathEffect;
|
||||
struct SkPoint;
|
||||
class SkRasterizer;
|
||||
class SkShader;
|
||||
class SkTypeface;
|
||||
|
@ -206,7 +208,7 @@ public:
|
|||
bool isVerticalText() const {
|
||||
return SkToBool(this->getFlags() & kVerticalText_Flag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper for setting or clearing the kVerticalText_Flag bit in
|
||||
* setFlags(...).
|
||||
|
@ -582,6 +584,17 @@ public:
|
|||
SkImageFilter* getImageFilter() const { return fImageFilter; }
|
||||
SkImageFilter* setImageFilter(SkImageFilter*);
|
||||
|
||||
SkAnnotation* getAnnotation() const { return fAnnotation; }
|
||||
SkAnnotation* setAnnotation(SkAnnotation*);
|
||||
|
||||
/**
|
||||
* Returns true if there is an annotation installed on this paint, and
|
||||
* the annotation specifics no-drawing.
|
||||
*/
|
||||
bool isNoDrawAnnotation() const {
|
||||
return SkToBool(fPrivFlags & kNoDrawAnnotation_PrivFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the paint's SkDrawLooper (if any). Does not affect the looper's
|
||||
* reference count.
|
||||
|
@ -655,6 +668,20 @@ public:
|
|||
*/
|
||||
void setTextSkewX(SkScalar skewX);
|
||||
|
||||
#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR
|
||||
/** Return the paint's scale factor used for correctly rendering
|
||||
glyphs in high DPI mode without text subpixel positioning.
|
||||
@return the scale factor used for rendering glyphs in high DPI mode.
|
||||
*/
|
||||
SkScalar getHintingScaleFactor() const { return fHintingScaleFactor; }
|
||||
|
||||
/** Set the paint's scale factor used for correctly rendering
|
||||
glyphs in high DPI mode without text subpixel positioning.
|
||||
@param the scale factor used for rendering glyphs in high DPI mode.
|
||||
*/
|
||||
void setHintingScaleFactor(SkScalar hintingScaleFactor);
|
||||
#endif
|
||||
|
||||
/** Describes how to interpret the text parameters that are passed to paint
|
||||
methods like measureText() and getTextWidths().
|
||||
*/
|
||||
|
@ -774,7 +801,7 @@ public:
|
|||
/** Return the number of bytes of text that were measured. If
|
||||
* isVerticalText() is true, then the vertical advances are used for
|
||||
* the measurement.
|
||||
*
|
||||
*
|
||||
* @param text The text to be measured
|
||||
* @param length Number of bytes of text to measure
|
||||
* @param maxWidth Maximum width. Only the subset of text whose accumulated
|
||||
|
@ -813,7 +840,7 @@ public:
|
|||
void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
|
||||
SkPath* path) const;
|
||||
|
||||
void getPosTextPath(const void* text, size_t length,
|
||||
void getPosTextPath(const void* text, size_t length,
|
||||
const SkPoint pos[], SkPath* path) const;
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
|
@ -845,18 +872,18 @@ public:
|
|||
}
|
||||
return !this->getRasterizer();
|
||||
}
|
||||
|
||||
|
||||
/** Only call this if canComputeFastBounds() returned true. This takes a
|
||||
raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
|
||||
effects in the paint (e.g. stroking). If needed, it uses the storage
|
||||
rect parameter. It returns the adjusted bounds that can then be used
|
||||
for quickReject tests.
|
||||
|
||||
|
||||
The returned rect will either be orig or storage, thus the caller
|
||||
should not rely on storage being set to the result, but should always
|
||||
use the retured value. It is legal for orig and storage to be the same
|
||||
rect.
|
||||
|
||||
|
||||
e.g.
|
||||
if (paint.canComputeFastBounds()) {
|
||||
SkRect r, storage;
|
||||
|
@ -878,25 +905,28 @@ public:
|
|||
return orig;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return this->doComputeFastBounds(orig, storage, style);
|
||||
}
|
||||
|
||||
|
||||
const SkRect& computeFastStrokeBounds(const SkRect& orig,
|
||||
SkRect* storage) const {
|
||||
return this->doComputeFastBounds(orig, storage, kStroke_Style);
|
||||
}
|
||||
|
||||
|
||||
// Take the style explicitly, so the caller can force us to be stroked
|
||||
// without having to make a copy of the paint just to change that field.
|
||||
const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
|
||||
Style) const;
|
||||
|
||||
|
||||
private:
|
||||
SkTypeface* fTypeface;
|
||||
SkScalar fTextSize;
|
||||
SkScalar fTextScaleX;
|
||||
SkScalar fTextSkewX;
|
||||
#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR
|
||||
SkScalar fHintingScaleFactor;
|
||||
#endif
|
||||
|
||||
SkPathEffect* fPathEffect;
|
||||
SkShader* fShader;
|
||||
|
@ -906,17 +936,24 @@ private:
|
|||
SkRasterizer* fRasterizer;
|
||||
SkDrawLooper* fLooper;
|
||||
SkImageFilter* fImageFilter;
|
||||
SkAnnotation* fAnnotation;
|
||||
|
||||
SkColor fColor;
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
||||
unsigned fFlags : 15;
|
||||
// all of these bitfields should add up to 32
|
||||
unsigned fFlags : 16;
|
||||
unsigned fTextAlign : 2;
|
||||
unsigned fCapType : 2;
|
||||
unsigned fJoinType : 2;
|
||||
unsigned fStyle : 2;
|
||||
unsigned fTextEncoding : 2; // 3 values
|
||||
unsigned fHinting : 2;
|
||||
unsigned fPrivFlags : 4; // these are not flattened/unflattened
|
||||
|
||||
enum PrivFlags {
|
||||
kNoDrawAnnotation_PrivFlag = 1 << 0,
|
||||
};
|
||||
|
||||
SkDrawCacheProc getDrawCacheProc() const;
|
||||
SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
|
||||
|
@ -931,12 +968,15 @@ private:
|
|||
void (*proc)(const SkDescriptor*, void*),
|
||||
void* context, bool ignoreGamma = false) const;
|
||||
|
||||
static void Term();
|
||||
|
||||
enum {
|
||||
kCanonicalTextSizeForPaths = 64
|
||||
};
|
||||
friend class SkAutoGlyphCache;
|
||||
friend class SkCanvas;
|
||||
friend class SkDraw;
|
||||
friend class SkGraphics; // So Term() can be called.
|
||||
friend class SkPDFDevice;
|
||||
friend class SkTextToPathIter;
|
||||
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
#ifndef SkPath_DEFINED
|
||||
#define SkPath_DEFINED
|
||||
|
||||
#include "SkInstCnt.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
#define GEN_ID_INC fGenerationID++
|
||||
|
@ -25,6 +27,7 @@ class SkReader32;
|
|||
class SkWriter32;
|
||||
class SkAutoPathBoundsUpdate;
|
||||
class SkString;
|
||||
class SkPathRef;
|
||||
|
||||
/** \class SkPath
|
||||
|
||||
|
@ -33,13 +36,15 @@ class SkString;
|
|||
*/
|
||||
class SK_API SkPath {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT_ROOT(SkPath);
|
||||
|
||||
SkPath();
|
||||
SkPath(const SkPath&);
|
||||
~SkPath();
|
||||
|
||||
SkPath& operator=(const SkPath&);
|
||||
|
||||
friend bool operator==(const SkPath&, const SkPath&);
|
||||
friend SK_API bool operator==(const SkPath&, const SkPath&);
|
||||
friend bool operator!=(const SkPath& a, const SkPath& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
@ -178,7 +183,7 @@ public:
|
|||
This does NOT change the fill-type setting nor isConvex
|
||||
*/
|
||||
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.
|
||||
|
@ -192,6 +197,17 @@ public:
|
|||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
/**
|
||||
* Returns true if all of the points in this path are finite, meaning there
|
||||
* are no infinities and no NaNs.
|
||||
*/
|
||||
bool isFinite() const {
|
||||
if (fBoundsIsDirty) {
|
||||
this->computeBounds();
|
||||
}
|
||||
return SkToBool(fIsFinite);
|
||||
}
|
||||
|
||||
/** Test a line for zero length
|
||||
|
||||
@return true if the line is of zero length; otherwise false.
|
||||
|
@ -232,7 +248,7 @@ public:
|
|||
/** 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
|
||||
|
@ -241,9 +257,7 @@ public:
|
|||
|
||||
/** Return the number of points in the path
|
||||
*/
|
||||
int countPoints() const {
|
||||
return this->getPoints(NULL, 0);
|
||||
}
|
||||
int countPoints() const;
|
||||
|
||||
/** Return the point at the specified index. If the index is out of range
|
||||
(i.e. is not 0 <= index < countPoints()) then the returned coordinates
|
||||
|
@ -252,13 +266,26 @@ public:
|
|||
SkPoint getPoint(int index) const;
|
||||
|
||||
/** Returns the number of points in the path. Up to max points are copied.
|
||||
|
||||
|
||||
@param points If not null, receives up to max points
|
||||
@param max The maximum number of points to copy into points
|
||||
@return the actual number of points in the path
|
||||
*/
|
||||
int getPoints(SkPoint points[], int max) const;
|
||||
|
||||
/** Return the number of verbs in the path
|
||||
*/
|
||||
int countVerbs() const;
|
||||
|
||||
/** Returns the number of verbs in the path. Up to max verbs are copied. The
|
||||
verbs are copied as one byte per verb.
|
||||
|
||||
@param verbs If not null, receives up to max verbs
|
||||
@param max The maximum number of verbs to copy into verbs
|
||||
@return the actual number of verbs in the path
|
||||
*/
|
||||
int getVerbs(uint8_t verbs[], int max) const;
|
||||
|
||||
//! Swap contents of this and other. Guaranteed not to throw
|
||||
void swap(SkPath& other);
|
||||
|
||||
|
@ -288,21 +315,21 @@ public:
|
|||
|
||||
/** 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) {
|
||||
|
@ -312,7 +339,7 @@ public:
|
|||
/** 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
|
||||
|
@ -342,7 +369,7 @@ public:
|
|||
/** 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
|
||||
|
@ -353,7 +380,7 @@ public:
|
|||
/** 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
|
||||
|
@ -364,7 +391,7 @@ public:
|
|||
/** 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
|
||||
*/
|
||||
|
@ -390,7 +417,7 @@ public:
|
|||
/** 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
|
||||
|
@ -404,7 +431,7 @@ public:
|
|||
/** 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
|
||||
|
@ -416,7 +443,7 @@ public:
|
|||
/** 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
|
||||
|
@ -438,7 +465,7 @@ public:
|
|||
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
|
||||
|
@ -533,7 +560,7 @@ public:
|
|||
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
|
||||
|
@ -559,6 +586,19 @@ public:
|
|||
void addRoundRect(const SkRect& rect, const SkScalar radii[],
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/**
|
||||
* Add a new contour made of just lines. This is just a fast version of
|
||||
* the following:
|
||||
* this->moveTo(pts[0]);
|
||||
* for (int i = 1; i < count; ++i) {
|
||||
* this->lineTo(pts[i]);
|
||||
* }
|
||||
* if (close) {
|
||||
* this->close();
|
||||
* }
|
||||
*/
|
||||
void addPoly(const SkPoint pts[], int count, bool close);
|
||||
|
||||
/** 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
|
||||
|
@ -585,17 +625,17 @@ public:
|
|||
void reverseAddPath(const SkPath& src);
|
||||
|
||||
/** Offset the path by (dx,dy), returning true on success
|
||||
|
||||
@param dx The amount in the X direction to offset the entire path
|
||||
@param dy The amount in the Y direction to offset the entire path
|
||||
|
||||
@param 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
|
||||
|
||||
@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);
|
||||
|
@ -603,7 +643,7 @@ public:
|
|||
|
||||
/** 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
|
||||
*/
|
||||
|
@ -620,14 +660,14 @@ public:
|
|||
/** Return the last point on the path. If no points have been added, (0,0)
|
||||
is returned. If there are no points, this returns false, otherwise it
|
||||
returns true.
|
||||
|
||||
|
||||
@param lastPt The last point on the path is returned here
|
||||
*/
|
||||
bool getLastPt(SkPoint* lastPt) const;
|
||||
|
||||
/** Set the last point on the path. If no points have been added,
|
||||
moveTo(x,y) is automatically called.
|
||||
|
||||
|
||||
@param x The new x-coordinate for the last point
|
||||
@param y The new y-coordinate for the last point
|
||||
*/
|
||||
|
@ -738,8 +778,9 @@ public:
|
|||
|
||||
/** Return the next verb in this iteration of the path. When all
|
||||
segments have been visited, return kDone_Verb.
|
||||
|
||||
|
||||
@param pts The points representing the current verb and/or segment
|
||||
This must not be NULL.
|
||||
@return The verb for the current segment
|
||||
*/
|
||||
Verb next(SkPoint pts[4]);
|
||||
|
@ -752,11 +793,25 @@ public:
|
|||
SkPoint fLastPt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the point { x, y } is contained by the path, taking into
|
||||
* account the FillType.
|
||||
*/
|
||||
bool contains(SkScalar x, SkScalar y) const;
|
||||
|
||||
void dump(bool forceClose, const char title[] = NULL) const;
|
||||
void dump() const;
|
||||
|
||||
void flatten(SkWriter32&) const;
|
||||
void unflatten(SkReader32&);
|
||||
/**
|
||||
* 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 writeToMemory(void* buffer) const;
|
||||
/**
|
||||
* Initialized the region from the buffer, returning the number
|
||||
* of bytes actually read.
|
||||
*/
|
||||
uint32_t readFromMemory(const void* buffer);
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
uint32_t getGenerationID() const;
|
||||
|
@ -767,15 +822,22 @@ public:
|
|||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
private:
|
||||
SkTDArray<SkPoint> fPts;
|
||||
SkTDArray<uint8_t> fVerbs;
|
||||
enum SerializationOffsets {
|
||||
kIsFinite_SerializationShift = 25,
|
||||
kIsOval_SerializationShift = 24,
|
||||
kConvexity_SerializationShift = 16,
|
||||
kFillType_SerializationShift = 8,
|
||||
kSegmentMask_SerializationShift = 0
|
||||
};
|
||||
|
||||
SkAutoTUnref<SkPathRef> fPathRef;
|
||||
mutable SkRect fBounds;
|
||||
int fLastMoveToIndex;
|
||||
uint8_t fFillType;
|
||||
uint8_t fSegmentMask;
|
||||
mutable uint8_t fBoundsIsDirty;
|
||||
mutable uint8_t fConvexity;
|
||||
|
||||
mutable SkBool8 fIsFinite; // only meaningful if bounds are valid
|
||||
mutable SkBool8 fIsOval;
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
uint32_t fGenerationID;
|
||||
|
@ -812,6 +874,7 @@ private:
|
|||
|
||||
friend class SkAutoPathBoundsUpdate;
|
||||
friend class SkAutoDisableOvalCheck;
|
||||
friend class SkBench_AddPathTest; // perf test pathTo/reversePathTo
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,9 +11,87 @@
|
|||
#define SkPathEffect_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkPaint.h"
|
||||
|
||||
class SkPath;
|
||||
|
||||
class SkStrokeRec {
|
||||
public:
|
||||
enum InitStyle {
|
||||
kHairline_InitStyle,
|
||||
kFill_InitStyle
|
||||
};
|
||||
SkStrokeRec(InitStyle style);
|
||||
|
||||
SkStrokeRec(const SkStrokeRec&);
|
||||
explicit SkStrokeRec(const SkPaint&);
|
||||
|
||||
enum Style {
|
||||
kHairline_Style,
|
||||
kFill_Style,
|
||||
kStroke_Style,
|
||||
kStrokeAndFill_Style
|
||||
};
|
||||
|
||||
Style getStyle() const;
|
||||
SkScalar getWidth() const { return fWidth; }
|
||||
SkScalar getMiter() const { return fMiterLimit; }
|
||||
SkPaint::Cap getCap() const { return fCap; }
|
||||
SkPaint::Join getJoin() const { return fJoin; }
|
||||
|
||||
bool isHairlineStyle() const {
|
||||
return kHairline_Style == this->getStyle();
|
||||
}
|
||||
|
||||
bool isFillStyle() const {
|
||||
return kFill_Style == this->getStyle();
|
||||
}
|
||||
|
||||
void setFillStyle();
|
||||
void setHairlineStyle();
|
||||
/**
|
||||
* Specify the strokewidth, and optionally if you want stroke + fill.
|
||||
* Note, if width==0, then this request is taken to mean:
|
||||
* strokeAndFill==true -> new style will be Fill
|
||||
* strokeAndFill==false -> new style will be Hairline
|
||||
*/
|
||||
void setStrokeStyle(SkScalar width, bool strokeAndFill = false);
|
||||
|
||||
void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
|
||||
fCap = cap;
|
||||
fJoin = join;
|
||||
fMiterLimit = miterLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this specifes any thick stroking, i.e. applyToPath()
|
||||
* will return true.
|
||||
*/
|
||||
bool needToApply() const {
|
||||
Style style = this->getStyle();
|
||||
return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply these stroke parameters to the src path, returning the result
|
||||
* in dst.
|
||||
*
|
||||
* If there was no change (i.e. style == hairline or fill) this returns
|
||||
* false and dst is unchanged. Otherwise returns true and the result is
|
||||
* stored in dst.
|
||||
*
|
||||
* src and dst may be the same path.
|
||||
*/
|
||||
bool applyToPath(SkPath* dst, const SkPath& src) const;
|
||||
|
||||
private:
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
||||
SkPaint::Cap fCap;
|
||||
SkPaint::Join fJoin;
|
||||
bool fStrokeAndFill;
|
||||
};
|
||||
|
||||
/** \class SkPathEffect
|
||||
|
||||
SkPathEffect is the base class for objects in the SkPaint that affect
|
||||
|
@ -24,15 +102,26 @@ class SkPath;
|
|||
*/
|
||||
class SK_API SkPathEffect : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkPathEffect)
|
||||
|
||||
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;
|
||||
/**
|
||||
* Given a src path (input) and a stroke-rec (input and output), apply
|
||||
* this effect to the src path, returning the new path in dst, and return
|
||||
* true. If this effect cannot be applied, return false and ignore dst
|
||||
* and stroke-rec.
|
||||
*
|
||||
* The stroke-rec specifies the initial request for stroking (if any).
|
||||
* The effect can treat this as input only, or it can choose to change
|
||||
* the rec as well. For example, the effect can decide to change the
|
||||
* stroke's width or join, or the effect can change the rec from stroke
|
||||
* to fill (or fill to stroke) in addition to returning a new (dst) path.
|
||||
*
|
||||
* If this method returns true, the caller will apply (as needed) the
|
||||
* resulting stroke-rec to dst and then draw.
|
||||
*/
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) = 0;
|
||||
|
||||
/**
|
||||
* Compute a conservative bounds for its effect, given the src bounds.
|
||||
|
@ -68,7 +157,7 @@ protected:
|
|||
|
||||
// these are visible to our subclasses
|
||||
SkPathEffect* fPE0, *fPE1;
|
||||
|
||||
|
||||
private:
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
@ -88,9 +177,7 @@ public:
|
|||
SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
|
||||
: INHERITED(outer, inner) {}
|
||||
|
||||
// overrides
|
||||
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) SK_OVERRIDE;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
|
||||
|
||||
|
@ -101,7 +188,7 @@ private:
|
|||
// illegal
|
||||
SkComposePathEffect(const SkComposePathEffect&);
|
||||
SkComposePathEffect& operator=(const SkComposePathEffect&);
|
||||
|
||||
|
||||
typedef SkPairPathEffect INHERITED;
|
||||
};
|
||||
|
||||
|
@ -120,8 +207,7 @@ public:
|
|||
SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
|
||||
: INHERITED(first, second) {}
|
||||
|
||||
// overrides
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) SK_OVERRIDE;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
position and tangent are unchanged.
|
||||
*/
|
||||
bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position,
|
||||
bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position,
|
||||
SkVector* tangent);
|
||||
|
||||
enum MatrixFlags {
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
matrix is unchanged.
|
||||
*/
|
||||
bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix,
|
||||
bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix,
|
||||
MatrixFlags flags = kGetPosAndTan_MatrixFlag);
|
||||
|
||||
/** Given a start and stop distance, return in dst the intervening segment(s).
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkCanvas;
|
||||
class SkPicturePlayback;
|
||||
class SkPictureRecord;
|
||||
|
@ -25,6 +26,8 @@ class SkWStream;
|
|||
*/
|
||||
class SK_API SkPicture : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkPicture)
|
||||
|
||||
/** 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.
|
||||
|
@ -34,14 +37,30 @@ public:
|
|||
this call, those elements will not appear in this picture.
|
||||
*/
|
||||
SkPicture(const SkPicture& src);
|
||||
/**
|
||||
* Recreate a picture that was serialized into a stream. If an error occurs
|
||||
* the picture will be "empty" : width and height == 0
|
||||
*/
|
||||
explicit SkPicture(SkStream*);
|
||||
virtual ~SkPicture();
|
||||
|
||||
|
||||
/**
|
||||
* Swap the contents of the two pictures. Guaranteed to succeed.
|
||||
*/
|
||||
void swap(SkPicture& other);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a thread-safe clone of the picture that is ready for playback.
|
||||
*/
|
||||
SkPicture* clone() const;
|
||||
|
||||
/**
|
||||
* Creates multiple thread-safe clones of this picture that are ready for
|
||||
* playback. The resulting clones are stored in the provided array of
|
||||
* SkPictures.
|
||||
*/
|
||||
void clone(SkPicture* pictures, int count) const;
|
||||
|
||||
enum RecordingFlags {
|
||||
/* This flag specifies that when clipPath() is called, the path will
|
||||
be faithfully recorded, but the recording canvas' current clip will
|
||||
|
@ -51,7 +70,25 @@ public:
|
|||
clip-query calls will reflect the path's bounds, not the actual
|
||||
path.
|
||||
*/
|
||||
kUsePathBoundsForClip_RecordingFlag = 0x01
|
||||
kUsePathBoundsForClip_RecordingFlag = 0x01,
|
||||
/* This flag causes the picture to compute bounding boxes and build
|
||||
up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas'
|
||||
usually stack-based clip/etc state. This requires an increase in
|
||||
recording time (often ~2x; likely more for very complex pictures),
|
||||
but allows us to perform much faster culling at playback time, and
|
||||
completely avoid some unnecessary clips and other operations. This
|
||||
is ideal for tiled rendering, or any other situation where you're
|
||||
drawing a fraction of a large scene into a smaller viewport.
|
||||
|
||||
In most cases the record cost is offset by the playback improvement
|
||||
after a frame or two of tiled rendering (and complex pictures that
|
||||
induce the worst record times will generally get the largest
|
||||
speedups at playback time).
|
||||
|
||||
Note: Currently this is not serializable, the bounding data will be
|
||||
discarded if you serialize into a stream and then deserialize.
|
||||
*/
|
||||
kOptimizeForClippedPlayback_RecordingFlag = 0x02
|
||||
};
|
||||
|
||||
/** Returns the canvas that records the drawing commands.
|
||||
|
@ -74,13 +111,18 @@ public:
|
|||
is drawn.
|
||||
*/
|
||||
void endRecording();
|
||||
|
||||
|
||||
/** Returns true if any draw commands have been recorded since the last
|
||||
call to beginRecording.
|
||||
*/
|
||||
bool hasRecorded() const;
|
||||
|
||||
/** 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.
|
||||
|
@ -99,10 +141,10 @@ public:
|
|||
|
||||
/** 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.
|
||||
is drawing. Has no effect if the picture is not drawing.
|
||||
*/
|
||||
void abortPlayback();
|
||||
|
||||
|
||||
private:
|
||||
int fWidth, fHeight;
|
||||
SkPictureRecord* fRecord;
|
||||
|
@ -110,6 +152,8 @@ private:
|
|||
|
||||
friend class SkFlatPicture;
|
||||
friend class SkPicturePlayback;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
class SkAutoPictureRecord : SkNoncopyable {
|
||||
|
@ -122,11 +166,11 @@ public:
|
|||
~SkAutoPictureRecord() {
|
||||
fPicture->endRecording();
|
||||
}
|
||||
|
||||
|
||||
/** Return the canvas to draw into for recording into the picture.
|
||||
*/
|
||||
SkCanvas* getRecordingCanvas() const { return fCanvas; }
|
||||
|
||||
|
||||
private:
|
||||
SkPicture* fPicture;
|
||||
SkCanvas* fCanvas;
|
||||
|
|
|
@ -32,6 +32,8 @@ class SkGpuTexture;
|
|||
*/
|
||||
class SK_API SkPixelRef : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkPixelRef)
|
||||
|
||||
explicit SkPixelRef(SkBaseMutex* mutex = NULL);
|
||||
|
||||
/** Return the pixel memory returned from lockPixels, or null if the
|
||||
|
@ -119,7 +121,7 @@ public:
|
|||
|
||||
/** Makes a deep copy of this PixelRef, respecting the requested config.
|
||||
Returns NULL if either there is an error (e.g. the destination could
|
||||
not be created with the given config), or this PixelRef does not
|
||||
not be created with the given config), or this PixelRef does not
|
||||
support deep copies. */
|
||||
virtual SkPixelRef* deepCopy(SkBitmap::Config config) { return NULL; }
|
||||
|
||||
|
@ -191,6 +193,10 @@ private:
|
|||
|
||||
mutable uint32_t fGenerationID;
|
||||
|
||||
// SkBitmap is only a friend so that when copying, it can modify the new SkPixelRef to have the
|
||||
// same fGenerationID as the original.
|
||||
friend class SkBitmap;
|
||||
|
||||
SkString fURI;
|
||||
|
||||
// can go from false to true, but never from true to false
|
||||
|
|
|
@ -145,6 +145,11 @@ struct SK_API SkPoint {
|
|||
SkScalar x() const { return fX; }
|
||||
SkScalar y() const { return fY; }
|
||||
|
||||
/**
|
||||
* Returns true iff fX and fY are both zero.
|
||||
*/
|
||||
bool isZero() const { return (0 == fX) & (0 == fY); }
|
||||
|
||||
/** Set the point's X and Y coordinates */
|
||||
void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
|
||||
|
||||
|
@ -168,7 +173,7 @@ struct SK_API SkPoint {
|
|||
fX = SkScalarAbs(pt.fX);
|
||||
fY = SkScalarAbs(pt.fY);
|
||||
}
|
||||
|
||||
|
||||
// counter-clockwise fan
|
||||
void setIRectFan(int l, int t, int r, int b) {
|
||||
SkPoint* v = this;
|
||||
|
@ -309,6 +314,29 @@ struct SK_API SkPoint {
|
|||
fY -= v.fY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if both X and Y are finite (not infinity or NaN)
|
||||
*/
|
||||
bool isFinite() const {
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
SkScalar accum = 0;
|
||||
accum *= fX;
|
||||
accum *= fY;
|
||||
|
||||
// accum is either NaN or it is finite (zero).
|
||||
SkASSERT(0 == accum || !(accum == accum));
|
||||
|
||||
// value==value will be true iff value is not NaN
|
||||
// TODO: is it faster to say !accum or accum==accum?
|
||||
return accum == accum;
|
||||
#else
|
||||
// use bit-or for speed, since we don't care about short-circuting the
|
||||
// tests, and we expect the common case will be that we need to check all.
|
||||
int isNaN = (SK_FixedNaN == fX) | (SK_FixedNaN == fX));
|
||||
return !isNaN;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Returns true if the point's coordinates equal (x,y)
|
||||
*/
|
||||
bool equals(SkScalar x, SkScalar y) const { return fX == x && fY == y; }
|
||||
|
@ -403,11 +431,11 @@ struct SK_API SkPoint {
|
|||
SkScalar dot(const SkPoint& vec) const {
|
||||
return DotProduct(*this, vec);
|
||||
}
|
||||
|
||||
|
||||
SkScalar lengthSqd() const {
|
||||
return DotProduct(*this, *this);
|
||||
}
|
||||
|
||||
|
||||
SkScalar distanceToSqd(const SkPoint& pt) const {
|
||||
SkScalar dx = fX - pt.fX;
|
||||
SkScalar dy = fY - pt.fY;
|
||||
|
|
|
@ -27,16 +27,7 @@
|
|||
#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
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#endif
|
||||
|
||||
#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
|
||||
|
@ -64,6 +55,10 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(SK_SUPPORT_GPU)
|
||||
#define SK_SUPPORT_GPU 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The clang static analyzer likes to know that when the program is not
|
||||
* expected to continue (crash, assertion failure, etc). It will notice that
|
||||
|
@ -75,7 +70,7 @@
|
|||
#if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
|
||||
namespace {
|
||||
inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
|
||||
void SkNO_RETURN_HINT() {}
|
||||
inline void SkNO_RETURN_HINT() {}
|
||||
}
|
||||
#else
|
||||
#define SkNO_RETURN_HINT() do {} while (false)
|
||||
|
@ -94,6 +89,9 @@
|
|||
#define SkNEW(type_name) new type_name
|
||||
#define SkNEW_ARGS(type_name, args) new type_name args
|
||||
#define SkNEW_ARRAY(type_name, count) new type_name[count]
|
||||
#define SkNEW_PLACEMENT(buf, type_name) new (buf) type_name
|
||||
#define SkNEW_PLACEMENT_ARGS(buf, type_name, args) \
|
||||
new (buf) type_name args
|
||||
#define SkDELETE(obj) delete obj
|
||||
#define SkDELETE_ARRAY(array) delete[] array
|
||||
#endif
|
||||
|
@ -285,24 +283,41 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_OVERRIDE
|
||||
#if defined(_MSC_VER)
|
||||
#define SK_OVERRIDE override
|
||||
#elif defined(__clang__)
|
||||
#if __has_feature(cxx_override_control)
|
||||
// Some documentation suggests we should be using __attribute__((override)),
|
||||
// but it doesn't work.
|
||||
#define SK_OVERRIDE override
|
||||
#elif defined(__has_extension)
|
||||
#if __has_extension(cxx_override_control)
|
||||
#define SK_OVERRIDE override
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SK_OVERRIDE
|
||||
#define SK_OVERRIDE
|
||||
#if defined(_MSC_VER)
|
||||
#define SK_OVERRIDE override
|
||||
#elif defined(__clang__)
|
||||
#if __has_feature(cxx_override_control)
|
||||
// Some documentation suggests we should be using __attribute__((override)),
|
||||
// but it doesn't work.
|
||||
#define SK_OVERRIDE override
|
||||
#elif defined(__has_extension)
|
||||
#if __has_extension(cxx_override_control)
|
||||
#define SK_OVERRIDE override
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
// Linux GCC ignores "__attribute__((override))" and rejects "override".
|
||||
#define SK_OVERRIDE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_PRINTF_LIKE
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
|
||||
#else
|
||||
// Linux GCC ignores "__attribute__((override))" and rejects "override".
|
||||
#define SK_OVERRIDE
|
||||
#define SK_PRINTF_LIKE(A, B)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_SIZE_T_SPECIFIER
|
||||
#if defined(_MSC_VER)
|
||||
#define SK_SIZE_T_SPECIFIER "%Iu"
|
||||
#else
|
||||
#define SK_SIZE_T_SPECIFIER "%zu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -331,7 +346,7 @@
|
|||
# undef SK_ARM_ARCH
|
||||
# define SK_ARM_ARCH 5
|
||||
# endif
|
||||
|
||||
|
||||
# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|
||||
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|
||||
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW)
|
||||
#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW)
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
|
@ -48,7 +48,7 @@
|
|||
|
||||
/* Even if the user only defined the NDK variant we still need to build
|
||||
* the default Android code. Therefore, when attempting to include/exclude
|
||||
* something from the NDK variant check first that we are building for
|
||||
* something from the NDK variant check first that we are building for
|
||||
* Android then check the status of the NDK define.
|
||||
*/
|
||||
#if defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_ANDROID)
|
||||
|
@ -89,7 +89,6 @@
|
|||
|
||||
#if !defined(SK_SCALAR_IS_FLOAT) && !defined(SK_SCALAR_IS_FIXED)
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#define SK_CAN_USE_FLOAT
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -104,8 +103,53 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if (defined(__arm__) && !defined(__thumb__)) || 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 */
|
||||
/**
|
||||
* SK_CPU_SSE_LEVEL
|
||||
*
|
||||
* If defined, SK_CPU_SSE_LEVEL should be set to the highest supported level.
|
||||
* On non-intel CPU this should be undefined.
|
||||
*/
|
||||
|
||||
#define SK_CPU_SSE_LEVEL_SSE1 10
|
||||
#define SK_CPU_SSE_LEVEL_SSE2 20
|
||||
#define SK_CPU_SSE_LEVEL_SSE3 30
|
||||
#define SK_CPU_SSE_LEVEL_SSSE3 31
|
||||
|
||||
// Are we in GCC?
|
||||
#ifndef SK_CPU_SSE_LEVEL
|
||||
#if defined(__SSE2__)
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
|
||||
#elif defined(__SSE3__)
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3
|
||||
#elif defined(__SSSE3__)
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Are we in VisualStudio?
|
||||
#ifndef SK_CPU_SSE_LEVEL
|
||||
#if _M_IX86_FP == 1
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1
|
||||
#elif _M_IX86_FP >= 2
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 64bit intel guarantees at least SSE2
|
||||
#if defined(__x86_64__) || defined(_WIN64)
|
||||
#if !defined(SK_CPU_SSE_LEVEL) || (SK_CPU_SSE_LEVEL < SK_CPU_SSE_LEVEL_SSE2)
|
||||
#undef SK_CPU_SSE_LEVEL
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* THUMB is the only known config where we avoid small branches in
|
||||
* favor of more complex math.
|
||||
*/
|
||||
#if !(defined(__arm__) && defined(__thumb__))
|
||||
#define SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
#endif
|
||||
|
||||
|
@ -129,5 +173,48 @@
|
|||
#define SK_API
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Use SK_PURE_FUNC as an attribute to indicate that a function's
|
||||
* return value only depends on the value of its parameters. This
|
||||
* can help the compiler optimize out successive calls.
|
||||
*
|
||||
* Usage:
|
||||
* void function(int params) SK_PURE_FUNC;
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
# define SK_PURE_FUNC __attribute__((pure))
|
||||
#else
|
||||
# define SK_PURE_FUNC /* nothing */
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* SK_HAS_ATTRIBUTE(<name>) should return true iff the compiler
|
||||
* supports __attribute__((<name>)). Mostly important because
|
||||
* Clang doesn't support all of GCC attributes.
|
||||
*/
|
||||
#if defined(__has_attribute)
|
||||
# define SK_HAS_ATTRIBUTE(x) __has_attribute(x)
|
||||
#elif defined(__GNUC__)
|
||||
# define SK_HAS_ATTRIBUTE(x) 1
|
||||
#else
|
||||
# define SK_HAS_ATTRIBUTE(x) 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SK_ATTRIBUTE_OPTIMIZE_O1 can be used as a function attribute
|
||||
* to specify individual optimization level of -O1, if the compiler
|
||||
* supports it.
|
||||
*
|
||||
* NOTE: Clang/ARM (r161757) does not support the 'optimize' attribute.
|
||||
*/
|
||||
#if SK_HAS_ATTRIBUTE(optimize)
|
||||
# define SK_ATTRIBUTE_OPTIMIZE_O1 __attribute__((optimize("O1")))
|
||||
#else
|
||||
# define SK_ATTRIBUTE_OPTIMIZE_O1 /* nothing */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,14 @@ public:
|
|||
return min + this->nextU() % (max - min + 1);
|
||||
}
|
||||
|
||||
/** Return the next pseudo random unsigned number, mapped to lie within
|
||||
[0, count).
|
||||
*/
|
||||
uint32_t nextULessThan(uint32_t count) {
|
||||
SkASSERT(count > 0);
|
||||
return this->nextRangeU(0, count - 1);
|
||||
}
|
||||
|
||||
/** Return the next pseudo random number expressed as an unsigned SkFixed
|
||||
in the range [0..SK_Fixed1).
|
||||
*/
|
||||
|
@ -72,11 +80,22 @@ public:
|
|||
*/
|
||||
SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
|
||||
|
||||
/** Return the next pseudo random number expressed as a SkScalar
|
||||
in the range [min..max).
|
||||
*/
|
||||
SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
|
||||
return SkScalarMul(this->nextSScalar1(), (max - min)) + min;
|
||||
}
|
||||
|
||||
/** Return the next pseudo random number expressed as a SkScalar
|
||||
in the range (-SK_Scalar1..SK_Scalar1).
|
||||
*/
|
||||
SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
|
||||
|
||||
/** Return the next pseudo random number as a bool.
|
||||
*/
|
||||
bool nextBool() { return this->nextU() >= 0x80000000; }
|
||||
|
||||
/** Return the next pseudo random number as a signed 64bit value.
|
||||
*/
|
||||
void next64(Sk64* a) {
|
||||
|
|
|
@ -20,6 +20,8 @@ struct SkIRect;
|
|||
|
||||
class SkRasterizer : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkRasterizer)
|
||||
|
||||
SkRasterizer() {}
|
||||
|
||||
/** Turn the path into a mask, respecting the specified local->device matrix.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define SkReader32_DEFINED
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
|
@ -26,20 +27,20 @@ public:
|
|||
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; }
|
||||
|
||||
uint32_t size() const { return SkToU32(fStop - fBase); }
|
||||
uint32_t offset() const { return SkToU32(fCurr - fBase); }
|
||||
bool eof() const { return fCurr >= fStop; }
|
||||
const void* base() const { return fBase; }
|
||||
const void* peek() const { return fCurr; }
|
||||
|
||||
uint32_t available() const { return fStop - fCurr; }
|
||||
uint32_t available() const { return SkToU32(fStop - fCurr); }
|
||||
bool isAvailable(uint32_t size) const { return fCurr + size <= fStop; }
|
||||
|
||||
|
||||
void rewind() { fCurr = fBase; }
|
||||
|
||||
void setOffset(size_t offset) {
|
||||
|
@ -47,9 +48,9 @@ public:
|
|||
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;
|
||||
|
@ -57,7 +58,19 @@ public:
|
|||
SkASSERT(fCurr <= fStop);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void* readPtr() {
|
||||
void* ptr;
|
||||
// we presume this "if" is resolved at compile-time
|
||||
if (4 == sizeof(void*)) {
|
||||
ptr = *(void**)fCurr;
|
||||
} else {
|
||||
memcpy(&ptr, fCurr, sizeof(void*));
|
||||
}
|
||||
fCurr += sizeof(void*);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
SkScalar readScalar() {
|
||||
SkASSERT(ptr_align_4(fCurr));
|
||||
SkScalar value = *(const SkScalar*)fCurr;
|
||||
|
@ -65,7 +78,7 @@ public:
|
|||
SkASSERT(fCurr <= fStop);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
const void* skip(size_t size) {
|
||||
SkASSERT(ptr_align_4(fCurr));
|
||||
const void* addr = fCurr;
|
||||
|
@ -73,7 +86,7 @@ public:
|
|||
SkASSERT(fCurr <= fStop);
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
template <typename T> const T& skipT() {
|
||||
SkASSERT(SkAlign4(sizeof(T)) == sizeof(T));
|
||||
return *(const T*)this->skip(sizeof(T));
|
||||
|
@ -86,20 +99,26 @@ public:
|
|||
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(); }
|
||||
|
||||
void readPath(SkPath* path) {
|
||||
size_t size = path->readFromMemory(this->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)this->skip(size);
|
||||
}
|
||||
|
||||
void readMatrix(SkMatrix* matrix) {
|
||||
size_t size = matrix->unflatten(this->peek());
|
||||
size_t size = matrix->readFromMemory(this->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)this->skip(size);
|
||||
}
|
||||
|
||||
void readRegion(SkRegion* rgn) {
|
||||
size_t size = rgn->unflatten(this->peek());
|
||||
size_t size = rgn->readFromMemory(this->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)this->skip(size);
|
||||
}
|
||||
|
@ -122,7 +141,7 @@ private:
|
|||
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;
|
||||
|
|
|
@ -25,25 +25,25 @@ struct SK_API SkIRect {
|
|||
r.setEmpty();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h) {
|
||||
SkIRect r;
|
||||
r.set(0, 0, w, h);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size) {
|
||||
SkIRect r;
|
||||
r.set(0, 0, size.width(), size.height());
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
|
||||
SkIRect rect;
|
||||
rect.set(l, t, r, b);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
static SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
|
||||
SkIRect r;
|
||||
r.set(x, y, x + w, y + h);
|
||||
|
@ -54,7 +54,7 @@ struct SK_API SkIRect {
|
|||
int top() const { return fTop; }
|
||||
int right() const { return fRight; }
|
||||
int bottom() const { return fBottom; }
|
||||
|
||||
|
||||
/** return the left edge of the rect */
|
||||
int x() const { return fLeft; }
|
||||
/** return the top edge of the rect */
|
||||
|
@ -64,18 +64,18 @@ struct SK_API SkIRect {
|
|||
* (i.e. left <= right) so the result may be negative.
|
||||
*/
|
||||
int width() const { return fRight - fLeft; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns the rectangle's height. This does not check for a valid rect
|
||||
* (i.e. top <= bottom) so the result may be negative.
|
||||
*/
|
||||
int height() const { return fBottom - fTop; }
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the rectangle's width or height are <= 0
|
||||
*/
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
|
||||
|
||||
friend bool operator==(const SkIRect& a, const SkIRect& b) {
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ struct SK_API SkIRect {
|
|||
fLeft = fTop = SK_MinS32;
|
||||
fRight = fBottom = SK_MaxS32;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make the largest representable rectangle, but inverted (e.g. fLeft will
|
||||
* be max 32bit and right will be min 32bit).
|
||||
|
@ -127,7 +127,7 @@ struct SK_API SkIRect {
|
|||
fLeft = fTop = SK_MaxS32;
|
||||
fRight = fBottom = SK_MinS32;
|
||||
}
|
||||
|
||||
|
||||
/** Offset set the rectangle by adding dx to its left and right,
|
||||
and adding dy to its top and bottom.
|
||||
*/
|
||||
|
@ -163,7 +163,7 @@ struct SK_API SkIRect {
|
|||
bool quickReject(int l, int t, int r, int b) const {
|
||||
return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
|
||||
}
|
||||
|
||||
|
||||
/** Returns true if (x,y) is inside the rectangle and the rectangle is not
|
||||
empty. The left and top are considered to be inside, while the right
|
||||
and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
|
||||
|
@ -205,7 +205,11 @@ struct SK_API SkIRect {
|
|||
return fLeft <= left && fTop <= top &&
|
||||
fRight >= right && fBottom >= bottom;
|
||||
}
|
||||
|
||||
|
||||
bool containsNoEmptyCheck(const SkIRect& r) const {
|
||||
return containsNoEmptyCheck(r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
}
|
||||
|
||||
/** If r intersects this rectangle, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
|
@ -221,7 +225,7 @@ struct SK_API SkIRect {
|
|||
*/
|
||||
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) {
|
||||
|
@ -233,7 +237,7 @@ struct SK_API SkIRect {
|
|||
}
|
||||
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.
|
||||
|
@ -243,7 +247,7 @@ struct SK_API SkIRect {
|
|||
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);
|
||||
|
@ -271,15 +275,25 @@ struct SK_API SkIRect {
|
|||
}
|
||||
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.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a and b intersect. debug-asserts that neither are empty.
|
||||
*/
|
||||
static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b) {
|
||||
SkASSERT(!a.isEmpty());
|
||||
SkASSERT(!b.isEmpty());
|
||||
return a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
|
||||
|
||||
/** Update this rectangle to enclose itself and the specified rectangle.
|
||||
If this rectangle is empty, just set it to the specified rectangle. If the specified
|
||||
rectangle is empty, do nothing.
|
||||
|
@ -346,7 +360,7 @@ struct SK_API SkRect {
|
|||
* Return true if the rectangle's width or height are <= 0
|
||||
*/
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns true iff all values in the rect are finite. If any are
|
||||
* infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this
|
||||
|
@ -359,7 +373,7 @@ struct SK_API SkRect {
|
|||
accum *= fTop;
|
||||
accum *= fRight;
|
||||
accum *= fBottom;
|
||||
|
||||
|
||||
// accum is either NaN or it is finite (zero).
|
||||
SkASSERT(0 == accum || !(accum == accum));
|
||||
|
||||
|
@ -434,13 +448,25 @@ struct SK_API SkRect {
|
|||
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);
|
||||
void set(const SkPoint pts[], int count) {
|
||||
// set() had been checking for non-finite values, so keep that behavior
|
||||
// for now. Now that we have setBoundsCheck(), we may decide to make
|
||||
// set() be simpler/faster, and not check for those.
|
||||
(void)this->setBoundsCheck(pts, count);
|
||||
}
|
||||
|
||||
// alias for set(pts, count)
|
||||
void setBounds(const SkPoint pts[], int count) {
|
||||
this->set(pts, count);
|
||||
(void)this->setBoundsCheck(pts, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the bounds of the array of points, and set this rect to that
|
||||
* bounds and return true... unless a non-finite value is encountered,
|
||||
* in which case this rect is set to empty and false is returned.
|
||||
*/
|
||||
bool setBoundsCheck(const SkPoint pts[], int count);
|
||||
|
||||
void set(const SkPoint& p0, const SkPoint& p1) {
|
||||
fLeft = SkMinScalar(p0.fX, p1.fX);
|
||||
fRight = SkMaxScalar(p0.fX, p1.fX);
|
||||
|
@ -462,7 +488,7 @@ struct SK_API SkRect {
|
|||
fLeft = fTop = SK_ScalarMin;
|
||||
fRight = fBottom = SK_ScalarMax;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make the largest representable rectangle, but inverted (e.g. fLeft will
|
||||
* be max and right will be min).
|
||||
|
@ -480,7 +506,7 @@ struct SK_API SkRect {
|
|||
fTop += dy;
|
||||
fRight += dx;
|
||||
fBottom += dy;
|
||||
}
|
||||
}
|
||||
|
||||
void offset(const SkPoint& delta) {
|
||||
this->offset(delta.fX, delta.fY);
|
||||
|
@ -536,7 +562,7 @@ struct SK_API SkRect {
|
|||
* rectangle. If either rectangle is empty, do nothing and return false.
|
||||
*/
|
||||
bool intersect(const SkRect& a, const SkRect& b);
|
||||
|
||||
|
||||
/**
|
||||
* Return true if rectangles a and b are not empty and intersect.
|
||||
*/
|
||||
|
@ -545,7 +571,7 @@ struct SK_API SkRect {
|
|||
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.
|
||||
|
@ -578,7 +604,7 @@ struct SK_API SkRect {
|
|||
fTop = SkMinScalar(y, fTop);
|
||||
fBottom = SkMaxScalar(y, fBottom);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if (p.fX,p.fY) is inside the rectangle, and the rectangle
|
||||
* is not empty.
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#define SkRefCnt_DEFINED
|
||||
|
||||
#include "SkThread.h"
|
||||
#include "SkInstCnt.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
/** \class SkRefCnt
|
||||
|
||||
|
@ -24,6 +26,8 @@
|
|||
*/
|
||||
class SK_API SkRefCnt : SkNoncopyable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT_ROOT(SkRefCnt)
|
||||
|
||||
/** Default construct, initializing the reference count to 1.
|
||||
*/
|
||||
SkRefCnt() : fRefCnt(1) {}
|
||||
|
@ -67,19 +71,36 @@ public:
|
|||
SkASSERT(fRefCnt > 0);
|
||||
}
|
||||
|
||||
private:
|
||||
/** Called when the ref count goes to 0.
|
||||
*/
|
||||
virtual void internal_dispose() const {
|
||||
protected:
|
||||
/**
|
||||
* Allow subclasses to call this if they've overridden internal_dispose
|
||||
* so they can reset fRefCnt before the destructor is called. Should only
|
||||
* be called right before calling through to inherited internal_dispose()
|
||||
* or before calling the destructor.
|
||||
*/
|
||||
void internal_dispose_restore_refcnt_to_1() const {
|
||||
#ifdef SK_DEBUG
|
||||
// so our destructor won't complain
|
||||
SkASSERT(0 == fRefCnt);
|
||||
fRefCnt = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Called when the ref count goes to 0.
|
||||
*/
|
||||
virtual void internal_dispose() const {
|
||||
this->internal_dispose_restore_refcnt_to_1();
|
||||
SkDELETE(this);
|
||||
}
|
||||
|
||||
friend class SkWeakRefCnt;
|
||||
friend class GrTexture; // to allow GrTexture's internal_dispose to
|
||||
// call SkRefCnt's & directly set fRefCnt (to 1)
|
||||
|
||||
mutable int32_t fRefCnt;
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,12 +117,21 @@ private:
|
|||
} while (0)
|
||||
|
||||
|
||||
/** Check if the argument is non-null, and if so, call obj->ref()
|
||||
/** Call obj->ref() and return obj. The obj must not be NULL.
|
||||
*/
|
||||
template <typename T> static inline void SkSafeRef(T* obj) {
|
||||
template <typename T> static inline T* SkRef(T* obj) {
|
||||
SkASSERT(obj);
|
||||
obj->ref();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/** Check if the argument is non-null, and if so, call obj->ref() and return obj.
|
||||
*/
|
||||
template <typename T> static inline T* SkSafeRef(T* obj) {
|
||||
if (obj) {
|
||||
obj->ref();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/** Check if the argument is non-null, and if so, call obj->unref()
|
||||
|
@ -129,6 +159,12 @@ public:
|
|||
fObj = obj;
|
||||
}
|
||||
|
||||
void swap(SkAutoTUnref* other) {
|
||||
T* tmp = fObj;
|
||||
fObj = other->fObj;
|
||||
other->fObj = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hosted object (which may be null), transferring ownership.
|
||||
* The reference count is not modified, and the internal ptr is set to NULL
|
||||
|
@ -141,7 +177,29 @@ public:
|
|||
return obj;
|
||||
}
|
||||
|
||||
T* operator->() { return fObj; }
|
||||
/**
|
||||
* BlockRef<B> is a type which inherits from B, cannot be created,
|
||||
* and makes ref and unref private.
|
||||
*/
|
||||
template<typename B> class BlockRef : public B {
|
||||
private:
|
||||
BlockRef();
|
||||
void ref() const;
|
||||
void unref() const;
|
||||
};
|
||||
|
||||
/** If T is const, the type returned from operator-> will also be const. */
|
||||
typedef typename SkTConstType<BlockRef<T>, SkTIsConst<T>::value>::type BlockRefType;
|
||||
|
||||
/**
|
||||
* SkAutoTUnref assumes ownership of the ref. As a result, it is an error
|
||||
* for the user to ref or unref through SkAutoTUnref. Therefore
|
||||
* SkAutoTUnref::operator-> returns BlockRef<T>*. This prevents use of
|
||||
* skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref().
|
||||
*/
|
||||
BlockRefType *operator->() const {
|
||||
return static_cast<BlockRefType*>(fObj);
|
||||
}
|
||||
operator T*() { return fObj; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
enum {
|
||||
kRunTypeSentinel = 0x7FFFFFFF
|
||||
};
|
||||
|
||||
|
||||
SkRegion();
|
||||
SkRegion(const SkRegion&);
|
||||
explicit SkRegion(const SkIRect&);
|
||||
|
@ -53,7 +53,7 @@ public:
|
|||
bool operator!=(const SkRegion& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace this region with the specified region, and return true if the
|
||||
* resulting region is non-empty.
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
* @return true if the resulting region is non-empty
|
||||
*/
|
||||
bool setRects(const SkIRect rects[], int count);
|
||||
|
||||
|
||||
/**
|
||||
* Set this region to the specified region, and return true if it is
|
||||
* non-empty.
|
||||
|
@ -131,13 +131,13 @@ public:
|
|||
* 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.
|
||||
|
@ -185,14 +185,14 @@ public:
|
|||
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
|
||||
|
@ -236,14 +236,14 @@ public:
|
|||
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).
|
||||
|
@ -254,7 +254,7 @@ public:
|
|||
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).
|
||||
|
@ -351,13 +351,13 @@ public:
|
|||
* 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;
|
||||
uint32_t writeToMemory(void* buffer) const;
|
||||
|
||||
/**
|
||||
* Initialized the region from the buffer, returning the number
|
||||
* of bytes actually read.
|
||||
*/
|
||||
uint32_t unflatten(const void* buffer);
|
||||
uint32_t readFromMemory(const void* buffer);
|
||||
|
||||
/**
|
||||
* Returns a reference to a global empty region. Just a convenience for
|
||||
|
@ -387,7 +387,7 @@ private:
|
|||
friend class android::Region; // needed for marshalling efficiently
|
||||
|
||||
struct RunHead;
|
||||
|
||||
|
||||
// allocate space for count runs
|
||||
void allocateRuns(int count);
|
||||
void allocateRuns(int count, int ySpanCount, int intervalCount);
|
||||
|
@ -397,21 +397,21 @@ private:
|
|||
RunHead* fRunHead;
|
||||
|
||||
void freeRuns();
|
||||
|
||||
|
||||
/**
|
||||
* Return the runs from this region, consing up fake runs if the region
|
||||
* is empty or a rect. In those 2 cases, we use tmpStorage to hold the
|
||||
* run data.
|
||||
*/
|
||||
const RunType* getRuns(RunType tmpStorage[], int* intervals) const;
|
||||
|
||||
|
||||
// This is called with runs[] that do not yet have their interval-count
|
||||
// field set on each scanline. That is computed as part of this call
|
||||
// (inside ComputeRunBounds).
|
||||
bool setRuns(RunType runs[], int count);
|
||||
|
||||
int count_runtype_values(int* itop, int* ibot) const;
|
||||
|
||||
|
||||
static void BuildRectRuns(const SkIRect& bounds,
|
||||
RunType runs[kRectRegionRuns]);
|
||||
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkTRelay_DEFINED
|
||||
#define SkTRelay_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
/**
|
||||
* Similar to a weakptr in java, a Relay allows for a back-ptr to an
|
||||
* object to be "safe", without using a hard reference-count.
|
||||
*
|
||||
* Typically, the target creates a Relay with a pointer to itself. Whenever it
|
||||
* wants to have another object maintain a safe-ptr to it, it gives them a
|
||||
* Relay, which they ref()/unref(). Through the Relay each external object can
|
||||
* retrieve a pointer to the Target. However, when the Target goes away, it
|
||||
* clears the Relay pointer to it (relay->set(NULL)) and then unref()s the
|
||||
* Relay. The other objects still have a ref on the Relay, but now when they
|
||||
* call get() the receive a NULL.
|
||||
*/
|
||||
template <template T> class SkTRelay : public SkRefCnt {
|
||||
public:
|
||||
SkTRelay(T* ptr) : fPtr(ptr) {}
|
||||
|
||||
// consumers call this
|
||||
T* get() const { return fPtr; }
|
||||
|
||||
// producer calls this
|
||||
void set(T* ptr) { fPtr = ptr; }
|
||||
|
||||
void clear() { this->set(NULL); }
|
||||
|
||||
private:
|
||||
T* fPtr;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -53,12 +53,19 @@
|
|||
/** SkScalarIsNaN(n) returns true if argument is not a number
|
||||
*/
|
||||
static inline bool SkScalarIsNaN(float x) { return x != x; }
|
||||
|
||||
/** Returns true if x is not NaN and not infinite */
|
||||
static inline bool SkScalarIsFinite(float x) {
|
||||
uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
|
||||
int exponent = bits << 1 >> 24;
|
||||
return exponent != 0xFF;
|
||||
// We rely on the following behavior of infinities and nans
|
||||
// 0 * finite --> 0
|
||||
// 0 * infinity --> NaN
|
||||
// 0 * NaN --> NaN
|
||||
float prod = x * 0;
|
||||
// At this point, prod will either be NaN or 0
|
||||
// Therefore we can return (prod == prod) or (0 == prod).
|
||||
return prod == prod;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
||||
*
|
||||
|
@ -84,7 +91,7 @@
|
|||
static inline float SkIntToScalar(unsigned long param) {
|
||||
return (float)param;
|
||||
}
|
||||
static inline float SkIntToScalar(float param) {
|
||||
static inline float SkIntToScalar(float /* param */) {
|
||||
/* If the parameter passed into SkIntToScalar is a float,
|
||||
* one of two things has happened:
|
||||
* 1. the parameter was an SkScalar (which is typedef'd to float)
|
||||
|
@ -175,6 +182,9 @@
|
|||
/** Returns the square root of the SkScalar
|
||||
*/
|
||||
#define SkScalarSqrt(x) sk_float_sqrt(x)
|
||||
/** Returns b to the e
|
||||
*/
|
||||
#define SkScalarPow(b, e) sk_float_pow(b, e)
|
||||
/** Returns the average of two SkScalars (a+b)/2
|
||||
*/
|
||||
#define SkScalarAve(a, b) (((a) + (b)) * 0.5f)
|
||||
|
@ -222,13 +232,11 @@
|
|||
#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 SkScalarToFloat(n) SkFixedToFloat(n)
|
||||
#define SkFloatToScalar(n) SkFloatToFixed(n)
|
||||
|
||||
#define SkScalarToDouble(n) SkFixedToDouble(n)
|
||||
#define SkDoubleToScalar(n) SkDoubleToFixed(n)
|
||||
#endif
|
||||
#define SkScalarToDouble(n) SkFixedToDouble(n)
|
||||
#define SkDoubleToScalar(n) SkDoubleToFixed(n)
|
||||
#define SkScalarFraction(x) SkFixedFraction(x)
|
||||
|
||||
#define SkScalarFloorToScalar(x) SkFixedFloorToFixed(x)
|
||||
|
@ -328,6 +336,12 @@ static inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) {
|
|||
return A + SkScalarMul(B - A, t);
|
||||
}
|
||||
|
||||
static inline SkScalar SkScalarLog2(SkScalar x) {
|
||||
static const SkScalar log2_conversion_factor = SkScalarDiv(1, SkScalarLog(2));
|
||||
|
||||
return SkScalarMul(SkScalarLog(x), log2_conversion_factor);
|
||||
}
|
||||
|
||||
/** Interpolate along the function described by (keys[length], values[length])
|
||||
for the passed searchKey. SearchKeys outside the range keys[0]-keys[Length]
|
||||
clamp to the min or max value. This function was inspired by a desire
|
||||
|
|
|
@ -1,373 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkScalerContext_DEFINED
|
||||
#define SkScalerContext_DEFINED
|
||||
|
||||
#include "SkMask.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
//#define SK_USE_COLOR_LUMINANCE
|
||||
|
||||
class SkDescriptor;
|
||||
class SkMaskFilter;
|
||||
class SkPathEffect;
|
||||
class SkRasterizer;
|
||||
|
||||
// needs to be != to any valid SkMask::Format
|
||||
#define MASK_FORMAT_UNKNOWN (0xFF)
|
||||
#define MASK_FORMAT_JUST_ADVANCE MASK_FORMAT_UNKNOWN
|
||||
|
||||
#define kMaxGlyphWidth (1<<13)
|
||||
|
||||
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
|
||||
|
||||
void init(uint32_t id) {
|
||||
fID = id;
|
||||
fImage = NULL;
|
||||
fPath = NULL;
|
||||
fMaskFormat = MASK_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the rowbytes for the specified width and mask-format.
|
||||
*/
|
||||
static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) {
|
||||
unsigned rb = width;
|
||||
if (SkMask::kBW_Format == format) {
|
||||
rb = (rb + 7) >> 3;
|
||||
} else if (SkMask::kARGB32_Format == format ||
|
||||
SkMask::kLCD32_Format == format)
|
||||
{
|
||||
rb <<= 2;
|
||||
} else if (SkMask::kLCD16_Format == format) {
|
||||
rb = SkAlign4(rb << 1);
|
||||
} else {
|
||||
rb = SkAlign4(rb);
|
||||
}
|
||||
return rb;
|
||||
}
|
||||
|
||||
unsigned rowBytes() const {
|
||||
return ComputeRowBytes(fWidth, (SkMask::Format)fMaskFormat);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/** Call this to set all of the metrics fields to 0 (e.g. if the scaler
|
||||
encounters an error measuring a glyph). Note: this does not alter the
|
||||
fImage, fPath, fID, fMaskFormat fields.
|
||||
*/
|
||||
void zeroMetrics();
|
||||
|
||||
enum {
|
||||
kSubBits = 2,
|
||||
kSubMask = ((1 << kSubBits) - 1),
|
||||
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 Flags {
|
||||
kFrameAndFill_Flag = 0x0001,
|
||||
kDevKernText_Flag = 0x0002,
|
||||
kEmbeddedBitmapText_Flag = 0x0004,
|
||||
kEmbolden_Flag = 0x0008,
|
||||
kSubpixelPositioning_Flag = 0x0010,
|
||||
kAutohinting_Flag = 0x0020,
|
||||
kVertical_Flag = 0x0040,
|
||||
|
||||
// together, these two flags resulting in a two bit value which matches
|
||||
// up with the SkPaint::Hinting enum.
|
||||
kHinting_Shift = 7, // to shift into the other flags above
|
||||
kHintingBit1_Flag = 0x0080,
|
||||
kHintingBit2_Flag = 0x0100,
|
||||
|
||||
// these should only ever be set if fMaskFormat is LCD16 or LCD32
|
||||
kLCD_Vertical_Flag = 0x0200, // else Horizontal
|
||||
kLCD_BGROrder_Flag = 0x0400, // else RGB order
|
||||
|
||||
// Generate A8 from LCD source (for GDI), only meaningful if fMaskFormat is kA8
|
||||
// Perhaps we can store this (instead) in fMaskFormat, in hight bit?
|
||||
kGenA8FromLCD_Flag = 0x0800,
|
||||
|
||||
#ifdef SK_USE_COLOR_LUMINANCE
|
||||
kLuminance_Bits = 3
|
||||
#else
|
||||
// luminance : 0 for black text, kLuminance_Max for white text
|
||||
kLuminance_Shift = 13, // shift to land in the high 3-bits of Flags
|
||||
kLuminance_Bits = 3 // ensure Flags doesn't exceed 16bits
|
||||
#endif
|
||||
};
|
||||
|
||||
// computed values
|
||||
enum {
|
||||
#ifdef SK_USE_COLOR_LUMINANCE
|
||||
kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag
|
||||
#else
|
||||
kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
|
||||
kLuminance_Max = (1 << kLuminance_Bits) - 1,
|
||||
kLuminance_Mask = kLuminance_Max << kLuminance_Shift
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Rec {
|
||||
uint32_t fOrigFontID;
|
||||
uint32_t fFontID;
|
||||
SkScalar fTextSize, fPreScaleX, fPreSkewX;
|
||||
SkScalar fPost2x2[2][2];
|
||||
SkScalar fFrameWidth, fMiterLimit;
|
||||
#ifdef SK_USE_COLOR_LUMINANCE
|
||||
uint32_t fLumBits;
|
||||
#endif
|
||||
uint8_t fMaskFormat;
|
||||
uint8_t fStrokeJoin;
|
||||
uint16_t fFlags;
|
||||
// Warning: when adding members note that the size of this structure
|
||||
// must be a multiple of 4. SkDescriptor requires that its arguments be
|
||||
// multiples of four and this structure is put in an SkDescriptor in
|
||||
// SkPaint::MakeRec.
|
||||
|
||||
void getMatrixFrom2x2(SkMatrix*) const;
|
||||
void getLocalMatrix(SkMatrix*) const;
|
||||
void getSingleMatrix(SkMatrix*) const;
|
||||
|
||||
SkPaint::Hinting getHinting() const {
|
||||
unsigned hint = (fFlags & kHinting_Mask) >> kHinting_Shift;
|
||||
return static_cast<SkPaint::Hinting>(hint);
|
||||
}
|
||||
|
||||
void setHinting(SkPaint::Hinting hinting) {
|
||||
fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift);
|
||||
}
|
||||
|
||||
SkMask::Format getFormat() const {
|
||||
return static_cast<SkMask::Format>(fMaskFormat);
|
||||
}
|
||||
|
||||
#ifdef SK_USE_COLOR_LUMINANCE
|
||||
SkColor getLuminanceColor() const {
|
||||
return fLumBits;
|
||||
}
|
||||
|
||||
void setLuminanceColor(SkColor c) {
|
||||
fLumBits = c;
|
||||
}
|
||||
#else
|
||||
unsigned getLuminanceBits() const {
|
||||
return (fFlags & kLuminance_Mask) >> kLuminance_Shift;
|
||||
}
|
||||
|
||||
void setLuminanceBits(unsigned lum) {
|
||||
SkASSERT(lum <= kLuminance_Max);
|
||||
fFlags = (fFlags & ~kLuminance_Mask) | (lum << kLuminance_Shift);
|
||||
}
|
||||
|
||||
U8CPU getLuminanceByte() const {
|
||||
SkASSERT(3 == kLuminance_Bits);
|
||||
unsigned lum = this->getLuminanceBits();
|
||||
lum |= (lum << kLuminance_Bits);
|
||||
lum |= (lum << kLuminance_Bits*2);
|
||||
return lum >> (4*kLuminance_Bits - 8);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
SkScalerContext(const SkDescriptor* desc);
|
||||
virtual ~SkScalerContext();
|
||||
|
||||
SkMask::Format getMaskFormat() const {
|
||||
return (SkMask::Format)fRec.fMaskFormat;
|
||||
}
|
||||
|
||||
bool isSubpixel() const {
|
||||
return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
|
||||
}
|
||||
|
||||
// remember our glyph offset/base
|
||||
void setBaseGlyphCount(unsigned baseGlyphCount) {
|
||||
fBaseGlyphCount = baseGlyphCount;
|
||||
}
|
||||
|
||||
/** Return the corresponding glyph for the specified unichar. Since contexts
|
||||
may be chained (under the hood), the glyphID that is returned may in
|
||||
fact correspond to a different font/context. In that case, we use the
|
||||
base-glyph-count to know how to translate back into local glyph space.
|
||||
*/
|
||||
uint16_t charToGlyphID(SkUnichar uni);
|
||||
|
||||
/** Map the glyphID to its glyph index, and then to its char code. Unmapped
|
||||
glyphs return zero.
|
||||
*/
|
||||
SkUnichar glyphIDToChar(uint16_t glyphID);
|
||||
|
||||
unsigned getGlyphCount() { 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);
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
unsigned getBaseGlyphCount(SkUnichar charCode);
|
||||
#endif
|
||||
|
||||
static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
|
||||
static inline void PostMakeRec(Rec*);
|
||||
|
||||
static SkScalerContext* Create(const SkDescriptor*);
|
||||
|
||||
protected:
|
||||
Rec fRec;
|
||||
unsigned fBaseGlyphCount;
|
||||
|
||||
virtual unsigned generateGlyphCount() = 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;
|
||||
// default impl returns 0, indicating failure.
|
||||
virtual SkUnichar generateGlyphToChar(uint16_t);
|
||||
|
||||
void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
|
||||
|
||||
private:
|
||||
SkPathEffect* fPathEffect;
|
||||
SkMaskFilter* fMaskFilter;
|
||||
SkRasterizer* fRasterizer;
|
||||
|
||||
// if this is set, we draw the image from a path, rather than
|
||||
// calling generateImage.
|
||||
bool fGenerateImageFromPath;
|
||||
|
||||
void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
|
||||
SkPath* devPath, SkMatrix* fillToDevMatrix);
|
||||
|
||||
// return the next context, treating fNextContext as a cache of the answer
|
||||
SkScalerContext* getNextContext();
|
||||
|
||||
// returns the right context from our link-list for this glyph. If no match
|
||||
// is found, just returns the original context (this)
|
||||
SkScalerContext* getGlyphContext(const SkGlyph& glyph);
|
||||
|
||||
// link-list of context, to handle missing chars. null-terminated.
|
||||
SkScalerContext* fNextContext;
|
||||
};
|
||||
|
||||
#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')
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum SkAxisAlignment {
|
||||
kNone_SkAxisAlignment,
|
||||
kX_SkAxisAlignment,
|
||||
kY_SkAxisAlignment
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the axis (if any) that the baseline for horizontal text will land on
|
||||
* after running through the specified matrix.
|
||||
*
|
||||
* As an example, the identity matrix will return kX_SkAxisAlignment
|
||||
*/
|
||||
SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix);
|
||||
|
||||
#endif
|
||||
|
|
@ -17,6 +17,9 @@
|
|||
#include "SkPaint.h"
|
||||
|
||||
class SkPath;
|
||||
class GrContext;
|
||||
class GrCustomStage;
|
||||
class GrSamplerState;
|
||||
|
||||
/** \class SkShader
|
||||
*
|
||||
|
@ -30,7 +33,9 @@ class SkPath;
|
|||
*/
|
||||
class SK_API SkShader : public SkFlattenable {
|
||||
public:
|
||||
SkShader();
|
||||
SK_DECLARE_INST_COUNT(SkShader)
|
||||
|
||||
SkShader();
|
||||
virtual ~SkShader();
|
||||
|
||||
/**
|
||||
|
@ -210,8 +215,20 @@ public:
|
|||
// space
|
||||
// 2: the second radius minus the first radius
|
||||
// in pre-transformed space.
|
||||
kTwoPointConical_BitmapType,
|
||||
//<! Matrix transforms to space where (0,0) is
|
||||
// the center of the starting circle. The second
|
||||
// circle will be centered (x, 0) where x may be
|
||||
// 0.
|
||||
// Three extra parameters are returned:
|
||||
// 0: x-offset of second circle center
|
||||
// to first.
|
||||
// 1: radius of first circle
|
||||
// 2: the second radius minus the first radius
|
||||
kLinear_BitmapType, //<! Access bitmap using local coords transformed
|
||||
// by matrix. No extras
|
||||
|
||||
kLast_BitmapType = kTwoPointRadial_BitmapType
|
||||
kLast_BitmapType = kLinear_BitmapType
|
||||
};
|
||||
/** Optional methods for shaders that can pretend to be a bitmap/texture
|
||||
to play along with opengl. Default just returns kNone_BitmapType and
|
||||
|
@ -229,7 +246,7 @@ public:
|
|||
about the first point.
|
||||
*/
|
||||
virtual BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
|
||||
TileMode xy[2], SkScalar* twoPointRadialParams) const;
|
||||
TileMode xy[2]) const;
|
||||
|
||||
/**
|
||||
* If the shader subclass can be represented as a gradient, asAGradient
|
||||
|
@ -267,7 +284,8 @@ public:
|
|||
kRadial_GradientType,
|
||||
kRadial2_GradientType,
|
||||
kSweep_GradientType,
|
||||
kLast_GradientType = kSweep_GradientType
|
||||
kConical_GradientType,
|
||||
kLast_GradientType = kConical_GradientType
|
||||
};
|
||||
|
||||
struct GradientInfo {
|
||||
|
@ -284,6 +302,16 @@ public:
|
|||
|
||||
virtual GradientType asAGradient(GradientInfo* info) const;
|
||||
|
||||
/**
|
||||
* If the shader subclass has a GrCustomStage implementation, this returns
|
||||
* a new custom stage (the caller assumes ownership, and will need to
|
||||
* unref it). A GrContext pointer is required since custom stages may
|
||||
* need to create textures. The sampler parameter is necessary to set
|
||||
* up matrix/tile modes/etc, and will eventually be removed.
|
||||
*/
|
||||
virtual GrCustomStage* asNewCustomStage(GrContext* context,
|
||||
GrSamplerState* sampler) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Factory methods for stock shaders
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkShape_DEFINED
|
||||
#define SkShape_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkMatrix;
|
||||
class SkWStream;
|
||||
|
||||
class SkShape : public SkFlattenable {
|
||||
public:
|
||||
SkShape();
|
||||
virtual ~SkShape();
|
||||
|
||||
void draw(SkCanvas*);
|
||||
|
||||
/** Draw the shape translated by (dx,dy), which is applied before the
|
||||
shape's matrix (if any).
|
||||
*/
|
||||
void drawXY(SkCanvas*, SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Draw the shape with the specified matrix, applied before the shape's
|
||||
matrix (if any).
|
||||
*/
|
||||
void drawMatrix(SkCanvas*, const SkMatrix&);
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkShape)
|
||||
|
||||
protected:
|
||||
virtual void onDraw(SkCanvas*);
|
||||
|
||||
SkShape(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -36,15 +36,15 @@ template <typename T> struct SkTSize {
|
|||
bool isEmpty() const {
|
||||
return fWidth <= 0 || fHeight <= 0;
|
||||
}
|
||||
|
||||
|
||||
/** Set the width and height to 0 */
|
||||
void setEmpty() {
|
||||
fWidth = fHeight = 0;
|
||||
}
|
||||
|
||||
T width() const { return fWidth; }
|
||||
T height() const { return fHeight; }
|
||||
|
||||
|
||||
T width() const { return fWidth; }
|
||||
T height() const { return fHeight; }
|
||||
|
||||
/** If width or height is < 0, it is set to 0 */
|
||||
void clampNegToZero() {
|
||||
if (fWidth < 0) {
|
||||
|
@ -54,7 +54,7 @@ template <typename T> struct SkTSize {
|
|||
fHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool equals(T w, T h) const {
|
||||
return fWidth == w && fHeight == h;
|
||||
}
|
||||
|
@ -83,8 +83,8 @@ struct SkSize : public SkTSize<SkScalar> {
|
|||
s.fHeight = h;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SkSize& operator=(const SkISize& src) {
|
||||
this->set(SkIntToScalar(src.fWidth), SkIntToScalar(src.fHeight));
|
||||
return *this;
|
||||
|
|
|
@ -17,7 +17,8 @@ class SkData;
|
|||
|
||||
class SK_API SkStream : public SkRefCnt {
|
||||
public:
|
||||
virtual ~SkStream();
|
||||
SK_DECLARE_INST_COUNT(SkStream)
|
||||
|
||||
/** Called to rewind to the beginning of the stream. If this cannot be
|
||||
done, return false.
|
||||
*/
|
||||
|
@ -39,7 +40,7 @@ public:
|
|||
/** 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.
|
||||
*/
|
||||
|
@ -63,10 +64,21 @@ public:
|
|||
bool readBool() { return this->readU8() != 0; }
|
||||
SkScalar readScalar();
|
||||
size_t readPackedUInt();
|
||||
|
||||
/**
|
||||
* Create a new SkData from the stream contents. This balances the call
|
||||
* SkWStream::writeData().
|
||||
*/
|
||||
SkData* readData();
|
||||
|
||||
private:
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
class SK_API SkWStream : SkNoncopyable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT_ROOT(SkWStream)
|
||||
|
||||
virtual ~SkWStream();
|
||||
|
||||
/** Called to write bytes to a SkWStream. Returns true on success
|
||||
|
@ -79,7 +91,7 @@ public:
|
|||
virtual void flush();
|
||||
|
||||
// helpers
|
||||
|
||||
|
||||
bool write8(U8CPU);
|
||||
bool write16(U16CPU);
|
||||
bool write32(uint32_t);
|
||||
|
@ -89,11 +101,11 @@ public:
|
|||
bool writeBigDecAsText(int64_t, int minDigits = 0);
|
||||
bool writeHexAsText(uint32_t, int minDigits = 0);
|
||||
bool writeScalarAsText(SkScalar);
|
||||
|
||||
|
||||
bool writeBool(bool v) { return this->write8(v); }
|
||||
bool writeScalar(SkScalar);
|
||||
bool writePackedUInt(size_t);
|
||||
|
||||
|
||||
bool writeStream(SkStream* input, size_t length);
|
||||
|
||||
bool writeData(const SkData*);
|
||||
|
@ -110,6 +122,8 @@ struct SkFILE;
|
|||
*/
|
||||
class SkFILEStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkFILEStream)
|
||||
|
||||
/** Initialize the stream by calling fopen on the specified path. Will be
|
||||
closed in the destructor.
|
||||
*/
|
||||
|
@ -131,34 +145,42 @@ public:
|
|||
private:
|
||||
SkFILE* fFILE;
|
||||
SkString fName;
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
/** A stream that reads from a file descriptor
|
||||
*/
|
||||
class SkFDStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkFDStream)
|
||||
|
||||
/** 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() SK_OVERRIDE;
|
||||
virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual const char* getFileName() SK_OVERRIDE { return NULL; }
|
||||
|
||||
|
||||
private:
|
||||
int fFD;
|
||||
bool fCloseWhenDone;
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
class SkMemoryStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkMemoryStream)
|
||||
|
||||
SkMemoryStream();
|
||||
/** We allocate (and free) the memory. Write to it via getMemoryBase()
|
||||
*/
|
||||
|
@ -200,10 +222,12 @@ public:
|
|||
const void* getAtPos();
|
||||
size_t seek(size_t offset);
|
||||
size_t peek() const { return fOffset; }
|
||||
|
||||
|
||||
private:
|
||||
SkData* fData;
|
||||
size_t fOffset;
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
/** \class SkBufferStream
|
||||
|
@ -213,6 +237,8 @@ private:
|
|||
*/
|
||||
class SkBufferStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkBufferStream)
|
||||
|
||||
/** 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.
|
||||
|
@ -249,13 +275,17 @@ private:
|
|||
bool fWeOwnTheBuffer;
|
||||
|
||||
void init(void*, size_t);
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkFILEWStream : public SkWStream {
|
||||
class SK_API SkFILEWStream : public SkWStream {
|
||||
public:
|
||||
SkFILEWStream(const char path[]);
|
||||
SK_DECLARE_INST_COUNT(SkFILEWStream)
|
||||
|
||||
SkFILEWStream(const char path[]);
|
||||
virtual ~SkFILEWStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
|
@ -264,12 +294,17 @@ public:
|
|||
|
||||
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual void flush() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkFILE* fFILE;
|
||||
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
class SkMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkMemoryWStream)
|
||||
|
||||
SkMemoryWStream(void* buffer, size_t size);
|
||||
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
|
||||
size_t bytesWritten() const { return fBytesWritten; }
|
||||
|
@ -278,10 +313,14 @@ private:
|
|||
char* fBuffer;
|
||||
size_t fMaxLength;
|
||||
size_t fBytesWritten;
|
||||
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
class SK_API SkDynamicMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream)
|
||||
|
||||
SkDynamicMemoryWStream();
|
||||
virtual ~SkDynamicMemoryWStream();
|
||||
|
||||
|
@ -313,14 +352,21 @@ private:
|
|||
mutable SkData* fCopy; // is invalidated if we write after it is created
|
||||
|
||||
void invalidateCopy();
|
||||
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
|
||||
class SkDebugWStream : public SkWStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDebugWStream)
|
||||
|
||||
// overrides
|
||||
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual void newline() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
// for now
|
||||
|
|
|
@ -55,9 +55,7 @@ char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
|
|||
#define SkStrAppendScalar SkStrAppendFixed
|
||||
#endif
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
char* SkStrAppendFloat(char buffer[], float);
|
||||
#endif
|
||||
char* SkStrAppendFixed(char buffer[], SkFixed);
|
||||
|
||||
/** \class SkString
|
||||
|
@ -144,9 +142,9 @@ public:
|
|||
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 printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
||||
void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
||||
void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
||||
|
||||
void remove(size_t offset, size_t length);
|
||||
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef 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
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkSurface_DEFINED
|
||||
#define SkSurface_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkImage.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
class GrContext;
|
||||
class GrRenderTarget;
|
||||
|
||||
/**
|
||||
* SkSurface represents the backend/results of drawing to a canvas. For raster
|
||||
* drawing, the surface will be pixels, but (for example) when drawing into
|
||||
* a PDF or Picture canvas, the surface stores the recorded commands.
|
||||
*
|
||||
* To draw into a canvas, first create the appropriate type of Surface, and
|
||||
* then request the canvas from the surface.
|
||||
*/
|
||||
class SkSurface : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkSurface)
|
||||
|
||||
/**
|
||||
* Create a new surface, using the specified pixels/rowbytes as its
|
||||
* backend.
|
||||
*
|
||||
* If the requested surface cannot be created, or the request is not a
|
||||
* supported configuration, NULL will be returned.
|
||||
*/
|
||||
static SkSurface* NewRasterDirect(const SkImage::Info&, SkColorSpace*,
|
||||
void* pixels, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Return a new surface, with the memory for the pixels automatically
|
||||
* allocated.
|
||||
*
|
||||
* If the requested surface cannot be created, or the request is not a
|
||||
* supported configuration, NULL will be returned.
|
||||
*/
|
||||
static SkSurface* NewRaster(const SkImage::Info&, SkColorSpace*);
|
||||
|
||||
/**
|
||||
* Return a new surface whose contents will be recorded into a picture.
|
||||
* When this surface is drawn into another canvas, its contents will be
|
||||
* "replayed" into that canvas.
|
||||
*/
|
||||
static SkSurface* NewPicture(int width, int height);
|
||||
|
||||
/**
|
||||
* Return a new surface using the specified render target.
|
||||
*/
|
||||
static SkSurface* NewRenderTargetDirect(GrContext*, GrRenderTarget*);
|
||||
|
||||
/**
|
||||
* Return a new surface whose contents will be drawn to an offscreen
|
||||
* render target, allocated by the surface.
|
||||
*/
|
||||
static SkSurface* NewRenderTarget(GrContext*, const SkImage::Info&,
|
||||
SkColorSpace*, int sampleCount = 0);
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
|
||||
/**
|
||||
* Returns a unique non-zero, unique value identifying the content of this
|
||||
* surface. Each time the content is changed changed, either by drawing
|
||||
* into this surface, or explicitly calling notifyContentChanged()) this
|
||||
* method will return a new value.
|
||||
*
|
||||
* If this surface is empty (i.e. has a zero-dimention), this will return
|
||||
* 0.
|
||||
*/
|
||||
uint32_t generationID();
|
||||
|
||||
/**
|
||||
* Call this if the contents have changed. This will (lazily) force a new
|
||||
* value to be returned from generationID() when it is called next.
|
||||
*/
|
||||
void notifyContentChanged();
|
||||
|
||||
/**
|
||||
* Return a canvas that will draw into this surface. This will always
|
||||
* return the same canvas for a given surface, and is manged/owned by the
|
||||
* surface. It should not be used when its parent surface has gone out of
|
||||
* scope.
|
||||
*/
|
||||
SkCanvas* getCanvas();
|
||||
|
||||
/**
|
||||
* Return a new surface that is "compatible" with this one, in that it will
|
||||
* efficiently be able to be drawn into this surface. Typical calling
|
||||
* pattern:
|
||||
*
|
||||
* SkSurface* A = SkSurface::New...();
|
||||
* SkCanvas* canvasA = surfaceA->newCanvas();
|
||||
* ...
|
||||
* SkSurface* surfaceB = surfaceA->newSurface(...);
|
||||
* SkCanvas* canvasB = surfaceB->newCanvas();
|
||||
* ... // draw using canvasB
|
||||
* canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
|
||||
*/
|
||||
SkSurface* newSurface(const SkImage::Info&, SkColorSpace*);
|
||||
|
||||
/**
|
||||
* Returns an image of the current state of the surface pixels up to this
|
||||
* point. Subsequent changes to the surface (by drawing into its canvas)
|
||||
* will not be reflected in this image.
|
||||
*/
|
||||
SkImage* newImageShapshot();
|
||||
|
||||
/**
|
||||
* Thought the caller could get a snapshot image explicitly, and draw that,
|
||||
* it seems that directly drawing a surface into another canvas might be
|
||||
* a common pattern, and that we could possibly be more efficient, since
|
||||
* we'd know that the "snapshot" need only live until we've handed it off
|
||||
* to the canvas.
|
||||
*/
|
||||
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
|
||||
|
||||
protected:
|
||||
SkSurface(int width, int height);
|
||||
|
||||
// called by subclass if their contents have changed
|
||||
void dirtyGenerationID() {
|
||||
fGenerationID = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const int fWidth;
|
||||
const int fHeight;
|
||||
uint32_t fGenerationID;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -60,13 +60,13 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates an empty array that will preallocate space for reserveCount
|
||||
* Creates an empty array that will preallocate space for reserveCount
|
||||
* elements.
|
||||
*/
|
||||
explicit SkTArray(int reserveCount) {
|
||||
this->init(NULL, 0, NULL, reserveCount);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies one array to another. The new array will be heap allocated.
|
||||
*/
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a SkTArray by copying contents of a standard C array. The new
|
||||
* Creates a SkTArray by copying contents of a standard C array. The new
|
||||
* array will be heap allocated. Be careful not to use this constructor
|
||||
* when you really want the (void*, int) version.
|
||||
*/
|
||||
|
@ -331,13 +331,11 @@ private:
|
|||
int newCount = fCount + delta;
|
||||
int newAllocCount = fAllocCount;
|
||||
|
||||
if (newCount > fAllocCount) {
|
||||
newAllocCount = SkMax32(newCount + ((newCount + 1) >> 1),
|
||||
fReserveCount);
|
||||
} else if (newCount < fAllocCount / 3) {
|
||||
newAllocCount = SkMax32(fAllocCount / 2, fReserveCount);
|
||||
if (newCount > fAllocCount || newCount < (fAllocCount / 3)) {
|
||||
// whether we're growing or shrinking, we leave at least 50% extra space for future
|
||||
// growth (clamped to the reserve count).
|
||||
newAllocCount = SkMax32(newCount + ((newCount + 1) >> 1), fReserveCount);
|
||||
}
|
||||
|
||||
if (newAllocCount != fAllocCount) {
|
||||
|
||||
fAllocCount = newAllocCount;
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
/**
|
||||
* Return the number of elements in the array
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
int count() const { return (int)fCount; }
|
||||
|
||||
/**
|
||||
* return the number of bytes in the array: count * sizeof(T)
|
||||
|
@ -121,7 +121,7 @@ public:
|
|||
SkASSERT(fReserve == 0 && fCount == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rewind() {
|
||||
// same as setCount(0)
|
||||
fCount = 0;
|
||||
|
@ -166,9 +166,9 @@ public:
|
|||
}
|
||||
return fArray + oldCount;
|
||||
}
|
||||
|
||||
|
||||
T* appendClear() {
|
||||
T* result = this->append();
|
||||
T* result = this->append();
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
|
@ -228,6 +228,32 @@ public:
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff the array contains this element.
|
||||
*/
|
||||
bool contains(const T& elem) const {
|
||||
return (this->find(elem) >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies up to max elements into dst. The number of items copied is
|
||||
* capped by count - index. The actual number copied is returned.
|
||||
*/
|
||||
int copyRange(T* dst, size_t index, int max) const {
|
||||
SkASSERT(max >= 0);
|
||||
SkASSERT(!max || dst);
|
||||
if (index >= fCount) {
|
||||
return 0;
|
||||
}
|
||||
int count = SkMin32(max, fCount - index);
|
||||
memcpy(dst, fArray + index, sizeof(T) * count);
|
||||
return count;
|
||||
}
|
||||
|
||||
void copy(T* dst) const {
|
||||
this->copyRange(0, fCount, dst);
|
||||
}
|
||||
|
||||
// routines to treat the array like a stack
|
||||
T* push() { return this->append(); }
|
||||
void push(const T& elem) { *this->append() = elem; }
|
||||
|
@ -240,7 +266,7 @@ public:
|
|||
T* iter = fArray;
|
||||
T* stop = fArray + fCount;
|
||||
while (iter < stop) {
|
||||
delete (*iter);
|
||||
SkDELETE (*iter);
|
||||
iter += 1;
|
||||
}
|
||||
this->reset();
|
||||
|
@ -314,4 +340,3 @@ private:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkTDLinkedList_DEFINED
|
||||
#define SkTDLinkedList_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/**
|
||||
* Helper class to automatically initialize the doubly linked list
|
||||
* created pointers.
|
||||
*/
|
||||
template <typename T> class SkPtrWrapper {
|
||||
public:
|
||||
SkPtrWrapper() : fPtr(NULL) {}
|
||||
SkPtrWrapper& operator =(T* ptr) { fPtr = ptr; return *this; }
|
||||
operator T*() const { return fPtr; }
|
||||
T* operator->() { return fPtr; }
|
||||
private:
|
||||
T* fPtr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This macro creates the member variables required by
|
||||
* the SkTDLinkedList class. It should be placed in the private section
|
||||
* of any class that will be stored in a double linked list.
|
||||
*/
|
||||
#define SK_DEFINE_DLINKEDLIST_INTERFACE(ClassName) \
|
||||
friend class SkTDLinkedList<ClassName>; \
|
||||
/* back pointer to the owning list - for debugging */ \
|
||||
SkDEBUGCODE(SkPtrWrapper<SkTDLinkedList<ClassName> > fList;)\
|
||||
SkPtrWrapper<ClassName> fPrev; \
|
||||
SkPtrWrapper<ClassName> fNext;
|
||||
|
||||
/**
|
||||
* This class implements a templated internal doubly linked list data structure.
|
||||
*/
|
||||
template <class T> class SkTDLinkedList : public SkNoncopyable {
|
||||
public:
|
||||
SkTDLinkedList()
|
||||
: fHead(NULL)
|
||||
, fTail(NULL) {
|
||||
}
|
||||
|
||||
void remove(T* entry) {
|
||||
SkASSERT(NULL != fHead && NULL != fTail);
|
||||
SkASSERT(this->isInList(entry));
|
||||
|
||||
T* prev = entry->fPrev;
|
||||
T* next = entry->fNext;
|
||||
|
||||
if (NULL != prev) {
|
||||
prev->fNext = next;
|
||||
} else {
|
||||
fHead = next;
|
||||
}
|
||||
if (NULL != next) {
|
||||
next->fPrev = prev;
|
||||
} else {
|
||||
fTail = prev;
|
||||
}
|
||||
|
||||
entry->fPrev = NULL;
|
||||
entry->fNext = NULL;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
entry->fList = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void addToHead(T* entry) {
|
||||
SkASSERT(NULL == entry->fPrev && NULL == entry->fNext);
|
||||
SkASSERT(NULL == entry->fList);
|
||||
|
||||
entry->fPrev = NULL;
|
||||
entry->fNext = fHead;
|
||||
if (NULL != fHead) {
|
||||
fHead->fPrev = entry;
|
||||
}
|
||||
fHead = entry;
|
||||
if (NULL == fTail) {
|
||||
fTail = entry;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
entry->fList = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isEmpty() const {
|
||||
return NULL == fHead && NULL == fTail;
|
||||
}
|
||||
|
||||
T* head() { return fHead; }
|
||||
T* tail() { return fTail; }
|
||||
|
||||
class Iter {
|
||||
public:
|
||||
enum IterStart {
|
||||
kHead_IterStart,
|
||||
kTail_IterStart
|
||||
};
|
||||
|
||||
Iter() : fCur(NULL) {}
|
||||
|
||||
T* init(SkTDLinkedList& list, IterStart startLoc) {
|
||||
if (kHead_IterStart == startLoc) {
|
||||
fCur = list.fHead;
|
||||
} else {
|
||||
SkASSERT(kTail_IterStart == startLoc);
|
||||
fCur = list.fTail;
|
||||
}
|
||||
|
||||
return fCur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next/previous element in the list or NULL if at the end.
|
||||
*/
|
||||
T* next() {
|
||||
if (NULL == fCur) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fCur = fCur->fNext;
|
||||
return fCur;
|
||||
}
|
||||
|
||||
T* prev() {
|
||||
if (NULL == fCur) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fCur = fCur->fPrev;
|
||||
return fCur;
|
||||
}
|
||||
|
||||
private:
|
||||
T* fCur;
|
||||
};
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const {
|
||||
GrAssert(!fHead == !fTail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Debugging-only method that uses the list back pointer to check if
|
||||
* 'entry' is indeed in 'this' list.
|
||||
*/
|
||||
bool isInList(const T* entry) const {
|
||||
return entry->fList == this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debugging-only method that laboriously counts the list entries.
|
||||
*/
|
||||
int countEntries() const {
|
||||
int count = 0;
|
||||
for (T* entry = fHead; NULL != entry; entry = entry->fNext) {
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
#endif // SK_DEBUG
|
||||
|
||||
private:
|
||||
T* fHead;
|
||||
T* fTail;
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
#endif // SkTDLinkedList_DEFINED
|
|
@ -76,13 +76,13 @@ public:
|
|||
* false otherwise.
|
||||
*/
|
||||
bool isValid() const { return NULL != fPtr; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns either NULL, or a copy of the object that was passed to
|
||||
* set() or the constructor.
|
||||
*/
|
||||
T* get() const { SkASSERT(this->isValid()); return fPtr; }
|
||||
|
||||
|
||||
private:
|
||||
T* fPtr; // NULL or fStorage
|
||||
char fStorage[sizeof(T)];
|
||||
|
|
|
@ -63,6 +63,39 @@ int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
|
|||
return hi;
|
||||
}
|
||||
|
||||
template <typename T, int (COMPARE)(const T*, const 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 (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*))
|
||||
|
@ -132,6 +165,39 @@ int SkTSearch(const T** base, int count, const T* target, size_t elemSize,
|
|||
return hi;
|
||||
}
|
||||
|
||||
template <typename T, int (COMPARE)(const T*, const 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 (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[],
|
||||
|
@ -154,7 +220,7 @@ 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; }
|
||||
|
||||
|
|
|
@ -18,6 +18,27 @@
|
|||
resource management.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SkTIsConst<T>::value is true if the type T is const.
|
||||
* The type T is constrained not to be an array or reference type.
|
||||
*/
|
||||
template <typename T> struct SkTIsConst {
|
||||
static T* t;
|
||||
static uint16_t test(const volatile void*);
|
||||
static uint32_t test(volatile void *);
|
||||
static const bool value = (sizeof(uint16_t) == sizeof(test(t)));
|
||||
};
|
||||
|
||||
///@{
|
||||
/** SkTConstType<T, CONST>::type will be 'const T' if CONST is true, 'T' otherwise. */
|
||||
template <typename T, bool CONST> struct SkTConstType {
|
||||
typedef T type;
|
||||
};
|
||||
template <typename T> struct SkTConstType<T, true> {
|
||||
typedef const T type;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \class SkAutoTCallVProc
|
||||
|
||||
Call a function when this goes out of scope. The template uses two
|
||||
|
@ -72,10 +93,10 @@ private:
|
|||
template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTDeleteArray(T array[]) : fArray(array) {}
|
||||
~SkAutoTDeleteArray() { delete[] fArray; }
|
||||
~SkAutoTDeleteArray() { SkDELETE_ARRAY(fArray); }
|
||||
|
||||
T* get() const { return fArray; }
|
||||
void free() { delete[] fArray; fArray = NULL; }
|
||||
void free() { SkDELETE_ARRAY(fArray); fArray = NULL; }
|
||||
T* detach() { T* array = fArray; fArray = NULL; return array; }
|
||||
|
||||
private:
|
||||
|
@ -86,9 +107,26 @@ private:
|
|||
*/
|
||||
template <typename T> class SkAutoTArray : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTArray() {
|
||||
fArray = NULL;
|
||||
SkDEBUGCODE(fCount = 0;)
|
||||
}
|
||||
/** Allocate count number of T elements
|
||||
*/
|
||||
SkAutoTArray(size_t count) {
|
||||
explicit SkAutoTArray(int count) {
|
||||
SkASSERT(count >= 0);
|
||||
fArray = NULL;
|
||||
if (count) {
|
||||
fArray = new T[count];
|
||||
}
|
||||
SkDEBUGCODE(fCount = count;)
|
||||
}
|
||||
|
||||
/** Reallocates given a new count. Reallocation occurs even if new count equals old count.
|
||||
*/
|
||||
void reset(int count) {
|
||||
delete[] fArray;
|
||||
SkASSERT(count >= 0);
|
||||
fArray = NULL;
|
||||
if (count) {
|
||||
fArray = new T[count];
|
||||
|
@ -103,17 +141,17 @@ public:
|
|||
/** 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);
|
||||
SkASSERT((unsigned)index < (unsigned)fCount);
|
||||
return fArray[index];
|
||||
}
|
||||
|
||||
private:
|
||||
T* fArray;
|
||||
SkDEBUGCODE(size_t fCount;)
|
||||
SkDEBUGCODE(int fCount;)
|
||||
};
|
||||
|
||||
/** Wraps SkAutoTArray, with room for up to N elements preallocated
|
||||
|
@ -132,7 +170,7 @@ public:
|
|||
}
|
||||
fCount = count;
|
||||
}
|
||||
|
||||
|
||||
~SkAutoSTArray() {
|
||||
if (fCount > N) {
|
||||
delete[] fArray;
|
||||
|
@ -144,22 +182,22 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** 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;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
/****** SkThread_platform needs to define the following...
|
||||
|
||||
int32_t sk_atomic_inc(int32_t*);
|
||||
int32_t sk_atomic_add(int32_t*, int32_t);
|
||||
int32_t sk_atomic_dec(int32_t*);
|
||||
int32_t sk_atomic_conditional_inc(int32_t*);
|
||||
|
||||
|
@ -36,7 +37,7 @@ public:
|
|||
SkASSERT(fMutex != NULL);
|
||||
mutex.acquire();
|
||||
}
|
||||
|
||||
|
||||
SkAutoMutexAcquire(SkBaseMutex* mutex) : fMutex(mutex) {
|
||||
if (mutex) {
|
||||
mutex->acquire();
|
||||
|
@ -59,7 +60,7 @@ public:
|
|||
fMutex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
SkBaseMutex* fMutex;
|
||||
};
|
||||
|
|
|
@ -23,6 +23,10 @@ static inline __attribute__((always_inline)) int32_t sk_atomic_inc(int32_t *addr
|
|||
return __sync_fetch_and_add(addr, 1);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) int32_t sk_atomic_add(int32_t *addr, int32_t inc) {
|
||||
return __sync_fetch_and_add(addr, inc);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) int32_t sk_atomic_dec(int32_t *addr) {
|
||||
return __sync_fetch_and_add(addr, -1);
|
||||
}
|
||||
|
@ -54,8 +58,9 @@ static inline __attribute__((always_inline)) void sk_membar_aquire__after_atomic
|
|||
*/
|
||||
#include <utils/Atomic.h>
|
||||
|
||||
#define sk_atomic_inc(addr) android_atomic_inc(addr)
|
||||
#define sk_atomic_dec(addr) android_atomic_dec(addr)
|
||||
#define sk_atomic_inc(addr) android_atomic_inc(addr)
|
||||
#define sk_atomic_add(addr, inc) android_atomic_add(inc, addr)
|
||||
#define sk_atomic_dec(addr) android_atomic_dec(addr)
|
||||
void sk_membar_aquire__after_atomic_dec() {
|
||||
//HACK: Android is actually using full memory barriers.
|
||||
// Should this change, uncomment below.
|
||||
|
@ -92,6 +97,14 @@ void sk_membar_aquire__after_atomic_conditional_inc() {
|
|||
*/
|
||||
SK_API int32_t sk_atomic_inc(int32_t* addr);
|
||||
|
||||
/** Implemented by the porting layer, this function adds inc to the int
|
||||
specified by the address (in a thread-safe manner), and returns the
|
||||
previous value.
|
||||
No additional memory barrier is required.
|
||||
This must act as a compiler barrier.
|
||||
*/
|
||||
SK_API int32_t sk_atomic_add(int32_t* addr, int32_t inc);
|
||||
|
||||
/** Implemented by the porting layer, this function subtracts one from the int
|
||||
specified by the address (in a thread-safe manner), and returns the
|
||||
previous value.
|
||||
|
@ -140,7 +153,7 @@ struct SkBaseMutex {
|
|||
// Special case used when the static mutex must be available globally.
|
||||
#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER }
|
||||
|
||||
#define SK_DECLARE_MUTEX_ARRAY(name, count) SkBaseMutex name[count] = { PTHREAD_MUTEX_INITIALIZER }
|
||||
#define SK_DECLARE_MUTEX_ARRAY(name, count) SkBaseMutex name[count] = { { PTHREAD_MUTEX_INITIALIZER } }
|
||||
|
||||
// A normal mutex that requires to be initialized through normal C++ construction,
|
||||
// i.e. when it's a member of another class, or allocated on the heap.
|
||||
|
|
|
@ -31,6 +31,8 @@ typedef uint32_t SkFontTableTag;
|
|||
*/
|
||||
class SK_API SkTypeface : public SkWeakRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkTypeface)
|
||||
|
||||
/** Style specifies the intrinsic style attributes of a given typeface
|
||||
*/
|
||||
enum Style {
|
||||
|
@ -62,7 +64,7 @@ public:
|
|||
data. Will never return 0.
|
||||
*/
|
||||
SkFontID uniqueID() const { return fUniqueID; }
|
||||
|
||||
|
||||
/** Return the uniqueID for the specified typeface. If the face is null,
|
||||
resolve it to the default font and return its uniqueID. Will never
|
||||
return 0.
|
||||
|
@ -140,25 +142,25 @@ public:
|
|||
|
||||
/** Return the number of tables in the font. */
|
||||
int countTables() const;
|
||||
|
||||
|
||||
/** Copy into tags[] (allocated by the caller) the list of table tags in
|
||||
* the font, and return the number. This will be the same as CountTables()
|
||||
* or 0 if an error occured. If tags == NULL, this only returns the count
|
||||
* (the same as calling countTables()).
|
||||
*/
|
||||
int getTableTags(SkFontTableTag tags[]) const;
|
||||
|
||||
|
||||
/** Given a table tag, return the size of its contents, or 0 if not present
|
||||
*/
|
||||
size_t getTableSize(SkFontTableTag) const;
|
||||
|
||||
|
||||
/** Copy the contents of a table into data (allocated by the caller). Note
|
||||
* that the contents of the table will be in their native endian order
|
||||
* (which for most truetype tables is big endian). If the table tag is
|
||||
* not found, or there is an error copying the data, then 0 is returned.
|
||||
* If this happens, it is possible that some or all of the memory pointed
|
||||
* to by data may have been written to, even though an error has occured.
|
||||
*
|
||||
*
|
||||
* @param fontID the font to copy the table from
|
||||
* @param tag The table tag whose contents are to be copied
|
||||
* @param offset The offset in bytes into the table's contents where the
|
||||
|
@ -174,7 +176,13 @@ public:
|
|||
*/
|
||||
size_t getTableData(SkFontTableTag tag, size_t offset, size_t length,
|
||||
void* data) const;
|
||||
|
||||
|
||||
/**
|
||||
* Return the units-per-em value for this typeface, or zero if there is an
|
||||
* error.
|
||||
*/
|
||||
int getUnitsPerEm() const;
|
||||
|
||||
protected:
|
||||
/** uniqueID must be unique (please!) and non-zero
|
||||
*/
|
||||
|
|
|
@ -211,14 +211,14 @@ static inline bool SkIsU16(long x) {
|
|||
*/
|
||||
#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)
|
||||
#define SkIsAlign2(x) (0 == ((x) & 1))
|
||||
|
||||
#define SkIsAlign4(x) (((x) & 3) == 0)
|
||||
#define SkAlign4(x) (((x) + 3) >> 2 << 2)
|
||||
#define SkIsAlign4(x) (0 == ((x) & 3))
|
||||
|
||||
#define SkAlign8(x) (((x) + 7) >> 3 << 3)
|
||||
#define SkIsAlign8(x) (0 == ((x) & 7))
|
||||
|
||||
typedef uint32_t SkFourByteTag;
|
||||
#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
|
@ -432,7 +432,7 @@ public:
|
|||
* malloc a new block of the smaller size.
|
||||
*/
|
||||
kAlloc_OnShrink,
|
||||
|
||||
|
||||
/**
|
||||
* If the requested size is smaller than the current size, and the
|
||||
* current block is dynamically allocated, just return the old
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
class SK_API SkUnPreMultiply {
|
||||
public:
|
||||
typedef uint32_t Scale;
|
||||
|
||||
|
||||
// index this table with alpha [0..255]
|
||||
static const Scale* GetScaleTable() {
|
||||
return gTable;
|
||||
|
@ -28,15 +28,15 @@ public:
|
|||
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
|
||||
|
@ -46,9 +46,9 @@ public:
|
|||
SkASSERT(component <= 255);
|
||||
return (scale * component + (1 << 23)) >> 24;
|
||||
}
|
||||
|
||||
|
||||
static SkColor PMColorToColor(SkPMColor c);
|
||||
|
||||
|
||||
private:
|
||||
static const uint32_t gTable[256];
|
||||
};
|
||||
|
|
|
@ -17,14 +17,19 @@
|
|||
|
||||
class SkUnitMapper : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkUnitMapper)
|
||||
|
||||
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) {}
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
*/
|
||||
class SK_API SkWeakRefCnt : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkWeakRefCnt)
|
||||
|
||||
/** Default construct, initializing the reference counts to 1.
|
||||
The strong references collectively hold one weak reference. When the
|
||||
strong reference count goes to zero, the collectively held weak
|
||||
|
@ -150,6 +152,8 @@ private:
|
|||
|
||||
/* Invariant: fWeakCnt = #weak + (fRefCnt > 0 ? 1 : 0) */
|
||||
mutable int32_t fWeakCnt;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "SkTypes.h"
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkMatrix.h"
|
||||
|
@ -48,6 +49,14 @@ public:
|
|||
*/
|
||||
void* getSingleBlock() const { return fSingleBlock; }
|
||||
|
||||
// return the current offset (will always be a multiple of 4)
|
||||
uint32_t bytesWritten() const { return fSize; }
|
||||
// DEPRECATED: use byetsWritten instead
|
||||
uint32_t size() const { return this->bytesWritten(); }
|
||||
|
||||
void reset();
|
||||
uint32_t* reserve(size_t size); // size MUST be multiple of 4
|
||||
|
||||
/**
|
||||
* Specify the single block to back the writer, rathern than dynamically
|
||||
* allocating the memory. If block == NULL, then the writer reverts to
|
||||
|
@ -59,45 +68,62 @@ public:
|
|||
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 writePtr(void* ptr) {
|
||||
// Since we "know" that we're always 4-byte aligned, we can tell the
|
||||
// compiler that here, by assigning to an int32 ptr.
|
||||
int32_t* addr = (int32_t*)this->reserve(sizeof(void*));
|
||||
if (4 == sizeof(void*)) {
|
||||
*(void**)addr = ptr;
|
||||
} else {
|
||||
memcpy(addr, &ptr, sizeof(void*));
|
||||
}
|
||||
}
|
||||
|
||||
void writeScalar(SkScalar value) {
|
||||
*(SkScalar*)this->reserve(sizeof(value)) = value;
|
||||
}
|
||||
|
||||
|
||||
void writePoint(const SkPoint& pt) {
|
||||
*(SkPoint*)this->reserve(sizeof(pt)) = pt;
|
||||
}
|
||||
|
||||
|
||||
void writeRect(const SkRect& rect) {
|
||||
*(SkRect*)this->reserve(sizeof(rect)) = rect;
|
||||
}
|
||||
|
||||
void writeMatrix(const SkMatrix& matrix) {
|
||||
size_t size = matrix.flatten(NULL);
|
||||
void writePath(const SkPath& path) {
|
||||
size_t size = path.writeToMemory(NULL);
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
matrix.flatten(this->reserve(size));
|
||||
path.writeToMemory(this->reserve(size));
|
||||
}
|
||||
|
||||
void writeRegion(const SkRegion& rgn) {
|
||||
size_t size = rgn.flatten(NULL);
|
||||
|
||||
void writeMatrix(const SkMatrix& matrix) {
|
||||
size_t size = matrix.writeToMemory(NULL);
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
rgn.flatten(this->reserve(size));
|
||||
matrix.writeToMemory(this->reserve(size));
|
||||
}
|
||||
|
||||
void writeRegion(const SkRegion& rgn) {
|
||||
size_t size = rgn.writeToMemory(NULL);
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
rgn.writeToMemory(this->reserve(size));
|
||||
}
|
||||
|
||||
// write count bytes (must be a multiple of 4)
|
||||
|
@ -116,7 +142,7 @@ public:
|
|||
// in the current block
|
||||
memcpy(this->reserve(size), values, size);
|
||||
}
|
||||
|
||||
|
||||
void writePad(const void* src, size_t size);
|
||||
|
||||
/**
|
||||
|
@ -134,23 +160,25 @@ public:
|
|||
*/
|
||||
static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
/**
|
||||
* Move the cursor back to offset bytes from the beginning.
|
||||
* This has the same restrictions as peek32: offset must be <= size() and
|
||||
* offset must be a multiple of 4.
|
||||
*/
|
||||
void rewindToOffset(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:
|
||||
|
@ -167,6 +195,26 @@ private:
|
|||
bool fHeadIsExternalStorage;
|
||||
|
||||
Block* newBlock(size_t bytes);
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class to allocated SIZE bytes as part of the writer, and to provide
|
||||
* that storage to the constructor as its initial storage buffer.
|
||||
*
|
||||
* This wrapper ensures proper alignment rules are met for the storage.
|
||||
*/
|
||||
template <size_t SIZE> class SkSWriter32 : public SkWriter32 {
|
||||
public:
|
||||
SkSWriter32(size_t minSize) : SkWriter32(minSize, fData.fStorage, SIZE) {}
|
||||
|
||||
private:
|
||||
union {
|
||||
void* fPtrAlignment;
|
||||
double fDoubleAlignment;
|
||||
char fStorage[SIZE];
|
||||
} fData;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
class SK_API SkXfermode : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkXfermode)
|
||||
|
||||
SkXfermode() {}
|
||||
|
||||
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
|
||||
|
@ -99,11 +101,11 @@ public:
|
|||
// all remaining modes are defined in the SVG Compositing standard
|
||||
// http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/
|
||||
kPlus_Mode,
|
||||
kMultiply_Mode,
|
||||
|
||||
kMultiply_Mode,
|
||||
|
||||
// all above modes can be expressed as pair of src/dst Coeffs
|
||||
kCoeffModesCnt,
|
||||
|
||||
kCoeffModesCnt,
|
||||
|
||||
kScreen_Mode = kCoeffModesCnt,
|
||||
kOverlay_Mode,
|
||||
kDarken_Mode,
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkConstexprMath_DEFINED
|
||||
#define SkConstexprMath_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include <limits.h>
|
||||
|
||||
template <uintmax_t N, uintmax_t B>
|
||||
struct SK_LOG {
|
||||
//! Compile-time constant ceiling(logB(N)).
|
||||
static const uintmax_t value = 1 + SK_LOG<N/B, B>::value;
|
||||
};
|
||||
template <uintmax_t B>
|
||||
struct SK_LOG<1, B> {
|
||||
static const uintmax_t value = 0;
|
||||
};
|
||||
template <uintmax_t B>
|
||||
struct SK_LOG<0, B> {
|
||||
static const uintmax_t value = 0;
|
||||
};
|
||||
|
||||
template<uintmax_t N>
|
||||
struct SK_2N1 {
|
||||
//! Compile-time constant (2^N)-1.
|
||||
static const uintmax_t value = (SK_2N1<N-1>::value << 1) + 1;
|
||||
};
|
||||
template<>
|
||||
struct SK_2N1<1> {
|
||||
static const uintmax_t value = 1;
|
||||
};
|
||||
|
||||
/** Compile-time constant number of base n digits in type t
|
||||
if the bits of type t are considered as unsigned base two.
|
||||
*/
|
||||
#define SK_BASE_N_DIGITS_IN(n, t) (\
|
||||
SK_LOG<SK_2N1<(sizeof(t) * CHAR_BIT)>::value, n>::value\
|
||||
)
|
||||
/** Compile-time constant number of base 10 digits in type t
|
||||
if the bits of type t are considered as unsigned base two.
|
||||
*/
|
||||
#define SK_DIGITS_IN(t) SK_BASE_N_DIGITS_IN(10, (t))
|
||||
|
||||
//! a > b ? a : b
|
||||
#define SK_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#endif
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkXPSDevice_DEFINED
|
||||
#define SkXPSDevice_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include <ObjBase.h>
|
||||
#include <XpsObjectModel.h>
|
||||
|
||||
#include "SkAutoCoInitialize.h"
|
||||
#include "SkBitSet.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkSize.h"
|
||||
#include "SkTArray.h"
|
||||
#include "SkTScopedComPtr.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
/** \class SkXPSDevice
|
||||
|
||||
The drawing context for the XPS backend.
|
||||
*/
|
||||
class SkXPSDevice : public SkDevice {
|
||||
public:
|
||||
SK_API SkXPSDevice();
|
||||
SK_API virtual ~SkXPSDevice();
|
||||
|
||||
virtual bool beginPortfolio(SkWStream* outputStream);
|
||||
/**
|
||||
@param unitsPerMeter converts geometry units into physical units.
|
||||
@param pixelsPerMeter resolution to use when geometry must be rasterized.
|
||||
@param trimSize final page size in physical units.
|
||||
The top left of the trim is the origin of physical space.
|
||||
@param mediaBox The size of the physical media in physical units.
|
||||
The top and left must be less than zero.
|
||||
The bottom and right must be greater than the trimSize.
|
||||
The default is to coincide with the trimSize.
|
||||
@param bleedBox The size of the bleed box in physical units.
|
||||
Must be contained within the mediaBox.
|
||||
The default is to coincide with the mediaBox.
|
||||
@param artBox The size of the content box in physical units.
|
||||
Must be contained within the trimSize.
|
||||
The default is to coincide with the trimSize.
|
||||
@param cropBox The size of the recommended view port in physical units.
|
||||
Must be contained within the mediaBox.
|
||||
The default is to coincide with the mediaBox.
|
||||
*/
|
||||
virtual bool beginSheet(
|
||||
const SkVector& unitsPerMeter,
|
||||
const SkVector& pixelsPerMeter,
|
||||
const SkSize& trimSize,
|
||||
const SkRect* mediaBox = NULL,
|
||||
const SkRect* bleedBox = NULL,
|
||||
const SkRect* artBox = NULL,
|
||||
const SkRect* cropBox = NULL);
|
||||
|
||||
virtual bool endSheet();
|
||||
virtual bool endPortfolio();
|
||||
|
||||
virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual void clear(SkColor color) SK_OVERRIDE;
|
||||
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawPoints(
|
||||
const SkDraw&,
|
||||
SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint[],
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawRect(
|
||||
const SkDraw&,
|
||||
const SkRect& r,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawPath(
|
||||
const SkDraw&,
|
||||
const SkPath& platonicPath,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) SK_OVERRIDE;
|
||||
|
||||
virtual void drawBitmap(
|
||||
const SkDraw&,
|
||||
const SkBitmap& bitmap,
|
||||
const SkIRect* srcRectOrNull,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawSprite(
|
||||
const SkDraw&,
|
||||
const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawText(
|
||||
const SkDraw&,
|
||||
const void* text, size_t len,
|
||||
SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawPosText(
|
||||
const SkDraw&,
|
||||
const void* text, size_t len,
|
||||
const SkScalar pos[], SkScalar constY, int scalarsPerPos,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawTextOnPath(
|
||||
const SkDraw&,
|
||||
const void* text, size_t len,
|
||||
const SkPath& path,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawVertices(
|
||||
const SkDraw&,
|
||||
SkCanvas::VertexMode,
|
||||
int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual void drawDevice(
|
||||
const SkDraw&,
|
||||
SkDevice* device,
|
||||
int x, int y,
|
||||
const SkPaint& paint) SK_OVERRIDE;
|
||||
|
||||
virtual bool onReadPixels(const SkBitmap& bitmap,
|
||||
int x,
|
||||
int y,
|
||||
SkCanvas::Config8888) SK_OVERRIDE;
|
||||
|
||||
virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
class TypefaceUse : ::SkNoncopyable {
|
||||
public:
|
||||
SkFontID typefaceId;
|
||||
SkStream* fontData;
|
||||
IXpsOMFontResource* xpsFont;
|
||||
SkBitSet* glyphsUsed;
|
||||
|
||||
explicit TypefaceUse();
|
||||
~TypefaceUse();
|
||||
};
|
||||
friend static HRESULT subset_typeface(TypefaceUse* current);
|
||||
|
||||
SkXPSDevice(IXpsOMObjectFactory* xpsFactory);
|
||||
|
||||
SkAutoCoInitialize fAutoCo;
|
||||
SkTScopedComPtr<IXpsOMObjectFactory> fXpsFactory;
|
||||
SkTScopedComPtr<IStream> fOutputStream;
|
||||
SkTScopedComPtr<IXpsOMPackageWriter> fPackageWriter;
|
||||
|
||||
unsigned int fCurrentPage;
|
||||
SkTScopedComPtr<IXpsOMCanvas> fCurrentXpsCanvas;
|
||||
SkSize fCurrentCanvasSize;
|
||||
SkVector fCurrentUnitsPerMeter;
|
||||
SkVector fCurrentPixelsPerMeter;
|
||||
|
||||
SkTArray<TypefaceUse, true> fTypefaces;
|
||||
|
||||
HRESULT initXpsDocumentWriter(IXpsOMImageResource* image);
|
||||
|
||||
HRESULT createXpsPage(
|
||||
const XPS_SIZE& pageSize,
|
||||
IXpsOMPage** page);
|
||||
|
||||
HRESULT createXpsThumbnail(
|
||||
IXpsOMPage* page, const unsigned int pageNumber,
|
||||
IXpsOMImageResource** image);
|
||||
|
||||
void internalDrawRect(
|
||||
const SkDraw&,
|
||||
const SkRect& r,
|
||||
bool transformRect,
|
||||
const SkPaint& paint);
|
||||
|
||||
HRESULT createXpsBrush(
|
||||
const SkPaint& skPaint,
|
||||
IXpsOMBrush** xpsBrush,
|
||||
const SkMatrix* parentTransform = NULL);
|
||||
|
||||
HRESULT createXpsSolidColorBrush(
|
||||
const SkColor skColor, const SkAlpha alpha,
|
||||
IXpsOMBrush** xpsBrush);
|
||||
|
||||
HRESULT createXpsImageBrush(
|
||||
const SkBitmap& bitmap,
|
||||
const SkMatrix& localMatrix,
|
||||
const SkShader::TileMode (&xy)[2],
|
||||
const SkAlpha alpha,
|
||||
IXpsOMTileBrush** xpsBrush);
|
||||
|
||||
HRESULT createXpsLinearGradient(
|
||||
SkShader::GradientInfo info,
|
||||
const SkAlpha alpha,
|
||||
const SkMatrix& localMatrix,
|
||||
IXpsOMMatrixTransform* xpsMatrixToUse,
|
||||
IXpsOMBrush** xpsBrush);
|
||||
|
||||
HRESULT createXpsRadialGradient(
|
||||
SkShader::GradientInfo info,
|
||||
const SkAlpha alpha,
|
||||
const SkMatrix& localMatrix,
|
||||
IXpsOMMatrixTransform* xpsMatrixToUse,
|
||||
IXpsOMBrush** xpsBrush);
|
||||
|
||||
HRESULT createXpsGradientStop(
|
||||
const SkColor skColor,
|
||||
const SkScalar offset,
|
||||
IXpsOMGradientStop** xpsGradStop);
|
||||
|
||||
HRESULT createXpsTransform(
|
||||
const SkMatrix& matrix,
|
||||
IXpsOMMatrixTransform ** xpsTransform);
|
||||
|
||||
HRESULT createXpsRect(
|
||||
const SkRect& rect,
|
||||
BOOL stroke, BOOL fill,
|
||||
IXpsOMGeometryFigure** xpsRect);
|
||||
|
||||
HRESULT createXpsQuad(
|
||||
const SkPoint (&points)[4],
|
||||
BOOL stroke, BOOL fill,
|
||||
IXpsOMGeometryFigure** xpsQuad);
|
||||
|
||||
HRESULT CreateTypefaceUse(
|
||||
const SkPaint& paint,
|
||||
TypefaceUse** fontResource);
|
||||
|
||||
HRESULT AddGlyphs(
|
||||
const SkDraw& d,
|
||||
IXpsOMObjectFactory* xpsFactory,
|
||||
IXpsOMCanvas* canvas,
|
||||
IXpsOMFontResource* font,
|
||||
LPCWSTR text,
|
||||
XPS_GLYPH_INDEX* xpsGlyphs,
|
||||
UINT32 xpsGlyphsLen,
|
||||
XPS_POINT *origin,
|
||||
FLOAT fontSize,
|
||||
XPS_STYLE_SIMULATION sims,
|
||||
const SkMatrix& transform,
|
||||
const SkPaint& paint);
|
||||
|
||||
HRESULT addXpsPathGeometry(
|
||||
IXpsOMGeometryFigureCollection* figures,
|
||||
BOOL stroke, BOOL fill, const SkPath& path);
|
||||
|
||||
HRESULT createPath(
|
||||
IXpsOMGeometryFigure* figure,
|
||||
IXpsOMVisualCollection* visuals,
|
||||
IXpsOMPath** path);
|
||||
|
||||
HRESULT sideOfClamp(
|
||||
const SkRect& leftPoints, const XPS_RECT& left,
|
||||
IXpsOMImageResource* imageResource,
|
||||
IXpsOMVisualCollection* visuals);
|
||||
|
||||
HRESULT cornerOfClamp(
|
||||
const SkRect& tlPoints,
|
||||
const SkColor color,
|
||||
IXpsOMVisualCollection* visuals);
|
||||
|
||||
HRESULT clip(
|
||||
IXpsOMVisual* xpsVisual,
|
||||
const SkDraw& d);
|
||||
HRESULT clipToPath(
|
||||
IXpsOMVisual* xpsVisual,
|
||||
const SkPath& clipPath,
|
||||
XPS_FILL_RULE fillRule);
|
||||
|
||||
HRESULT drawInverseWindingPath(
|
||||
const SkDraw& d,
|
||||
const SkPath& devicePath,
|
||||
IXpsOMPath* xpsPath);
|
||||
|
||||
HRESULT shadePath(
|
||||
IXpsOMPath* shadedPath,
|
||||
const SkPaint& shaderPaint,
|
||||
const SkMatrix& matrix,
|
||||
BOOL* fill, BOOL* stroke);
|
||||
|
||||
void convertToPpm(
|
||||
const SkMaskFilter* filter,
|
||||
SkMatrix* matrix,
|
||||
SkVector* ppuScale,
|
||||
const SkIRect& clip, SkIRect* clipIRect);
|
||||
|
||||
HRESULT applyMask(
|
||||
const SkDraw& d,
|
||||
const SkMask& mask,
|
||||
const SkVector& ppuScale,
|
||||
IXpsOMPath* shadedPath);
|
||||
|
||||
// override from SkDevice
|
||||
virtual SkDevice* onCreateCompatibleDevice(
|
||||
SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque,
|
||||
Usage usage) SK_OVERRIDE;
|
||||
|
||||
// Disable the default copy and assign implementation.
|
||||
SkXPSDevice(const SkXPSDevice&);
|
||||
void operator=(const SkXPSDevice&);
|
||||
|
||||
typedef SkDevice INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -18,8 +18,7 @@ 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);
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) SK_OVERRIDE;
|
||||
|
||||
protected:
|
||||
/** Called at the start of each contour, returns the initial offset
|
||||
|
@ -43,10 +42,10 @@ public:
|
|||
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
|
||||
|
@ -56,8 +55,7 @@ public:
|
|||
*/
|
||||
SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
|
||||
|
||||
// override from SkPathEffect
|
||||
virtual bool filterPath(SkPath*, const SkPath&, SkScalar* width) SK_OVERRIDE;
|
||||
virtual bool filterPath(SkPath*, const SkPath&, SkStrokeRec*) SK_OVERRIDE;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath1DPathEffect)
|
||||
|
||||
|
@ -68,7 +66,7 @@ protected:
|
|||
// overrides from Sk1DPathEffect
|
||||
virtual SkScalar begin(SkScalar contourLength) SK_OVERRIDE;
|
||||
virtual SkScalar next(SkPath*, SkScalar distance, SkPathMeasure&) SK_OVERRIDE;
|
||||
|
||||
|
||||
private:
|
||||
SkPath fPath; // copied from constructor
|
||||
SkScalar fAdvance; // copied from constructor
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
Sk2DPathEffect(const SkMatrix& mat);
|
||||
|
||||
// overrides
|
||||
virtual bool filterPath(SkPath*, const SkPath&, SkScalar* width) SK_OVERRIDE;
|
||||
virtual bool filterPath(SkPath*, const SkPath&, SkStrokeRec*) SK_OVERRIDE;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk2DPathEffect)
|
||||
|
||||
|
@ -58,6 +58,28 @@ private:
|
|||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
class SkLine2DPathEffect : public Sk2DPathEffect {
|
||||
public:
|
||||
SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix)
|
||||
: Sk2DPathEffect(matrix), fWidth(width) {}
|
||||
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec) SK_OVERRIDE;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLine2DPathEffect)
|
||||
|
||||
protected:
|
||||
virtual void nextSpan(int u, int v, int ucount, SkPath* dst) SK_OVERRIDE;
|
||||
|
||||
SkLine2DPathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkScalar fWidth;
|
||||
|
||||
typedef Sk2DPathEffect INHERITED;
|
||||
};
|
||||
|
||||
class SkPath2DPathEffect : public Sk2DPathEffect {
|
||||
public:
|
||||
/**
|
||||
|
@ -65,7 +87,7 @@ public:
|
|||
* the latice.
|
||||
*/
|
||||
SkPath2DPathEffect(const SkMatrix&, const SkPath&);
|
||||
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath2DPathEffect)
|
||||
|
||||
protected:
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2012 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkBitmapSource_DEFINED
|
||||
#define SkBitmapSource_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkBitmap.h"
|
||||
|
||||
class SK_API SkBitmapSource : public SkImageFilter {
|
||||
public:
|
||||
explicit SkBitmapSource(const SkBitmap& bitmap);
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapSource)
|
||||
|
||||
protected:
|
||||
explicit SkBitmapSource(SkFlattenableReadBuffer& buffer);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkBitmap fBitmap;
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2012 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkBlendImageFilter_DEFINED
|
||||
#define SkBlendImageFilter_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkBitmap.h"
|
||||
|
||||
class SK_API SkBlendImageFilter : public SkImageFilter {
|
||||
public:
|
||||
enum Mode {
|
||||
kNormal_Mode,
|
||||
kMultiply_Mode,
|
||||
kScreen_Mode,
|
||||
kDarken_Mode,
|
||||
kLighten_Mode,
|
||||
};
|
||||
SkBlendImageFilter(Mode mode, SkImageFilter* background, SkImageFilter* foreground = NULL);
|
||||
|
||||
~SkBlendImageFilter();
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlendImageFilter)
|
||||
|
||||
virtual bool onFilterImage(Proxy* proxy,
|
||||
const SkBitmap& src,
|
||||
const SkMatrix& ctm,
|
||||
SkBitmap* dst,
|
||||
SkIPoint* offset) SK_OVERRIDE;
|
||||
#if SK_SUPPORT_GPU
|
||||
virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
|
||||
virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
explicit SkBlendImageFilter(SkFlattenableReadBuffer& buffer);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
Mode fMode;
|
||||
SkImageFilter* fBackground;
|
||||
SkImageFilter* fForeground;
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -25,8 +25,8 @@ class SK_API SkBlurDrawLooper : public SkDrawLooper {
|
|||
public:
|
||||
enum BlurFlags {
|
||||
kNone_BlurFlag = 0x00,
|
||||
/**
|
||||
The blur layer's dx/dy/radius aren't affected by the canvas
|
||||
/**
|
||||
The blur layer's dx/dy/radius aren't affected by the canvas
|
||||
transform.
|
||||
*/
|
||||
kIgnoreTransform_BlurFlag = 0x01,
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
kAll_BlurFlag = 0x07
|
||||
};
|
||||
|
||||
SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color,
|
||||
SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color,
|
||||
uint32_t flags = kNone_BlurFlag);
|
||||
virtual ~SkBlurDrawLooper();
|
||||
|
||||
|
@ -55,7 +55,7 @@ private:
|
|||
SkColorFilter* fColorFilter;
|
||||
SkScalar fDx, fDy;
|
||||
SkColor fBlurColor;
|
||||
uint32_t fBlurFlags;
|
||||
uint32_t fBlurFlags;
|
||||
|
||||
enum State {
|
||||
kBeforeEdge,
|
||||
|
@ -63,7 +63,7 @@ private:
|
|||
kDone
|
||||
};
|
||||
State fState;
|
||||
|
||||
|
||||
typedef SkDrawLooper INHERITED;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,13 +9,12 @@
|
|||
#ifndef SkBlurImageFilter_DEFINED
|
||||
#define SkBlurImageFilter_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkSingleInputImageFilter.h"
|
||||
#include "SkSize.h"
|
||||
|
||||
class SK_API SkBlurImageFilter : public SkImageFilter {
|
||||
class SK_API SkBlurImageFilter : public SkSingleInputImageFilter {
|
||||
public:
|
||||
SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY);
|
||||
|
||||
virtual bool asABlur(SkSize* sigma) const SK_OVERRIDE;
|
||||
SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY, SkImageFilter* input = NULL);
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
|
||||
|
||||
|
@ -26,9 +25,12 @@ protected:
|
|||
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
|
||||
|
||||
bool canFilterImageGPU() const SK_OVERRIDE { return true; }
|
||||
virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkSize fSigma;
|
||||
typedef SkImageFilter INHERITED;
|
||||
typedef SkSingleInputImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
@param flags Flags to use - defaults to none
|
||||
@return The new blur maskfilter
|
||||
*/
|
||||
static SkMaskFilter* Create(SkScalar radius, BlurStyle style,
|
||||
static SkMaskFilter* Create(SkScalar radius, BlurStyle style,
|
||||
uint32_t flags = kNone_BlurFlag);
|
||||
|
||||
/** Create an emboss maskfilter
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2012 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkColorFilterImageFilter_DEFINED
|
||||
#define SkColorFilterImageFilter_DEFINED
|
||||
|
||||
#include "SkSingleInputImageFilter.h"
|
||||
|
||||
class SkColorFilter;
|
||||
|
||||
class SkColorFilterImageFilter : public SkSingleInputImageFilter {
|
||||
public:
|
||||
SkColorFilterImageFilter(SkColorFilter* cf, SkImageFilter* input = NULL);
|
||||
virtual ~SkColorFilterImageFilter();
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterImageFilter)
|
||||
|
||||
protected:
|
||||
SkColorFilterImageFilter(SkFlattenableReadBuffer& buffer);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkColorFilter* fColorFilter;
|
||||
|
||||
typedef SkSingleInputImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -15,7 +15,7 @@
|
|||
class SkColorMatrix {
|
||||
public:
|
||||
SkScalar fMat[20];
|
||||
|
||||
|
||||
void setIdentity();
|
||||
void setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
|
||||
SkScalar aScale = SK_Scalar1);
|
||||
|
|
|
@ -15,13 +15,9 @@
|
|||
|
||||
class SK_API 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[]) SK_OVERRIDE;
|
||||
virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]) SK_OVERRIDE;
|
||||
|
@ -41,6 +37,7 @@ protected:
|
|||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkColorMatrix fMatrix;
|
||||
|
||||
typedef void (*Proc)(State*, unsigned r, unsigned g, unsigned b,
|
||||
unsigned a);
|
||||
|
@ -49,7 +46,7 @@ private:
|
|||
State fState;
|
||||
uint32_t fFlags;
|
||||
|
||||
void setup(const SkScalar array[20]);
|
||||
void initState(const SkScalar array[20]);
|
||||
|
||||
typedef SkColorFilter INHERITED;
|
||||
};
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче