зеркало из https://github.com/mozilla/moz-skia.git
grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
2559c62907
Коммит
8a1c16ff38
|
@ -0,0 +1,60 @@
|
|||
#include "SkMatrix.h"
|
||||
|
||||
static void computeOuterProduct(SkScalar op[4],
|
||||
const SkPoint pts0[3], const SkPoint& ave0,
|
||||
const SkPoint pts1[3], const SkPoint& ave1) {
|
||||
bzero(op, 4 * sizeof(op[0]));
|
||||
for (int i = 0; i < 3; i++) {
|
||||
SkScalar x0 = pts0[i].fX - ave0.fX;
|
||||
SkScalar y0 = pts0[i].fY - ave0.fY;
|
||||
SkScalar x1 = pts1[i].fX - ave1.fX;
|
||||
SkScalar y1 = pts1[i].fY - ave1.fY;
|
||||
op[0] += SkScalarMul(x0, x1);
|
||||
op[1] += SkScalarMul(x0, y1);
|
||||
op[2] += SkScalarMul(y0, x1);
|
||||
op[3] += SkScalarMul(y0, y1);
|
||||
}
|
||||
}
|
||||
|
||||
static SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) {
|
||||
return SkScalarMul(ax, bx) + SkScalarMul(ay, by);
|
||||
}
|
||||
|
||||
bool SkSetPoly3To3(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) {
|
||||
const SkPoint& srcAve = src[0];
|
||||
const SkPoint& dstAve = dst[0];
|
||||
|
||||
SkScalar srcOP[4], dstOP[4];
|
||||
|
||||
computeOuterProduct(srcOP, src, srcAve, src, srcAve);
|
||||
computeOuterProduct(dstOP, src, srcAve, dst, dstAve);
|
||||
|
||||
SkScalar det = SkScalarMul(srcOP[0], srcOP[3]) - SkScalarMul(srcOP[1], srcOP[2]);
|
||||
|
||||
// need SkScalarNearlyZeroSquared for this (to match Chrome's fix)
|
||||
if (SkScalarNearlyZero(det)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkScalar invDet = SkScalarInvert(det);
|
||||
|
||||
// now compute invDet * [srcOP]T * [dstOP]
|
||||
|
||||
// scale and transpose
|
||||
const SkScalar srcOP0 = SkScalarMul( srcOP[3], invDet);
|
||||
const SkScalar srcOP1 = SkScalarMul(-srcOP[1], invDet);
|
||||
const SkScalar srcOP2 = SkScalarMul(-srcOP[2], invDet);
|
||||
const SkScalar srcOP3 = SkScalarMul( srcOP[0], invDet);
|
||||
|
||||
matrix->reset();
|
||||
matrix->setScaleX(dot(srcOP0, srcOP1, dstOP[0], dstOP[2]));
|
||||
matrix->setSkewX( dot(srcOP2, srcOP3, dstOP[0], dstOP[2]));
|
||||
matrix->setSkewY (dot(srcOP0, srcOP1, dstOP[1], dstOP[3]));
|
||||
matrix->setScaleY(dot(srcOP2, srcOP3, dstOP[1], dstOP[3]));
|
||||
matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY,
|
||||
matrix->getScaleX(), matrix->getSkewX()));
|
||||
matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY,
|
||||
matrix->getSkewY(), matrix->getScaleY()));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#include "SkMatrix.h"
|
||||
|
||||
#ifdef SK_SCALAR_IS_FIXED
|
||||
typedef int64_t SkDScalar;
|
||||
|
||||
static SkScalar SkDScalar_toScalar(SkDScalar value) {
|
||||
SkDScalar result = (value + (1 << 15)) >> 16;
|
||||
int top = result >> 31;
|
||||
SkASSERT(top == 0 || top == -1);
|
||||
return (SkScalar)result;
|
||||
}
|
||||
static SkScalar div(SkDScalar numer, SkDScalar denom) {
|
||||
denom >>= 16;
|
||||
return numer / denom;
|
||||
}
|
||||
#else
|
||||
typedef double SkDScalar;
|
||||
|
||||
static SkScalar SkDScalar_toScalar(SkDScalar value) {
|
||||
return static_cast<float>(value);
|
||||
}
|
||||
static SkScalar div(SkDScalar numer, SkDScalar denom) {
|
||||
return static_cast<float>(numer / denom);
|
||||
}
|
||||
#endif
|
||||
|
||||
static SkDScalar SkDScalar_setMul(SkScalar a, SkScalar b) {
|
||||
return (SkDScalar)a * b;
|
||||
}
|
||||
|
||||
static void computeOuterProduct(SkScalar op[4],
|
||||
const SkPoint pts0[3], const SkPoint& ave0,
|
||||
const SkPoint pts1[3], const SkPoint& ave1) {
|
||||
bzero(op, 4 * sizeof(op[0]));
|
||||
for (int i = 0; i < 3; i++) {
|
||||
SkScalar x0 = pts0[i].fX - ave0.fX;
|
||||
SkScalar y0 = pts0[i].fY - ave0.fY;
|
||||
SkScalar x1 = pts1[i].fX - ave1.fX;
|
||||
SkScalar y1 = pts1[i].fY - ave1.fY;
|
||||
op[0] += SkScalarMul(x0, x1);
|
||||
op[1] += SkScalarMul(x0, y1);
|
||||
op[2] += SkScalarMul(y0, x1);
|
||||
op[3] += SkScalarMul(y0, y1);
|
||||
}
|
||||
}
|
||||
|
||||
static SkDScalar ddot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) {
|
||||
return SkDScalar_setMul(ax, bx) + SkDScalar_setMul(ay, by);
|
||||
}
|
||||
|
||||
static SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) {
|
||||
return SkDScalar_toScalar(ddot(ax, ay, bx, by));
|
||||
}
|
||||
|
||||
bool SkSetPoly3To3(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) {
|
||||
const SkPoint& srcAve = src[0];
|
||||
const SkPoint& dstAve = dst[0];
|
||||
|
||||
SkScalar srcOP[4], dstOP[4];
|
||||
|
||||
computeOuterProduct(srcOP, src, srcAve, src, srcAve);
|
||||
computeOuterProduct(dstOP, src, srcAve, dst, dstAve);
|
||||
|
||||
SkDScalar det = SkDScalar_setMul(srcOP[0], srcOP[3]) -
|
||||
SkDScalar_setMul(srcOP[1], srcOP[2]);
|
||||
|
||||
SkDScalar M[4];
|
||||
|
||||
const SkScalar srcOP0 = srcOP[3];
|
||||
const SkScalar srcOP1 = -srcOP[1];
|
||||
const SkScalar srcOP2 = -srcOP[2];
|
||||
const SkScalar srcOP3 = srcOP[0];
|
||||
|
||||
M[0] = ddot(srcOP0, srcOP1, dstOP[0], dstOP[2]);
|
||||
M[1] = ddot(srcOP2, srcOP3, dstOP[0], dstOP[2]);
|
||||
M[2] = ddot(srcOP0, srcOP1, dstOP[1], dstOP[3]);
|
||||
M[3] = ddot(srcOP2, srcOP3, dstOP[1], dstOP[3]);
|
||||
|
||||
matrix->reset();
|
||||
matrix->setScaleX(div(M[0], det));
|
||||
matrix->setSkewX( div(M[1], det));
|
||||
matrix->setSkewY (div(M[2], det));
|
||||
matrix->setScaleY(div(M[3], det));
|
||||
matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY,
|
||||
matrix->getScaleX(), matrix->getSkewX()));
|
||||
matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY,
|
||||
matrix->getSkewY(), matrix->getScaleY()));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include "SkMatrix.h"
|
||||
|
||||
typedef int64_t SkDScalar;
|
||||
|
||||
static SkScalar SkDScalar_toScalar(SkDScalar value) {
|
||||
SkDScalar result = (value + (1 << 15)) >> 16;
|
||||
int top = result >> 31;
|
||||
SkASSERT(top == 0 || top == -1);
|
||||
return (SkScalar)result;
|
||||
}
|
||||
|
||||
static SkDScalar SkDScalar_setMul(SkScalar a, SkScalar b) {
|
||||
return (SkDScalar)a * b;
|
||||
}
|
||||
|
||||
static void computeOuterProduct(SkMatrix* matrix,
|
||||
const SkPoint pts0[3], const SkPoint& ave0,
|
||||
const SkPoint pts1[3], const SkPoint& ave1) {
|
||||
SkDScalar tmp[4];
|
||||
bzero(tmp, sizeof(tmp));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
SkScalar x0 = pts0[i].fX - ave0.fX;
|
||||
SkScalar y0 = pts0[i].fY - ave0.fY;
|
||||
SkScalar x1 = pts1[i].fX - ave1.fX;
|
||||
SkScalar y1 = pts1[i].fY - ave1.fY;
|
||||
tmp[0] += SkDScalar_setMul(x0, x1);
|
||||
tmp[1] += SkDScalar_setMul(x0, y1);
|
||||
tmp[2] += SkDScalar_setMul(y0, x1);
|
||||
tmp[3] += SkDScalar_setMul(y0, y1);
|
||||
}
|
||||
matrix->reset();
|
||||
matrix->setScaleX(SkDScalar_toScalar(tmp[0]));
|
||||
matrix->setSkewY( SkDScalar_toScalar(tmp[1]));
|
||||
matrix->setSkewX( SkDScalar_toScalar(tmp[2]));
|
||||
matrix->setScaleY(SkDScalar_toScalar(tmp[3]));
|
||||
}
|
||||
|
||||
static SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) {
|
||||
return SkDScalar_toScalar(SkDScalar_setMul(ax, bx) +
|
||||
SkDScalar_setMul(ay, by));
|
||||
}
|
||||
|
||||
bool SkSetPoly3To3(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) {
|
||||
const SkPoint& srcAve = src[0];
|
||||
const SkPoint& dstAve = dst[0];
|
||||
|
||||
SkMatrix srcOP, dstOP;
|
||||
|
||||
computeOuterProduct(&srcOP, src, srcAve, src, srcAve);
|
||||
|
||||
if (!srcOP.invert(&srcOP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
computeOuterProduct(&dstOP, src, srcAve, dst, dstAve);
|
||||
|
||||
matrix->setConcat(dstOP, srcOP);
|
||||
matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY,
|
||||
matrix->getScaleX(), matrix->getSkewX()));
|
||||
matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY,
|
||||
matrix->getSkewY(), matrix->getScaleY()));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,508 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkAnimator_DEFINED
|
||||
#define SkAnimator_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkKey.h"
|
||||
#include "SkEventSink.h"
|
||||
|
||||
class SkAnimateMaker;
|
||||
class SkCanvas;
|
||||
class SkDisplayable;
|
||||
class SkEvent;
|
||||
class SkExtras;
|
||||
struct SkMemberInfo;
|
||||
class SkPaint;
|
||||
struct SkRect;
|
||||
class SkStream;
|
||||
class SkTypedArray;
|
||||
class SkXMLParserError;
|
||||
class SkDOM;
|
||||
struct SkDOMNode;
|
||||
|
||||
/** SkElementType is the type of element: a rectangle, a color, an animator, and so on.
|
||||
This enum is incomplete and will be fleshed out in a future release */
|
||||
enum SkElementType {
|
||||
kElementDummyType
|
||||
};
|
||||
/** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on.
|
||||
This enum is incomplete and will be fleshed out in a future release */
|
||||
enum SkFieldType {
|
||||
kFieldDummyType
|
||||
};
|
||||
|
||||
/** \class SkAnimator
|
||||
|
||||
The SkAnimator class decodes an XML stream into a display list. The
|
||||
display list can be drawn statically as a picture, or can drawn
|
||||
different elements at different times to form a moving animation.
|
||||
|
||||
SkAnimator does not read the system time on its own; it relies on the
|
||||
caller to pass the current time. The caller can pause, speed up, or
|
||||
reverse the animation by varying the time passed in.
|
||||
|
||||
The XML describing the display list must conform to the schema
|
||||
described by SkAnimateSchema.xsd.
|
||||
|
||||
The XML must contain an <event> element to draw. Usually, it contains
|
||||
an <event kind="onload" /> block to add some drawing elements to the
|
||||
display list when the document is first decoded.
|
||||
|
||||
Here's an "Hello World" XML sample:
|
||||
|
||||
<screenplay>
|
||||
<event kind="onload" >
|
||||
<text text="Hello World" y="20" />
|
||||
</event>
|
||||
</screenplay>
|
||||
|
||||
To read and draw this sample:
|
||||
|
||||
// choose one of these two
|
||||
SkAnimator animator; // declare an animator instance on the stack
|
||||
// SkAnimator* animator = new SkAnimator() // or one could instantiate the class
|
||||
|
||||
// choose one of these three
|
||||
animator.decodeMemory(buffer, size); // to read from RAM
|
||||
animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file)
|
||||
animator.decodeURI(filename); // to read from a web location, or from a local text file
|
||||
|
||||
// to draw to the current window:
|
||||
SkCanvas canvas(getBitmap()); // create a canvas
|
||||
animator.draw(canvas, &paint, 0); // draw the scene
|
||||
*/
|
||||
class SkAnimator : public SkEventSink {
|
||||
public:
|
||||
SkAnimator();
|
||||
virtual ~SkAnimator();
|
||||
|
||||
/** Add a drawable extension to the graphics engine. Experimental.
|
||||
@param extras A derived class that implements methods that identify and instantiate the class
|
||||
*/
|
||||
void addExtras(SkExtras* extras);
|
||||
|
||||
/** Read in XML from a stream, and append it to the current
|
||||
animator. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param stream The stream to append.
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
bool appendStream(SkStream* stream);
|
||||
|
||||
/** Read in XML from memory. Returns true if the file can be
|
||||
read without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param buffer The XML text as UTF-8 characters.
|
||||
@param size The XML text length in bytes.
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
bool decodeMemory(const void* buffer, size_t size);
|
||||
|
||||
/** Read in XML from a stream. Returns true if the file can be
|
||||
read without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param stream The stream containg the XML text as UTF-8 characters.
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
virtual bool decodeStream(SkStream* stream);
|
||||
|
||||
/** Parse the DOM tree starting at the specified node. Returns true if it can be
|
||||
parsed without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@return true if the DOM was parsed successfully.
|
||||
*/
|
||||
virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);
|
||||
|
||||
/** Read in XML from a URI. Returns true if the file can be
|
||||
read without error. Returns false if an error was encountered.
|
||||
Error diagnostics are stored in fErrorCode and fLineNumber.
|
||||
@param uri The complete url path to be read (either ftp, http or https).
|
||||
@return true if the XML was parsed successfully.
|
||||
*/
|
||||
bool decodeURI(const char uri[]);
|
||||
|
||||
/** Pass a char event, usually a keyboard symbol, to the animator.
|
||||
This triggers events of the form <event kind="keyChar" key="... />
|
||||
@param ch The character to match against <event> element "key"
|
||||
attributes.
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doCharEvent(SkUnichar ch);
|
||||
|
||||
/** Experimental:
|
||||
Pass a mouse click event along with the mouse coordinates to
|
||||
the animator. This triggers events of the form <event kind="mouseDown" ... />
|
||||
and other mouse events.
|
||||
@param state The mouse state, described by SkView::Click::State : values are
|
||||
down == 0, moved == 1, up == 2
|
||||
@param x The x-position of the mouse
|
||||
@param y The y-position of the mouse
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doClickEvent(int state, SkScalar x, SkScalar y);
|
||||
|
||||
/** Pass a meta-key event, such as an arrow , to the animator.
|
||||
This triggers events of the form <event kind="keyPress" code="... />
|
||||
@param code The key to match against <event> element "code"
|
||||
attributes.
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doKeyEvent(SkKey code);
|
||||
bool doKeyUpEvent(SkKey code);
|
||||
|
||||
/** Send an event to the animator. The animator's clock is set
|
||||
relative to the current time.
|
||||
@return true if the event was dispatched successfully.
|
||||
*/
|
||||
bool doUserEvent(const SkEvent& evt);
|
||||
|
||||
/** The possible results from the draw function.
|
||||
*/
|
||||
enum DifferenceType {
|
||||
kNotDifferent,
|
||||
kDifferent,
|
||||
kPartiallyDifferent
|
||||
};
|
||||
/** Draws one frame of the animation. The first call to draw always
|
||||
draws the initial frame of the animation. Subsequent calls draw
|
||||
the offset into the animation by
|
||||
subtracting the initial time from the current time.
|
||||
@param canvas The canvas to draw into.
|
||||
@param paint The paint to draw with.
|
||||
@param time The offset into the current animation.
|
||||
@return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
|
||||
kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
|
||||
redraw area.
|
||||
*/
|
||||
DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);
|
||||
|
||||
/** Draws one frame of the animation, using a new Paint each time.
|
||||
The first call to draw always
|
||||
draws the initial frame of the animation. Subsequent calls draw
|
||||
the offset into the animation by
|
||||
subtracting the initial time from the current time.
|
||||
@param canvas The canvas to draw into.
|
||||
@param time The offset into the current animation.
|
||||
@return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
|
||||
kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
|
||||
redraw area.
|
||||
*/
|
||||
DifferenceType draw(SkCanvas* canvas, SkMSec time);
|
||||
|
||||
/** Experimental:
|
||||
Helper to choose whether to return a SkView::Click handler.
|
||||
@param x ignored
|
||||
@param y ignored
|
||||
@return true if a mouseDown event handler is enabled.
|
||||
*/
|
||||
bool findClickEvent(SkScalar x, SkScalar y);
|
||||
|
||||
|
||||
/** Get the nested animator associated with this element, if any.
|
||||
Use this to access a movie's event sink, to send events to movies.
|
||||
@param element the value returned by getElement
|
||||
@return the internal animator.
|
||||
*/
|
||||
const SkAnimator* getAnimator(const SkDisplayable* element) const;
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param element the value returned by getElement
|
||||
@param field the value returned by getField
|
||||
@param index the array entry
|
||||
@return the integer value to retrieve, or SK_NaN32 if unsuccessful
|
||||
*/
|
||||
int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the integer value to retrieve, or SK_NaN32 if unsuccessful
|
||||
*/
|
||||
int32_t getArrayInt(const char* elementID, const char* fieldName, int index);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param element the value returned by getElement
|
||||
@param field the value returned by getField
|
||||
@param index the array entry
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
|
||||
*/
|
||||
SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute[index]
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
|
||||
*/
|
||||
SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);
|
||||
|
||||
/** Returns the string value of the specified element's attribute[index]
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@param index the array entry
|
||||
@return the string value to retrieve, or null if unsuccessful
|
||||
*/
|
||||
const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);
|
||||
|
||||
/** Returns the string value of the specified element's attribute[index]
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param index the array entry
|
||||
@return the string value to retrieve, or null if unsuccessful
|
||||
*/
|
||||
const char* getArrayString(const char* elementID, const char* fieldName, int index);
|
||||
|
||||
/** Returns the XML element corresponding to the given ID.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@return the element matching the ID, or null if the element can't be found
|
||||
*/
|
||||
const SkDisplayable* getElement(const char* elementID);
|
||||
|
||||
/** Returns the element type corresponding to the XML element.
|
||||
The element type matches the element name; for instance, <line> returns kElement_LineType
|
||||
@param element is a value returned by getElement
|
||||
@return element type, or 0 if the element can't be found
|
||||
*/
|
||||
SkElementType getElementType(const SkDisplayable* element);
|
||||
|
||||
/** Returns the element type corresponding to the given ID.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@return element type, or 0 if the element can't be found
|
||||
*/
|
||||
SkElementType getElementType(const char* elementID);
|
||||
|
||||
/** Returns the XML field of the named attribute in the XML element.
|
||||
@param element is a value returned by getElement
|
||||
@param fieldName is the attribute to return
|
||||
@return the attribute matching the fieldName, or null if the element can't be found
|
||||
*/
|
||||
const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);
|
||||
|
||||
/** Returns the XML field of the named attribute in the XML element matching the elementID.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName is the attribute to return
|
||||
@return the attribute matching the fieldName, or null if the element can't be found
|
||||
*/
|
||||
const SkMemberInfo* getField(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the value type coresponding to the element's attribute.
|
||||
The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
|
||||
@param field is a value returned by getField
|
||||
@return the attribute type, or 0 if the element can't be found
|
||||
*/
|
||||
SkFieldType getFieldType(const SkMemberInfo* field);
|
||||
|
||||
/** Returns the value type coresponding to the element's attribute.
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the attribute type, or 0 if the element can't be found
|
||||
*/
|
||||
SkFieldType getFieldType(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the recommended animation interval. Returns zero if no
|
||||
interval is specified.
|
||||
*/
|
||||
SkMSec getInterval();
|
||||
|
||||
/** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
|
||||
kIsPartiallyDifferent to do a mimimal inval(). */
|
||||
void getInvalBounds(SkRect* inval);
|
||||
|
||||
/** Returns the details of any error encountered while parsing the XML.
|
||||
*/
|
||||
const SkXMLParserError* getParserError();
|
||||
|
||||
/** Returns the details of any error encountered while parsing the XML as string.
|
||||
*/
|
||||
const char* getParserErrorString();
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@return the integer value to retrieve, or SK_NaN32 if not found
|
||||
*/
|
||||
int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the integer value to retrieve, or SK_NaN32 if not found
|
||||
*/
|
||||
int32_t getInt(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if not found
|
||||
*/
|
||||
SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);
|
||||
|
||||
/** Returns the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the scalar value to retrieve, or SK_ScalarNaN if not found
|
||||
*/
|
||||
SkScalar getScalar(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Returns the string value of the specified element's attribute
|
||||
@param element is a value returned by getElement
|
||||
@param field is a value returned by getField
|
||||
@return the string value to retrieve, or null if not found
|
||||
*/
|
||||
const char* getString(const SkDisplayable* element, const SkMemberInfo* field);
|
||||
|
||||
/** Returns the string value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@return the string value to retrieve, or null if not found
|
||||
*/
|
||||
const char* getString(const char* elementID, const char* fieldName);
|
||||
|
||||
/** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
|
||||
const char* getURIBase();
|
||||
|
||||
/** Resets the animator to a newly created state with no animation data. */
|
||||
void initialize();
|
||||
|
||||
/** Experimental. Resets any active animations so that the next time passed is treated as
|
||||
time zero. */
|
||||
void reset();
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param array is the c-style array of integers
|
||||
@param count is the length of the array
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param array is the c-style array of strings
|
||||
@param count is the length of the array
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param data the integer value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setInt(const char* elementID, const char* fieldName, int32_t data);
|
||||
|
||||
/** Sets the scalar value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param data the scalar value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setScalar(const char* elementID, const char* fieldName, SkScalar data);
|
||||
|
||||
/** Sets the string value of the specified element's attribute
|
||||
@param elementID is the value of the id attribute in the XML of this element
|
||||
@param fieldName specifies the name of the attribute
|
||||
@param data the string value to set
|
||||
@return true if the value was set successfully
|
||||
*/
|
||||
bool setString(const char* elementID, const char* fieldName, const char* data);
|
||||
|
||||
/** Sets the file default directory of the URL base path
|
||||
@param path the directory path
|
||||
*/
|
||||
void setURIBase(const char* path);
|
||||
|
||||
typedef void* Handler;
|
||||
// This guy needs to be exported to java, so don't make it virtual
|
||||
void setHostHandler(Handler handler) {
|
||||
this->onSetHostHandler(handler);
|
||||
}
|
||||
|
||||
/** \class Timeline
|
||||
Returns current time to animator. To return a custom timeline, create a child
|
||||
class and override the getMSecs method.
|
||||
*/
|
||||
class Timeline {
|
||||
public:
|
||||
virtual ~Timeline() {}
|
||||
|
||||
/** Returns the current time in milliseconds */
|
||||
virtual SkMSec getMSecs() const = 0;
|
||||
};
|
||||
|
||||
/** Sets a user class to return the current time to the animator.
|
||||
Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead.
|
||||
@param callBack the time function
|
||||
*/
|
||||
void setTimeline(const Timeline& );
|
||||
|
||||
static void Init(bool runUnitTests);
|
||||
static void Term();
|
||||
|
||||
/** The event sink events generated by the animation are posted to.
|
||||
Screenplay also posts an inval event to this event sink after processing an
|
||||
event to force a redraw.
|
||||
@param target the event sink id
|
||||
*/
|
||||
void setHostEventSinkID(SkEventSinkID hostID);
|
||||
SkEventSinkID getHostEventSinkID() const;
|
||||
|
||||
// helper
|
||||
void setHostEventSink(SkEventSink* sink) {
|
||||
this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
|
||||
}
|
||||
|
||||
virtual void setJavaOwner(Handler owner);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
virtual void eventDone(const SkEvent& evt);
|
||||
virtual bool isTrackingEvents();
|
||||
static bool NoLeaks();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void onSetHostHandler(Handler handler);
|
||||
virtual void onEventPost(SkEvent*, SkEventSinkID);
|
||||
virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);
|
||||
|
||||
private:
|
||||
// helper functions for setters
|
||||
bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
|
||||
bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
|
||||
bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
|
||||
bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
|
||||
bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);
|
||||
|
||||
virtual bool onEvent(const SkEvent&);
|
||||
SkAnimateMaker* fMaker;
|
||||
friend class SkAnimateMaker;
|
||||
friend class SkAnimatorScript;
|
||||
friend class SkAnimatorScript2;
|
||||
friend class SkApply;
|
||||
friend class SkDisplayMovie;
|
||||
friend class SkDisplayType;
|
||||
friend class SkPost;
|
||||
friend class SkXMLAnimatorWriter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkAnimatorView_DEFINED
|
||||
#define SkAnimatorView_DEFINED
|
||||
|
||||
#include "SkView.h"
|
||||
#include "SkAnimator.h"
|
||||
|
||||
class SkAnimatorView : public SkView {
|
||||
public:
|
||||
SkAnimatorView();
|
||||
virtual ~SkAnimatorView();
|
||||
|
||||
SkAnimator* getAnimator() const { return fAnimator; }
|
||||
|
||||
bool decodeFile(const char path[]);
|
||||
bool decodeMemory(const void* buffer, size_t size);
|
||||
bool decodeStream(SkStream* stream);
|
||||
|
||||
protected:
|
||||
// overrides
|
||||
virtual bool onEvent(const SkEvent&);
|
||||
virtual void onDraw(SkCanvas*);
|
||||
virtual void onInflate(const SkDOM&, const SkDOM::Node*);
|
||||
|
||||
private:
|
||||
SkAnimator* fAnimator;
|
||||
|
||||
typedef SkView INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef Sk64_DEFINED
|
||||
#define Sk64_DEFINED
|
||||
|
||||
#include "SkFixed.h"
|
||||
#include "SkMath.h"
|
||||
|
||||
/** \class Sk64
|
||||
|
||||
Sk64 is a 64-bit math package that does not require long long support from the compiler.
|
||||
*/
|
||||
struct Sk64 {
|
||||
int32_t fHi; //!< the high 32 bits of the number (including sign)
|
||||
uint32_t fLo; //!< the low 32 bits of the number
|
||||
|
||||
/** Returns non-zero if the Sk64 can be represented as a signed 32 bit integer
|
||||
*/
|
||||
SkBool is32() const { return fHi == ((int32_t)fLo >> 31); }
|
||||
|
||||
/** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit integer
|
||||
*/
|
||||
SkBool is64() const { return fHi != ((int32_t)fLo >> 31); }
|
||||
|
||||
/** Returns non-zero if the Sk64 can be represented as a signed 48 bit integer. Used to know
|
||||
if we can shift the value down by 16 to treat it as a SkFixed.
|
||||
*/
|
||||
SkBool isFixed() const;
|
||||
|
||||
/** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero.
|
||||
*/
|
||||
int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; }
|
||||
|
||||
/** Return the number >> 16. Asserts that this does not loose any significant high bits.
|
||||
*/
|
||||
SkFixed getFixed() const {
|
||||
SkASSERT(this->isFixed());
|
||||
|
||||
uint32_t sum = fLo + (1 << 15);
|
||||
int32_t hi = fHi;
|
||||
if (sum < fLo) {
|
||||
hi += 1;
|
||||
}
|
||||
return (hi << 16) | (sum >> 16);
|
||||
}
|
||||
|
||||
/** Return the number >> 30. Asserts that this does not loose any
|
||||
significant high bits.
|
||||
*/
|
||||
SkFract getFract() const;
|
||||
|
||||
/** Returns the square-root of the number as a signed 32 bit value. */
|
||||
int32_t getSqrt() const;
|
||||
|
||||
/** Returns the number of leading zeros of the absolute value of this.
|
||||
Will return in the range [0..64]
|
||||
*/
|
||||
int getClzAbs() const;
|
||||
|
||||
/** Returns non-zero if the number is zero */
|
||||
SkBool isZero() const { return (fHi | fLo) == 0; }
|
||||
|
||||
/** Returns non-zero if the number is non-zero */
|
||||
SkBool nonZero() const { return fHi | fLo; }
|
||||
|
||||
/** Returns non-zero if the number is negative (number < 0) */
|
||||
SkBool isNeg() const { return (uint32_t)fHi >> 31; }
|
||||
|
||||
/** Returns non-zero if the number is positive (number > 0) */
|
||||
SkBool isPos() const { return ~(fHi >> 31) & (fHi | fLo); }
|
||||
|
||||
/** Returns -1,0,+1 based on the sign of the number */
|
||||
int sign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); }
|
||||
|
||||
/** Negate the number */
|
||||
void negate();
|
||||
|
||||
/** If the number < 0, negate the number
|
||||
*/
|
||||
void abs();
|
||||
|
||||
/** Returns the number of bits needed to shift the Sk64 to the right
|
||||
in order to make it fit in a signed 32 bit integer.
|
||||
*/
|
||||
int shiftToMake32() const;
|
||||
|
||||
/** Set the number to zero */
|
||||
void setZero() { fHi = fLo = 0; }
|
||||
|
||||
/** Set the high and low 32 bit values of the number */
|
||||
void set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; }
|
||||
|
||||
/** Set the number to the specified 32 bit integer */
|
||||
void set(int32_t a) { fHi = a >> 31; fLo = a; }
|
||||
|
||||
/** Set the number to the product of the two 32 bit integers */
|
||||
void setMul(int32_t a, int32_t b);
|
||||
|
||||
/** extract 32bits after shifting right by bitCount.
|
||||
Note: itCount must be [0..63].
|
||||
Asserts that no significant high bits were lost.
|
||||
*/
|
||||
int32_t getShiftRight(unsigned bitCount) const;
|
||||
|
||||
/** Shift the number left by the specified number of bits.
|
||||
@param bits How far to shift left, must be [0..63]
|
||||
*/
|
||||
void shiftLeft(unsigned bits);
|
||||
|
||||
/** Shift the number right by the specified number of bits.
|
||||
@param bits How far to shift right, must be [0..63]. This
|
||||
performs an arithmetic right-shift (sign extending).
|
||||
*/
|
||||
void shiftRight(unsigned bits);
|
||||
|
||||
/** Shift the number right by the specified number of bits, but
|
||||
round the result.
|
||||
@param bits How far to shift right, must be [0..63]. This
|
||||
performs an arithmetic right-shift (sign extending).
|
||||
*/
|
||||
void roundRight(unsigned bits);
|
||||
|
||||
/** Add the specified 32 bit integer to the number */
|
||||
void add(int32_t lo) {
|
||||
int32_t hi = lo >> 31; // 0 or -1
|
||||
uint32_t sum = fLo + (uint32_t)lo;
|
||||
|
||||
fHi = fHi + hi + (sum < fLo);
|
||||
fLo = sum;
|
||||
}
|
||||
|
||||
/** Add the specified Sk64 to the number */
|
||||
void add(int32_t hi, uint32_t lo) {
|
||||
uint32_t sum = fLo + lo;
|
||||
|
||||
fHi = fHi + hi + (sum < fLo);
|
||||
fLo = sum;
|
||||
}
|
||||
|
||||
/** Add the specified Sk64 to the number */
|
||||
void add(const Sk64& other) { this->add(other.fHi, other.fLo); }
|
||||
|
||||
/** Subtract the specified Sk64 from the number. (*this) = (*this) - num
|
||||
*/
|
||||
void sub(const Sk64& num);
|
||||
|
||||
/** Subtract the number from the specified Sk64. (*this) = num - (*this)
|
||||
*/
|
||||
void rsub(const Sk64& num);
|
||||
|
||||
/** Multiply the number by the specified 32 bit integer
|
||||
*/
|
||||
void mul(int32_t);
|
||||
|
||||
enum DivOptions {
|
||||
kTrunc_DivOption, //!< truncate the result when calling div()
|
||||
kRound_DivOption //!< round the result when calling div()
|
||||
};
|
||||
|
||||
/** Divide the number by the specified 32 bit integer, using the specified
|
||||
divide option (either truncate or round).
|
||||
*/
|
||||
void div(int32_t, DivOptions);
|
||||
|
||||
/** return (this + other >> 16) as a 32bit result */
|
||||
SkFixed addGetFixed(const Sk64& other) const {
|
||||
return this->addGetFixed(other.fHi, other.fLo);
|
||||
}
|
||||
|
||||
/** return (this + Sk64(hi, lo) >> 16) as a 32bit result */
|
||||
SkFixed addGetFixed(int32_t hi, uint32_t lo) const {
|
||||
#ifdef SK_DEBUG
|
||||
Sk64 tmp(*this);
|
||||
tmp.add(hi, lo);
|
||||
#endif
|
||||
|
||||
uint32_t sum = fLo + lo;
|
||||
hi += fHi + (sum < fLo);
|
||||
lo = sum;
|
||||
|
||||
sum = lo + (1 << 15);
|
||||
if (sum < lo)
|
||||
hi += 1;
|
||||
|
||||
hi = (hi << 16) | (sum >> 16);
|
||||
SkASSERT(hi == tmp.getFixed());
|
||||
return hi;
|
||||
}
|
||||
|
||||
/** Return the result of dividing the number by denom, treating the answer
|
||||
as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0.
|
||||
*/
|
||||
SkFixed getFixedDiv(const Sk64& denom) const;
|
||||
|
||||
friend bool operator==(const Sk64& a, const Sk64& b) {
|
||||
return a.fHi == b.fHi && a.fLo == b.fLo;
|
||||
}
|
||||
|
||||
friend bool operator!=(const Sk64& a, const Sk64& b) {
|
||||
return a.fHi != b.fHi || a.fLo != b.fLo;
|
||||
}
|
||||
|
||||
friend bool operator<(const Sk64& a, const Sk64& b) {
|
||||
return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo);
|
||||
}
|
||||
|
||||
friend bool operator<=(const Sk64& a, const Sk64& b) {
|
||||
return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo);
|
||||
}
|
||||
|
||||
friend bool operator>(const Sk64& a, const Sk64& b) {
|
||||
return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo);
|
||||
}
|
||||
|
||||
friend bool operator>=(const Sk64& a, const Sk64& b) {
|
||||
return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo);
|
||||
}
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
SkLONGLONG getLongLong() const;
|
||||
#endif
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** @cond UNIT_TEST */
|
||||
static void UnitTest();
|
||||
/** @endcond */
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,684 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkBitmap_DEFINED
|
||||
#define SkBitmap_DEFINED
|
||||
|
||||
#include "Sk64.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
#if defined(SK_BUILD_FOR_MAC)
|
||||
#include <carbon/carbon.h>
|
||||
#endif
|
||||
|
||||
struct SkIRect;
|
||||
class SkColorTable;
|
||||
class SkPaint;
|
||||
class SkPixelRef;
|
||||
class SkRegion;
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
|
||||
/** \class SkBitmap
|
||||
|
||||
The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
|
||||
and height, and a format (config), and a pointer to the actual pixels.
|
||||
Bitmaps can be drawn into a SkCanvas, but they are also used to specify the target
|
||||
of a SkCanvas' drawing operations.
|
||||
*/
|
||||
class SkBitmap {
|
||||
public:
|
||||
class Allocator;
|
||||
|
||||
enum Config {
|
||||
kNo_Config, //!< bitmap has not been configured
|
||||
kA1_Config, //!< 1-bit per pixel, (0 is transparent, 1 is opaque)
|
||||
kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
|
||||
kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
|
||||
kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kRLE_Index8_Config,
|
||||
|
||||
kConfigCount
|
||||
};
|
||||
|
||||
/** Default construct creates a bitmap with zero width and height, and no pixels.
|
||||
Its config is set to kNo_Config.
|
||||
*/
|
||||
SkBitmap();
|
||||
/** Constructor initializes the new bitmap by copying the src bitmap. All fields are copied,
|
||||
but ownership of the pixels remains with the src bitmap.
|
||||
*/
|
||||
SkBitmap(const SkBitmap& src);
|
||||
/** Decrements our (shared) pixel ownership if needed.
|
||||
*/
|
||||
~SkBitmap();
|
||||
|
||||
/** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
|
||||
with the src bitmap.
|
||||
*/
|
||||
SkBitmap& operator=(const SkBitmap& src);
|
||||
/** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
|
||||
*/
|
||||
// This method is not exported to java.
|
||||
void swap(SkBitmap& other);
|
||||
|
||||
/** Return true iff the bitmap has empty dimensions.
|
||||
*/
|
||||
bool empty() const { return 0 == fWidth || 0 == fHeight; }
|
||||
|
||||
/** Return true iff the bitmap has no pixels nor a pixelref. Note: this can
|
||||
return true even if the dimensions of the bitmap are > 0 (see empty()).
|
||||
*/
|
||||
bool isNull() const { return NULL == fPixels && NULL == fPixelRef; }
|
||||
|
||||
/** Return the config for the bitmap.
|
||||
*/
|
||||
Config config() const { return (Config)fConfig; }
|
||||
/** DEPRECATED, use config()
|
||||
*/
|
||||
Config getConfig() const { return this->config(); }
|
||||
/** Return the bitmap's width, in pixels.
|
||||
*/
|
||||
int width() const { return fWidth; }
|
||||
/** Return the bitmap's height, in pixels.
|
||||
*/
|
||||
int height() const { return fHeight; }
|
||||
/** Return the number of bytes between subsequent rows of the bitmap.
|
||||
*/
|
||||
int rowBytes() const { return fRowBytes; }
|
||||
|
||||
/** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
|
||||
2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
|
||||
for configs that are not at least 1-byte per pixel (e.g. kA1_Config
|
||||
or kNo_Config)
|
||||
*/
|
||||
int shiftPerPixel() const { return fBytesPerPixel >> 1; }
|
||||
|
||||
/** Return the number of bytes per pixel based on the config. If the config
|
||||
does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
|
||||
*/
|
||||
int bytesPerPixel() const { return fBytesPerPixel; }
|
||||
|
||||
/** Return the rowbytes expressed as a number of pixels (like width and
|
||||
height). Note, for 1-byte per pixel configs like kA8_Config, this will
|
||||
return the same as rowBytes(). Is undefined for configs that are less
|
||||
than 1-byte per pixel (e.g. kA1_Config)
|
||||
*/
|
||||
int rowBytesAsPixels() const { return fRowBytes >> (fBytesPerPixel >> 1); }
|
||||
|
||||
/** Return the address of the pixels for this SkBitmap.
|
||||
*/
|
||||
void* getPixels() const { return fPixels; }
|
||||
|
||||
/** Return the byte size of the pixels, based on the height and rowBytes.
|
||||
Note this truncates the result to 32bits. Call getSize64() to detect
|
||||
if the real size exceeds 32bits.
|
||||
*/
|
||||
size_t getSize() const { return fHeight * fRowBytes; }
|
||||
|
||||
/** Return the byte size of the pixels, based on the height and rowBytes.
|
||||
This routine is slightly slower than getSize(), but does not truncate
|
||||
the answer to 32bits.
|
||||
*/
|
||||
Sk64 getSize64() const {
|
||||
Sk64 size;
|
||||
size.setMul(fHeight, fRowBytes);
|
||||
return size;
|
||||
}
|
||||
|
||||
/** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
|
||||
*/
|
||||
bool isOpaque() const;
|
||||
/** Specify if this bitmap's pixels are all opaque or not. Is only meaningful for configs
|
||||
that support per-pixel alpha (RGB32, A1, A8).
|
||||
*/
|
||||
void setIsOpaque(bool);
|
||||
|
||||
/** Reset the bitmap to its initial state (see default constructor). If we are a (shared)
|
||||
owner of the pixels, that ownership is decremented.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Given a config and a width, this computes the optimal rowBytes value. This is called automatically
|
||||
if you pass 0 for rowBytes to setConfig().
|
||||
*/
|
||||
static int ComputeRowBytes(Config c, int width);
|
||||
|
||||
/** Return the bytes-per-pixel for the specified config. If the config is
|
||||
not at least 1-byte per pixel, return 0, including for kNo_Config.
|
||||
*/
|
||||
static int ComputeBytesPerPixel(Config c);
|
||||
|
||||
/** Return the shift-per-pixel for the specified config. If the config is
|
||||
not at least 1-byte per pixel, return 0, including for kNo_Config.
|
||||
*/
|
||||
static int ComputeShiftPerPixel(Config c) {
|
||||
return ComputeBytesPerPixel(c) >> 1;
|
||||
}
|
||||
|
||||
static Sk64 ComputeSize64(Config, int width, int height);
|
||||
static size_t ComputeSize(Config, int width, int height);
|
||||
|
||||
/** Set the bitmap's config and dimensions. If rowBytes is 0, then
|
||||
ComputeRowBytes() is called to compute the optimal value. This resets
|
||||
any pixel/colortable ownership, just like reset().
|
||||
*/
|
||||
void setConfig(Config, int width, int height, int rowBytes = 0);
|
||||
/** Use this to assign a new pixel address for an existing bitmap. This
|
||||
will automatically release any pixelref previously installed. Only call
|
||||
this if you are handling ownership/lifetime of the pixel memory.
|
||||
|
||||
If the bitmap retains a reference to the colortable (assuming it is
|
||||
not null) it will take care of incrementing the reference count.
|
||||
|
||||
@param pixels Address for the pixels, managed by the caller.
|
||||
@param ctable ColorTable (or null) that matches the specified pixels
|
||||
*/
|
||||
void setPixels(void* p, SkColorTable* ctable = NULL);
|
||||
|
||||
/** Use the standard HeapAllocator to create the pixelref that manages the
|
||||
pixel memory. It will be sized based on the current width/height/config.
|
||||
If this is called multiple times, a new pixelref object will be created
|
||||
each time.
|
||||
|
||||
If the bitmap retains a reference to the colortable (assuming it is
|
||||
not null) it will take care of incrementing the reference count.
|
||||
|
||||
@param ctable ColorTable (or null) to use with the pixels that will
|
||||
be allocated. Only used if config == Index8_Config
|
||||
@return true if the allocation succeeds. If not the pixelref field of
|
||||
the bitmap will be unchanged.
|
||||
*/
|
||||
bool allocPixels(SkColorTable* ctable = NULL) {
|
||||
return this->allocPixels(NULL, ctable);
|
||||
}
|
||||
|
||||
/** Use the specified Allocator to create the pixelref that manages the
|
||||
pixel memory. It will be sized based on the current width/height/config.
|
||||
If this is called multiple times, a new pixelref object will be created
|
||||
each time.
|
||||
|
||||
If the bitmap retains a reference to the colortable (assuming it is
|
||||
not null) it will take care of incrementing the reference count.
|
||||
|
||||
@param allocator The Allocator to use to create a pixelref that can
|
||||
manage the pixel memory for the current
|
||||
width/height/config. If allocator is NULL, the standard
|
||||
HeapAllocator will be used.
|
||||
@param ctable ColorTable (or null) to use with the pixels that will
|
||||
be allocated. Only used if config == Index8_Config.
|
||||
If it is non-null and the config is not Index8, it will
|
||||
be ignored.
|
||||
@return true if the allocation succeeds. If not the pixelref field of
|
||||
the bitmap will be unchanged.
|
||||
*/
|
||||
bool allocPixels(Allocator* allocator, SkColorTable* ctable);
|
||||
|
||||
/** Return the current pixelref object, of any
|
||||
*/
|
||||
SkPixelRef* pixelRef() const { return fPixelRef; }
|
||||
/** Return the offset into the pixelref, if any. Will return 0 if there is
|
||||
no pixelref installed.
|
||||
*/
|
||||
size_t pixelRefOffset() const { return fPixelRefOffset; }
|
||||
/** Assign a pixelref and optional offset. Pixelrefs are reference counted,
|
||||
so the existing one (if any) will be unref'd and the new one will be
|
||||
ref'd.
|
||||
*/
|
||||
SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset = 0);
|
||||
|
||||
/** Call this to ensure that the bitmap points to the current pixel address
|
||||
in the pixelref. Balance it with a call to unlockPixels(). These calls
|
||||
are harmless if there is no pixelref.
|
||||
*/
|
||||
void lockPixels() const;
|
||||
/** When you are finished access the pixel memory, call this to balance a
|
||||
previous call to lockPixels(). This allows pixelrefs that implement
|
||||
cached/deferred image decoding to know when there are active clients of
|
||||
a given image.
|
||||
*/
|
||||
void unlockPixels() const;
|
||||
|
||||
/** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
|
||||
it has non-null pixels, and if required by its config, it has a
|
||||
non-null colortable. Returns true if all of the above are met.
|
||||
*/
|
||||
bool readyToDraw() const {
|
||||
return this->getPixels() != NULL &&
|
||||
((this->config() != kIndex8_Config && this->config() != kRLE_Index8_Config) ||
|
||||
fColorTable != NULL);
|
||||
}
|
||||
|
||||
/** Return the bitmap's colortable (if any). Does not affect the colortable's
|
||||
reference count.
|
||||
*/
|
||||
SkColorTable* getColorTable() const { return fColorTable; }
|
||||
|
||||
/** Returns a non-zero, unique value corresponding to the pixels in our
|
||||
pixelref, or 0 if we do not have a pixelref. Each time the pixels are
|
||||
changed (and notifyPixelsChanged is called), a different generation ID
|
||||
will be returned.
|
||||
*/
|
||||
uint32_t getGenerationID() const;
|
||||
|
||||
/** Call this if you have changed the contents of the pixels. This will in-
|
||||
turn cause a different generation ID value to be returned from
|
||||
getGenerationID().
|
||||
*/
|
||||
void notifyPixelsChanged() const;
|
||||
|
||||
/** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is ignored.
|
||||
If the config is kA8_Config, then the r,g,b parameters are ignored.
|
||||
*/
|
||||
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
|
||||
/** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is presumed
|
||||
to be 0xFF. If the config is kA8_Config, then the r,g,b parameters are ignored and the
|
||||
pixels are all set to 0xFF.
|
||||
*/
|
||||
void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
|
||||
this->eraseARGB(0xFF, r, g, b);
|
||||
}
|
||||
/** Initialize the bitmap's pixels with the specified color, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the color's alpha value is presumed
|
||||
to be 0xFF. If the config is kA8_Config, then only the color's alpha value is used.
|
||||
*/
|
||||
void eraseColor(SkColor c) const {
|
||||
this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
|
||||
SkColorGetB(c));
|
||||
}
|
||||
|
||||
/** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are
|
||||
no pixels allocated (i.e. getPixels() returns null) the method will
|
||||
still update the inval region (if present).
|
||||
|
||||
@param subset The subset of the bitmap to scroll/move. To scroll the
|
||||
entire contents, specify [0, 0, width, height] or just
|
||||
pass null.
|
||||
@param dx The amount to scroll in X
|
||||
@param dy The amount to scroll in Y
|
||||
@param inval Optional (may be null). Returns the area of the bitmap that
|
||||
was scrolled away. E.g. if dx = dy = 0, then inval would
|
||||
be set to empty. If dx >= width or dy >= height, then
|
||||
inval would be set to the entire bounds of the bitmap.
|
||||
@return true if the scroll was doable. Will return false if the bitmap
|
||||
uses an unsupported config for scrolling (only kA8,
|
||||
kIndex8, kRGB_565, kARGB_4444, kARGB_8888 are supported).
|
||||
If no pixels are present (i.e. getPixels() returns false)
|
||||
inval will still be updated, and true will be returned.
|
||||
*/
|
||||
bool scrollRect(const SkIRect* subset, int dx, int dy,
|
||||
SkRegion* inval = NULL) const;
|
||||
|
||||
/** Returns the address of the specified pixel. This performs a runtime
|
||||
check to know the size of the pixels, and will return the same answer
|
||||
as the corresponding size-specific method (e.g. getAddr16). Since the
|
||||
check happens at runtime, it is much slower than using a size-specific
|
||||
version. Unlike the size-specific methods, this routine also checks if
|
||||
getPixels() returns null, and returns that. The size-specific routines
|
||||
perform a debugging assert that getPixels() is not null, but they do
|
||||
not do any runtime checks.
|
||||
*/
|
||||
void* getAddr(int x, int y) const;
|
||||
|
||||
/** Returns the address of the pixel specified by x,y for 32bit pixels.
|
||||
*/
|
||||
inline uint32_t* getAddr32(int x, int y) const;
|
||||
/** Returns the address of the pixel specified by x,y for 16bit pixels.
|
||||
*/
|
||||
inline uint16_t* getAddr16(int x, int y) const;
|
||||
/** Returns the address of the pixel specified by x,y for 8bit pixels.
|
||||
*/
|
||||
inline uint8_t* getAddr8(int x, int y) const;
|
||||
/** Returns the address of the byte containing the pixel specified by x,y
|
||||
for 1bit pixels.
|
||||
*/
|
||||
inline uint8_t* getAddr1(int x, int y) const;
|
||||
|
||||
/** Returns the color corresponding to the pixel specified by x,y for
|
||||
colortable based bitmaps.
|
||||
*/
|
||||
inline SkPMColor getIndex8Color(int x, int y) const;
|
||||
|
||||
// OS-specific helpers
|
||||
#ifndef SK_USE_WXWIDGETS
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
/** On Windows and PocketPC builds, this will draw the SkBitmap onto the
|
||||
specified HDC
|
||||
*/
|
||||
void drawToHDC(HDC, int left, int top) const;
|
||||
#elif defined(SK_BUILD_FOR_MAC)
|
||||
/** On Mac OS X and Carbon builds, this will draw the SkBitmap onto the
|
||||
specified WindowRef
|
||||
*/
|
||||
void drawToPort(WindowRef, CGContextRef) const;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Set dst to be a setset of this bitmap. If possible, it will share the
|
||||
pixel memory, and just point into a subset of it. However, if the config
|
||||
does not support this, a local copy will be made and associated with
|
||||
the dst bitmap. If the subset rectangle, intersected with the bitmap's
|
||||
dimensions is empty, or if there is an unsupported config, false will be
|
||||
returned and dst will be untouched.
|
||||
@param dst The bitmap that will be set to a subset of this bitmap
|
||||
@param subset The rectangle of pixels in this bitmap that dst will
|
||||
reference.
|
||||
@return true if the subset copy was successfully made.
|
||||
*/
|
||||
bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
|
||||
|
||||
/** Tries to make a new bitmap based on the dimensions of this bitmap,
|
||||
setting the new bitmap's config to the one specified, and then copying
|
||||
this bitmap's pixels into the new bitmap. If the conversion is not
|
||||
supported, or the allocator fails, then this method returns false and
|
||||
dst is left unchanged.
|
||||
@param dst The bitmap to be sized and allocated
|
||||
@param c The desired config for dst
|
||||
@param allocator Allocator used to allocate the pixelref for the dst
|
||||
bitmap. If this is null, the standard HeapAllocator
|
||||
will be used.
|
||||
@return true if the copy could be made.
|
||||
*/
|
||||
bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const;
|
||||
|
||||
bool hasMipMap() const;
|
||||
void buildMipMap(bool forceRebuild = false);
|
||||
void freeMipMap();
|
||||
|
||||
/** Given scale factors sx, sy, determine the miplevel available in the
|
||||
bitmap, and return it (this is the amount to shift matrix iterators
|
||||
by). If dst is not null, it is set to the correct level.
|
||||
*/
|
||||
int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
|
||||
|
||||
void extractAlpha(SkBitmap* dst) const {
|
||||
this->extractAlpha(dst, NULL, NULL);
|
||||
}
|
||||
|
||||
void extractAlpha(SkBitmap* dst, const SkPaint* paint,
|
||||
SkIPoint* offset) const;
|
||||
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
void unflatten(SkFlattenableReadBuffer&);
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
class Allocator : public SkRefCnt {
|
||||
public:
|
||||
/** Allocate the pixel memory for the bitmap, given its dimensions and
|
||||
config. Return true on success, where success means either setPixels
|
||||
or setPixelRef was called. The pixels need not be locked when this
|
||||
returns. If the config requires a colortable, it also must be
|
||||
installed via setColorTable. If false is returned, the bitmap and
|
||||
colortable should be left unchanged.
|
||||
*/
|
||||
virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
|
||||
};
|
||||
|
||||
/** Subclass of Allocator that returns a pixelref that allocates its pixel
|
||||
memory from the heap. This is the default Allocator invoked by
|
||||
allocPixels().
|
||||
*/
|
||||
class HeapAllocator : public Allocator {
|
||||
public:
|
||||
virtual bool allocPixelRef(SkBitmap*, SkColorTable*);
|
||||
};
|
||||
|
||||
class RLEPixels {
|
||||
public:
|
||||
RLEPixels(int width, int height);
|
||||
virtual ~RLEPixels();
|
||||
|
||||
uint8_t* packedAtY(int y) const {
|
||||
SkASSERT((unsigned)y < (unsigned)fHeight);
|
||||
return fYPtrs[y];
|
||||
}
|
||||
|
||||
// called by subclasses during creation
|
||||
void setPackedAtY(int y, uint8_t* addr) {
|
||||
SkASSERT((unsigned)y < (unsigned)fHeight);
|
||||
fYPtrs[y] = addr;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t** fYPtrs;
|
||||
int fHeight;
|
||||
};
|
||||
|
||||
private:
|
||||
#ifdef SK_SUPPORT_MIPMAP
|
||||
struct MipMap;
|
||||
mutable MipMap* fMipMap;
|
||||
#endif
|
||||
|
||||
mutable SkPixelRef* fPixelRef;
|
||||
mutable size_t fPixelRefOffset;
|
||||
mutable int fPixelLockCount;
|
||||
// either user-specified (in which case it is not treated as mutable)
|
||||
// or a cache of the returned value from fPixelRef->lockPixels()
|
||||
mutable void* fPixels;
|
||||
mutable SkColorTable* fColorTable; // only meaningful for kIndex8
|
||||
|
||||
enum Flags {
|
||||
kImageIsOpaque_Flag = 0x01
|
||||
};
|
||||
|
||||
uint32_t fRowBytes;
|
||||
uint16_t fWidth, fHeight;
|
||||
uint8_t fConfig;
|
||||
uint8_t fFlags;
|
||||
uint8_t fBytesPerPixel; // based on config
|
||||
|
||||
/* Unreference any pixelrefs or colortables
|
||||
*/
|
||||
void freePixels();
|
||||
void updatePixelsFromRef() const;
|
||||
|
||||
static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy);
|
||||
};
|
||||
|
||||
/** \class SkColorTable
|
||||
|
||||
SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
|
||||
8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
|
||||
*/
|
||||
class SkColorTable : public SkRefCnt {
|
||||
public:
|
||||
/** Constructs an empty color table (zero colors).
|
||||
*/
|
||||
explicit SkColorTable(int count);
|
||||
explicit SkColorTable(SkFlattenableReadBuffer&);
|
||||
SkColorTable(const SkPMColor colors[], int count);
|
||||
virtual ~SkColorTable();
|
||||
|
||||
enum Flags {
|
||||
kColorsAreOpaque_Flag = 0x01 //!< if set, all of the colors in the table are opaque (alpha==0xFF)
|
||||
};
|
||||
/** Returns the flag bits for the color table. These can be changed with setFlags().
|
||||
*/
|
||||
unsigned getFlags() const { return fFlags; }
|
||||
/** Set the flags for the color table. See the Flags enum for possible values.
|
||||
*/
|
||||
void setFlags(unsigned flags);
|
||||
|
||||
/** Returns the number of colors in the table.
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
|
||||
/** Returns the specified color from the table. In the debug build, this asserts that
|
||||
the index is in range (0 <= index < count).
|
||||
*/
|
||||
SkPMColor operator[](int index) const {
|
||||
SkASSERT(fColors != NULL && (unsigned)index < fCount);
|
||||
return fColors[index];
|
||||
}
|
||||
|
||||
/** Specify the number of colors in the color table. This does not initialize the colors
|
||||
to any value, just allocates memory for them. To initialize the values, either call
|
||||
setColors(array, count), or follow setCount(count) with a call to
|
||||
lockColors()/{set the values}/unlockColors(true).
|
||||
*/
|
||||
// void setColors(int count) { this->setColors(NULL, count); }
|
||||
// void setColors(const SkPMColor[], int count);
|
||||
|
||||
/** Return the array of colors for reading and/or writing. This must be
|
||||
balanced by a call to unlockColors(changed?), telling the colortable if
|
||||
the colors were changed during the lock.
|
||||
*/
|
||||
SkPMColor* lockColors() {
|
||||
SkDEBUGCODE(fColorLockCount += 1;)
|
||||
return fColors;
|
||||
}
|
||||
/** Balancing call to lockColors(). If the colors have been changed, pass true.
|
||||
*/
|
||||
void unlockColors(bool changed);
|
||||
|
||||
/** Similar to lockColors(), lock16BitCache() returns the array of
|
||||
RGB16 colors that mirror the 32bit colors. However, this function
|
||||
will return null if kColorsAreOpaque_Flag is not set.
|
||||
Also, unlike lockColors(), the returned array here cannot be modified.
|
||||
*/
|
||||
const uint16_t* lock16BitCache();
|
||||
/** Balancing call to lock16BitCache().
|
||||
*/
|
||||
void unlock16BitCache() {
|
||||
SkASSERT(f16BitCacheLockCount > 0);
|
||||
SkDEBUGCODE(f16BitCacheLockCount -= 1);
|
||||
}
|
||||
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
|
||||
private:
|
||||
SkPMColor* fColors;
|
||||
uint16_t* f16BitCache;
|
||||
uint16_t fCount;
|
||||
uint8_t fFlags;
|
||||
SkDEBUGCODE(int fColorLockCount;)
|
||||
SkDEBUGCODE(int f16BitCacheLockCount;)
|
||||
|
||||
void inval16BitCache();
|
||||
};
|
||||
|
||||
class SkAutoLockPixels {
|
||||
public:
|
||||
SkAutoLockPixels(const SkBitmap& bitmap) : fBitmap(bitmap) {
|
||||
bitmap.lockPixels();
|
||||
}
|
||||
~SkAutoLockPixels() {
|
||||
fBitmap.unlockPixels();
|
||||
}
|
||||
|
||||
private:
|
||||
const SkBitmap& fBitmap;
|
||||
};
|
||||
|
||||
/** Helper class that performs the lock/unlockColors calls on a colortable.
|
||||
The destructor will call unlockColors(false) if it has a bitmap's colortable
|
||||
*/
|
||||
class SkAutoLockColors : public SkNoncopyable {
|
||||
public:
|
||||
/** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's
|
||||
colortable
|
||||
*/
|
||||
SkAutoLockColors() : fCTable(NULL), fColors(NULL) {}
|
||||
/** Initialize with bitmap, locking its colortable if present
|
||||
*/
|
||||
explicit SkAutoLockColors(const SkBitmap& bm) {
|
||||
fCTable = bm.getColorTable();
|
||||
fColors = fCTable ? fCTable->lockColors() : NULL;
|
||||
}
|
||||
/** Initialize with a colortable (may be null)
|
||||
*/
|
||||
explicit SkAutoLockColors(SkColorTable* ctable) {
|
||||
fCTable = ctable;
|
||||
fColors = ctable ? ctable->lockColors() : NULL;
|
||||
}
|
||||
~SkAutoLockColors() {
|
||||
if (fCTable) {
|
||||
fCTable->unlockColors(false);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the currently locked colors, or NULL if no bitmap's colortable
|
||||
is currently locked.
|
||||
*/
|
||||
const SkPMColor* colors() const { return fColors; }
|
||||
|
||||
/** If a previous bitmap has been locked by this object, unlock its colors
|
||||
first. If the specified bitmap has a colortable, lock its colors and
|
||||
return them.
|
||||
*/
|
||||
const SkPMColor* lockColors(const SkBitmap& bm) {
|
||||
if (fCTable) {
|
||||
fCTable->unlockColors(false);
|
||||
}
|
||||
fCTable = bm.getColorTable();
|
||||
fColors = fCTable ? fCTable->lockColors() : NULL;
|
||||
return fColors;
|
||||
}
|
||||
|
||||
private:
|
||||
SkColorTable* fCTable;
|
||||
const SkPMColor* fColors;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kARGB_8888_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
|
||||
}
|
||||
|
||||
inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kRGB_565_Config || fConfig == kARGB_4444_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
|
||||
}
|
||||
|
||||
inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint8_t*)fPixels + y * fRowBytes + x;
|
||||
}
|
||||
|
||||
inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
SkASSERT(fColorTable);
|
||||
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
|
||||
}
|
||||
|
||||
// returns the address of the byte that contains the x coordinate
|
||||
inline uint8_t* SkBitmap::getAddr1(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kA1_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint8_t*)fPixels + y * fRowBytes + (x >> 3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkBounder_DEFINED
|
||||
#define SkBounder_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
struct SkIRect;
|
||||
struct SkPoint;
|
||||
struct SkRect;
|
||||
class SkPaint;
|
||||
class SkPath;
|
||||
class SkRegion;
|
||||
|
||||
/** \class SkBounder
|
||||
|
||||
Base class for intercepting the device bounds of shapes before they are drawn.
|
||||
Install a subclass of this in your canvas.
|
||||
*/
|
||||
class SkBounder : public SkRefCnt {
|
||||
public:
|
||||
/* Call to perform a clip test before calling onIRect.
|
||||
Returns the result from onIRect.
|
||||
*/
|
||||
bool doIRect(const SkIRect&);
|
||||
|
||||
protected:
|
||||
/** Override in your subclass. This is called with the device bounds of an
|
||||
object (text, geometry, image) just before it is drawn. If your method
|
||||
returns false, the drawing for that shape is aborted. If your method
|
||||
returns true, drawing continues. The bounds your method receives have already
|
||||
been transformed in to device coordinates, and clipped to the current clip.
|
||||
*/
|
||||
virtual bool onIRect(const SkIRect&) = 0;
|
||||
|
||||
/** Called after each shape has been drawn. The default implementation does
|
||||
nothing, but your override could use this notification to signal itself
|
||||
that the offscreen being rendered into needs to be updated to the screen.
|
||||
*/
|
||||
virtual void commit();
|
||||
|
||||
private:
|
||||
bool doHairline(const SkPoint&, const SkPoint&, const SkPaint&);
|
||||
bool doRect(const SkRect&, const SkPaint&);
|
||||
bool doPath(const SkPath&, const SkPaint&, bool doFill);
|
||||
void setClip(const SkRegion* clip) { fClip = clip; }
|
||||
|
||||
const SkRegion* fClip;
|
||||
friend class SkAutoBounderCommit;
|
||||
friend class SkDraw;
|
||||
friend class SkDrawIter;
|
||||
friend struct Draw1Glyph;
|
||||
friend class SkMaskFilter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkBuffer_DEFINED
|
||||
#define SkBuffer_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
/** \class SkRBuffer
|
||||
|
||||
Light weight class for reading data from a memory block.
|
||||
The RBuffer is given the buffer to read from, with either a specified size
|
||||
or no size (in which case no range checking is performed). It is iillegal
|
||||
to attempt to read a value from an empty RBuffer (data == null).
|
||||
*/
|
||||
class SkRBuffer : SkNoncopyable {
|
||||
public:
|
||||
SkRBuffer() : fData(0), fPos(0), fStop(0) {}
|
||||
/** Initialize RBuffer with a data pointer, but no specified length.
|
||||
This signals the RBuffer to not perform range checks during reading.
|
||||
*/
|
||||
SkRBuffer(const void* data)
|
||||
{
|
||||
fData = (const char*)data;
|
||||
fPos = (const char*)data;
|
||||
fStop = 0; // no bounds checking
|
||||
}
|
||||
/** Initialize RBuffer with a data point and length.
|
||||
*/
|
||||
SkRBuffer(const void* data, size_t size)
|
||||
{
|
||||
SkASSERT(data != 0 || size == 0);
|
||||
fData = (const char*)data;
|
||||
fPos = (const char*)data;
|
||||
fStop = (const char*)data + size;
|
||||
}
|
||||
|
||||
/** Return the number of bytes that have been read from the beginning
|
||||
of the data pointer.
|
||||
*/
|
||||
size_t pos() const { return fPos - fData; }
|
||||
/** Return the total size of the data pointer. Only defined if the length was
|
||||
specified in the constructor or in a call to reset().
|
||||
*/
|
||||
size_t size() const { return fStop - fData; }
|
||||
/** Return true if the buffer has read to the end of the data pointer.
|
||||
Only defined if the length was specified in the constructor or in a call
|
||||
to reset(). Always returns true if the length was not specified.
|
||||
*/
|
||||
bool eof() const { return fPos >= fStop; }
|
||||
|
||||
/** Read the specified number of bytes from the data pointer. If buffer is not
|
||||
null, copy those bytes into buffer.
|
||||
*/
|
||||
void read(void* buffer, size_t size) { if (size) this->readNoSizeCheck(buffer, size); }
|
||||
const void* skip(size_t size); // return start of skipped data
|
||||
size_t skipToAlign4();
|
||||
|
||||
void* readPtr() { void* ptr; read(&ptr, sizeof(ptr)); return ptr; }
|
||||
SkScalar readScalar() { SkScalar x; read(&x, 4); return x; }
|
||||
uint32_t readU32() { uint32_t x; read(&x, 4); return x; }
|
||||
int32_t readS32() { int32_t x; read(&x, 4); return x; }
|
||||
uint16_t readU16() { uint16_t x; read(&x, 2); return x; }
|
||||
int16_t readS16() { int16_t x; read(&x, 2); return x; }
|
||||
uint8_t readU8() { uint8_t x; read(&x, 1); return x; }
|
||||
bool readBool() { return this->readU8() != 0; }
|
||||
|
||||
protected:
|
||||
void readNoSizeCheck(void* buffer, size_t size);
|
||||
|
||||
const char* fData;
|
||||
const char* fPos;
|
||||
const char* fStop;
|
||||
};
|
||||
|
||||
/** \class SkWBuffer
|
||||
|
||||
Light weight class for writing data to a memory block.
|
||||
The WBuffer is given the buffer to write into, with either a specified size
|
||||
or no size, in which case no range checking is performed. An empty WBuffer
|
||||
is legal, in which case no data is ever written, but the relative pos()
|
||||
is updated.
|
||||
*/
|
||||
class SkWBuffer : SkNoncopyable {
|
||||
public:
|
||||
SkWBuffer() : fData(0), fPos(0), fStop(0) {}
|
||||
SkWBuffer(void* data) { reset(data); }
|
||||
SkWBuffer(void* data, size_t size) { reset(data, size); }
|
||||
|
||||
void reset(void* data)
|
||||
{
|
||||
fData = (char*)data;
|
||||
fPos = (char*)data;
|
||||
fStop = 0; // no bounds checking
|
||||
}
|
||||
void reset(void* data, size_t size)
|
||||
{
|
||||
SkASSERT(data != 0 || size == 0);
|
||||
fData = (char*)data;
|
||||
fPos = (char*)data;
|
||||
fStop = (char*)data + size;
|
||||
}
|
||||
|
||||
void* data() const { return fData; }
|
||||
size_t pos() const { return fPos - fData; }
|
||||
size_t size() const { return fStop - fData; }
|
||||
bool eof() const { return fPos >= fStop; }
|
||||
void* skip(size_t size); // return start of skipped data
|
||||
void write(const void* buffer, size_t size) { if (size) this->writeNoSizeCheck(buffer, size); }
|
||||
size_t padToAlign4();
|
||||
|
||||
void writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
|
||||
void writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
|
||||
void write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
|
||||
void write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
|
||||
void write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
|
||||
void writeBool(bool x) { this->write8(x); }
|
||||
|
||||
protected:
|
||||
void writeNoSizeCheck(const void* buffer, size_t size);
|
||||
|
||||
char* fData;
|
||||
char* fPos;
|
||||
char* fStop;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,794 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkCanvas_DEFINED
|
||||
#define SkCanvas_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkDeque.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkPorterDuff.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkScalarCompare.h"
|
||||
|
||||
class SkBounder;
|
||||
class SkDevice;
|
||||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
class SkPicture;
|
||||
|
||||
/** \class SkCanvas
|
||||
|
||||
A Canvas encapsulates all of the state about drawing into a device (bitmap).
|
||||
This includes a reference to the device itself, and a stack of matrix/clip
|
||||
values. For any given draw call (e.g. drawRect), the geometry of the object
|
||||
being drawn is transformed by the concatenation of all the matrices in the
|
||||
stack. The transformed geometry is clipped by the intersection of all of
|
||||
the clips in the stack.
|
||||
|
||||
While the Canvas holds the state of the drawing device, the state (style)
|
||||
of the object being drawn is held by the Paint, which is provided as a
|
||||
parameter to each of the draw() methods. The Paint holds attributes such as
|
||||
color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
|
||||
etc.
|
||||
*/
|
||||
class SkCanvas : public SkRefCnt {
|
||||
public:
|
||||
/** Construct a canvas with the specified bitmap to draw into.
|
||||
@param bitmap Specifies a bitmap for the canvas to draw into. Its
|
||||
structure are copied to the canvas.
|
||||
*/
|
||||
explicit SkCanvas(const SkBitmap& bitmap);
|
||||
/** Construct a canvas with the specified device to draw into.
|
||||
@param device Specifies a device for the canvas to draw into. The
|
||||
device may be null.
|
||||
*/
|
||||
explicit SkCanvas(SkDevice* device = NULL);
|
||||
virtual ~SkCanvas();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** If this subclass of SkCanvas supports GL viewports, return true and set
|
||||
size (if not null) to the size of the viewport. If it is not supported,
|
||||
ignore vp and return false.
|
||||
*/
|
||||
virtual bool getViewport(SkIPoint* size) const;
|
||||
|
||||
/** If this subclass of SkCanvas supports GL viewports, return true and set
|
||||
the viewport to the specified x and y dimensions. If it is not
|
||||
supported, ignore x and y and return false.
|
||||
*/
|
||||
virtual bool setViewport(int x, int y);
|
||||
|
||||
/** Return the canvas' device object, which may be null. The device holds
|
||||
the bitmap of the pixels that the canvas draws into. The reference count
|
||||
of the returned device is not changed by this call.
|
||||
*/
|
||||
SkDevice* getDevice() const;
|
||||
|
||||
/** Specify a device for this canvas to draw into. If it is not null, its
|
||||
reference count is incremented. If the canvas was already holding a
|
||||
device, its reference count is decremented. The new device is returned.
|
||||
*/
|
||||
SkDevice* setDevice(SkDevice* device);
|
||||
|
||||
/** Specify a bitmap for the canvas to draw into. This is a help method for
|
||||
setDevice(), and it creates a device for the bitmap by calling
|
||||
createDevice(). The structure of the bitmap is copied into the device.
|
||||
*/
|
||||
virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum SaveFlags {
|
||||
/** save the matrix state, restoring it on restore() */
|
||||
kMatrix_SaveFlag = 0x01,
|
||||
/** save the clip state, restoring it on restore() */
|
||||
kClip_SaveFlag = 0x02,
|
||||
/** the layer needs to support per-pixel alpha */
|
||||
kHasAlphaLayer_SaveFlag = 0x04,
|
||||
/** the layer needs to support 8-bits per color component */
|
||||
kFullColorLayer_SaveFlag = 0x08,
|
||||
/** the layer should clip against the bounds argument */
|
||||
kClipToLayer_SaveFlag = 0x10,
|
||||
|
||||
// helper masks for common choices
|
||||
kMatrixClip_SaveFlag = 0x03,
|
||||
kARGB_NoClipLayer_SaveFlag = 0x0F,
|
||||
kARGB_ClipLayer_SaveFlag = 0x1F
|
||||
};
|
||||
|
||||
/** This call saves the current matrix and clip information, and pushes a
|
||||
copy onto a private stack. Subsequent calls to translate, scale,
|
||||
rotate, skew, concat or clipRect, clipPath all operate on this copy.
|
||||
When the balancing call to restore() is made, this copy is deleted and
|
||||
the previous matrix/clip state is restored.
|
||||
@return The value to pass to restoreToCount() to balance this save()
|
||||
*/
|
||||
virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
|
||||
|
||||
/** This behaves the same as save(), but in addition it allocates an
|
||||
offscreen bitmap. All drawing calls are directed there, and only when
|
||||
the balancing call to restore() is made is that offscreen transfered to
|
||||
the canvas (or the previous layer). Subsequent calls to translate,
|
||||
scale, rotate, skew, concat or clipRect, clipPath all operate on this
|
||||
copy. When the balancing call to restore() is made, this copy is deleted
|
||||
and the previous matrix/clip state is restored.
|
||||
@param bounds (may be null) the maximum size the offscreen bitmap needs
|
||||
to be (in local coordinates)
|
||||
@param paint (may be null) This is copied, and is applied to the
|
||||
offscreen when restore() is called
|
||||
@param flags LayerFlags
|
||||
@return The value to pass to restoreToCount() to balance this save()
|
||||
*/
|
||||
virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
|
||||
SaveFlags flags = kARGB_ClipLayer_SaveFlag);
|
||||
|
||||
/** This behaves the same as save(), but in addition it allocates an
|
||||
offscreen bitmap. All drawing calls are directed there, and only when
|
||||
the balancing call to restore() is made is that offscreen transfered to
|
||||
the canvas (or the previous layer). Subsequent calls to translate,
|
||||
scale, rotate, skew, concat or clipRect, clipPath all operate on this
|
||||
copy. When the balancing call to restore() is made, this copy is deleted
|
||||
and the previous matrix/clip state is restored.
|
||||
@param bounds (may be null) the maximum size the offscreen bitmap needs
|
||||
to be (in local coordinates)
|
||||
@param alpha This is applied to the offscreen when restore() is called.
|
||||
@param flags LayerFlags
|
||||
@return The value to pass to restoreToCount() to balance this save()
|
||||
*/
|
||||
int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
|
||||
SaveFlags flags = kARGB_ClipLayer_SaveFlag);
|
||||
|
||||
/** This call balances a previous call to save(), and is used to remove all
|
||||
modifications to the matrix/clip state since the last save call. It is
|
||||
an error to call restore() more times than save() was called.
|
||||
*/
|
||||
virtual void restore();
|
||||
|
||||
/** Returns the number of matrix/clip states on the SkCanvas' private stack.
|
||||
This will equal # save() calls - # restore() calls.
|
||||
*/
|
||||
int getSaveCount() const;
|
||||
|
||||
/** Efficient way to pop any calls to save() that happened after the save
|
||||
count reached saveCount. It is an error for saveCount to be less than
|
||||
getSaveCount()
|
||||
@param saveCount The number of save() levels to restore from
|
||||
*/
|
||||
void restoreToCount(int saveCount);
|
||||
|
||||
/** Preconcat the current matrix with the specified translation
|
||||
@param dx The distance to translate in X
|
||||
@param dy The distance to translate in Y
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
virtual bool translate(SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Preconcat the current matrix with the specified scale.
|
||||
@param sx The amount to scale in X
|
||||
@param sy The amount to scale in Y
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
virtual bool scale(SkScalar sx, SkScalar sy);
|
||||
|
||||
/** Preconcat the current matrix with the specified rotation.
|
||||
@param degrees The amount to rotate, in degrees
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
virtual bool rotate(SkScalar degrees);
|
||||
|
||||
/** Preconcat the current matrix with the specified skew.
|
||||
@param sx The amount to skew in X
|
||||
@param sy The amount to skew in Y
|
||||
returns true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
virtual bool skew(SkScalar sx, SkScalar sy);
|
||||
|
||||
/** Preconcat the current matrix with the specified matrix.
|
||||
@param matrix The matrix to preconcatenate with the current matrix
|
||||
@return true if the operation succeeded (e.g. did not overflow)
|
||||
*/
|
||||
virtual bool concat(const SkMatrix& matrix);
|
||||
|
||||
/** Replace the current matrix with a copy of the specified matrix.
|
||||
@param matrix The matrix that will be copied into the current matrix.
|
||||
*/
|
||||
virtual void setMatrix(const SkMatrix& matrix);
|
||||
|
||||
/** Helper for setMatrix(identity). Sets the current matrix to identity.
|
||||
*/
|
||||
void resetMatrix();
|
||||
|
||||
/** Modify the current clip with the specified rectangle.
|
||||
@param rect The rect to intersect with the current clip
|
||||
@param op The region op to apply to the current clip
|
||||
@return true if the canvas' clip is non-empty
|
||||
*/
|
||||
virtual bool clipRect(const SkRect& rect,
|
||||
SkRegion::Op op = SkRegion::kIntersect_Op);
|
||||
|
||||
/** Modify the current clip with the specified path.
|
||||
@param path The path to apply to the current clip
|
||||
@param op The region op to apply to the current clip
|
||||
@return true if the canvas' new clip is non-empty
|
||||
*/
|
||||
virtual bool clipPath(const SkPath& path,
|
||||
SkRegion::Op op = SkRegion::kIntersect_Op);
|
||||
|
||||
/** Modify the current clip with the specified region. Note that unlike
|
||||
clipRect() and clipPath() which transform their arguments by the current
|
||||
matrix, clipRegion() assumes its argument is already in device
|
||||
coordinates, and so no transformation is performed.
|
||||
@param deviceRgn The region to apply to the current clip
|
||||
@param op The region op to apply to the current clip
|
||||
@return true if the canvas' new clip is non-empty
|
||||
*/
|
||||
virtual bool clipRegion(const SkRegion& deviceRgn,
|
||||
SkRegion::Op op = SkRegion::kIntersect_Op);
|
||||
|
||||
/** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
|
||||
specified region. This does not intersect or in any other way account
|
||||
for the existing clip region.
|
||||
@param deviceRgn The region to copy into the current clip.
|
||||
@return true if the new clip region is non-empty
|
||||
*/
|
||||
bool setClipRegion(const SkRegion& deviceRgn) {
|
||||
return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
|
||||
}
|
||||
|
||||
/** Enum describing how to treat edges when performing quick-reject tests
|
||||
of a geometry against the current clip. Treating them as antialiased
|
||||
(kAA_EdgeType) will take into account the extra pixels that may be drawn
|
||||
if the edge does not lie exactly on a device pixel boundary (after being
|
||||
transformed by the current matrix).
|
||||
*/
|
||||
enum EdgeType {
|
||||
/** Treat the edges as B&W (not antialiased) for the purposes of testing
|
||||
against the current clip
|
||||
*/
|
||||
kBW_EdgeType,
|
||||
/** Treat the edges as antialiased for the purposes of testing
|
||||
against the current clip
|
||||
*/
|
||||
kAA_EdgeType
|
||||
};
|
||||
|
||||
/** Return true if the specified rectangle, after being transformed by the
|
||||
current matrix, would lie completely outside of the current clip. Call
|
||||
this to check if an area you intend to draw into is clipped out (and
|
||||
therefore you can skip making the draw calls).
|
||||
@param rect the rect to compare with the current clip
|
||||
@param et specifies how to treat the edges (see EdgeType)
|
||||
@return true if the rect (transformed by the canvas' matrix) does not
|
||||
intersect with the canvas' clip
|
||||
*/
|
||||
bool quickReject(const SkRect& rect, EdgeType et) const;
|
||||
|
||||
/** Return true if the specified path, after being transformed by the
|
||||
current matrix, would lie completely outside of the current clip. Call
|
||||
this to check if an area you intend to draw into is clipped out (and
|
||||
therefore you can skip making the draw calls). Note, for speed it may
|
||||
return false even if the path itself might not intersect the clip
|
||||
(i.e. the bounds of the path intersects, but the path does not).
|
||||
@param path The path to compare with the current clip
|
||||
@param et specifies how to treat the edges (see EdgeType)
|
||||
@return true if the path (transformed by the canvas' matrix) does not
|
||||
intersect with the canvas' clip
|
||||
*/
|
||||
bool quickReject(const SkPath& path, EdgeType et) const;
|
||||
|
||||
/** Return true if the horizontal band specified by top and bottom is
|
||||
completely clipped out. This is a conservative calculation, meaning
|
||||
that it is possible that if the method returns false, the band may still
|
||||
in fact be clipped out, but the converse is not true. If this method
|
||||
returns true, then the band is guaranteed to be clipped out.
|
||||
@param top The top of the horizontal band to compare with the clip
|
||||
@param bottom The bottom of the horizontal and to compare with the clip
|
||||
@return true if the horizontal band is completely clipped out (i.e. does
|
||||
not intersect the current clip)
|
||||
*/
|
||||
bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const;
|
||||
|
||||
/** Return the bounds of the current clip (in local coordinates) in the
|
||||
bounds parameter, and return true if it is non-empty. This can be useful
|
||||
in a way similar to quickReject, in that it tells you that drawing
|
||||
outside of these bounds will be clipped out.
|
||||
*/
|
||||
bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
|
||||
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified ARGB color, using the specified PorterDuff mode.
|
||||
@param a the alpha component (0..255) of the color to fill the canvas
|
||||
@param r the red component (0..255) of the color to fill the canvas
|
||||
@param g the green component (0..255) of the color to fill the canvas
|
||||
@param b the blue component (0..255) of the color to fill the canvas
|
||||
@param mode the mode to apply the color in (defaults to SrcOver)
|
||||
*/
|
||||
void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
|
||||
SkPorterDuff::Mode mode = SkPorterDuff::kSrcOver_Mode);
|
||||
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified color and porter-duff xfermode.
|
||||
@param color the color to draw with
|
||||
@param mode the mode to apply the color in (defaults to SrcOver)
|
||||
*/
|
||||
void drawColor(SkColor color,
|
||||
SkPorterDuff::Mode mode = SkPorterDuff::kSrcOver_Mode);
|
||||
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified paint.
|
||||
@param paint The paint used to fill the canvas
|
||||
*/
|
||||
virtual void drawPaint(const SkPaint& paint);
|
||||
|
||||
enum PointMode {
|
||||
/** drawPoints draws each point separately */
|
||||
kPoints_PointMode,
|
||||
/** drawPoints draws each pair of points as a line segment */
|
||||
kLines_PointMode,
|
||||
/** drawPoints draws the array of points as a polygon */
|
||||
kPolygon_PointMode
|
||||
};
|
||||
|
||||
/** Draw a series of points, interpreted based on the PointMode mode. For
|
||||
all modes, the count parameter is interpreted as the total number of
|
||||
points. For kLine mode, count/2 line segments are drawn.
|
||||
For kPoint mode, each point is drawn centered at its coordinate, and its
|
||||
size is specified by the paint's stroke-width. It draws as a square,
|
||||
unless the paint's cap-type is round, in which the points are drawn as
|
||||
circles.
|
||||
For kLine mode, each pair of points is drawn as a line segment,
|
||||
respecting the paint's settings for cap/join/width.
|
||||
For kPolygon mode, the entire array is drawn as a series of connected
|
||||
line segments.
|
||||
Note that, while similar, kLine and kPolygon modes draw slightly
|
||||
differently than the equivalent path built with a series of moveto,
|
||||
lineto calls, in that the path will draw all of its contours at once,
|
||||
with no interactions if contours intersect each other (think XOR
|
||||
xfermode). drawPoints always draws each element one at a time.
|
||||
@param mode PointMode specifying how to draw the array of points.
|
||||
@param count The number of points in the array
|
||||
@param pts Array of points to draw
|
||||
@param paint The paint used to draw the points
|
||||
*/
|
||||
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Helper method for drawing a single point. See drawPoints() for a more
|
||||
details.
|
||||
*/
|
||||
void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
|
||||
|
||||
/** Draws a single pixel in the specified color.
|
||||
@param x The X coordinate of which pixel to draw
|
||||
@param y The Y coordiante of which pixel to draw
|
||||
@param color The color to draw
|
||||
*/
|
||||
void drawPoint(SkScalar x, SkScalar y, SkColor color);
|
||||
|
||||
/** Draw a line segment with the specified start and stop x,y coordinates,
|
||||
using the specified paint. NOTE: since a line is always "framed", the
|
||||
paint's Style is ignored.
|
||||
@param x0 The x-coordinate of the start point of the line
|
||||
@param y0 The y-coordinate of the start point of the line
|
||||
@param x1 The x-coordinate of the end point of the line
|
||||
@param y1 The y-coordinate of the end point of the line
|
||||
@param paint The paint used to draw the line
|
||||
*/
|
||||
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the specified rectangle using the specified paint. The rectangle
|
||||
will be filled or stroked based on the Style in the paint.
|
||||
@param rect The rect to be drawn
|
||||
@param paint The paint used to draw the rect
|
||||
*/
|
||||
virtual void drawRect(const SkRect& rect, const SkPaint& paint);
|
||||
|
||||
/** Draw the specified rectangle using the specified paint. The rectangle
|
||||
will be filled or framed based on the Style in the paint.
|
||||
@param rect The rect to be drawn
|
||||
@param paint The paint used to draw the rect
|
||||
*/
|
||||
void drawIRect(const SkIRect& rect, const SkPaint& paint)
|
||||
{
|
||||
SkRect r;
|
||||
r.set(rect); // promotes the ints to scalars
|
||||
this->drawRect(r, paint);
|
||||
}
|
||||
|
||||
/** Draw the specified rectangle using the specified paint. The rectangle
|
||||
will be filled or framed based on the Style in the paint.
|
||||
@param left The left side of the rectangle to be drawn
|
||||
@param top The top side of the rectangle to be drawn
|
||||
@param right The right side of the rectangle to be drawn
|
||||
@param bottom The bottom side of the rectangle to be drawn
|
||||
@param paint The paint used to draw the rect
|
||||
*/
|
||||
void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
|
||||
SkScalar bottom, const SkPaint& paint);
|
||||
|
||||
/** Draw the specified oval using the specified paint. The oval will be
|
||||
filled or framed based on the Style in the paint.
|
||||
@param oval The rectangle bounds of the oval to be drawn
|
||||
@param paint The paint used to draw the oval
|
||||
*/
|
||||
void drawOval(const SkRect& oval, const SkPaint&);
|
||||
|
||||
/** Draw the specified circle using the specified paint. If radius is <= 0,
|
||||
then nothing will be drawn. The circle will be filled
|
||||
or framed based on the Style in the paint.
|
||||
@param cx The x-coordinate of the center of the cirle to be drawn
|
||||
@param cy The y-coordinate of the center of the cirle to be drawn
|
||||
@param radius The radius of the cirle to be drawn
|
||||
@param paint The paint used to draw the circle
|
||||
*/
|
||||
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the specified arc, which will be scaled to fit inside the
|
||||
specified oval. If the sweep angle is >= 360, then the oval is drawn
|
||||
completely. Note that this differs slightly from SkPath::arcTo, which
|
||||
treats the sweep angle mod 360.
|
||||
@param oval The bounds of oval used to define the shape of the arc
|
||||
@param startAngle Starting angle (in degrees) where the arc begins
|
||||
@param sweepAngle Sweep angle (in degrees) measured clockwise
|
||||
@param useCenter true means include the center of the oval. For filling
|
||||
this will draw a wedge. False means just use the arc.
|
||||
@param paint The paint used to draw the arc
|
||||
*/
|
||||
void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
bool useCenter, const SkPaint& paint);
|
||||
|
||||
/** Draw the specified round-rect using the specified paint. The round-rect
|
||||
will be filled or framed based on the Style in the paint.
|
||||
@param rect The rectangular bounds of the roundRect to be drawn
|
||||
@param rx The x-radius of the oval used to round the corners
|
||||
@param ry The y-radius of the oval used to round the corners
|
||||
@param paint The paint used to draw the roundRect
|
||||
*/
|
||||
void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the specified path using the specified paint. The path will be
|
||||
filled or framed based on the Style in the paint.
|
||||
@param path The path to be drawn
|
||||
@param paint The paint used to draw the path
|
||||
*/
|
||||
virtual void drawPath(const SkPath& path, const SkPaint& paint);
|
||||
|
||||
/** Draw the specified bitmap, with its top/left corner at (x,y), using the
|
||||
specified paint, transformed by the current matrix. Note: if the paint
|
||||
contains a maskfilter that generates a mask which extends beyond the
|
||||
bitmap's original width/height, then the bitmap will be drawn as if it
|
||||
were in a Shader with CLAMP mode. Thus the color outside of the original
|
||||
width/height will be the edge color replicated.
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param left The position of the left side of the bitmap being drawn
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
@param paint The paint used to draw the bitmap, or NULL
|
||||
*/
|
||||
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
/** Draw the specified bitmap, with the specified matrix applied (before the
|
||||
canvas' matrix is applied).
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param src Optional: specify the subset of the bitmap to be drawn
|
||||
@param dst The destination rectangle where the scaled/translated
|
||||
image will be drawn
|
||||
@param paint The paint used to draw the bitmap, or NULL
|
||||
*/
|
||||
virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
|
||||
const SkRect& dst, const SkPaint* paint = NULL);
|
||||
|
||||
virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
/** Draw the specified bitmap, with its top/left corner at (x,y),
|
||||
NOT transformed by the current matrix. Note: if the paint
|
||||
contains a maskfilter that generates a mask which extends beyond the
|
||||
bitmap's original width/height, then the bitmap will be drawn as if it
|
||||
were in a Shader with CLAMP mode. Thus the color outside of the original
|
||||
width/height will be the edge color replicated.
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param left The position of the left side of the bitmap being drawn
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
@param paint The paint used to draw the bitmap, or NULL
|
||||
*/
|
||||
virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
/** Draw the text, with origin at (x,y), using the specified paint.
|
||||
The origin is interpreted based on the Align setting in the paint.
|
||||
@param text The text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param x The x-coordinate of the origin of the text being drawn
|
||||
@param y The y-coordinate of the origin of the text being drawn
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
|
||||
SkScalar y, const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with each character/glyph origin specified by the pos[]
|
||||
array. The origin is interpreted by the Align setting in the paint.
|
||||
@param text The text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param pos Array of positions, used to position each character
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
virtual void drawPosText(const void* text, size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with each character/glyph origin specified by the x
|
||||
coordinate taken from the xpos[] array, and the y from the constY param.
|
||||
The origin is interpreted by the Align setting in the paint.
|
||||
@param text The text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param xpos Array of x-positions, used to position each character
|
||||
@param constY The shared Y coordinate for all of the positions
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
virtual void drawPosTextH(const void* text, size_t byteLength,
|
||||
const SkScalar xpos[], SkScalar constY,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with origin at (x,y), using the specified paint, along
|
||||
the specified path. The paint's Align setting determins where along the
|
||||
path to start the text.
|
||||
@param text The text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param path The path the text should follow for its baseline
|
||||
@param hOffset The distance along the path to add to the text's
|
||||
starting position
|
||||
@param vOffset The distance above(-) or below(+) the path to
|
||||
position the text
|
||||
@param paint The paint used for the text
|
||||
*/
|
||||
void drawTextOnPathHV(const void* text, size_t byteLength,
|
||||
const SkPath& path, SkScalar hOffset,
|
||||
SkScalar vOffset, const SkPaint& paint);
|
||||
|
||||
/** Draw the text, with origin at (x,y), using the specified paint, along
|
||||
the specified path. The paint's Align setting determins where along the
|
||||
path to start the text.
|
||||
@param text The text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param path The path the text should follow for its baseline
|
||||
@param matrix (may be null) Applied to the text before it is
|
||||
mapped onto the path
|
||||
@param paint The paint used for the text
|
||||
*/
|
||||
virtual void drawTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint);
|
||||
|
||||
/** Draw the picture into this canvas. This method effective brackets the
|
||||
playback of the picture's draw calls with save/restore, so the state
|
||||
of this canvas will be unchanged after this call. This contrasts with
|
||||
the more immediate method SkPicture::draw(), which does not bracket
|
||||
the canvas with save/restore, thus the canvas may be left in a changed
|
||||
state after the call.
|
||||
@param picture The recorded drawing commands to playback into this
|
||||
canvas.
|
||||
*/
|
||||
virtual void drawPicture(SkPicture& picture);
|
||||
|
||||
enum VertexMode {
|
||||
kTriangles_VertexMode,
|
||||
kTriangleStrip_VertexMode,
|
||||
kTriangleFan_VertexMode
|
||||
};
|
||||
|
||||
/** Draw the array of vertices, interpreted as triangles (based on mode).
|
||||
@param vmode How to interpret the array of vertices
|
||||
@param vertexCount The number of points in the vertices array (and
|
||||
corresponding texs and colors arrays if non-null)
|
||||
@param vertices Array of vertices for the mesh
|
||||
@param texs May be null. If not null, specifies the coordinate
|
||||
in texture space for each vertex.
|
||||
@param colors May be null. If not null, specifies a color for each
|
||||
vertex, to be interpolated across the triangle.
|
||||
@param xmode Used if both texs and colors are present. In this
|
||||
case the colors are combined with the texture using mode,
|
||||
before being drawn using the paint. If mode is null, then
|
||||
the porter-duff MULTIPLY mode is used.
|
||||
@param indices If not null, array of indices to reference into the
|
||||
vertex (texs, colors) array.
|
||||
@param indexCount number of entries in the indices array (if not null)
|
||||
@param paint Specifies the shader/texture if present.
|
||||
*/
|
||||
virtual void drawVertices(VertexMode vmode, int vertexCount,
|
||||
const SkPoint vertices[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Get the current bounder object.
|
||||
The bounder's reference count is unchaged.
|
||||
@return the canva's bounder (or NULL).
|
||||
*/
|
||||
SkBounder* getBounder() const { return fBounder; }
|
||||
|
||||
/** Set a new bounder (or NULL).
|
||||
Pass NULL to clear any previous bounder.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous bounder exists, its reference count is decremented.
|
||||
If bounder is not NULL, its reference count is incremented.
|
||||
@param bounder the new bounder (or NULL) to be installed in the canvas
|
||||
@return the set bounder object
|
||||
*/
|
||||
virtual SkBounder* setBounder(SkBounder* bounder);
|
||||
|
||||
/** Get the current filter object. The filter's reference count is not
|
||||
affected. The filter is part of the state this is affected by
|
||||
save/restore.
|
||||
@return the canvas' filter (or NULL).
|
||||
*/
|
||||
SkDrawFilter* getDrawFilter() const;
|
||||
|
||||
/** Set the new filter (or NULL). Pass NULL to clear any existing filter.
|
||||
As a convenience, the parameter is returned. If an existing filter
|
||||
exists, its refcnt is decrement. If the new filter is not null, its
|
||||
refcnt is incremented. The filter is part of the state this is affected
|
||||
by save/restore.
|
||||
@param filter the new filter (or NULL)
|
||||
@return the new filter
|
||||
*/
|
||||
virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Return the current matrix on the canvas.
|
||||
This does not account for the translate in any of the devices.
|
||||
@return The current matrix on the canvas.
|
||||
*/
|
||||
const SkMatrix& getTotalMatrix() const;
|
||||
|
||||
/** Return the current device clip (concatenation of all clip calls).
|
||||
This does not account for the translate in any of the devices.
|
||||
@return the current device clip (concatenation of all clip calls).
|
||||
*/
|
||||
const SkRegion& getTotalClip() const;
|
||||
|
||||
/** May be overridden by subclasses. This returns a compatible device
|
||||
for this canvas, with the specified config/width/height. If isOpaque
|
||||
is true, then the underlying bitmap is optimized to assume that every
|
||||
pixel will be drawn to, and thus it does not need to clear the alpha
|
||||
channel ahead of time (assuming the specified config supports per-pixel
|
||||
alpha.) If isOpaque is false, then the bitmap should clear its alpha
|
||||
channel.
|
||||
*/
|
||||
virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
|
||||
bool isOpaque, bool isForLayer);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** After calling saveLayer(), there can be any number of devices that make
|
||||
up the top-most drawing area. LayerIter can be used to iterate through
|
||||
those devices. Note that the iterator is only valid until the next API
|
||||
call made on the canvas. Ownership of all pointers in the iterator stays
|
||||
with the canvas, so none of them should be modified or deleted.
|
||||
*/
|
||||
class LayerIter /*: SkNoncopyable*/ {
|
||||
public:
|
||||
/** Initialize iterator with canvas, and set values for 1st device */
|
||||
LayerIter(SkCanvas*, bool skipEmptyClips);
|
||||
~LayerIter();
|
||||
|
||||
/** Return true if the iterator is done */
|
||||
bool done() const { return fDone; }
|
||||
/** Cycle to the next device */
|
||||
void next();
|
||||
|
||||
// These reflect the current device in the iterator
|
||||
|
||||
SkDevice* device() const;
|
||||
const SkMatrix& matrix() const;
|
||||
const SkRegion& clip() const;
|
||||
const SkPaint& paint() const;
|
||||
int x() const;
|
||||
int y() const;
|
||||
|
||||
private:
|
||||
// used to embed the SkDrawIter object directly in our instance, w/o
|
||||
// having to expose that class def to the public. There is an assert
|
||||
// in our constructor to ensure that fStorage is large enough
|
||||
// (though needs to be a compile-time-assert!). We use intptr_t to work
|
||||
// safely with 32 and 64 bit machines (to ensure the storage is enough)
|
||||
intptr_t fStorage[12];
|
||||
class SkDrawIter* fImpl; // this points at fStorage
|
||||
SkPaint fDefaultPaint;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
protected:
|
||||
// all of the drawBitmap variants call this guy
|
||||
virtual void commonDrawBitmap(const SkBitmap&, const SkMatrix& m,
|
||||
const SkPaint& paint);
|
||||
|
||||
private:
|
||||
class MCRec;
|
||||
|
||||
SkDeque fMCStack;
|
||||
// points to top of stack
|
||||
MCRec* fMCRec;
|
||||
// the first N recs that can fit here mean we won't call malloc
|
||||
uint32_t fMCRecStorage[32];
|
||||
|
||||
SkBounder* fBounder;
|
||||
|
||||
void prepareForDeviceDraw(SkDevice*);
|
||||
|
||||
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
|
||||
void updateDeviceCMCache();
|
||||
|
||||
friend class SkDrawIter; // needs setupDrawForLayerDevice()
|
||||
|
||||
SkDevice* init(SkDevice*);
|
||||
void internalDrawBitmap(const SkBitmap&, const SkMatrix& m,
|
||||
const SkPaint* paint);
|
||||
void drawDevice(SkDevice*, int x, int y, const SkPaint*);
|
||||
// shared by save() and saveLayer()
|
||||
int internalSave(SaveFlags flags);
|
||||
void internalRestore();
|
||||
|
||||
/* These maintain a cache of the clip bounds in local coordinates,
|
||||
(converted to 2s-compliment if floats are slow).
|
||||
*/
|
||||
mutable SkRectCompareType fLocalBoundsCompareType;
|
||||
mutable bool fLocalBoundsCompareTypeDirty;
|
||||
|
||||
const SkRectCompareType& getLocalClipBoundsCompareType() const {
|
||||
if (fLocalBoundsCompareTypeDirty) {
|
||||
this->computeLocalClipBoundsCompareType();
|
||||
fLocalBoundsCompareTypeDirty = false;
|
||||
}
|
||||
return fLocalBoundsCompareType;
|
||||
}
|
||||
void computeLocalClipBoundsCompareType() const;
|
||||
};
|
||||
|
||||
/** Stack helper class to automatically call restoreToCount() on the canvas
|
||||
when this object goes out of scope. Use this to guarantee that the canvas
|
||||
is restored to a known state.
|
||||
*/
|
||||
class SkAutoCanvasRestore : SkNoncopyable {
|
||||
public:
|
||||
SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
|
||||
SkASSERT(canvas);
|
||||
fSaveCount = canvas->getSaveCount();
|
||||
if (doSave) {
|
||||
canvas->save();
|
||||
}
|
||||
}
|
||||
~SkAutoCanvasRestore() {
|
||||
fCanvas->restoreToCount(fSaveCount);
|
||||
}
|
||||
|
||||
private:
|
||||
SkCanvas* fCanvas;
|
||||
int fSaveCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkChunkAlloc_DEFINED
|
||||
#define SkChunkAlloc_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkChunkAlloc : SkNoncopyable {
|
||||
public:
|
||||
SkChunkAlloc(size_t minSize);
|
||||
~SkChunkAlloc();
|
||||
|
||||
/** Free up all allocated blocks. This invalidates all returned
|
||||
pointers.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Reuse all allocated blocks. This invalidates all returned
|
||||
pointers (like reset) but doesn't necessarily free up all
|
||||
of the privately allocated blocks. This is more efficient
|
||||
if you plan to reuse the allocator multiple times.
|
||||
*/
|
||||
void reuse();
|
||||
|
||||
enum AllocFailType {
|
||||
kReturnNil_AllocFailType,
|
||||
kThrow_AllocFailType
|
||||
};
|
||||
|
||||
void* alloc(size_t bytes, AllocFailType);
|
||||
void* allocThrow(size_t bytes) {
|
||||
return this->alloc(bytes, kThrow_AllocFailType);
|
||||
}
|
||||
|
||||
size_t totalCapacity() const { return fTotalCapacity; }
|
||||
|
||||
private:
|
||||
struct Block;
|
||||
Block* fBlock;
|
||||
size_t fMinSize;
|
||||
Block* fPool;
|
||||
size_t fTotalCapacity;
|
||||
|
||||
Block* newBlock(size_t bytes, AllocFailType ftype);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkColor_DEFINED
|
||||
#define SkColor_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
/** \file SkColor.h
|
||||
|
||||
Types and macros for colors
|
||||
*/
|
||||
|
||||
/** 8-bit type for an alpha value. 0xFF is 100% opaque, 0x00 is 100% transparent.
|
||||
*/
|
||||
typedef uint8_t SkAlpha;
|
||||
/** 32 bit ARGB color value, not premultiplied. The color components are always in
|
||||
a known order. This is different from SkPMColor, which has its bytes in a configuration
|
||||
dependent order, to match the format of kARGB32 bitmaps. SkColor is the type used to
|
||||
specify colors in SkPaint and in gradients.
|
||||
*/
|
||||
typedef uint32_t SkColor;
|
||||
|
||||
/** Return a SkColor value from 8 bit component values
|
||||
*/
|
||||
static inline SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
|
||||
{
|
||||
SkASSERT(a <= 255 && r <= 255 && g <= 255 && b <= 255);
|
||||
|
||||
return (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
||||
}
|
||||
|
||||
/** Return a SkColor value from 8 bit component values, with an implied value
|
||||
of 0xFF for alpha (fully opaque)
|
||||
*/
|
||||
#define SkColorSetRGB(r, g, b) SkColorSetARGB(0xFF, r, g, b)
|
||||
|
||||
/** return the alpha byte from a SkColor value */
|
||||
#define SkColorGetA(color) (((color) >> 24) & 0xFF)
|
||||
/** return the red byte from a SkColor value */
|
||||
#define SkColorGetR(color) (((color) >> 16) & 0xFF)
|
||||
/** return the green byte from a SkColor value */
|
||||
#define SkColorGetG(color) (((color) >> 8) & 0xFF)
|
||||
/** return the blue byte from a SkColor value */
|
||||
#define SkColorGetB(color) (((color) >> 0) & 0xFF)
|
||||
|
||||
static inline SkColor SkColorSetA(SkColor c, U8CPU a) {
|
||||
return (c & 0x00FFFFFF) | (a << 24);
|
||||
}
|
||||
|
||||
// common colors
|
||||
|
||||
#define SK_ColorBLACK 0xFF000000 //!< black SkColor value
|
||||
#define SK_ColorDKGRAY 0xFF444444 //!< dark gray SkColor value
|
||||
#define SK_ColorGRAY 0xFF888888 //!< gray SkColor value
|
||||
#define SK_ColorLTGRAY 0xFFCCCCCC //!< light gray SkColor value
|
||||
#define SK_ColorWHITE 0xFFFFFFFF //!< white SkColor value
|
||||
|
||||
#define SK_ColorRED 0xFFFF0000 //!< red SkColor value
|
||||
#define SK_ColorGREEN 0xFF00FF00 //!< green SkColor value
|
||||
#define SK_ColorBLUE 0xFF0000FF //!< blue SkColor value
|
||||
#define SK_ColorYELLOW 0xFFFFFF00 //!< yellow SkColor value
|
||||
#define SK_ColorCYAN 0xFF00FFFF //!< cyan SkColor value
|
||||
#define SK_ColorMAGENTA 0xFFFF00FF //!< magenta SkColor value
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Convert RGB components to HSV.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
@param red red component value [0..255]
|
||||
@param green green component value [0..255]
|
||||
@param blue blue component value [0..255]
|
||||
@param hsv 3 element array which holds the resulting HSV components.
|
||||
*/
|
||||
void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]);
|
||||
|
||||
/** Convert the argb color to its HSV components.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
@param color the argb color to convert. Note: the alpha component is ignored.
|
||||
@param hsv 3 element array which holds the resulting HSV components.
|
||||
*/
|
||||
static inline void SkColorToHSV(SkColor color, SkScalar hsv[3])
|
||||
{
|
||||
SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv);
|
||||
}
|
||||
|
||||
/** Convert HSV components to an ARGB color. The alpha component is passed through unchanged.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
If hsv values are out of range, they are pinned.
|
||||
@param alpha the alpha component of the returned argb color.
|
||||
@param hsv 3 element array which holds the input HSV components.
|
||||
@return the resulting argb color
|
||||
*/
|
||||
SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]);
|
||||
|
||||
/** Convert HSV components to an ARGB color. The alpha component set to 0xFF.
|
||||
hsv[0] is Hue [0 .. 360)
|
||||
hsv[1] is Saturation [0...1]
|
||||
hsv[2] is Value [0...1]
|
||||
If hsv values are out of range, they are pinned.
|
||||
@param hsv 3 element array which holds the input HSV components.
|
||||
@return the resulting argb color
|
||||
*/
|
||||
static inline SkColor SkHSVToColor(const SkScalar hsv[3])
|
||||
{
|
||||
return SkHSVToColor(0xFF, hsv);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** 32 bit ARGB color value, premultiplied. The byte order for this value is
|
||||
configuration dependent, matching the format of kARGB32 bitmaps. This is different
|
||||
from SkColor, which is nonpremultiplied, and is always in the same byte order.
|
||||
*/
|
||||
typedef uint32_t SkPMColor;
|
||||
|
||||
/** Return a SkPMColor value from unpremultiplied 8 bit component values
|
||||
*/
|
||||
SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
/** Return a SkPMColor value from a SkColor value. This is done by multiplying the color
|
||||
components by the color's alpha, and by arranging the bytes in a configuration
|
||||
dependent order, to match the format of kARGB32 bitmaps.
|
||||
*/
|
||||
SkPMColor SkPreMultiplyColor(SkColor c);
|
||||
|
||||
/** Define a function pointer type for combining two premultiplied colors
|
||||
*/
|
||||
typedef SkPMColor (*SkXfermodeProc)(SkPMColor src, SkPMColor dst);
|
||||
|
||||
/** Define a function pointer type for combining a premultiplied src color
|
||||
and a 16bit device color.
|
||||
*/
|
||||
typedef uint16_t (*SkXfermodeProc16)(SkPMColor src, uint16_t dst);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkColorFilter_DEFINED
|
||||
#define SkColorFilter_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkPorterDuff.h"
|
||||
|
||||
class SkColorFilter : public SkFlattenable {
|
||||
public:
|
||||
/** Called with a scanline of colors, as if there was a shader installed.
|
||||
The implementation writes out its filtered version into result[].
|
||||
Note: shader and result may be the same buffer.
|
||||
@param src array of colors, possibly generated by a shader
|
||||
@param count the number of entries in the src[] and result[] arrays
|
||||
@param result written by the filter
|
||||
*/
|
||||
virtual void filterSpan(const SkPMColor src[], int count,
|
||||
SkPMColor result[]) = 0;
|
||||
/** Called with a scanline of colors, as if there was a shader installed.
|
||||
The implementation writes out its filtered version into result[].
|
||||
Note: shader and result may be the same buffer.
|
||||
@param src array of colors, possibly generated by a shader
|
||||
@param count the number of entries in the src[] and result[] arrays
|
||||
@param result written by the filter
|
||||
*/
|
||||
virtual void filterSpan16(const uint16_t shader[], int count,
|
||||
uint16_t result[]);
|
||||
|
||||
enum Flags {
|
||||
/** If set the filter methods will not change the alpha channel of the
|
||||
colors.
|
||||
*/
|
||||
kAlphaUnchanged_Flag = 0x01,
|
||||
/** If set, this subclass implements filterSpan16(). If this flag is
|
||||
set, then kAlphaUnchanged_Flag must also be set.
|
||||
*/
|
||||
kHasFilter16_Flag = 0x02
|
||||
};
|
||||
|
||||
/** Returns the flags for this filter. Override in subclasses to return
|
||||
custom flags.
|
||||
*/
|
||||
virtual uint32_t getFlags() { return 0; }
|
||||
|
||||
/** Create a colorfilter that uses the specified color and porter-duff mode.
|
||||
If porterDuffMode is DST, this function will return NULL (since that
|
||||
mode will have no effect on the result).
|
||||
@param srcColor The source color used with the specified mode
|
||||
@param mode The porter-duff mode that is applied to each color in
|
||||
the colorfilter's filterSpan[16,32] methods
|
||||
@return colorfilter object that applies the src color and porter-duff
|
||||
mode, or NULL if the mode will have no effect.
|
||||
*/
|
||||
static SkColorFilter* CreatePorterDuffFilter(SkColor srcColor,
|
||||
SkPorterDuff::Mode mode);
|
||||
|
||||
/** Create a colorfilter that calls through to the specified procs to
|
||||
filter the colors. The SkXfermodeProc parameter must be non-null, but
|
||||
the SkXfermodeProc16 is optional, and may be null.
|
||||
*/
|
||||
static SkColorFilter* CreatXfermodeProcFilter(SkColor srcColor,
|
||||
SkXfermodeProc proc,
|
||||
SkXfermodeProc16 proc16 = NULL);
|
||||
|
||||
/** Create a colorfilter that multiplies the RGB channels by one color, and
|
||||
then adds a second color, pinning the result for each component to
|
||||
[0..255]. The alpha components of the mul and add arguments
|
||||
are ignored.
|
||||
*/
|
||||
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
|
||||
|
||||
protected:
|
||||
SkColorFilter() {}
|
||||
SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkFilterShader : public SkShader {
|
||||
public:
|
||||
SkFilterShader(SkShader* shader, SkColorFilter* filter);
|
||||
virtual ~SkFilterShader();
|
||||
|
||||
// override
|
||||
virtual uint32_t getFlags();
|
||||
virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
|
||||
const SkMatrix& matrix);
|
||||
virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
|
||||
virtual void shadeSpan16(int x, int y, uint16_t result[], int count);
|
||||
virtual void beginSession();
|
||||
virtual void endSession();
|
||||
|
||||
protected:
|
||||
SkFilterShader(SkFlattenableReadBuffer& );
|
||||
virtual void flatten(SkFlattenableWriteBuffer& );
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkFilterShader, (buffer)); }
|
||||
SkShader* fShader;
|
||||
SkColorFilter* fFilter;
|
||||
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,657 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkColorPriv_DEFINED
|
||||
#define SkColorPriv_DEFINED
|
||||
|
||||
// turn this own for extra debug checking when blending onto 565
|
||||
#ifdef SK_DEBUG
|
||||
#define CHECK_FOR_565_OVERFLOW
|
||||
#endif
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkMath.h"
|
||||
|
||||
/** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a
|
||||
byte into a scale value, so that we can say scale * value >> 8 instead of
|
||||
alpha * value / 255.
|
||||
|
||||
In debugging, asserts that alpha is 0..255
|
||||
*/
|
||||
static inline unsigned SkAlpha255To256(U8CPU alpha) {
|
||||
SkASSERT(SkToU8(alpha) == alpha);
|
||||
return alpha + (alpha >> 7);
|
||||
}
|
||||
|
||||
/** Multiplify value by 0..256, and shift the result down 8
|
||||
(i.e. return (value * alpha256) >> 8)
|
||||
*/
|
||||
#define SkAlphaMul(value, alpha256) (SkMulS16(value, alpha256) >> 8)
|
||||
|
||||
// The caller may want negative values, so keep all params signed (int)
|
||||
// so we don't accidentally slip into unsigned math and lose the sign
|
||||
// extension when we shift (in SkAlphaMul)
|
||||
inline int SkAlphaBlend(int src, int dst, int scale256) {
|
||||
SkASSERT((unsigned)scale256 <= 256);
|
||||
return dst + SkAlphaMul(src - dst, scale256);
|
||||
}
|
||||
|
||||
#define SK_R16_BITS 5
|
||||
#define SK_G16_BITS 6
|
||||
#define SK_B16_BITS 5
|
||||
|
||||
#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
|
||||
#define SK_G16_SHIFT (SK_B16_BITS)
|
||||
#define SK_B16_SHIFT 0
|
||||
|
||||
#define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
|
||||
#define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
|
||||
#define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
|
||||
|
||||
#define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
|
||||
#define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
|
||||
#define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
|
||||
|
||||
#define SkR16Assert(r) SkASSERT((unsigned)(r) <= SK_R16_MASK)
|
||||
#define SkG16Assert(g) SkASSERT((unsigned)(g) <= SK_G16_MASK)
|
||||
#define SkB16Assert(b) SkASSERT((unsigned)(b) <= SK_B16_MASK)
|
||||
|
||||
static inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) {
|
||||
SkASSERT(r <= SK_R16_MASK);
|
||||
SkASSERT(g <= SK_G16_MASK);
|
||||
SkASSERT(b <= SK_B16_MASK);
|
||||
|
||||
return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT));
|
||||
}
|
||||
|
||||
#define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT)
|
||||
#define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT)
|
||||
#define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT)
|
||||
|
||||
/** Expand the 16bit color into a 32bit value that can be scaled all at once
|
||||
by a value up to 32. Used in conjunction with SkCompact_rgb_16.
|
||||
*/
|
||||
static inline uint32_t SkExpand_rgb_16(U16CPU c) {
|
||||
SkASSERT(c == (uint16_t)c);
|
||||
|
||||
return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
|
||||
}
|
||||
|
||||
/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit
|
||||
color value. The computation yields only 16bits of valid data, but we claim
|
||||
to return 32bits, so that the compiler won't generate extra instructions to
|
||||
"clean" the top 16bits. However, the top 16 can contain garbage, so it is
|
||||
up to the caller to safely ignore them.
|
||||
*/
|
||||
static inline U16CPU SkCompact_rgb_16(uint32_t c) {
|
||||
return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
|
||||
}
|
||||
|
||||
/** Scale the 16bit color value by the 0..256 scale parameter.
|
||||
The computation yields only 16bits of valid data, but we claim
|
||||
to return 32bits, so that the compiler won't generate extra instructions to
|
||||
"clean" the top 16bits.
|
||||
*/
|
||||
static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) {
|
||||
return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5);
|
||||
}
|
||||
|
||||
// this helper explicitly returns a clean 16bit value (but slower)
|
||||
#define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s)
|
||||
|
||||
/** Blend src and dst 16bit colors by the 0..256 scale parameter.
|
||||
The computation yields only 16bits of valid data, but we claim
|
||||
to return 32bits, so that the compiler won't generate extra instructions to
|
||||
"clean" the top 16bits.
|
||||
*/
|
||||
static inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) {
|
||||
SkASSERT((unsigned)srcScale <= 256);
|
||||
|
||||
srcScale >>= 3;
|
||||
|
||||
uint32_t src32 = SkExpand_rgb_16(src);
|
||||
uint32_t dst32 = SkExpand_rgb_16(dst);
|
||||
return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
|
||||
}
|
||||
|
||||
static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[],
|
||||
int srcScale, int count) {
|
||||
SkASSERT(count > 0);
|
||||
SkASSERT((unsigned)srcScale <= 256);
|
||||
|
||||
srcScale >>= 3;
|
||||
|
||||
do {
|
||||
uint32_t src32 = SkExpand_rgb_16(*src++);
|
||||
uint32_t dst32 = SkExpand_rgb_16(*dst);
|
||||
*dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
|
||||
} while (--count > 0);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static U16CPU SkRGB16Add(U16CPU a, U16CPU b) {
|
||||
SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK);
|
||||
SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK);
|
||||
SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK);
|
||||
|
||||
return a + b;
|
||||
}
|
||||
#else
|
||||
#define SkRGB16Add(a, b) ((a) + (b))
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SK_A32_BITS 8
|
||||
#define SK_R32_BITS 8
|
||||
#define SK_G32_BITS 8
|
||||
#define SK_B32_BITS 8
|
||||
|
||||
/* we check to see if the SHIFT value has already been defined (SkUserConfig.h)
|
||||
if not, we define it ourself to some default values. We default to OpenGL
|
||||
order (in memory: r,g,b,a)
|
||||
*/
|
||||
#ifndef SK_A32_SHIFT
|
||||
#ifdef SK_CPU_BENDIAN
|
||||
#define SK_R32_SHIFT 24
|
||||
#define SK_G32_SHIFT 16
|
||||
#define SK_B32_SHIFT 8
|
||||
#define SK_A32_SHIFT 0
|
||||
#else
|
||||
#define SK_R32_SHIFT 0
|
||||
#define SK_G32_SHIFT 8
|
||||
#define SK_B32_SHIFT 16
|
||||
#define SK_A32_SHIFT 24
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
|
||||
#define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
|
||||
#define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
|
||||
#define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
|
||||
|
||||
#define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
|
||||
#define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
|
||||
#define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
|
||||
#define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
|
||||
|
||||
#define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK)
|
||||
#define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK)
|
||||
#define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK)
|
||||
#define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK)
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
inline void SkPMColorAssert(SkPMColor c) {
|
||||
unsigned a = SkGetPackedA32(c);
|
||||
unsigned r = SkGetPackedR32(c);
|
||||
unsigned g = SkGetPackedG32(c);
|
||||
unsigned b = SkGetPackedB32(c);
|
||||
|
||||
SkA32Assert(a);
|
||||
SkASSERT(r <= a);
|
||||
SkASSERT(g <= a);
|
||||
SkASSERT(b <= a);
|
||||
}
|
||||
#else
|
||||
#define SkPMColorAssert(c)
|
||||
#endif
|
||||
|
||||
inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
|
||||
SkA32Assert(a);
|
||||
SkASSERT(r <= a);
|
||||
SkASSERT(g <= a);
|
||||
SkASSERT(b <= a);
|
||||
|
||||
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
|
||||
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
|
||||
}
|
||||
|
||||
extern const uint32_t gMask_00FF00FF;
|
||||
|
||||
inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
|
||||
uint32_t mask = gMask_00FF00FF;
|
||||
// uint32_t mask = 0xFF00FF;
|
||||
|
||||
uint32_t rb = ((c & mask) * scale) >> 8;
|
||||
uint32_t ag = ((c >> 8) & mask) * scale;
|
||||
return (rb & mask) | (ag & ~mask);
|
||||
}
|
||||
|
||||
inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
|
||||
return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
|
||||
}
|
||||
|
||||
inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
|
||||
SkASSERT((unsigned)aa <= 255);
|
||||
|
||||
unsigned src_scale = SkAlpha255To256(aa);
|
||||
unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale));
|
||||
|
||||
return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a 32bit pixel to a 16bit pixel (no dither)
|
||||
|
||||
#define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
|
||||
#define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
|
||||
#define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
inline unsigned SkR32ToR16(unsigned r)
|
||||
{
|
||||
SkR32Assert(r);
|
||||
return SkR32ToR16_MACRO(r);
|
||||
}
|
||||
inline unsigned SkG32ToG16(unsigned g)
|
||||
{
|
||||
SkG32Assert(g);
|
||||
return SkG32ToG16_MACRO(g);
|
||||
}
|
||||
inline unsigned SkB32ToB16(unsigned b)
|
||||
{
|
||||
SkB32Assert(b);
|
||||
return SkB32ToB16_MACRO(b);
|
||||
}
|
||||
#else
|
||||
#define SkR32ToR16(r) SkR32ToR16_MACRO(r)
|
||||
#define SkG32ToG16(g) SkG32ToG16_MACRO(g)
|
||||
#define SkB32ToB16(b) SkB32ToB16_MACRO(b)
|
||||
#endif
|
||||
|
||||
#define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK)
|
||||
#define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK)
|
||||
#define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK)
|
||||
|
||||
inline U16CPU SkPixel32ToPixel16(SkPMColor c)
|
||||
{
|
||||
unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT;
|
||||
unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT;
|
||||
unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT;
|
||||
return r | g | b;
|
||||
}
|
||||
|
||||
inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b)
|
||||
{
|
||||
return (SkR32ToR16(r) << SK_R16_SHIFT) |
|
||||
(SkG32ToG16(g) << SK_G16_SHIFT) |
|
||||
(SkB32ToB16(b) << SK_B16_SHIFT);
|
||||
}
|
||||
|
||||
#define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src))
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Fast dither from 32->16
|
||||
|
||||
#define SkShouldDitherXY(x, y) (((x) ^ (y)) & 1)
|
||||
|
||||
inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b)
|
||||
{
|
||||
r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS);
|
||||
g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS);
|
||||
b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS);
|
||||
|
||||
return SkPackRGB16(r, g, b);
|
||||
}
|
||||
|
||||
inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c)
|
||||
{
|
||||
return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c));
|
||||
}
|
||||
|
||||
/* Return c in expanded_rgb_16 format, but also scaled up by 32 (5 bits)
|
||||
It is now suitable for combining with a scaled expanded_rgb_16 color
|
||||
as in SkSrcOver32To16().
|
||||
We must do this 565 high-bit replication, in order for the subsequent add
|
||||
to saturate properly (and not overflow). If we take the 8 bits as is, it is
|
||||
possible to overflow.
|
||||
*/
|
||||
static inline uint32_t SkPMColorToExpanded16x5(SkPMColor c)
|
||||
{
|
||||
unsigned sr = SkPacked32ToR16(c);
|
||||
unsigned sg = SkPacked32ToG16(c);
|
||||
unsigned sb = SkPacked32ToB16(c);
|
||||
|
||||
sr = (sr << 5) | sr;
|
||||
sg = (sg << 5) | (sg >> 1);
|
||||
sb = (sb << 5) | sb;
|
||||
return (sr << 11) | (sg << 21) | (sb << 0);
|
||||
}
|
||||
|
||||
/* SrcOver the 32bit src color with the 16bit dst, returning a 16bit value
|
||||
(with dirt in the high 16bits, so caller beware).
|
||||
*/
|
||||
static inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) {
|
||||
unsigned sr = SkGetPackedR32(src);
|
||||
unsigned sg = SkGetPackedG32(src);
|
||||
unsigned sb = SkGetPackedB32(src);
|
||||
|
||||
unsigned dr = SkGetPackedR16(dst);
|
||||
unsigned dg = SkGetPackedG16(dst);
|
||||
unsigned db = SkGetPackedB16(dst);
|
||||
|
||||
unsigned isa = 255 - SkGetPackedA32(src);
|
||||
|
||||
dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS);
|
||||
dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS);
|
||||
db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS);
|
||||
|
||||
return SkPackRGB16(dr, dg, db);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a 16bit pixel to a 32bit pixel
|
||||
|
||||
inline unsigned SkR16ToR32(unsigned r)
|
||||
{
|
||||
return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
|
||||
}
|
||||
inline unsigned SkG16ToG32(unsigned g)
|
||||
{
|
||||
return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
|
||||
}
|
||||
inline unsigned SkB16ToB32(unsigned b)
|
||||
{
|
||||
return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
|
||||
}
|
||||
|
||||
#define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c))
|
||||
#define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c))
|
||||
#define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c))
|
||||
|
||||
inline SkPMColor SkPixel16ToPixel32(U16CPU src)
|
||||
{
|
||||
SkASSERT(src == SkToU16(src));
|
||||
|
||||
unsigned r = SkPacked16ToR32(src);
|
||||
unsigned g = SkPacked16ToG32(src);
|
||||
unsigned b = SkPacked16ToB32(src);
|
||||
|
||||
SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
|
||||
SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
|
||||
SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
|
||||
|
||||
return SkPackARGB32(0xFF, r, g, b);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef uint16_t SkPMColor16;
|
||||
|
||||
// Put in OpenGL order (r g b a)
|
||||
#define SK_A4444_SHIFT 0
|
||||
#define SK_R4444_SHIFT 12
|
||||
#define SK_G4444_SHIFT 8
|
||||
#define SK_B4444_SHIFT 4
|
||||
|
||||
#define SkA32To4444(a) ((unsigned)(a) >> 4)
|
||||
#define SkR32To4444(r) ((unsigned)(r) >> 4)
|
||||
#define SkG32To4444(g) ((unsigned)(g) >> 4)
|
||||
#define SkB32To4444(b) ((unsigned)(b) >> 4)
|
||||
|
||||
static U8CPU SkReplicateNibble(unsigned nib)
|
||||
{
|
||||
SkASSERT(nib <= 0xF);
|
||||
return (nib << 4) | nib;
|
||||
}
|
||||
|
||||
#define SkA4444ToA32(a) SkReplicateNibble(a)
|
||||
#define SkR4444ToR32(r) SkReplicateNibble(r)
|
||||
#define SkG4444ToG32(g) SkReplicateNibble(g)
|
||||
#define SkB4444ToB32(b) SkReplicateNibble(b)
|
||||
|
||||
#define SkGetPackedA4444(c) (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF)
|
||||
#define SkGetPackedR4444(c) (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF)
|
||||
#define SkGetPackedG4444(c) (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF)
|
||||
#define SkGetPackedB4444(c) (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF)
|
||||
|
||||
#define SkPacked4444ToA32(c) SkReplicateNibble(SkGetPackedA4444(c))
|
||||
#define SkPacked4444ToR32(c) SkReplicateNibble(SkGetPackedR4444(c))
|
||||
#define SkPacked4444ToG32(c) SkReplicateNibble(SkGetPackedG4444(c))
|
||||
#define SkPacked4444ToB32(c) SkReplicateNibble(SkGetPackedB4444(c))
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static inline void SkPMColor16Assert(U16CPU c)
|
||||
{
|
||||
unsigned a = SkGetPackedA4444(c);
|
||||
unsigned r = SkGetPackedR4444(c);
|
||||
unsigned g = SkGetPackedG4444(c);
|
||||
unsigned b = SkGetPackedB4444(c);
|
||||
|
||||
SkASSERT(a <= 0xF);
|
||||
SkASSERT(r <= a);
|
||||
SkASSERT(g <= a);
|
||||
SkASSERT(b <= a);
|
||||
}
|
||||
#else
|
||||
#define SkPMColor16Assert(c)
|
||||
#endif
|
||||
|
||||
static inline unsigned SkAlpha15To16(unsigned a)
|
||||
{
|
||||
SkASSERT(a <= 0xF);
|
||||
return a + (a >> 3);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static inline int SkAlphaMul4(int value, int scale)
|
||||
{
|
||||
SkASSERT((unsigned)scale <= 0x10);
|
||||
return value * scale >> 4;
|
||||
}
|
||||
#else
|
||||
#define SkAlphaMul4(value, scale) ((value) * (scale) >> 4)
|
||||
#endif
|
||||
|
||||
static inline unsigned SkR4444ToR565(unsigned r)
|
||||
{
|
||||
SkASSERT(r <= 0xF);
|
||||
return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS));
|
||||
}
|
||||
|
||||
static inline unsigned SkG4444ToG565(unsigned g)
|
||||
{
|
||||
SkASSERT(g <= 0xF);
|
||||
return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS));
|
||||
}
|
||||
|
||||
static inline unsigned SkB4444ToB565(unsigned b)
|
||||
{
|
||||
SkASSERT(b <= 0xF);
|
||||
return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS));
|
||||
}
|
||||
|
||||
static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r,
|
||||
unsigned g, unsigned b)
|
||||
{
|
||||
SkASSERT(a <= 0xF);
|
||||
SkASSERT(r <= a);
|
||||
SkASSERT(g <= a);
|
||||
SkASSERT(b <= a);
|
||||
|
||||
return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) |
|
||||
(g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
|
||||
}
|
||||
|
||||
extern const uint16_t gMask_0F0F;
|
||||
|
||||
inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale)
|
||||
{
|
||||
SkASSERT(scale <= 16);
|
||||
|
||||
const unsigned mask = 0xF0F; //gMask_0F0F;
|
||||
|
||||
#if 0
|
||||
unsigned rb = ((c & mask) * scale) >> 4;
|
||||
unsigned ag = ((c >> 4) & mask) * scale;
|
||||
return (rb & mask) | (ag & ~mask);
|
||||
#else
|
||||
c = (c & mask) | ((c & (mask << 4)) << 12);
|
||||
c = c * scale >> 4;
|
||||
return (c & mask) | ((c >> 12) & (mask << 4));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Expand the SkPMColor16 color into a 32bit value that can be scaled all at
|
||||
once by a value up to 16. Used in conjunction with SkCompact_4444.
|
||||
*/
|
||||
inline uint32_t SkExpand_4444(U16CPU c)
|
||||
{
|
||||
SkASSERT(c == (uint16_t)c);
|
||||
|
||||
const unsigned mask = 0xF0F; //gMask_0F0F;
|
||||
return (c & mask) | ((c & ~mask) << 12);
|
||||
}
|
||||
|
||||
/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16.
|
||||
NOTE: this explicitly does not clean the top 16 bits (which may be garbage).
|
||||
It does this for speed, since if it is being written directly to 16bits of
|
||||
memory, the top 16bits will be ignored. Casting the result to uint16_t here
|
||||
would add 2 more instructions, slow us down. It is up to the caller to
|
||||
perform the cast if needed.
|
||||
*/
|
||||
static inline U16CPU SkCompact_4444(uint32_t c)
|
||||
{
|
||||
const unsigned mask = 0xF0F; //gMask_0F0F;
|
||||
return (c & mask) | ((c >> 12) & ~mask);
|
||||
}
|
||||
|
||||
static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d)
|
||||
{
|
||||
unsigned sa = SkGetPackedA4444(s);
|
||||
unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
|
||||
unsigned sg = SkG4444ToG565(SkGetPackedG4444(s));
|
||||
unsigned sb = SkB4444ToB565(SkGetPackedB4444(s));
|
||||
|
||||
// To avoid overflow, we have to clear the low bit of the synthetic sg
|
||||
// if the src alpha is <= 7.
|
||||
// to see why, try blending 0x4444 on top of 565-white and watch green
|
||||
// overflow (sum == 64)
|
||||
sg &= ~(~(sa >> 3) & 1);
|
||||
|
||||
unsigned scale = SkAlpha15To16(15 - sa);
|
||||
unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale);
|
||||
unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale);
|
||||
unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale);
|
||||
|
||||
#if 0
|
||||
if (sg + dg > 63) {
|
||||
SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg);
|
||||
}
|
||||
#endif
|
||||
return SkPackRGB16(sr + dr, sg + dg, sb + db);
|
||||
}
|
||||
|
||||
static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16)
|
||||
{
|
||||
SkASSERT((unsigned)scale16 <= 16);
|
||||
|
||||
return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
|
||||
}
|
||||
|
||||
static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16)
|
||||
{
|
||||
SkASSERT((unsigned)scale16 <= 16);
|
||||
|
||||
uint32_t src32 = SkExpand_4444(src) * scale16;
|
||||
// the scaled srcAlpha is the bottom byte
|
||||
#ifdef SK_DEBUG
|
||||
{
|
||||
unsigned srcA = SkGetPackedA4444(src) * scale16;
|
||||
SkASSERT(srcA == (src32 & 0xFF));
|
||||
}
|
||||
#endif
|
||||
unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4;
|
||||
uint32_t dst32 = SkExpand_4444(dst) * dstScale;
|
||||
return SkCompact_4444((src32 + dst32) >> 4);
|
||||
}
|
||||
|
||||
static inline SkPMColor SkPixel4444ToPixel32(U16CPU c)
|
||||
{
|
||||
uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
|
||||
(SkGetPackedR4444(c) << SK_R32_SHIFT) |
|
||||
(SkGetPackedG4444(c) << SK_G32_SHIFT) |
|
||||
(SkGetPackedB4444(c) << SK_B32_SHIFT);
|
||||
return d | (d << 4);
|
||||
}
|
||||
|
||||
static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c)
|
||||
{
|
||||
return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) |
|
||||
(((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) |
|
||||
(((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) |
|
||||
(((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT);
|
||||
}
|
||||
|
||||
// cheap 2x2 dither
|
||||
static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r,
|
||||
U8CPU g, U8CPU b)
|
||||
{
|
||||
a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4;
|
||||
r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4;
|
||||
g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4;
|
||||
b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4;
|
||||
|
||||
return SkPackARGB4444(a, r, g, b);
|
||||
}
|
||||
|
||||
static inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c)
|
||||
{
|
||||
return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c),
|
||||
SkGetPackedG32(c), SkGetPackedB32(c));
|
||||
}
|
||||
|
||||
/* Assumes 16bit is in standard RGBA order.
|
||||
Transforms a normal ARGB_8888 into the same byte order as
|
||||
expanded ARGB_4444, but keeps each component 8bits
|
||||
*/
|
||||
static uint32_t SkExpand_8888(SkPMColor c)
|
||||
{
|
||||
return (((c >> SK_R32_SHIFT) & 0xFF) << 24) |
|
||||
(((c >> SK_G32_SHIFT) & 0xFF) << 8) |
|
||||
(((c >> SK_B32_SHIFT) & 0xFF) << 16) |
|
||||
(((c >> SK_A32_SHIFT) & 0xFF) << 0);
|
||||
}
|
||||
|
||||
/* Undo the operation of SkExpand_8888, turning the argument back into
|
||||
a SkPMColor.
|
||||
*/
|
||||
static SkPMColor SkCompact_8888(uint32_t c)
|
||||
{
|
||||
return (((c >> 24) & 0xFF) << SK_R32_SHIFT) |
|
||||
(((c >> 8) & 0xFF) << SK_G32_SHIFT) |
|
||||
(((c >> 16) & 0xFF) << SK_B32_SHIFT) |
|
||||
(((c >> 0) & 0xFF) << SK_A32_SHIFT);
|
||||
}
|
||||
|
||||
/* Like SkExpand_8888, this transforms a pmcolor into the expanded 4444 format,
|
||||
but this routine just keeps the high 4bits of each component in the low
|
||||
4bits of the result (just like a newly expanded PMColor16).
|
||||
*/
|
||||
static uint32_t SkExpand32_4444(SkPMColor c)
|
||||
{
|
||||
return (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) |
|
||||
(((c >> (SK_G32_SHIFT + 4)) & 0xF) << 8) |
|
||||
(((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) |
|
||||
(((c >> (SK_A32_SHIFT + 4)) & 0xF) << 0);
|
||||
}
|
||||
|
||||
// takes two values and alternamtes them as part of a memset16
|
||||
// used for cheap 2x2 dithering when the colors are opaque
|
||||
void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkColorShader_DEFINED
|
||||
#define SkColorShader_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
/** \class SkColorShader
|
||||
A Shader that represents a single color. In general, this effect can be
|
||||
accomplished by just using the color field on the paint, but if an
|
||||
actual shader object is needed, this provides that feature.
|
||||
*/
|
||||
class SkColorShader : public SkShader {
|
||||
public:
|
||||
/** Create a ColorShader that will inherit its color from the Paint
|
||||
at draw time.
|
||||
*/
|
||||
SkColorShader() : fInheritColor(true) {}
|
||||
/** Create a ColorShader that ignores the color in the paint, and uses the
|
||||
specified color. Note: like all shaders, at draw time the paint's alpha
|
||||
will be respected, and is applied to the specified color.
|
||||
*/
|
||||
SkColorShader(SkColor c) : fColor(c), fInheritColor(false) {}
|
||||
|
||||
virtual uint32_t getFlags();
|
||||
virtual uint8_t getSpan16Alpha() const;
|
||||
virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
|
||||
const SkMatrix& matrix);
|
||||
virtual void shadeSpan(int x, int y, SkPMColor span[], int count);
|
||||
virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
|
||||
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
|
||||
|
||||
protected:
|
||||
SkColorShader(SkFlattenableReadBuffer& );
|
||||
virtual void flatten(SkFlattenableWriteBuffer& );
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkColorShader, (buffer));
|
||||
}
|
||||
SkColor fColor; // ignored if fInheritColor is true
|
||||
SkPMColor fPMColor; // cached after setContext()
|
||||
uint16_t fColor16; // cached after setContext()
|
||||
SkBool8 fInheritColor;
|
||||
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkComposeShader_DEFINED
|
||||
#define SkComposeShader_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkXfermode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** \class SkComposeShader
|
||||
This subclass of shader returns the coposition of two other shaders, combined by
|
||||
a xfermode.
|
||||
*/
|
||||
class SkComposeShader : public SkShader {
|
||||
public:
|
||||
/** Create a new compose shader, given shaders A, B, and a combining xfermode mode.
|
||||
When the xfermode is called, it will be given the result from shader A as its
|
||||
"dst", and the result of from shader B as its "src".
|
||||
mode->xfer32(sA_result, sB_result, ...)
|
||||
@param shaderA The colors from this shader are seen as the "dst" by the xfermode
|
||||
@param shaderB The colors from this shader are seen as the "src" by the xfermode
|
||||
@param mode The xfermode that combines the colors from the two shaders. If mode
|
||||
is null, then SRC_OVER is assumed.
|
||||
*/
|
||||
SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL);
|
||||
virtual ~SkComposeShader();
|
||||
|
||||
// override
|
||||
virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix);
|
||||
virtual void shadeSpan(int x, int y, SkPMColor result[], int count);
|
||||
virtual void beginSession();
|
||||
virtual void endSession();
|
||||
|
||||
protected:
|
||||
SkComposeShader(SkFlattenableReadBuffer& );
|
||||
virtual void flatten(SkFlattenableWriteBuffer& );
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkComposeShader, (buffer)); }
|
||||
|
||||
SkShader* fShaderA;
|
||||
SkShader* fShaderB;
|
||||
SkXfermode* fMode;
|
||||
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDeque_DEFINED
|
||||
#define SkDeque_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkDeque : SkNoncopyable {
|
||||
public:
|
||||
explicit SkDeque(size_t elemSize);
|
||||
SkDeque(size_t elemSize, void* storage, size_t storageSize);
|
||||
~SkDeque();
|
||||
|
||||
bool empty() const { return 0 == fCount; }
|
||||
int count() const { return fCount; }
|
||||
size_t elemSize() const { return fElemSize; }
|
||||
|
||||
const void* front() const;
|
||||
const void* back() const;
|
||||
|
||||
void* front() {
|
||||
return (void*)((const SkDeque*)this)->front();
|
||||
}
|
||||
|
||||
void* back() {
|
||||
return (void*)((const SkDeque*)this)->back();
|
||||
}
|
||||
|
||||
void* push_front();
|
||||
void* push_back();
|
||||
|
||||
void pop_front();
|
||||
void pop_back();
|
||||
|
||||
private:
|
||||
struct Head;
|
||||
|
||||
public:
|
||||
class Iter {
|
||||
public:
|
||||
Iter(const SkDeque& d);
|
||||
void* next();
|
||||
|
||||
private:
|
||||
SkDeque::Head* fHead;
|
||||
char* fPos;
|
||||
size_t fElemSize;
|
||||
};
|
||||
|
||||
private:
|
||||
Head* fFront;
|
||||
Head* fBack;
|
||||
size_t fElemSize;
|
||||
void* fInitialStorage;
|
||||
int fCount;
|
||||
|
||||
friend class Iter;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDescriptor_DEFINED
|
||||
#define SkDescriptor_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkDescriptor : SkNoncopyable {
|
||||
public:
|
||||
static size_t ComputeOverhead(int entryCount)
|
||||
{
|
||||
SkASSERT(entryCount >= 0);
|
||||
return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
|
||||
}
|
||||
|
||||
static SkDescriptor* Alloc(size_t length)
|
||||
{
|
||||
SkASSERT(SkAlign4(length) == length);
|
||||
SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length);
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void Free(SkDescriptor* desc)
|
||||
{
|
||||
sk_free(desc);
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
fLength = sizeof(SkDescriptor);
|
||||
fCount = 0;
|
||||
}
|
||||
|
||||
uint32_t getLength() const { return fLength; }
|
||||
|
||||
void* addEntry(uint32_t tag, uint32_t length, const void* data = NULL)
|
||||
{
|
||||
SkASSERT(tag);
|
||||
SkASSERT(SkAlign4(length) == length);
|
||||
SkASSERT(this->findEntry(tag, NULL) == NULL);
|
||||
|
||||
Entry* entry = (Entry*)((char*)this + fLength);
|
||||
entry->fTag = tag;
|
||||
entry->fLen = length;
|
||||
if (data)
|
||||
memcpy(entry + 1, data, length);
|
||||
|
||||
fCount += 1;
|
||||
fLength += sizeof(Entry) + length;
|
||||
return (entry + 1); // return its data
|
||||
}
|
||||
|
||||
void computeChecksum()
|
||||
{
|
||||
fChecksum = SkDescriptor::ComputeChecksum(this);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void assertChecksum() const
|
||||
{
|
||||
SkASSERT(fChecksum == SkDescriptor::ComputeChecksum(this));
|
||||
}
|
||||
#endif
|
||||
|
||||
const void* findEntry(uint32_t tag, uint32_t* length) const
|
||||
{
|
||||
const Entry* entry = (const Entry*)(this + 1);
|
||||
int count = fCount;
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
if (entry->fTag == tag)
|
||||
{
|
||||
if (length)
|
||||
*length = entry->fLen;
|
||||
return entry + 1;
|
||||
}
|
||||
entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkDescriptor* copy() const
|
||||
{
|
||||
SkDescriptor* desc = SkDescriptor::Alloc(fLength);
|
||||
memcpy(desc, this, fLength);
|
||||
return desc;
|
||||
}
|
||||
|
||||
bool equals(const SkDescriptor& other) const
|
||||
{
|
||||
// probe to see if we have a good checksum algo
|
||||
// SkASSERT(a.fChecksum != b.fChecksum || memcmp(&a, &b, a.fLength) == 0);
|
||||
|
||||
// the first value we should look at is the checksum, so this loop
|
||||
// should terminate early if they descriptors are different.
|
||||
// NOTE: if we wrote a sentinel value at the end of each, we chould
|
||||
// remove the aa < stop test in the loop...
|
||||
const uint32_t* aa = (const uint32_t*)this;
|
||||
const uint32_t* bb = (const uint32_t*)&other;
|
||||
const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength);
|
||||
do {
|
||||
if (*aa++ != *bb++)
|
||||
return false;
|
||||
} while (aa < stop);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
uint32_t fTag;
|
||||
uint32_t fLen;
|
||||
};
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
uint32_t getChecksum() const { return fChecksum; }
|
||||
uint32_t getCount() const { return fCount; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
uint32_t fChecksum; // must be first
|
||||
uint32_t fLength; // must be second
|
||||
uint32_t fCount;
|
||||
|
||||
static uint32_t ComputeChecksum(const SkDescriptor* desc)
|
||||
{
|
||||
const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field
|
||||
const uint32_t* stop = (const uint32_t*)((const char*)desc + desc->fLength);
|
||||
uint32_t sum = 0;
|
||||
|
||||
SkASSERT(ptr < stop);
|
||||
do {
|
||||
sum = (sum << 1) | (sum >> 31);
|
||||
sum ^= *ptr++;
|
||||
} while (ptr < stop);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
// private so no one can create one except our factories
|
||||
SkDescriptor() {}
|
||||
};
|
||||
|
||||
#include "SkScalerContext.h"
|
||||
|
||||
class SkAutoDescriptor : SkNoncopyable {
|
||||
public:
|
||||
SkAutoDescriptor(size_t size)
|
||||
{
|
||||
if (size <= sizeof(fStorage))
|
||||
fDesc = (SkDescriptor*)(void*)fStorage;
|
||||
else
|
||||
fDesc = SkDescriptor::Alloc(size);
|
||||
}
|
||||
~SkAutoDescriptor()
|
||||
{
|
||||
if (fDesc != (SkDescriptor*)(void*)fStorage)
|
||||
SkDescriptor::Free(fDesc);
|
||||
}
|
||||
SkDescriptor* getDesc() const { return fDesc; }
|
||||
private:
|
||||
enum {
|
||||
kStorageSize = sizeof(SkDescriptor)
|
||||
+ sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec) // for rec
|
||||
+ sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface
|
||||
+ 32 // slop for occational small extras
|
||||
};
|
||||
SkDescriptor* fDesc;
|
||||
uint32_t fStorage[(kStorageSize + 3) >> 2];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDevice_DEFINED
|
||||
#define SkDevice_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColor.h"
|
||||
|
||||
class SkDraw;
|
||||
struct SkIRect;
|
||||
class SkMatrix;
|
||||
class SkRegion;
|
||||
|
||||
class SkDevice : public SkRefCnt {
|
||||
public:
|
||||
SkDevice();
|
||||
/** Construct a new device, extracting the width/height/config/isOpaque values from
|
||||
the bitmap. If transferPixelOwnership is true, and the bitmap claims to own its
|
||||
own pixels (getOwnsPixels() == true), then transfer this responsibility to the
|
||||
device, and call setOwnsPixels(false) on the bitmap.
|
||||
|
||||
Subclasses may override the destructor, which is virtual, even though this class
|
||||
doesn't have one. SkRefCnt does.
|
||||
|
||||
@param bitmap A copy of this bitmap is made and stored in the device
|
||||
*/
|
||||
SkDevice(const SkBitmap& bitmap);
|
||||
|
||||
/** Return the width of the device (in pixels).
|
||||
*/
|
||||
int width() const { return fBitmap.width(); }
|
||||
/** Return the height of the device (in pixels).
|
||||
*/
|
||||
int height() const { return fBitmap.height(); }
|
||||
/** Return the bitmap config of the device's pixels
|
||||
*/
|
||||
SkBitmap::Config config() const { return fBitmap.getConfig(); }
|
||||
/** Returns true if the device's bitmap's config treats every pixels as
|
||||
implicitly opaque.
|
||||
*/
|
||||
bool isOpaque() const { return fBitmap.isOpaque(); }
|
||||
|
||||
/** Return the bounds of the device
|
||||
*/
|
||||
void getBounds(SkIRect* bounds) const;
|
||||
|
||||
/** Return true if the specified rectangle intersects the bounds of the
|
||||
device. If sect is not NULL and there is an intersection, sect returns
|
||||
the intersection.
|
||||
*/
|
||||
bool intersects(const SkIRect& r, SkIRect* sect = NULL) const;
|
||||
|
||||
/** Return the bitmap associated with this device. Call this each time you need
|
||||
to access the bitmap, as it notifies the subclass to perform any flushing
|
||||
etc. before you examine the pixels.
|
||||
@param changePixels set to true if the caller plans to change the pixels
|
||||
@return the device's bitmap
|
||||
*/
|
||||
const SkBitmap& accessBitmap(bool changePixels);
|
||||
|
||||
/** Helper to erase the entire device to the specified color (including
|
||||
alpha).
|
||||
*/
|
||||
void eraseColor(SkColor eraseColor);
|
||||
|
||||
/** Called when this device is installed into a Canvas. Balanaced by a call
|
||||
to unlockPixels() when the device is removed from a Canvas.
|
||||
*/
|
||||
virtual void lockPixels();
|
||||
virtual void unlockPixels();
|
||||
|
||||
/** Called with the correct matrix and clip before this device is drawn
|
||||
to using those settings. If your subclass overrides this, be sure to
|
||||
call through to the base class as well.
|
||||
*/
|
||||
virtual void setMatrixClip(const SkMatrix&, const SkRegion&);
|
||||
|
||||
/** Called when this device gains focus (i.e becomes the current device
|
||||
for drawing).
|
||||
*/
|
||||
virtual void gainFocus(SkCanvas*) {}
|
||||
|
||||
/** These are called inside the per-device-layer loop for each draw call.
|
||||
When these are called, we have already applied any saveLayer operations,
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint);
|
||||
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint);
|
||||
virtual void drawRect(const SkDraw&, const SkRect& r,
|
||||
const SkPaint& paint);
|
||||
virtual void drawPath(const SkDraw&, const SkPath& path,
|
||||
const SkPaint& paint);
|
||||
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint);
|
||||
virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint);
|
||||
virtual void drawText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint);
|
||||
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPos, const SkPaint& paint);
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint);
|
||||
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint);
|
||||
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
|
||||
const SkPaint&);
|
||||
|
||||
protected:
|
||||
/** Update as needed the pixel value in the bitmap, so that the caller can access
|
||||
the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
|
||||
must remain unchanged.
|
||||
*/
|
||||
virtual void onAccessBitmap(SkBitmap*);
|
||||
|
||||
private:
|
||||
SkBitmap fBitmap;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDither_DEFINED
|
||||
#define SkDither_DEFINED
|
||||
|
||||
#include "SkColorPriv.h"
|
||||
|
||||
#define SK_DitherValueMax4444 15
|
||||
#define SK_DitherValueMax565 7
|
||||
|
||||
/* need to use macros for bit-counts for each component, and then
|
||||
move these into SkColorPriv.h
|
||||
*/
|
||||
|
||||
#define SkDITHER_R32_FOR_565_MACRO(r, d) (r + d - (r >> 5))
|
||||
#define SkDITHER_G32_FOR_565_MACRO(g, d) (g + (d >> 1) - (g >> 6))
|
||||
#define SkDITHER_B32_FOR_565_MACRO(b, d) (b + d - (b >> 5))
|
||||
|
||||
#define SkDITHER_A32_FOR_4444_MACRO(a, d) (a + 15 - (a >> 4))
|
||||
#define SkDITHER_R32_FOR_4444_MACRO(r, d) (r + d - (r >> 4))
|
||||
#define SkDITHER_G32_FOR_4444_MACRO(g, d) (g + d - (g >> 4))
|
||||
#define SkDITHER_B32_FOR_4444_MACRO(b, d) (b + d - (b >> 4))
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
inline unsigned SkDITHER_R32_FOR_565(unsigned r, unsigned d)
|
||||
{
|
||||
SkASSERT(d <= SK_DitherValueMax565);
|
||||
SkA32Assert(r);
|
||||
r = SkDITHER_R32_FOR_565_MACRO(r, d);
|
||||
SkA32Assert(r);
|
||||
return r;
|
||||
}
|
||||
inline unsigned SkDITHER_G32_FOR_565(unsigned g, unsigned d)
|
||||
{
|
||||
SkASSERT(d <= SK_DitherValueMax565);
|
||||
SkG32Assert(g);
|
||||
g = SkDITHER_G32_FOR_565_MACRO(g, d);
|
||||
SkG32Assert(g);
|
||||
return g;
|
||||
}
|
||||
inline unsigned SkDITHER_B32_FOR_565(unsigned b, unsigned d)
|
||||
{
|
||||
SkASSERT(d <= SK_DitherValueMax565);
|
||||
SkB32Assert(b);
|
||||
b = SkDITHER_B32_FOR_565_MACRO(b, d);
|
||||
SkB32Assert(b);
|
||||
return b;
|
||||
}
|
||||
#else
|
||||
#define SkDITHER_R32_FOR_565(r, d) SkDITHER_R32_FOR_565_MACRO(r, d)
|
||||
#define SkDITHER_G32_FOR_565(g, d) SkDITHER_G32_FOR_565_MACRO(g, d)
|
||||
#define SkDITHER_B32_FOR_565(b, d) SkDITHER_B32_FOR_565_MACRO(b, d)
|
||||
#endif
|
||||
|
||||
#define SkDITHER_R32To565(r, d) SkR32ToR16(SkDITHER_R32_FOR_565(r, d))
|
||||
#define SkDITHER_G32To565(g, d) SkG32ToG16(SkDITHER_G32_FOR_565(g, d))
|
||||
#define SkDITHER_B32To565(b, d) SkB32ToB16(SkDITHER_B32_FOR_565(b, d))
|
||||
|
||||
#define SkDITHER_A32To4444(a, d) SkA32To4444(SkDITHER_A32_FOR_4444_MACRO(a, d))
|
||||
#define SkDITHER_R32To4444(r, d) SkR32To4444(SkDITHER_R32_FOR_4444_MACRO(r, d))
|
||||
#define SkDITHER_G32To4444(g, d) SkG32To4444(SkDITHER_G32_FOR_4444_MACRO(g, d))
|
||||
#define SkDITHER_B32To4444(b, d) SkB32To4444(SkDITHER_B32_FOR_4444_MACRO(b, d))
|
||||
|
||||
static inline SkPMColor SkDitherARGB32For565(SkPMColor c, unsigned dither)
|
||||
{
|
||||
SkASSERT(dither <= SK_DitherValueMax565);
|
||||
|
||||
unsigned sa = SkGetPackedA32(c);
|
||||
dither = SkAlphaMul(dither, SkAlpha255To256(sa));
|
||||
|
||||
unsigned sr = SkGetPackedR32(c);
|
||||
unsigned sg = SkGetPackedG32(c);
|
||||
unsigned sb = SkGetPackedB32(c);
|
||||
sr = SkDITHER_R32_FOR_565(sr, dither);
|
||||
sg = SkDITHER_G32_FOR_565(sg, dither);
|
||||
sb = SkDITHER_B32_FOR_565(sb, dither);
|
||||
|
||||
return SkPackARGB32(sa, sr, sg, sb);
|
||||
}
|
||||
|
||||
static inline SkPMColor SkDitherRGB32For565(SkPMColor c, unsigned dither)
|
||||
{
|
||||
SkASSERT(dither <= SK_DitherValueMax565);
|
||||
|
||||
unsigned sr = SkGetPackedR32(c);
|
||||
unsigned sg = SkGetPackedG32(c);
|
||||
unsigned sb = SkGetPackedB32(c);
|
||||
sr = SkDITHER_R32_FOR_565(sr, dither);
|
||||
sg = SkDITHER_G32_FOR_565(sg, dither);
|
||||
sb = SkDITHER_B32_FOR_565(sb, dither);
|
||||
|
||||
return SkPackARGB32(0xFF, sr, sg, sb);
|
||||
}
|
||||
|
||||
static inline uint16_t SkDitherRGBTo565(U8CPU r, U8CPU g, U8CPU b,
|
||||
unsigned dither)
|
||||
{
|
||||
SkASSERT(dither <= SK_DitherValueMax565);
|
||||
r = SkDITHER_R32To565(r, dither);
|
||||
g = SkDITHER_G32To565(g, dither);
|
||||
b = SkDITHER_B32To565(b, dither);
|
||||
return SkPackRGB16(r, g, b);
|
||||
}
|
||||
|
||||
static inline uint16_t SkDitherRGB32To565(SkPMColor c, unsigned dither)
|
||||
{
|
||||
SkASSERT(dither <= SK_DitherValueMax565);
|
||||
|
||||
unsigned sr = SkGetPackedR32(c);
|
||||
unsigned sg = SkGetPackedG32(c);
|
||||
unsigned sb = SkGetPackedB32(c);
|
||||
sr = SkDITHER_R32To565(sr, dither);
|
||||
sg = SkDITHER_G32To565(sg, dither);
|
||||
sb = SkDITHER_B32To565(sb, dither);
|
||||
|
||||
return SkPackRGB16(sr, sg, sb);
|
||||
}
|
||||
|
||||
static inline uint16_t SkDitherARGB32To565(U8CPU sa, SkPMColor c, unsigned dither)
|
||||
{
|
||||
SkASSERT(dither <= SK_DitherValueMax565);
|
||||
dither = SkAlphaMul(dither, SkAlpha255To256(sa));
|
||||
|
||||
unsigned sr = SkGetPackedR32(c);
|
||||
unsigned sg = SkGetPackedG32(c);
|
||||
unsigned sb = SkGetPackedB32(c);
|
||||
sr = SkDITHER_R32To565(sr, dither);
|
||||
sg = SkDITHER_G32To565(sg, dither);
|
||||
sb = SkDITHER_B32To565(sb, dither);
|
||||
|
||||
return SkPackRGB16(sr, sg, sb);
|
||||
}
|
||||
|
||||
///////////////////////// 4444
|
||||
|
||||
static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, U8CPU g,
|
||||
U8CPU b, unsigned dither)
|
||||
{
|
||||
dither = SkAlphaMul(dither, SkAlpha255To256(a));
|
||||
|
||||
a = SkDITHER_A32To4444(a, dither);
|
||||
r = SkDITHER_R32To4444(r, dither);
|
||||
g = SkDITHER_G32To4444(g, dither);
|
||||
b = SkDITHER_B32To4444(b, dither);
|
||||
|
||||
return SkPackARGB4444(a, r, g, b);
|
||||
}
|
||||
|
||||
static inline SkPMColor16 SkDitherARGB32To4444(SkPMColor c, unsigned dither)
|
||||
{
|
||||
unsigned a = SkGetPackedA32(c);
|
||||
unsigned r = SkGetPackedR32(c);
|
||||
unsigned g = SkGetPackedG32(c);
|
||||
unsigned b = SkGetPackedB32(c);
|
||||
|
||||
dither = SkAlphaMul(dither, SkAlpha255To256(a));
|
||||
|
||||
a = SkDITHER_A32To4444(a, dither);
|
||||
r = SkDITHER_R32To4444(r, dither);
|
||||
g = SkDITHER_G32To4444(g, dither);
|
||||
b = SkDITHER_B32To4444(b, dither);
|
||||
|
||||
return SkPackARGB4444(a, r, g, b);
|
||||
}
|
||||
|
||||
// TODO: need dither routines for 565 -> 4444
|
||||
|
||||
// this toggles between a 4x4 and a 1x4 array
|
||||
//#define ENABLE_DITHER_MATRIX_4X4
|
||||
|
||||
#ifdef ENABLE_DITHER_MATRIX_4X4
|
||||
extern const uint8_t gDitherMatrix_4Bit_4X4[4][4];
|
||||
extern const uint8_t gDitherMatrix_3Bit_4X4[4][4];
|
||||
|
||||
#define DITHER_4444_SCAN(y) const uint8_t* dither_scan = gDitherMatrix_4Bit_4X4[(y) & 3]
|
||||
#define DITHER_565_SCAN(y) const uint8_t* dither_scan = gDitherMatrix_3Bit_4X4[(y) & 3]
|
||||
|
||||
#define DITHER_VALUE(x) dither_scan[(x) & 3]
|
||||
#else
|
||||
extern const uint16_t gDitherMatrix_4Bit_16[4];
|
||||
extern const uint16_t gDitherMatrix_3Bit_16[4];
|
||||
|
||||
#define DITHER_4444_SCAN(y) const uint16_t dither_scan = gDitherMatrix_4Bit_16[(y) & 3]
|
||||
#define DITHER_565_SCAN(y) const uint16_t dither_scan = gDitherMatrix_3Bit_16[(y) & 3]
|
||||
|
||||
#define DITHER_VALUE(x) ((dither_scan >> (((x) & 3) << 2)) & 0xF)
|
||||
#endif
|
||||
|
||||
#define DITHER_INC_X(x) ++(x)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDraw_DEFINED
|
||||
#define SkDraw_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkMask.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkAutoKern.h"
|
||||
|
||||
class SkBounder;
|
||||
class SkDevice;
|
||||
class SkPath;
|
||||
class SkRegion;
|
||||
struct SkDrawProcs;
|
||||
|
||||
class SkDraw {
|
||||
public:
|
||||
SkDraw() : fDevice(NULL), fBounder(NULL), fProcs(NULL) {}
|
||||
SkDraw(const SkDraw& src);
|
||||
|
||||
void drawPaint(const SkPaint&) const;
|
||||
void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[],
|
||||
const SkPaint&) const;
|
||||
void drawRect(const SkRect&, const SkPaint&) const;
|
||||
/* To save on mallocs, we allow a flag that tells us that srcPath is
|
||||
mutable, so that we don't have to make copies of it as we transform it.
|
||||
*/
|
||||
void drawPath(const SkPath& srcPath, const SkPaint&,
|
||||
const SkMatrix* prePathMatrix, bool pathIsMutable) const;
|
||||
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const;
|
||||
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
|
||||
void drawText(const char text[], size_t byteLength, SkScalar x,
|
||||
SkScalar y, const SkPaint& paint) const;
|
||||
void drawPosText(const char text[], size_t byteLength,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPosition, const SkPaint& paint) const;
|
||||
void drawTextOnPath(const char text[], size_t byteLength,
|
||||
const SkPath&, const SkMatrix*, const SkPaint&) const;
|
||||
void drawVertices(SkCanvas::VertexMode mode, int count,
|
||||
const SkPoint vertices[], const SkPoint textures[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int ptCount,
|
||||
const SkPaint& paint) const;
|
||||
|
||||
void drawPath(const SkPath& src, const SkPaint& paint) const {
|
||||
this->drawPath(src, paint, NULL, false);
|
||||
}
|
||||
|
||||
/** Helper function that creates a mask from a path and an optional maskfilter.
|
||||
Note however, that the resulting mask will not have been actually filtered,
|
||||
that must be done afterwards (by calling filterMask). The maskfilter is provided
|
||||
solely to assist in computing the mask's bounds (if the mode requests that).
|
||||
*/
|
||||
static bool DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
|
||||
SkMaskFilter* filter, const SkMatrix* filterMatrix,
|
||||
SkMask* mask, SkMask::CreateMode mode);
|
||||
|
||||
private:
|
||||
void drawText_asPaths(const char text[], size_t byteLength,
|
||||
SkScalar x, SkScalar y, const SkPaint&) const;
|
||||
void drawDevMask(const SkMask& mask, const SkPaint&) const;
|
||||
void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
|
||||
|
||||
public:
|
||||
const SkBitmap* fBitmap; // required
|
||||
const SkMatrix* fMatrix; // required
|
||||
const SkRegion* fClip; // required
|
||||
SkDevice* fDevice; // optional
|
||||
SkBounder* fBounder; // optional
|
||||
SkDrawProcs* fProcs; // optional
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
#include "SkGlyphCache.h"
|
||||
|
||||
class SkTextToPathIter {
|
||||
public:
|
||||
SkTextToPathIter(const char text[], size_t length, const SkPaint&,
|
||||
bool applyStrokeAndPathEffects, bool forceLinearTextOn);
|
||||
~SkTextToPathIter();
|
||||
|
||||
const SkPaint& getPaint() const { return fPaint; }
|
||||
SkScalar getPathScale() const { return fScale; }
|
||||
|
||||
const SkPath* next(SkScalar* xpos); //!< returns nil when there are no more paths
|
||||
|
||||
private:
|
||||
SkGlyphCache* fCache;
|
||||
SkPaint fPaint;
|
||||
SkScalar fScale;
|
||||
SkFixed fPrevAdvance;
|
||||
const char* fText;
|
||||
const char* fStop;
|
||||
SkMeasureCacheProc fGlyphCacheProc;
|
||||
|
||||
const SkPath* fPath; // returned in next
|
||||
SkScalar fXPos; // accumulated xpos, returned in next
|
||||
SkAutoKern fAutoKern;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDrawFilter_DEFINED
|
||||
#define SkDrawFilter_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
////////////////// EXPERIMENTAL //////////////////////////
|
||||
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
|
||||
/** Right before something is being draw, filter() is called with the
|
||||
current canvas and paint. If it returns true, then drawing proceeds
|
||||
with the (possibly modified) canvas/paint, and then restore() is called
|
||||
to restore the canvas/paint to their state before filter() was called.
|
||||
If filter returns false, canvas/paint should not have been changed, and
|
||||
restore() will not be called.
|
||||
*/
|
||||
class SkDrawFilter : public SkRefCnt {
|
||||
public:
|
||||
enum Type {
|
||||
kPaint_Type,
|
||||
kPoint_Type,
|
||||
kLine_Type,
|
||||
kBitmap_Type,
|
||||
kRect_Type,
|
||||
kPath_Type,
|
||||
kText_Type
|
||||
};
|
||||
|
||||
/** Return true to allow the draw to continue (with possibly modified
|
||||
canvas/paint). If true is returned, then restore() will be called.
|
||||
*/
|
||||
virtual bool filter(SkCanvas*, SkPaint*, Type) = 0;
|
||||
/** If filter() returned true, then restore() will be called to restore the
|
||||
canvas/paint to their previous states
|
||||
*/
|
||||
virtual void restore(SkCanvas*, SkPaint*, Type) = 0;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDrawLooper_DEFINED
|
||||
#define SkDrawLooper_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
////////////////// EXPERIMENTAL //////////////////////////
|
||||
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
|
||||
/** \class SkDrawLooper
|
||||
Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
|
||||
and something is drawn to a canvas with that paint, the looper subclass will
|
||||
be called, allowing it to modify the canvas and/or paint for that draw call.
|
||||
More than that, via the next() method, the looper can modify the draw to be
|
||||
invoked multiple times (hence the name loop-er), allow it to perform effects
|
||||
like shadows or frame/fills, that require more than one pass.
|
||||
*/
|
||||
class SkDrawLooper : public SkFlattenable {
|
||||
public:
|
||||
/** Called right before something is being drawn to the specified canvas
|
||||
with the specified paint. Subclass that want to modify either parameter
|
||||
can do so now.
|
||||
*/
|
||||
virtual void init(SkCanvas*, SkPaint*) {}
|
||||
/** Called in a loop (after init()). Each time true is returned, the object
|
||||
is drawn (possibly with a modified canvas and/or paint). When false is
|
||||
finally returned, drawing for the object stops.
|
||||
*/
|
||||
virtual bool next() { return false; }
|
||||
/** Called after the looper has finally returned false from next(), allowing
|
||||
the looper to restore the canvas/paint to their original states.
|
||||
is this required, since the subclass knows when it is done???
|
||||
should we pass the canvas/paint here, and/or to the next call
|
||||
so that subclasses don't need to retain pointers to them during the
|
||||
loop?
|
||||
*/
|
||||
virtual void restore() {}
|
||||
|
||||
protected:
|
||||
SkDrawLooper() {}
|
||||
SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkEndian_DEFINED
|
||||
#define SkEndian_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkEndian.h
|
||||
|
||||
Macros and helper functions for handling 16 and 32 bit values in
|
||||
big and little endian formats.
|
||||
*/
|
||||
|
||||
#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
|
||||
#error "can't have both LENDIAN and BENDIAN defined"
|
||||
#endif
|
||||
|
||||
#if !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
|
||||
#error "need either LENDIAN or BENDIAN defined"
|
||||
#endif
|
||||
|
||||
/** Swap the two bytes in the low 16bits of the parameters.
|
||||
e.g. 0x1234 -> 0x3412
|
||||
*/
|
||||
inline uint16_t SkEndianSwap16(U16CPU value)
|
||||
{
|
||||
SkASSERT(value == (uint16_t)value);
|
||||
return (uint16_t)((value >> 8) | (value << 8));
|
||||
}
|
||||
|
||||
/** Vector version of SkEndianSwap16(), which swaps the
|
||||
low two bytes of each value in the array.
|
||||
*/
|
||||
inline void SkEndianSwap16s(uint16_t array[], int count)
|
||||
{
|
||||
SkASSERT(count == 0 || array != NULL);
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
*array = SkEndianSwap16(*array);
|
||||
array += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Reverse all 4 bytes in a 32bit value.
|
||||
e.g. 0x12345678 -> 0x78563412
|
||||
*/
|
||||
inline uint32_t SkEndianSwap32(uint32_t value)
|
||||
{
|
||||
return ((value & 0xFF) << 24) |
|
||||
((value & 0xFF00) << 8) |
|
||||
((value & 0xFF0000) >> 8) |
|
||||
(value >> 24);
|
||||
}
|
||||
|
||||
/** Vector version of SkEndianSwap16(), which swaps the
|
||||
bytes of each value in the array.
|
||||
*/
|
||||
inline void SkEndianSwap32s(uint32_t array[], int count)
|
||||
{
|
||||
SkASSERT(count == 0 || array != NULL);
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
*array = SkEndianSwap32(*array);
|
||||
array += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_CPU_LENDIAN
|
||||
#define SkEndian_SwapBE16(n) SkEndianSwap16(n)
|
||||
#define SkEndian_SwapBE32(n) SkEndianSwap32(n)
|
||||
#define SkEndian_SwapLE16(n) (n)
|
||||
#define SkEndian_SwapLE32(n) (n)
|
||||
#else // SK_CPU_BENDIAN
|
||||
#define SkEndian_SwapBE16(n) (n)
|
||||
#define SkEndian_SwapBE32(n) (n)
|
||||
#define SkEndian_SwapLE16(n) SkEndianSwap16(n)
|
||||
#define SkEndian_SwapLE32(n) SkEndianSwap32(n)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkFDot6_DEFINED
|
||||
#define SkFDot6_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
|
||||
typedef int32_t SkFDot6;
|
||||
|
||||
#define SK_FDot61 (64)
|
||||
#define SK_FDot6Half (32)
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
inline SkFDot6 SkIntToFDot6(S16CPU x)
|
||||
{
|
||||
SkASSERT(SkToS16(x) == x);
|
||||
return x << 6;
|
||||
}
|
||||
#else
|
||||
#define SkIntToFDot6(x) ((x) << 6)
|
||||
#endif
|
||||
|
||||
#define SkFDot6Floor(x) ((x) >> 6)
|
||||
#define SkFDot6Ceil(x) (((x) + 63) >> 6)
|
||||
#define SkFDot6Round(x) (((x) + 32) >> 6)
|
||||
|
||||
#define SkFixedToFDot6(x) ((x) >> 10)
|
||||
|
||||
inline SkFixed SkFDot6ToFixed(SkFDot6 x)
|
||||
{
|
||||
SkASSERT((x << 10 >> 10) == x);
|
||||
|
||||
return x << 10;
|
||||
}
|
||||
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#define SkScalarToFDot6(x) (SkFDot6)((x) * 64)
|
||||
#else
|
||||
#define SkScalarToFDot6(x) ((x) >> 10)
|
||||
#endif
|
||||
|
||||
inline SkFixed SkFDot6Div(SkFDot6 a, SkFDot6 b)
|
||||
{
|
||||
SkASSERT(b != 0);
|
||||
|
||||
if (a == (int16_t)a)
|
||||
return (a << 16) / b;
|
||||
else
|
||||
return SkFixedDiv(a, b);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkFixed_DEFINED
|
||||
#define SkFixed_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkFixed.h
|
||||
|
||||
Types and macros for 16.16 fixed point
|
||||
*/
|
||||
|
||||
/** 32 bit signed integer used to represent fractions values with 16 bits to the right of the decimal point
|
||||
*/
|
||||
typedef int32_t SkFixed;
|
||||
#define SK_Fixed1 (1 << 16)
|
||||
#define SK_FixedHalf (1 << 15)
|
||||
#define SK_FixedMax (0x7FFFFFFF)
|
||||
#define SK_FixedMin (0x1)
|
||||
#define SK_FixedNaN ((int) 0x80000000)
|
||||
#define SK_FixedPI (0x3243F)
|
||||
#define SK_FixedSqrt2 (92682)
|
||||
#define SK_FixedTanPIOver8 (0x6A0A)
|
||||
#define SK_FixedRoot2Over2 (0xB505)
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SkFixedToFloat(x) ((x) * 1.5258789e-5f)
|
||||
#define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
|
||||
#define SkFixedToDouble(x) ((x) * 1.5258789e-5)
|
||||
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
#endif
|
||||
|
||||
/** 32 bit signed integer used to represent fractions values with 30 bits to the right of the decimal point
|
||||
*/
|
||||
typedef int32_t SkFract;
|
||||
#define SK_Fract1 (1 << 30)
|
||||
#define Sk_FracHalf (1 << 29)
|
||||
#define SK_FractPIOver180 (0x11DF46A)
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SkFractToFloat(x) ((float)(x) * 0.00000000093132257f)
|
||||
#define SkFloatToFract(x) ((SkFract)((x) * SK_Fract1))
|
||||
#endif
|
||||
|
||||
/** Converts an integer to a SkFixed, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
*/
|
||||
#ifdef SK_DEBUG
|
||||
inline SkFixed SkIntToFixed(int n)
|
||||
{
|
||||
SkASSERT(n >= -32768 && n <= 32767);
|
||||
return n << 16;
|
||||
}
|
||||
#else
|
||||
// force the cast to SkFixed to ensure that the answer is signed (like the debug version)
|
||||
#define SkIntToFixed(n) (SkFixed)((n) << 16)
|
||||
#endif
|
||||
|
||||
/** Converts a SkFixed to a SkFract, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
*/
|
||||
#ifdef SK_DEBUG
|
||||
inline SkFract SkFixedToFract(SkFixed x)
|
||||
{
|
||||
SkASSERT(x >= (-2 << 16) && x <= (2 << 16) - 1);
|
||||
return x << 14;
|
||||
}
|
||||
#else
|
||||
#define SkFixedToFract(x) ((x) << 14)
|
||||
#endif
|
||||
|
||||
/** Returns the signed fraction of a SkFixed
|
||||
*/
|
||||
inline SkFixed SkFixedFraction(SkFixed x)
|
||||
{
|
||||
SkFixed mask = x >> 31 << 16;
|
||||
return (x & 0xFFFF) | mask;
|
||||
}
|
||||
|
||||
/** Converts a SkFract to a SkFixed
|
||||
*/
|
||||
#define SkFractToFixed(x) ((x) >> 14)
|
||||
/** Round a SkFixed to an integer
|
||||
*/
|
||||
#define SkFixedRound(x) (((x) + SK_FixedHalf) >> 16)
|
||||
#define SkFixedCeil(x) (((x) + SK_Fixed1 - 1) >> 16)
|
||||
#define SkFixedFloor(x) ((x) >> 16)
|
||||
#define SkFixedAbs(x) SkAbs32(x)
|
||||
#define SkFixedAve(a, b) (((a) + (b)) >> 1)
|
||||
|
||||
SkFixed SkFixedMul_portable(SkFixed, SkFixed);
|
||||
SkFract SkFractMul_portable(SkFract, SkFract);
|
||||
inline SkFixed SkFixedSquare_portable(SkFixed value)
|
||||
{
|
||||
uint32_t a = SkAbs32(value);
|
||||
uint32_t ah = a >> 16;
|
||||
uint32_t al = a & 0xFFFF;
|
||||
return ah * a + al * ah + (al * al >> 16);
|
||||
}
|
||||
|
||||
#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
|
||||
SkFixed SkFixedDivInt(int32_t numer, int32_t denom);
|
||||
SkFixed SkFixedMod(SkFixed numer, SkFixed denom);
|
||||
#define SkFixedInvert(n) SkDivBits(SK_Fixed1, n, 16)
|
||||
SkFixed SkFixedFastInvert(SkFixed n);
|
||||
#define SkFixedSqrt(n) SkSqrtBits(n, 23)
|
||||
SkFixed SkFixedMean(SkFixed a, SkFixed b); //*< returns sqrt(x*y)
|
||||
int SkFixedMulCommon(SkFixed, int , int bias); // internal used by SkFixedMulFloor, SkFixedMulCeil, SkFixedMulRound
|
||||
|
||||
#define SkFractDiv(numer, denom) SkDivBits(numer, denom, 30)
|
||||
#define SkFractSqrt(n) SkSqrtBits(n, 30)
|
||||
|
||||
SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull);
|
||||
#define SkFixedSin(radians) SkFixedSinCos(radians, NULL)
|
||||
inline SkFixed SkFixedCos(SkFixed radians)
|
||||
{
|
||||
SkFixed cosValue;
|
||||
(void)SkFixedSinCos(radians, &cosValue);
|
||||
return cosValue;
|
||||
}
|
||||
SkFixed SkFixedTan(SkFixed radians);
|
||||
SkFixed SkFixedASin(SkFixed);
|
||||
SkFixed SkFixedACos(SkFixed);
|
||||
SkFixed SkFixedATan2(SkFixed y, SkFixed x);
|
||||
SkFixed SkFixedExp(SkFixed);
|
||||
SkFixed SkFixedLog(SkFixed);
|
||||
|
||||
#define SK_FixedNearlyZero (SK_Fixed1 >> 12)
|
||||
|
||||
inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero)
|
||||
{
|
||||
SkASSERT(tolerance > 0);
|
||||
return SkAbs32(x) < tolerance;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Now look for ASM overrides for our portable versions (should consider putting this in its own file)
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b)
|
||||
{
|
||||
return (SkFixed)((SkLONGLONG)a * b >> 16);
|
||||
}
|
||||
inline SkFract SkFractMul_longlong(SkFract a, SkFract b)
|
||||
{
|
||||
return (SkFixed)((SkLONGLONG)a * b >> 30);
|
||||
}
|
||||
inline SkFixed SkFixedSquare_longlong(SkFixed value)
|
||||
{
|
||||
return (SkFixed)((SkLONGLONG)value * value >> 16);
|
||||
}
|
||||
#define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
|
||||
#define SkFractMul(a,b) SkFractMul_longlong(a,b)
|
||||
#define SkFixedSquare(a) SkFixedSquare_longlong(a)
|
||||
#endif
|
||||
|
||||
#if defined(__arm__) && !defined(__thumb__)
|
||||
/* This guy does not handle NaN or other obscurities, but is faster than
|
||||
than (int)(x*65536) when we only have software floats
|
||||
*/
|
||||
inline SkFixed SkFloatToFixed_arm(float x)
|
||||
{
|
||||
register int32_t y, z;
|
||||
asm("movs %1, %3, lsl #1 \n"
|
||||
"mov %2, #0x8E \n"
|
||||
"sub %1, %2, %1, lsr #24 \n"
|
||||
"mov %2, %3, lsl #8 \n"
|
||||
"orr %2, %2, #0x80000000 \n"
|
||||
"mov %1, %2, lsr %1 \n"
|
||||
"rsbcs %1, %1, #0 \n"
|
||||
: "=r"(x), "=&r"(y), "=&r"(z)
|
||||
: "r"(x)
|
||||
: "cc"
|
||||
);
|
||||
return y;
|
||||
}
|
||||
inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y)
|
||||
{
|
||||
register int32_t t;
|
||||
asm("smull %0, %2, %1, %3 \n"
|
||||
"mov %0, %0, lsr #16 \n"
|
||||
"orr %0, %0, %2, lsl #16 \n"
|
||||
: "=r"(x), "=&r"(y), "=r"(t)
|
||||
: "r"(x), "1"(y)
|
||||
:
|
||||
);
|
||||
return x;
|
||||
}
|
||||
inline SkFixed SkFixedMulAdd_arm(SkFixed x, SkFixed y, SkFixed a)
|
||||
{
|
||||
register int32_t t;
|
||||
asm("smull %0, %3, %1, %4 \n"
|
||||
"add %0, %2, %0, lsr #16 \n"
|
||||
"add %0, %0, %3, lsl #16 \n"
|
||||
: "=r"(x), "=&r"(y), "=&r"(a), "=r"(t)
|
||||
: "%r"(x), "1"(y), "2"(a)
|
||||
:
|
||||
);
|
||||
return x;
|
||||
}
|
||||
inline SkFixed SkFractMul_arm(SkFixed x, SkFixed y)
|
||||
{
|
||||
register int32_t t;
|
||||
asm("smull %0, %2, %1, %3 \n"
|
||||
"mov %0, %0, lsr #30 \n"
|
||||
"orr %0, %0, %2, lsl #2 \n"
|
||||
: "=r"(x), "=&r"(y), "=r"(t)
|
||||
: "r"(x), "1"(y)
|
||||
:
|
||||
);
|
||||
return x;
|
||||
}
|
||||
#undef SkFixedMul
|
||||
#undef SkFractMul
|
||||
#define SkFixedMul(x, y) SkFixedMul_arm(x, y)
|
||||
#define SkFractMul(x, y) SkFractMul_arm(x, y)
|
||||
#define SkFixedMulAdd(x, y, a) SkFixedMulAdd_arm(x, y, a)
|
||||
|
||||
#undef SkFloatToFixed
|
||||
#define SkFloatToFixed(x) SkFloatToFixed_arm(x)
|
||||
#endif
|
||||
|
||||
/////////////////////// Now define our macros to the portable versions if they weren't overridden
|
||||
|
||||
#ifndef SkFixedSquare
|
||||
#define SkFixedSquare(x) SkFixedSquare_portable(x)
|
||||
#endif
|
||||
#ifndef SkFixedMul
|
||||
#define SkFixedMul(x, y) SkFixedMul_portable(x, y)
|
||||
#endif
|
||||
#ifndef SkFractMul
|
||||
#define SkFractMul(x, y) SkFractMul_portable(x, y)
|
||||
#endif
|
||||
#ifndef SkFixedMulAdd
|
||||
#define SkFixedMulAdd(x, y, a) (SkFixedMul(x, y) + (a))
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkFlattenable_DEFINED
|
||||
#define SkFlattenable_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkReader32.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkWriter32.h"
|
||||
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
class SkString;
|
||||
|
||||
/** \class SkFlattenable
|
||||
|
||||
SkFlattenable is the base class for objects that need to be flattened
|
||||
into a data stream for either transport or as part of the key to the
|
||||
font cache.
|
||||
*/
|
||||
class SkFlattenable : public SkRefCnt {
|
||||
public:
|
||||
typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
|
||||
|
||||
SkFlattenable() {}
|
||||
|
||||
/** Implement this to return a factory function pointer that can be called
|
||||
to recreate your class given a buffer (previously written to by your
|
||||
override of flatten().
|
||||
*/
|
||||
virtual Factory getFactory() = 0;
|
||||
/** Override this to write data specific to your subclass into the buffer,
|
||||
being sure to call your super-class' version first. This data will later
|
||||
be passed to your Factory function, returned by getFactory().
|
||||
*/
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
/** Set the string to describe the sublass and return true. If this is not
|
||||
overridden, ignore the string param and return false.
|
||||
*/
|
||||
virtual bool toDumpString(SkString*) const;
|
||||
|
||||
static Factory NameToFactory(const char name[]);
|
||||
static const char* FactoryToName(Factory);
|
||||
static void Register(const char name[], Factory);
|
||||
|
||||
class Registrar {
|
||||
public:
|
||||
Registrar(const char name[], Factory factory) {
|
||||
SkFlattenable::Register(name, factory);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
SkFlattenable(SkFlattenableReadBuffer&) {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkTypeface;
|
||||
|
||||
class SkFlattenableReadBuffer : public SkReader32 {
|
||||
public:
|
||||
SkFlattenableReadBuffer();
|
||||
explicit SkFlattenableReadBuffer(const void* data);
|
||||
SkFlattenableReadBuffer(const void* data, size_t size);
|
||||
|
||||
void setRefCntArray(SkRefCnt* array[], int count) {
|
||||
fRCArray = array;
|
||||
fRCCount = count;
|
||||
}
|
||||
|
||||
void setTypefaceArray(SkTypeface* array[], int count) {
|
||||
fTFArray = array;
|
||||
fTFCount = count;
|
||||
}
|
||||
|
||||
void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
|
||||
fFactoryArray = array;
|
||||
fFactoryCount = count;
|
||||
}
|
||||
|
||||
SkTypeface* readTypeface();
|
||||
SkRefCnt* readRefCnt();
|
||||
void* readFunctionPtr();
|
||||
SkFlattenable* readFlattenable();
|
||||
|
||||
private:
|
||||
SkRefCnt** fRCArray;
|
||||
int fRCCount;
|
||||
|
||||
SkTypeface** fTFArray;
|
||||
int fTFCount;
|
||||
|
||||
SkFlattenable::Factory* fFactoryArray;
|
||||
int fFactoryCount;
|
||||
|
||||
typedef SkReader32 INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkPtrRecorder.h"
|
||||
|
||||
class SkRefCntRecorder : public SkPtrRecorder {
|
||||
public:
|
||||
virtual ~SkRefCntRecorder();
|
||||
|
||||
/** Add a refcnt object to the set and ref it if not already present,
|
||||
or if it is already present, do nothing. Either way, returns 0 if obj
|
||||
is null, or a base-1 index if obj is not null.
|
||||
*/
|
||||
uint32_t record(SkRefCnt* ref) {
|
||||
return this->recordPtr(ref);
|
||||
}
|
||||
|
||||
// This does not change the owner counts on the objects
|
||||
void get(SkRefCnt* array[]) const {
|
||||
this->getPtrs((void**)array);
|
||||
}
|
||||
|
||||
protected:
|
||||
// overrides
|
||||
virtual void incPtr(void*);
|
||||
virtual void decPtr(void*);
|
||||
|
||||
private:
|
||||
typedef SkPtrRecorder INHERITED;
|
||||
};
|
||||
|
||||
class SkFactoryRecorder : public SkPtrRecorder {
|
||||
public:
|
||||
/** Add a factory to the set. If it is null return 0, otherwise return a
|
||||
base-1 index for the factory.
|
||||
*/
|
||||
uint32_t record(SkFlattenable::Factory fact) {
|
||||
return this->recordPtr((void*)fact);
|
||||
}
|
||||
|
||||
void get(SkFlattenable::Factory array[]) const {
|
||||
this->getPtrs((void**)array);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef SkPtrRecorder INHERITED;
|
||||
};
|
||||
|
||||
class SkFlattenableWriteBuffer : public SkWriter32 {
|
||||
public:
|
||||
SkFlattenableWriteBuffer(size_t minSize);
|
||||
virtual ~SkFlattenableWriteBuffer();
|
||||
|
||||
void writeTypeface(SkTypeface*);
|
||||
void writeRefCnt(SkRefCnt*);
|
||||
void writeFunctionPtr(void*);
|
||||
void writeFlattenable(SkFlattenable* flattenable);
|
||||
|
||||
SkRefCntRecorder* getTypefaceRecorder() const { return fTFRecorder; }
|
||||
SkRefCntRecorder* setTypefaceRecorder(SkRefCntRecorder*);
|
||||
|
||||
SkRefCntRecorder* getRefCntRecorder() const { return fRCRecorder; }
|
||||
SkRefCntRecorder* setRefCntRecorder(SkRefCntRecorder*);
|
||||
|
||||
SkFactoryRecorder* getFactoryRecorder() const { return fFactoryRecorder; }
|
||||
SkFactoryRecorder* setFactoryRecorder(SkFactoryRecorder*);
|
||||
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 0x01
|
||||
};
|
||||
Flags getFlags() const { return fFlags; }
|
||||
void setFlags(Flags flags) { fFlags = flags; }
|
||||
|
||||
bool isCrossProcess() const { return (fFlags & kCrossProcess_Flag) != 0; }
|
||||
|
||||
bool persistBitmapPixels() const {
|
||||
return (fFlags & kCrossProcess_Flag) != 0;
|
||||
}
|
||||
|
||||
bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
|
||||
|
||||
private:
|
||||
Flags fFlags;
|
||||
SkRefCntRecorder* fTFRecorder;
|
||||
SkRefCntRecorder* fRCRecorder;
|
||||
SkFactoryRecorder* fFactoryRecorder;
|
||||
|
||||
typedef SkWriter32 INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkFloatBits_DEFINED
|
||||
#define SkFloatBits_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement
|
||||
int. This also converts -0 (0x80000000) to 0. Doing this to a float allows
|
||||
it to be compared using normal C operators (<, <=, etc.)
|
||||
*/
|
||||
static inline int32_t SkSignBitTo2sCompliment(int32_t x) {
|
||||
if (x < 0) {
|
||||
x &= 0x7FFFFFFF;
|
||||
x = -x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/** Convert a 2s compliment int to a sign-bit (i.e. int interpreted as float).
|
||||
This undoes the result of SkSignBitTo2sCompliment().
|
||||
*/
|
||||
static inline int32_t Sk2sComplimentToSignBit(int32_t x) {
|
||||
int sign = x >> 31;
|
||||
// make x positive
|
||||
x = (x ^ sign) - sign;
|
||||
// set the sign bit as needed
|
||||
x |= sign << 31;
|
||||
return x;
|
||||
}
|
||||
|
||||
/** Given the bit representation of a float, return its value cast to an int.
|
||||
If the value is out of range, or NaN, return return +/- SK_MaxS32
|
||||
*/
|
||||
int32_t SkFloatBits_toIntCast(int32_t floatBits);
|
||||
|
||||
/** Given the bit representation of a float, return its floor as an int.
|
||||
If the value is out of range, or NaN, return return +/- SK_MaxS32
|
||||
*/
|
||||
int32_t SkFloatBits_toIntFloor(int32_t floatBits);
|
||||
|
||||
/** Given the bit representation of a float, return it rounded to an int.
|
||||
If the value is out of range, or NaN, return return +/- SK_MaxS32
|
||||
*/
|
||||
int32_t SkFloatBits_toIntRound(int32_t floatBits);
|
||||
|
||||
/** Given the bit representation of a float, return its ceiling as an int.
|
||||
If the value is out of range, or NaN, return return +/- SK_MaxS32
|
||||
*/
|
||||
int32_t SkFloatBits_toIntCeil(int32_t floatBits);
|
||||
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
|
||||
union SkFloatIntUnion {
|
||||
float fFloat;
|
||||
int32_t fSignBitInt;
|
||||
};
|
||||
|
||||
// Helper to see a float as its bit pattern (w/o aliasing warnings)
|
||||
static inline int32_t SkFloat2Bits(float x) {
|
||||
SkFloatIntUnion data;
|
||||
data.fFloat = x;
|
||||
return data.fSignBitInt;
|
||||
}
|
||||
|
||||
// Helper to see a bit pattern as a float (w/o aliasing warnings)
|
||||
static inline float SkBits2Float(int32_t floatAsBits) {
|
||||
SkFloatIntUnion data;
|
||||
data.fSignBitInt = floatAsBits;
|
||||
return data.fFloat;
|
||||
}
|
||||
|
||||
/** Return the float as a 2s compliment int. Just to be used to compare floats
|
||||
to each other or against positive float-bit-constants (like 0). This does
|
||||
not return the int equivalent of the float, just something cheaper for
|
||||
compares-only.
|
||||
*/
|
||||
static inline int32_t SkFloatAs2sCompliment(float x) {
|
||||
return SkSignBitTo2sCompliment(SkFloat2Bits(x));
|
||||
}
|
||||
|
||||
/** Return the 2s compliment int as a float. This undos the result of
|
||||
SkFloatAs2sCompliment
|
||||
*/
|
||||
static inline float Sk2sComplimentAsFloat(int32_t x) {
|
||||
return SkBits2Float(Sk2sComplimentToSignBit(x));
|
||||
}
|
||||
|
||||
/** Return x cast to a float (i.e. (float)x)
|
||||
*/
|
||||
float SkIntToFloatCast(int x);
|
||||
float SkIntToFloatCast_NoOverflowCheck(int x);
|
||||
|
||||
/** Return the float cast to an int.
|
||||
If the value is out of range, or NaN, return +/- SK_MaxS32
|
||||
*/
|
||||
static inline int32_t SkFloatToIntCast(float x) {
|
||||
return SkFloatBits_toIntCast(SkFloat2Bits(x));
|
||||
}
|
||||
|
||||
/** Return the floor of the float as an int.
|
||||
If the value is out of range, or NaN, return +/- SK_MaxS32
|
||||
*/
|
||||
static inline int32_t SkFloatToIntFloor(float x) {
|
||||
return SkFloatBits_toIntFloor(SkFloat2Bits(x));
|
||||
}
|
||||
|
||||
/** Return the float rounded to an int.
|
||||
If the value is out of range, or NaN, return +/- SK_MaxS32
|
||||
*/
|
||||
static inline int32_t SkFloatToIntRound(float x) {
|
||||
return SkFloatBits_toIntRound(SkFloat2Bits(x));
|
||||
}
|
||||
|
||||
/** Return the ceiling of the float as an int.
|
||||
If the value is out of range, or NaN, return +/- SK_MaxS32
|
||||
*/
|
||||
static inline int32_t SkFloatToIntCeil(float x) {
|
||||
return SkFloatBits_toIntCeil(SkFloat2Bits(x));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Scalar wrappers for float-bit routines
|
||||
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x)
|
||||
#define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x)
|
||||
#else
|
||||
#define SkScalarAs2sCompliment(x) (x)
|
||||
#define Sk2sComplimentAsScalar(x) (x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkFloatingPoint_DEFINED
|
||||
#define SkFloatingPoint_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include "SkFloatBits.h"
|
||||
|
||||
#ifdef SK_BUILD_FOR_WINCE
|
||||
#define sk_float_sqrt(x) (float)::sqrt(x)
|
||||
#define sk_float_sin(x) (float)::sin(x)
|
||||
#define sk_float_cos(x) (float)::cos(x)
|
||||
#define sk_float_tan(x) (float)::tan(x)
|
||||
#define sk_float_acos(x) (float)::acos(x)
|
||||
#define sk_float_asin(x) (float)::asin(x)
|
||||
#define sk_float_atan2(y,x) (float)::atan2(y,x)
|
||||
#define sk_float_abs(x) (float)::fabs(x)
|
||||
#define sk_float_mod(x,y) (float)::fmod(x,y)
|
||||
#define sk_float_exp(x) (float)::exp(x)
|
||||
#define sk_float_log(x) (float)::log(x)
|
||||
#define sk_float_floor(x) (float)::floor(x)
|
||||
#define sk_float_ceil(x) (float)::ceil(x)
|
||||
#else
|
||||
#define sk_float_sqrt(x) sqrtf(x)
|
||||
#define sk_float_sin(x) sinf(x)
|
||||
#define sk_float_cos(x) cosf(x)
|
||||
#define sk_float_tan(x) tanf(x)
|
||||
#define sk_float_floor(x) floorf(x)
|
||||
#define sk_float_ceil(x) ceilf(x)
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
#define sk_float_acos(x) acos(x)
|
||||
#define sk_float_asin(x) asin(x)
|
||||
#else
|
||||
#define sk_float_acos(x) acosf(x)
|
||||
#define sk_float_asin(x) asinf(x)
|
||||
#endif
|
||||
#define sk_float_atan2(y,x) atan2f(y,x)
|
||||
#define sk_float_abs(x) fabsf(x)
|
||||
#define sk_float_mod(x,y) fmodf(x,y)
|
||||
#define sk_float_exp(x) expf(x)
|
||||
#define sk_float_log(x) logf(x)
|
||||
#define sk_float_isNaN(x) _isnan(x)
|
||||
#endif
|
||||
|
||||
#ifdef SK_USE_FLOATBITS
|
||||
#define sk_float_floor2int(x) SkFloatToIntFloor(x)
|
||||
#define sk_float_round2int(x) SkFloatToIntRound(x)
|
||||
#define sk_float_ceil2int(x) SkFloatToIntCeil(x)
|
||||
#else
|
||||
#define sk_float_floor2int(x) (int)sk_float_floor(x)
|
||||
#define sk_float_round2int(x) (int)sk_float_floor((x) + 0.5f)
|
||||
#define sk_float_ceil2int(x) (int)sk_float_ceil(x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkFontHost_DEFINED
|
||||
#define SkFontHost_DEFINED
|
||||
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
class SkDescriptor;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
/** \class SkFontHost
|
||||
|
||||
This class is ported to each environment. It is responsible for bridging the gap
|
||||
between SkTypeface and the resulting platform-specific instance of SkScalerContext.
|
||||
*/
|
||||
class SkFontHost {
|
||||
public:
|
||||
/** Return the closest matching typeface given either an existing family
|
||||
(specified by a typeface in that family) or by a familyName, and a
|
||||
requested style.
|
||||
1) If familyFace is null, use famillyName.
|
||||
2) If famillyName is null, use familyFace.
|
||||
3) If both are null, return the default font that best matches style
|
||||
|
||||
NOTE: this does not return a new typeface, nor does it affect the
|
||||
owner count of an existing one, so the caller is free to ignore the
|
||||
return result, or just compare it against null.
|
||||
*/
|
||||
static SkTypeface* FindTypeface(const SkTypeface* familyFace,
|
||||
const char famillyName[],
|
||||
SkTypeface::Style style);
|
||||
|
||||
/** Return the typeface associated with the uniqueID, or null if that ID
|
||||
does not match any faces.
|
||||
|
||||
NOTE: this does not return a new typeface, nor does it affect the
|
||||
owner count of an existing one, so the caller is free to ignore the
|
||||
return result, or just compare it against null.
|
||||
*/
|
||||
static SkTypeface* ResolveTypeface(uint32_t uniqueID);
|
||||
|
||||
/** Return a new stream to read the font data, or null if the uniqueID does
|
||||
not match an existing typeface. The caller must call CloseStream() when
|
||||
it is finished reading the stream.
|
||||
*/
|
||||
static SkStream* OpenStream(uint32_t uniqueID);
|
||||
|
||||
/** Call this when finished reading from the stream returned by OpenStream.
|
||||
The caller should NOT try to delete the stream.
|
||||
*/
|
||||
static void CloseStream(uint32_t uniqueID, SkStream*);
|
||||
|
||||
/** Return a new typeface given the data buffer (owned by the caller).
|
||||
If the data does not represent a valid font, return null. The caller is
|
||||
responsible for unref-ing the returned typeface (if it is not null).
|
||||
*/
|
||||
static SkTypeface* CreateTypeface(SkStream*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Write a unique identifier to the stream, so that the same typeface can
|
||||
be retrieved with Deserialize().
|
||||
*/
|
||||
static void Serialize(const SkTypeface*, SkWStream*);
|
||||
|
||||
/** Given a stream created by Serialize(), return the corresponding typeface
|
||||
or null if no match is found.
|
||||
|
||||
NOTE: this does not return a new typeface, nor does it affect the
|
||||
owner count of an existing one, so the caller is free to ignore the
|
||||
return result, or just compare it against null.
|
||||
*/
|
||||
static SkTypeface* Deserialize(SkStream*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Return a subclass of SkScalarContext
|
||||
*/
|
||||
static SkScalerContext* CreateScalerContext(const SkDescriptor* desc);
|
||||
|
||||
/** Return a scalercontext using the "fallback" font. If there is no designated
|
||||
fallback, return null.
|
||||
*/
|
||||
static SkScalerContext* CreateFallbackScalerContext(const SkScalerContext::Rec&);
|
||||
|
||||
/** Return the number of bytes (approx) that should be purged from the font
|
||||
cache. The input parameter is the cache's estimate of how much as been
|
||||
allocated by the cache so far.
|
||||
To purge (basically) everything, return the input parameter.
|
||||
To purge nothing, return 0
|
||||
*/
|
||||
static size_t ShouldPurgeFontCache(size_t sizeAllocatedSoFar);
|
||||
|
||||
/** Return SkScalerContext gamma flag, or 0, based on the paint that will be
|
||||
used to draw something with antialiasing.
|
||||
*/
|
||||
static int ComputeGammaFlag(const SkPaint& paint);
|
||||
|
||||
/** Return NULL or a pointer to 256 bytes for the black (table[0]) and
|
||||
white (table[1]) gamma tables.
|
||||
*/
|
||||
static void GetGammaTables(const uint8_t* tables[2]);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkGlobals_DEFINED
|
||||
#define SkGlobals_DEFINED
|
||||
|
||||
#include "SkThread.h"
|
||||
|
||||
class SkGlobals {
|
||||
public:
|
||||
class Rec {
|
||||
public:
|
||||
virtual ~Rec();
|
||||
private:
|
||||
Rec* fNext;
|
||||
uint32_t fTag;
|
||||
|
||||
friend class SkGlobals;
|
||||
};
|
||||
|
||||
/** Look for a matching Rec for the specified tag. If one is found, return it.
|
||||
If one is not found, if create_proc is null, return null, else
|
||||
call the proc, and if it returns a Rec, add it to the global list
|
||||
and return it.
|
||||
|
||||
create_proc can NOT call back into SkGlobals::Find (it would deadlock)
|
||||
*/
|
||||
static Rec* Find(uint32_t tag, Rec* (*create_proc)());
|
||||
/** Helper for Find, when you want to assert that the Rec is already in the list
|
||||
*/
|
||||
static Rec* Get(uint32_t tag)
|
||||
{
|
||||
Rec* rec = SkGlobals::Find(tag, NULL);
|
||||
SkASSERT(rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
// used by porting layer
|
||||
struct BootStrap {
|
||||
SkMutex fMutex;
|
||||
Rec* fHead;
|
||||
};
|
||||
|
||||
private:
|
||||
static void Init();
|
||||
static void Term();
|
||||
friend class SkGraphics;
|
||||
|
||||
// This last function is implemented in the porting layer
|
||||
static BootStrap& GetBootStrap();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkGraphics_DEFINED
|
||||
#define SkGraphics_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkGraphics {
|
||||
public:
|
||||
static void Init(bool runUnitTests);
|
||||
static void Term();
|
||||
|
||||
/** Return the (approximate) number of bytes used by the font cache.
|
||||
*/
|
||||
static size_t GetFontCacheUsed();
|
||||
|
||||
/** Attempt to purge the font cache until <= the specified amount remains
|
||||
in the cache. Specifying 0 will attempt to purge the entire cache.
|
||||
Returns true if some amount was purged from the font cache.
|
||||
*/
|
||||
static bool SetFontCacheUsed(size_t usageInBytes);
|
||||
|
||||
private:
|
||||
/** This is automatically called by SkGraphics::Init(), and must be
|
||||
implemented by the host OS. This allows the host OS to register a callback
|
||||
with the C++ runtime to call SkGraphics::FreeCaches()
|
||||
*/
|
||||
static void InstallNewHandler();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkMMapStream_DEFINED
|
||||
#define SkMMapStream_DEFINED
|
||||
|
||||
#include "SkStream.h"
|
||||
|
||||
class SkMMAPStream : public SkMemoryStream {
|
||||
public:
|
||||
SkMMAPStream(const char filename[]);
|
||||
virtual ~SkMMAPStream();
|
||||
|
||||
virtual void setMemory(const void* data, size_t length);
|
||||
private:
|
||||
int fFildes;
|
||||
void* fAddr;
|
||||
size_t fSize;
|
||||
|
||||
void closeMMap();
|
||||
|
||||
typedef SkMemoryStream INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkMallocPixelRef_DEFINED
|
||||
#define SkMallocPixelRef_DEFINED
|
||||
|
||||
#include "SkPixelRef.h"
|
||||
|
||||
/** We explicitly use the same allocator for our pixels that SkMask does,
|
||||
so that we can freely assign memory allocated by one class to the other.
|
||||
*/
|
||||
class SkMallocPixelRef : public SkPixelRef {
|
||||
public:
|
||||
/** Allocate the specified buffer for pixels. The memory is freed when the
|
||||
last owner of this pixelref is gone.
|
||||
*/
|
||||
SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable);
|
||||
virtual ~SkMallocPixelRef();
|
||||
|
||||
//! Return the allocation size for the pixels
|
||||
size_t getSize() const { return fSize; }
|
||||
|
||||
// overrides from SkPixelRef
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const;
|
||||
virtual Factory getFactory() const {
|
||||
return Create;
|
||||
}
|
||||
static SkPixelRef* Create(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkMallocPixelRef, (buffer));
|
||||
}
|
||||
|
||||
protected:
|
||||
// overrides from SkPixelRef
|
||||
virtual void* onLockPixels(SkColorTable**);
|
||||
virtual void onUnlockPixels();
|
||||
|
||||
SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
|
||||
|
||||
private:
|
||||
void* fStorage;
|
||||
size_t fSize;
|
||||
SkColorTable* fCTable;
|
||||
|
||||
typedef SkPixelRef INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkMask_DEFINED
|
||||
#define SkMask_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
/** \class SkMask
|
||||
SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
|
||||
the 3-channel 3D format. These are passed to SkMaskFilter objects.
|
||||
*/
|
||||
struct SkMask {
|
||||
enum Format {
|
||||
kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
|
||||
kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
|
||||
k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
|
||||
kLCD_Format //!< 3 bytes/pixel: r/g/b
|
||||
};
|
||||
|
||||
enum {
|
||||
kCountMaskFormats = kLCD_Format + 1
|
||||
};
|
||||
|
||||
uint8_t* fImage;
|
||||
SkIRect fBounds;
|
||||
uint16_t fRowBytes;
|
||||
uint8_t fFormat; // Format
|
||||
|
||||
/** Return the byte size of the mask, assuming only 1 plane.
|
||||
Does not account for k3D_Format. For that, use computeFormatImageSize()
|
||||
*/
|
||||
size_t computeImageSize() const;
|
||||
/** Return the byte size of the mask, taking into account
|
||||
any extra planes (e.g. k3D_Format).
|
||||
*/
|
||||
size_t computeTotalImageSize() const;
|
||||
|
||||
/** Returns the address of the byte that holds the specified bit.
|
||||
Asserts that the mask is kBW_Format, and that x,y are in range.
|
||||
x,y are in the same coordiate space as fBounds.
|
||||
*/
|
||||
uint8_t* getAddr1(int x, int y) const
|
||||
{
|
||||
SkASSERT(fFormat == kBW_Format);
|
||||
SkASSERT(fBounds.contains(x, y));
|
||||
SkASSERT(fImage != NULL);
|
||||
return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
|
||||
}
|
||||
/** Returns the address of the specified byte.
|
||||
Asserts that the mask is kA8_Format, and that x,y are in range.
|
||||
x,y are in the same coordiate space as fBounds.
|
||||
*/
|
||||
uint8_t* getAddr(int x, int y) const
|
||||
{
|
||||
SkASSERT(fFormat != kBW_Format);
|
||||
SkASSERT(fBounds.contains(x, y));
|
||||
SkASSERT(fImage != NULL);
|
||||
return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
|
||||
}
|
||||
|
||||
static uint8_t* AllocImage(size_t bytes);
|
||||
static void FreeImage(void* image);
|
||||
|
||||
enum CreateMode {
|
||||
kJustComputeBounds_CreateMode, //!< compute bounds and return
|
||||
kJustRenderImage_CreateMode, //!< render into preallocate mask
|
||||
kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkMaskFilter_DEFINED
|
||||
#define SkMaskFilter_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkMask.h"
|
||||
|
||||
class SkBlitter;
|
||||
class SkBounder;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkRegion;
|
||||
|
||||
/** \class SkMaskFilter
|
||||
|
||||
SkMaskFilter is the base class for object that perform transformations on
|
||||
an alpha-channel mask before drawing it. A subclass of SkMaskFilter may be
|
||||
installed into a SkPaint. Once there, each time a primitive is drawn, it
|
||||
is first scan converted into a SkMask::kA8_Format mask, and handed to the
|
||||
filter, calling its filterMask() method. If this returns true, then the
|
||||
new mask is used to render into the device.
|
||||
|
||||
Blur and emboss are implemented as subclasses of SkMaskFilter.
|
||||
*/
|
||||
class SkMaskFilter : public SkFlattenable {
|
||||
public:
|
||||
SkMaskFilter() {}
|
||||
|
||||
/** Returns the format of the resulting mask that this subclass will return
|
||||
when its filterMask() method is called.
|
||||
*/
|
||||
virtual SkMask::Format getFormat() = 0;
|
||||
|
||||
/** Create a new mask by filter the src mask.
|
||||
If src.fImage == null, then do not allocate or create the dst image
|
||||
but do fill out the other fields in dstMask.
|
||||
If you do allocate a dst image, use SkMask::AllocImage()
|
||||
If this returns false, dst mask is ignored.
|
||||
@param dst the result of the filter. If src.fImage == null, dst should not allocate its image
|
||||
@param src the original image to be filtered.
|
||||
@param matrix the CTM
|
||||
@param margin if not null, return the buffer dx/dy need when calculating the effect. Used when
|
||||
drawing a clipped object to know how much larger to allocate the src before
|
||||
applying the filter. If returning false, ignore this parameter.
|
||||
@return true if the dst mask was correctly created.
|
||||
*/
|
||||
virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, SkIPoint* margin);
|
||||
|
||||
/** Helper method that, given a path in device space, will rasterize it into a kA8_Format mask
|
||||
and then call filterMask(). If this returns true, the specified blitter will be called
|
||||
to render that mask. Returns false if filterMask() returned false.
|
||||
This method is not exported to java.
|
||||
*/
|
||||
bool filterPath(const SkPath& devPath, const SkMatrix& devMatrix,
|
||||
const SkRegion& devClip, SkBounder*, SkBlitter* blitter);
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer& ) {}
|
||||
protected:
|
||||
// empty for now, but lets get our subclass to remember to init us for the future
|
||||
SkMaskFilter(SkFlattenableReadBuffer&) {}
|
||||
};
|
||||
|
||||
/** \class SkAutoMaskImage
|
||||
|
||||
Stack class used to manage the fImage buffer in a SkMask.
|
||||
When this object loses scope, the buffer is freed with SkMask::FreeImage().
|
||||
*/
|
||||
class SkAutoMaskImage {
|
||||
public:
|
||||
SkAutoMaskImage(SkMask* mask, bool alloc)
|
||||
{
|
||||
if (alloc)
|
||||
mask->fImage = SkMask::AllocImage(mask->computeImageSize());
|
||||
fImage = mask->fImage;
|
||||
}
|
||||
~SkAutoMaskImage()
|
||||
{
|
||||
SkMask::FreeImage(fImage);
|
||||
}
|
||||
private:
|
||||
uint8_t* fImage;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkMath_DEFINED
|
||||
#define SkMath_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
//! Returns the number of leading zero bits (0...32)
|
||||
int SkCLZ_portable(uint32_t);
|
||||
|
||||
/** Computes the 64bit product of a * b, and then shifts the answer down by
|
||||
shift bits, returning the low 32bits. shift must be [0..63]
|
||||
e.g. to perform a fixedmul, call SkMulShift(a, b, 16)
|
||||
*/
|
||||
int32_t SkMulShift(int32_t a, int32_t b, unsigned shift);
|
||||
|
||||
/** Computes numer1 * numer2 / denom in full 64 intermediate precision.
|
||||
It is an error for denom to be 0. There is no special handling if
|
||||
the result overflows 32bits.
|
||||
*/
|
||||
int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
|
||||
|
||||
/** Computes (numer1 << shift) / denom in full 64 intermediate precision.
|
||||
It is an error for denom to be 0. There is no special handling if
|
||||
the result overflows 32bits.
|
||||
*/
|
||||
int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
|
||||
|
||||
/** Return the integer square root of value, with a bias of bitBias
|
||||
*/
|
||||
int32_t SkSqrtBits(int32_t value, int bitBias);
|
||||
|
||||
/** Return the integer square root of n, treated as a SkFixed (16.16)
|
||||
*/
|
||||
#define SkSqrt32(n) SkSqrtBits(n, 15)
|
||||
|
||||
/** Return the integer cube root of value, with a bias of bitBias
|
||||
*/
|
||||
int32_t SkCubeRootBits(int32_t value, int bitBias);
|
||||
|
||||
/** Returns -1 if n < 0, else returns 0
|
||||
*/
|
||||
#define SkExtractSign(n) ((int32_t)(n) >> 31)
|
||||
|
||||
/** If sign == -1, returns -n, else sign must be 0, and returns n.
|
||||
Typically used in conjunction with SkExtractSign().
|
||||
*/
|
||||
static inline int32_t SkApplySign(int32_t n, int32_t sign) {
|
||||
SkASSERT(sign == 0 || sign == -1);
|
||||
return (n ^ sign) - sign;
|
||||
}
|
||||
|
||||
/** Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
|
||||
*/
|
||||
static inline int SkClampPos(int value) {
|
||||
return value & ~(value >> 31);
|
||||
}
|
||||
|
||||
/** Given an integer and a positive (max) integer, return the value
|
||||
pinned against 0 and max, inclusive.
|
||||
Note: only works as long as max - value doesn't wrap around
|
||||
@param value The value we want returned pinned between [0...max]
|
||||
@param max The positive max value
|
||||
@return 0 if value < 0, max if value > max, else value
|
||||
*/
|
||||
static inline int SkClampMax(int value, int max) {
|
||||
// ensure that max is positive
|
||||
SkASSERT(max >= 0);
|
||||
// ensure that if value is negative, max - value doesn't wrap around
|
||||
SkASSERT(value >= 0 || max - value > 0);
|
||||
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
}
|
||||
if (value > max) {
|
||||
value = max;
|
||||
}
|
||||
return value;
|
||||
#else
|
||||
|
||||
int diff = max - value;
|
||||
// clear diff if diff is positive
|
||||
diff &= diff >> 31;
|
||||
|
||||
// clear the result if value < 0
|
||||
return (value + diff) & ~(value >> 31);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Given a positive value and a positive max, return the value
|
||||
pinned against max.
|
||||
Note: only works as long as max - value doesn't wrap around
|
||||
@return max if value >= max, else value
|
||||
*/
|
||||
static inline unsigned SkClampUMax(unsigned value, unsigned max) {
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value > max) {
|
||||
value = max;
|
||||
}
|
||||
return value;
|
||||
#else
|
||||
int diff = max - value;
|
||||
// clear diff if diff is positive
|
||||
diff &= diff >> 31;
|
||||
|
||||
return value + diff;
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__arm__) && !defined(__thumb__)
|
||||
#define SkCLZ(x) __builtin_clz(x)
|
||||
#endif
|
||||
|
||||
#ifndef SkCLZ
|
||||
#define SkCLZ(x) SkCLZ_portable(x)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Returns the smallest power-of-2 that is >= the specified value. If value
|
||||
is already a power of 2, then it is returned unchanged. It is undefined
|
||||
if value is <= 0.
|
||||
*/
|
||||
static inline int SkNextPow2(int value) {
|
||||
SkASSERT(value > 0);
|
||||
return 1 << (32 - SkCLZ(value - 1));
|
||||
}
|
||||
|
||||
/** Returns the log2 of the specified value, were that value to be rounded up
|
||||
to the next power of 2. It is undefined to pass 0. Examples:
|
||||
SkNextLog2(1) -> 0
|
||||
SkNextLog2(2) -> 1
|
||||
SkNextLog2(3) -> 2
|
||||
SkNextLog2(4) -> 2
|
||||
SkNextLog2(5) -> 3
|
||||
*/
|
||||
static inline int SkNextLog2(uint32_t value) {
|
||||
SkASSERT(value != 0);
|
||||
return 32 - SkCLZ(value - 1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
|
||||
With this requirement, we can generate faster instructions on some
|
||||
architectures.
|
||||
*/
|
||||
#if defined(__arm__) && !defined(__thumb__)
|
||||
static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
|
||||
SkASSERT((int16_t)x == x);
|
||||
SkASSERT((int16_t)y == y);
|
||||
int32_t product;
|
||||
asm("smulbb %0, %1, %2 \n"
|
||||
: "=r"(product)
|
||||
: "r"(x), "r"(y)
|
||||
:
|
||||
);
|
||||
return product;
|
||||
}
|
||||
#else
|
||||
#ifdef SK_DEBUG
|
||||
static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
|
||||
SkASSERT((int16_t)x == x);
|
||||
SkASSERT((int16_t)y == y);
|
||||
return x * y;
|
||||
}
|
||||
#else
|
||||
#define SkMulS16(x, y) ((x) * (y))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Return a*b/255, truncating away any fractional bits. Only valid if both
|
||||
a and b are 0..255
|
||||
*/
|
||||
static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
|
||||
SkASSERT((uint8_t)a == a);
|
||||
SkASSERT((uint8_t)b == b);
|
||||
unsigned prod = SkMulS16(a, b) + 1;
|
||||
return (prod + (prod >> 8)) >> 8;
|
||||
}
|
||||
|
||||
/** Return a*b/255, rounding any fractional bits. Only valid if both
|
||||
a and b are 0..255
|
||||
*/
|
||||
static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
|
||||
SkASSERT((uint8_t)a == a);
|
||||
SkASSERT((uint8_t)b == b);
|
||||
unsigned prod = SkMulS16(a, b) + 128;
|
||||
return (prod + (prod >> 8)) >> 8;
|
||||
}
|
||||
|
||||
/** Return a*b/((1 << shift) - 1), rounding any fractional bits.
|
||||
Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
|
||||
*/
|
||||
static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
|
||||
SkASSERT(a <= 32767);
|
||||
SkASSERT(b <= 32767);
|
||||
SkASSERT(shift > 0 && shift <= 8);
|
||||
unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
|
||||
return (prod + (prod >> shift)) >> shift;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
class SkMath {
|
||||
public:
|
||||
static void UnitTest();
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkMatrix_DEFINED
|
||||
#define SkMatrix_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkString;
|
||||
|
||||
/** \class SkMatrix
|
||||
|
||||
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
|
||||
SkMatrix does not have a constructor, so it must be explicitly initialized
|
||||
using either reset() - to construct an identity matrix, or one of the set
|
||||
functions (e.g. setTranslate, setRotate, etc.).
|
||||
*/
|
||||
class SkMatrix {
|
||||
public:
|
||||
/** Enum of bit fields for the mask return by getType().
|
||||
Use this to identify the complexity of the matrix.
|
||||
*/
|
||||
enum TypeMask {
|
||||
kIdentity_Mask = 0,
|
||||
kTranslate_Mask = 0x01, //!< set if the matrix has translation
|
||||
kScale_Mask = 0x02, //!< set if the matrix has X or Y scale
|
||||
kAffine_Mask = 0x04, //!< set if the matrix skews or rotates
|
||||
kPerspective_Mask = 0x08 //!< set if the matrix is in perspective
|
||||
};
|
||||
|
||||
/** Returns a mask bitfield describing the types of transformations
|
||||
that the matrix will perform. This information is used by routines
|
||||
like mapPoints, to optimize its inner loops to only perform as much
|
||||
arithmetic as is necessary.
|
||||
*/
|
||||
TypeMask getType() const {
|
||||
if (fTypeMask & kUnknown_Mask) {
|
||||
fTypeMask = this->computeTypeMask();
|
||||
}
|
||||
// only return the public masks
|
||||
return (TypeMask)(fTypeMask & 0xF);
|
||||
}
|
||||
|
||||
/** Returns true if the matrix is identity.
|
||||
*/
|
||||
bool isIdentity() const {
|
||||
return this->getType() == 0;
|
||||
}
|
||||
|
||||
/** Returns true if will map a rectangle to another rectangle. This can be
|
||||
true if the matrix is identity, scale-only, or rotates a multiple of
|
||||
90 degrees.
|
||||
*/
|
||||
bool rectStaysRect() const {
|
||||
if (fTypeMask & kUnknown_Mask) {
|
||||
fTypeMask = this->computeTypeMask();
|
||||
}
|
||||
return (fTypeMask & kRectStaysRect_Mask) != 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
kMScaleX,
|
||||
kMSkewX,
|
||||
kMTransX,
|
||||
kMSkewY,
|
||||
kMScaleY,
|
||||
kMTransY,
|
||||
kMPersp0,
|
||||
kMPersp1,
|
||||
kMPersp2
|
||||
};
|
||||
|
||||
SkScalar operator[](int index) const {
|
||||
SkASSERT((unsigned)index < 9);
|
||||
return fMat[index];
|
||||
}
|
||||
|
||||
SkScalar get(int index) const {
|
||||
SkASSERT((unsigned)index < 9);
|
||||
return fMat[index];
|
||||
}
|
||||
|
||||
SkScalar getScaleX() const { return fMat[kMScaleX]; }
|
||||
SkScalar getScaleY() const { return fMat[kMScaleY]; }
|
||||
SkScalar getSkewY() const { return fMat[kMSkewY]; }
|
||||
SkScalar getSkewX() const { return fMat[kMSkewX]; }
|
||||
SkScalar getTranslateX() const { return fMat[kMTransX]; }
|
||||
SkScalar getTranslateY() const { return fMat[kMTransY]; }
|
||||
SkScalar getPerspX() const { return fMat[kMPersp0]; }
|
||||
SkScalar getPerspY() const { return fMat[kMPersp1]; }
|
||||
|
||||
void set(int index, SkScalar value) {
|
||||
SkASSERT((unsigned)index < 9);
|
||||
fMat[index] = value;
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
}
|
||||
|
||||
void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
|
||||
void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
|
||||
void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
|
||||
void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
|
||||
void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
|
||||
void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
|
||||
void setPerspX(SkScalar v) { this->set(kMPersp0, v); }
|
||||
void setPerspY(SkScalar v) { this->set(kMPersp1, v); }
|
||||
|
||||
/** Set the matrix to identity
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Set the matrix to translate by (dx, dy).
|
||||
*/
|
||||
void setTranslate(SkScalar dx, SkScalar dy);
|
||||
/** Set the matrix to scale by sx and sy, with a pivot point at (px, py).
|
||||
The pivot point is the coordinate that should remain unchanged by the
|
||||
specified transformation.
|
||||
*/
|
||||
void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
|
||||
/** Set the matrix to scale by sx and sy.
|
||||
*/
|
||||
void setScale(SkScalar sx, SkScalar sy);
|
||||
/** Set the matrix to rotate by the specified number of degrees, with a
|
||||
pivot point at (px, py). The pivot point is the coordinate that should
|
||||
remain unchanged by the specified transformation.
|
||||
*/
|
||||
void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
|
||||
/** Set the matrix to rotate about (0,0) by the specified number of degrees.
|
||||
*/
|
||||
void setRotate(SkScalar degrees);
|
||||
/** Set the matrix to rotate by the specified sine and cosine values, with
|
||||
a pivot point at (px, py). The pivot point is the coordinate that
|
||||
should remain unchanged by the specified transformation.
|
||||
*/
|
||||
void setSinCos(SkScalar sinValue, SkScalar cosValue,
|
||||
SkScalar px, SkScalar py);
|
||||
/** Set the matrix to rotate by the specified sine and cosine values.
|
||||
*/
|
||||
void setSinCos(SkScalar sinValue, SkScalar cosValue);
|
||||
/** Set the matrix to skew by sx and sy, with a pivot point at (px, py).
|
||||
The pivot point is the coordinate that should remain unchanged by the
|
||||
specified transformation.
|
||||
*/
|
||||
void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
|
||||
/** Set the matrix to skew by sx and sy.
|
||||
*/
|
||||
void setSkew(SkScalar kx, SkScalar ky);
|
||||
/** Set the matrix to the concatenation of the two specified matrices,
|
||||
returning true if the the result can be represented. Either of the
|
||||
two matrices may also be the target matrix. *this = a * b;
|
||||
*/
|
||||
bool setConcat(const SkMatrix& a, const SkMatrix& b);
|
||||
|
||||
/** Preconcats the matrix with the specified translation.
|
||||
M' = M * T(dx, dy)
|
||||
*/
|
||||
bool preTranslate(SkScalar dx, SkScalar dy);
|
||||
/** Preconcats the matrix with the specified scale.
|
||||
M' = M * S(sx, sy, px, py)
|
||||
*/
|
||||
bool preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
|
||||
/** Preconcats the matrix with the specified scale.
|
||||
M' = M * S(sx, sy)
|
||||
*/
|
||||
bool preScale(SkScalar sx, SkScalar sy);
|
||||
/** Preconcats the matrix with the specified rotation.
|
||||
M' = M * R(degrees, px, py)
|
||||
*/
|
||||
bool preRotate(SkScalar degrees, SkScalar px, SkScalar py);
|
||||
/** Preconcats the matrix with the specified rotation.
|
||||
M' = M * R(degrees)
|
||||
*/
|
||||
bool preRotate(SkScalar degrees);
|
||||
/** Preconcats the matrix with the specified skew.
|
||||
M' = M * K(kx, ky, px, py)
|
||||
*/
|
||||
bool preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
|
||||
/** Preconcats the matrix with the specified skew.
|
||||
M' = M * K(kx, ky)
|
||||
*/
|
||||
bool preSkew(SkScalar kx, SkScalar ky);
|
||||
/** Preconcats the matrix with the specified matrix.
|
||||
M' = M * other
|
||||
*/
|
||||
bool preConcat(const SkMatrix& other);
|
||||
|
||||
/** Postconcats the matrix with the specified translation.
|
||||
M' = T(dx, dy) * M
|
||||
*/
|
||||
bool postTranslate(SkScalar dx, SkScalar dy);
|
||||
/** Postconcats the matrix with the specified scale.
|
||||
M' = S(sx, sy, px, py) * M
|
||||
*/
|
||||
bool postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
|
||||
/** Postconcats the matrix with the specified scale.
|
||||
M' = S(sx, sy) * M
|
||||
*/
|
||||
bool postScale(SkScalar sx, SkScalar sy);
|
||||
/** Postconcats the matrix by dividing it by the specified integers.
|
||||
M' = S(1/divx, 1/divy, 0, 0) * M
|
||||
*/
|
||||
bool postIDiv(int divx, int divy);
|
||||
/** Postconcats the matrix with the specified rotation.
|
||||
M' = R(degrees, px, py) * M
|
||||
*/
|
||||
bool postRotate(SkScalar degrees, SkScalar px, SkScalar py);
|
||||
/** Postconcats the matrix with the specified rotation.
|
||||
M' = R(degrees) * M
|
||||
*/
|
||||
bool postRotate(SkScalar degrees);
|
||||
/** Postconcats the matrix with the specified skew.
|
||||
M' = K(kx, ky, px, py) * M
|
||||
*/
|
||||
bool postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
|
||||
/** Postconcats the matrix with the specified skew.
|
||||
M' = K(kx, ky) * M
|
||||
*/
|
||||
bool postSkew(SkScalar kx, SkScalar ky);
|
||||
/** Postconcats the matrix with the specified matrix.
|
||||
M' = other * M
|
||||
*/
|
||||
bool postConcat(const SkMatrix& other);
|
||||
|
||||
enum ScaleToFit {
|
||||
/**
|
||||
* Scale in X and Y independently, so that src matches dst exactly.
|
||||
* This may change the aspect ratio of the src.
|
||||
*/
|
||||
kFill_ScaleToFit,
|
||||
/**
|
||||
* Compute a scale that will maintain the original src aspect ratio,
|
||||
* but will also ensure that src fits entirely inside dst. At least one
|
||||
* axis (X or Y) will fit exactly. kStart aligns the result to the
|
||||
* left and top edges of dst.
|
||||
*/
|
||||
kStart_ScaleToFit,
|
||||
/**
|
||||
* Compute a scale that will maintain the original src aspect ratio,
|
||||
* but will also ensure that src fits entirely inside dst. At least one
|
||||
* axis (X or Y) will fit exactly. The result is centered inside dst.
|
||||
*/
|
||||
kCenter_ScaleToFit,
|
||||
/**
|
||||
* Compute a scale that will maintain the original src aspect ratio,
|
||||
* but will also ensure that src fits entirely inside dst. At least one
|
||||
* axis (X or Y) will fit exactly. kEnd aligns the result to the
|
||||
* right and bottom edges of dst.
|
||||
*/
|
||||
kEnd_ScaleToFit
|
||||
};
|
||||
|
||||
/** Set the matrix to the scale and translate values that map the source
|
||||
rectangle to the destination rectangle, returning true if the the result
|
||||
can be represented.
|
||||
@param src the source rectangle to map from.
|
||||
@param dst the destination rectangle to map to.
|
||||
@param stf the ScaleToFit option
|
||||
@return true if the matrix can be represented by the rectangle mapping.
|
||||
*/
|
||||
bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf);
|
||||
|
||||
/** Set the matrix such that the specified src points would map to the
|
||||
specified dst points. count must be within [0..4].
|
||||
@param src The array of src points
|
||||
@param dst The array of dst points
|
||||
@param count The number of points to use for the transformation
|
||||
@return true if the matrix was set to the specified transformation
|
||||
*/
|
||||
bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count);
|
||||
|
||||
/** If this matrix can be inverted, return true and if inverse is not null,
|
||||
set inverse to be the inverse of this matrix. If this matrix cannot be
|
||||
inverted, ignore inverse and return false
|
||||
*/
|
||||
bool invert(SkMatrix* inverse) const;
|
||||
|
||||
/** Apply this matrix to the array of points specified by src, and write
|
||||
the transformed points into the array of points specified by dst.
|
||||
dst[] = M * src[]
|
||||
@param dst Where the transformed coordinates are written. It must
|
||||
contain at least count entries
|
||||
@param src The original coordinates that are to be transformed. It
|
||||
must contain at least count entries
|
||||
@param count The number of points in src to read, and then transform
|
||||
into dst.
|
||||
*/
|
||||
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const;
|
||||
|
||||
/** Apply this matrix to the array of points, overwriting it with the
|
||||
transformed values.
|
||||
dst[] = M * pts[]
|
||||
@param pts The points to be transformed. It must contain at least
|
||||
count entries
|
||||
@param count The number of points in pts.
|
||||
*/
|
||||
void mapPoints(SkPoint pts[], int count) const {
|
||||
this->mapPoints(pts, pts, count);
|
||||
}
|
||||
|
||||
void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
|
||||
SkASSERT(result);
|
||||
this->getMapXYProc()(*this, x, y, result);
|
||||
}
|
||||
|
||||
/** Apply this matrix to the array of vectors specified by src, and write
|
||||
the transformed vectors into the array of vectors specified by dst.
|
||||
This is similar to mapPoints, but ignores any translation in the matrix.
|
||||
@param dst Where the transformed coordinates are written. It must
|
||||
contain at least count entries
|
||||
@param src The original coordinates that are to be transformed. It
|
||||
must contain at least count entries
|
||||
@param count The number of vectors in src to read, and then transform
|
||||
into dst.
|
||||
*/
|
||||
void mapVectors(SkVector dst[], const SkVector src[], int count) const;
|
||||
|
||||
/** Apply this matrix to the array of vectors specified by src, and write
|
||||
the transformed vectors into the array of vectors specified by dst.
|
||||
This is similar to mapPoints, but ignores any translation in the matrix.
|
||||
@param vecs The vectors to be transformed. It must contain at least
|
||||
count entries
|
||||
@param count The number of vectors in vecs.
|
||||
*/
|
||||
void mapVectors(SkVector vecs[], int count) const {
|
||||
this->mapVectors(vecs, vecs, count);
|
||||
}
|
||||
|
||||
/** Apply this matrix to the src rectangle, and write the transformed
|
||||
rectangle into dst. This is accomplished by transforming the 4 corners
|
||||
of src, and then setting dst to the bounds of those points.
|
||||
@param dst Where the transformed rectangle is written.
|
||||
@param src The original rectangle to be transformed.
|
||||
@return the result of calling rectStaysRect()
|
||||
*/
|
||||
bool mapRect(SkRect* dst, const SkRect& src) const;
|
||||
|
||||
/** Apply this matrix to the rectangle, and write the transformed rectangle
|
||||
back into it. This is accomplished by transforming the 4 corners of
|
||||
rect, and then setting it to the bounds of those points
|
||||
@param rect The rectangle to transform.
|
||||
@return the result of calling rectStaysRect()
|
||||
*/
|
||||
bool mapRect(SkRect* rect) const {
|
||||
return this->mapRect(rect, *rect);
|
||||
}
|
||||
|
||||
/** Return the mean radius of a circle after it has been mapped by
|
||||
this matrix. NOTE: in perspective this value assumes the circle
|
||||
has its center at the origin.
|
||||
*/
|
||||
SkScalar mapRadius(SkScalar radius) const;
|
||||
|
||||
typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y,
|
||||
SkPoint* result);
|
||||
|
||||
static MapXYProc GetMapXYProc(TypeMask mask) {
|
||||
SkASSERT((mask & ~kAllMasks) == 0);
|
||||
return gMapXYProcs[mask & kAllMasks];
|
||||
}
|
||||
|
||||
MapXYProc getMapXYProc() const {
|
||||
return GetMapXYProc(this->getType());
|
||||
}
|
||||
|
||||
typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[],
|
||||
const SkPoint src[], int count);
|
||||
|
||||
static MapPtsProc GetMapPtsProc(TypeMask mask) {
|
||||
SkASSERT((mask & ~kAllMasks) == 0);
|
||||
return gMapPtsProcs[mask & kAllMasks];
|
||||
}
|
||||
|
||||
MapPtsProc getMapPtsProc() const {
|
||||
return GetMapPtsProc(this->getType());
|
||||
}
|
||||
|
||||
/** If the matrix can be stepped in X (not complex perspective)
|
||||
then return true and if step[XY] is not null, return the step[XY] value.
|
||||
If it cannot, return false and ignore step.
|
||||
*/
|
||||
bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;
|
||||
|
||||
friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
|
||||
return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) == 0;
|
||||
}
|
||||
|
||||
friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
|
||||
return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
|
||||
}
|
||||
|
||||
void dump() const;
|
||||
void toDumpString(SkString*) const;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** @cond UNIT_TEST */
|
||||
|
||||
static void UnitTest();
|
||||
/** @endcond */
|
||||
#endif
|
||||
|
||||
private:
|
||||
enum {
|
||||
/** Set if the matrix will map a rectangle to another rectangle. This
|
||||
can be true if the matrix is scale-only, or rotates a multiple of
|
||||
90 degrees. This bit is not set if the matrix is identity.
|
||||
|
||||
This bit will be set on identity matrices
|
||||
*/
|
||||
kRectStaysRect_Mask = 0x10,
|
||||
|
||||
kUnknown_Mask = 0x80,
|
||||
|
||||
kAllMasks = kTranslate_Mask |
|
||||
kScale_Mask |
|
||||
kAffine_Mask |
|
||||
kPerspective_Mask |
|
||||
kRectStaysRect_Mask
|
||||
};
|
||||
|
||||
SkScalar fMat[9];
|
||||
mutable uint8_t fTypeMask;
|
||||
|
||||
uint8_t computeTypeMask() const;
|
||||
|
||||
void setTypeMask(int mask) {
|
||||
// allow kUnknown or a valid mask
|
||||
SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask);
|
||||
fTypeMask = SkToU8(mask);
|
||||
}
|
||||
|
||||
void clearTypeMask(int mask) {
|
||||
// only allow a valid mask
|
||||
SkASSERT((mask & kAllMasks) == mask);
|
||||
fTypeMask &= ~mask;
|
||||
}
|
||||
|
||||
static bool Poly2Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
|
||||
static bool Poly3Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
|
||||
static bool Poly4Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
|
||||
|
||||
static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
|
||||
|
||||
static const MapXYProc gMapXYProcs[];
|
||||
|
||||
static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int);
|
||||
static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
|
||||
static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
|
||||
static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
|
||||
int count);
|
||||
static void Rot_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
|
||||
static void RotTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
|
||||
int count);
|
||||
static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
|
||||
|
||||
static const MapPtsProc gMapPtsProcs[];
|
||||
|
||||
friend class SkPerspIter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPackBits_DEFINED
|
||||
#define SkPackBits_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkPackBits {
|
||||
public:
|
||||
/** Given the number of 16bit values that will be passed to Pack16,
|
||||
returns the worst-case size needed for the dst[] buffer.
|
||||
*/
|
||||
static size_t ComputeMaxSize16(int count);
|
||||
|
||||
/** Given the number of 8bit values that will be passed to Pack8,
|
||||
returns the worst-case size needed for the dst[] buffer.
|
||||
*/
|
||||
static size_t ComputeMaxSize8(int count);
|
||||
|
||||
/** Write the src array into a packed format. The packing process may end
|
||||
up writing more bytes than it read, so dst[] must be large enough.
|
||||
@param src Input array of 16bit values
|
||||
@param count Number of entries in src[]
|
||||
@param dst Buffer (allocated by caller) to write the packed data
|
||||
into
|
||||
@return the number of bytes written to dst[]
|
||||
*/
|
||||
static size_t Pack16(const uint16_t src[], int count, uint8_t dst[]);
|
||||
|
||||
/** Write the src array into a packed format. The packing process may end
|
||||
up writing more bytes than it read, so dst[] must be large enough.
|
||||
@param src Input array of 8bit values
|
||||
@param count Number of entries in src[]
|
||||
@param dst Buffer (allocated by caller) to write the packed data
|
||||
into
|
||||
@return the number of bytes written to dst[]
|
||||
*/
|
||||
static size_t Pack8(const uint8_t src[], int count, uint8_t dst[]);
|
||||
|
||||
/** Unpack the data in src[], and expand it into dst[]. The src[] data was
|
||||
written by a previous call to Pack16.
|
||||
@param src Input data to unpack, previously created by Pack16.
|
||||
@param srcSize Number of bytes of src to unpack
|
||||
@param dst Buffer (allocated by caller) to expand the src[] into.
|
||||
@return the number of dst elements (not bytes) written into dst.
|
||||
*/
|
||||
static int Unpack16(const uint8_t src[], size_t srcSize, uint16_t dst[]);
|
||||
|
||||
/** Unpack the data in src[], and expand it into dst[]. The src[] data was
|
||||
written by a previous call to Pack8.
|
||||
@param src Input data to unpack, previously created by Pack8.
|
||||
@param srcSize Number of bytes of src to unpack
|
||||
@param dst Buffer (allocated by caller) to expand the src[] into.
|
||||
@return the number of bytes written into dst.
|
||||
*/
|
||||
static int Unpack8(const uint8_t src[], size_t srcSize, uint8_t dst[]);
|
||||
|
||||
/** Unpack the data from src[], skip the first dstSkip bytes, then write
|
||||
dstWrite bytes into dst[]. The src[] data was written by a previous
|
||||
call to Pack8. Return the number of bytes actually writtten into dst[]
|
||||
@param src Input data to unpack, previously created by Pack8.
|
||||
@param dst Buffer (allocated by caller) to expand the src[] into.
|
||||
@param dstSkip Number of bytes of unpacked src to skip before writing
|
||||
into dst
|
||||
@param dstWrite Number of bytes of unpacked src to write into dst (after
|
||||
skipping dstSkip bytes)
|
||||
*/
|
||||
static void Unpack8(uint8_t dst[], size_t dstSkip, size_t dstWrite,
|
||||
const uint8_t src[]);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,814 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPaint_DEFINED
|
||||
#define SkPaint_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkMath.h"
|
||||
#include "SkPorterDuff.h"
|
||||
|
||||
class SkAutoGlyphCache;
|
||||
class SkColorFilter;
|
||||
class SkDescriptor;
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
struct SkGlyph;
|
||||
struct SkRect;
|
||||
class SkGlyphCache;
|
||||
class SkMaskFilter;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkPathEffect;
|
||||
class SkRasterizer;
|
||||
class SkShader;
|
||||
class SkDrawLooper;
|
||||
class SkTypeface;
|
||||
class SkXfermode;
|
||||
|
||||
typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
|
||||
SkFixed x, SkFixed y);
|
||||
|
||||
typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
|
||||
|
||||
/** \class SkPaint
|
||||
|
||||
The SkPaint class holds the style and color information about how to draw
|
||||
geometries, text and bitmaps.
|
||||
*/
|
||||
class SkPaint {
|
||||
public:
|
||||
SkPaint();
|
||||
SkPaint(const SkPaint& paint);
|
||||
~SkPaint();
|
||||
|
||||
SkPaint& operator=(const SkPaint&);
|
||||
|
||||
friend int operator==(const SkPaint& a, const SkPaint& b);
|
||||
friend int operator!=(const SkPaint& a, const SkPaint& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
void unflatten(SkFlattenableReadBuffer&);
|
||||
|
||||
/** Restores the paint to its initial settings.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Specifies the bit values that are stored in the paint's flags.
|
||||
*/
|
||||
enum Flags {
|
||||
kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
|
||||
kFilterBitmap_Flag = 0x02, //!< mask to enable bitmap filtering
|
||||
kDither_Flag = 0x04, //!< mask to enable dithering
|
||||
kUnderlineText_Flag = 0x08, //!< mask to enable underline text
|
||||
kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
|
||||
kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
|
||||
kLinearText_Flag = 0x40, //!< mask to enable linear-text
|
||||
kSubpixelText_Flag = 0x80, //!< mask to enable subpixel-text
|
||||
kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
|
||||
|
||||
kAllFlags = 0x1FF
|
||||
};
|
||||
|
||||
/** Return the paint's flags. Use the Flag enum to test flag values.
|
||||
@return the paint's flags (see enums ending in _Flag for bit masks)
|
||||
*/
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
|
||||
/** Set the paint's flags. Use the Flag enum to specific flag values.
|
||||
@param flags The new flag bits for the paint (see Flags enum)
|
||||
*/
|
||||
void setFlags(uint32_t flags);
|
||||
|
||||
/** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
|
||||
@return true if the antialias bit is set in the paint's flags.
|
||||
*/
|
||||
bool isAntiAlias() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kAntiAlias_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
|
||||
@param aa true to enable antialiasing, false to disable it
|
||||
*/
|
||||
void setAntiAlias(bool aa);
|
||||
|
||||
/** Helper for getFlags(), returning true if kDither_Flag bit is set
|
||||
@return true if the dithering bit is set in the paint's flags.
|
||||
*/
|
||||
bool isDither() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kDither_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kDither_Flag bit
|
||||
@param dither true to enable dithering, false to disable it
|
||||
*/
|
||||
void setDither(bool dither);
|
||||
|
||||
/** Helper for getFlags(), returning true if kLinearText_Flag bit is set
|
||||
@return true if the lineartext bit is set in the paint's flags
|
||||
*/
|
||||
bool isLinearText() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kLinearText_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
|
||||
@param linearText true to set the linearText bit in the paint's flags,
|
||||
false to clear it.
|
||||
*/
|
||||
void setLinearText(bool linearText);
|
||||
|
||||
/** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
|
||||
@return true if the lineartext bit is set in the paint's flags
|
||||
*/
|
||||
bool isSubpixelText() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kSubpixelText_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kSubpixelText_Flag bit
|
||||
@param subpixelText true to set the subpixelText bit in the paint's
|
||||
flags, false to clear it.
|
||||
*/
|
||||
void setSubpixelText(bool subpixelText);
|
||||
|
||||
/** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
|
||||
@return true if the underlineText bit is set in the paint's flags.
|
||||
*/
|
||||
bool isUnderlineText() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kUnderlineText_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
|
||||
@param underlineText true to set the underlineText bit in the paint's
|
||||
flags, false to clear it.
|
||||
*/
|
||||
void setUnderlineText(bool underlineText);
|
||||
|
||||
/** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
|
||||
@return true if the strikeThruText bit is set in the paint's flags.
|
||||
*/
|
||||
bool isStrikeThruText() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kStrikeThruText_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
|
||||
@param strikeThruText true to set the strikeThruText bit in the
|
||||
paint's flags, false to clear it.
|
||||
*/
|
||||
void setStrikeThruText(bool strikeThruText);
|
||||
|
||||
/** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
|
||||
@return true if the kFakeBoldText_Flag bit is set in the paint's flags.
|
||||
*/
|
||||
bool isFakeBoldText() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kFakeBoldText_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
|
||||
@param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
|
||||
flags, false to clear it.
|
||||
*/
|
||||
void setFakeBoldText(bool fakeBoldText);
|
||||
|
||||
/** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
|
||||
@return true if the kernText bit is set in the paint's flags.
|
||||
*/
|
||||
bool isDevKernText() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kDevKernText_Flag);
|
||||
}
|
||||
|
||||
/** Helper for setFlags(), setting or clearing the kKernText_Flag bit
|
||||
@param kernText true to set the kKernText_Flag bit in the paint's
|
||||
flags, false to clear it.
|
||||
*/
|
||||
void setDevKernText(bool devKernText);
|
||||
|
||||
bool isFilterBitmap() const
|
||||
{
|
||||
return SkToBool(this->getFlags() & kFilterBitmap_Flag);
|
||||
}
|
||||
|
||||
void setFilterBitmap(bool filterBitmap);
|
||||
|
||||
/** Styles apply to rect, oval, path, and text.
|
||||
Bitmaps are always drawn in "fill", and lines are always drawn in
|
||||
"stroke".
|
||||
*/
|
||||
enum Style {
|
||||
kFill_Style, //!< fill with the paint's color
|
||||
kStroke_Style, //!< stroke with the paint's color
|
||||
kStrokeAndFill_Style, //!< fill and stroke with the paint's color
|
||||
|
||||
kStyleCount,
|
||||
};
|
||||
|
||||
/** Return the paint's style, used for controlling how primitives'
|
||||
geometries are interpreted (except for drawBitmap, which always assumes
|
||||
kFill_Style).
|
||||
@return the paint's Style
|
||||
*/
|
||||
Style getStyle() const { return (Style)fStyle; }
|
||||
|
||||
/** Set the paint's style, used for controlling how primitives'
|
||||
geometries are interpreted (except for drawBitmap, which always assumes
|
||||
Fill).
|
||||
@param style The new style to set in the paint
|
||||
*/
|
||||
void setStyle(Style style);
|
||||
|
||||
/** Return the paint's color. Note that the color is a 32bit value
|
||||
containing alpha as well as r,g,b. This 32bit value is not
|
||||
premultiplied, meaning that its alpha can be any value, regardless of
|
||||
the values of r,g,b.
|
||||
@return the paint's color (and alpha).
|
||||
*/
|
||||
SkColor getColor() const { return fColor; }
|
||||
|
||||
/** Set the paint's color. Note that the color is a 32bit value containing
|
||||
alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
|
||||
that its alpha can be any value, regardless of the values of r,g,b.
|
||||
@param color The new color (including alpha) to set in the paint.
|
||||
*/
|
||||
void setColor(SkColor color);
|
||||
|
||||
/** Helper to getColor() that just returns the color's alpha value.
|
||||
@return the alpha component of the paint's color.
|
||||
*/
|
||||
uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
|
||||
|
||||
/** Helper to setColor(), that only assigns the color's alpha value,
|
||||
leaving its r,g,b values unchanged.
|
||||
@param a set the alpha component (0..255) of the paint's color.
|
||||
*/
|
||||
void setAlpha(U8CPU a);
|
||||
|
||||
/** Helper to setColor(), that takes a,r,g,b and constructs the color value
|
||||
using SkColorSetARGB()
|
||||
@param a The new alpha component (0..255) of the paint's color.
|
||||
@param r The new red component (0..255) of the paint's color.
|
||||
@param g The new green component (0..255) of the paint's color.
|
||||
@param b The new blue component (0..255) of the paint's color.
|
||||
*/
|
||||
void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
|
||||
/** Return the width for stroking.
|
||||
<p />
|
||||
A value of 0 strokes in hairline mode.
|
||||
Hairlines always draw 1-pixel wide, regardless of the matrix.
|
||||
@return the paint's stroke width, used whenever the paint's style is
|
||||
Stroke or StrokeAndFill.
|
||||
*/
|
||||
SkScalar getStrokeWidth() const { return fWidth; }
|
||||
|
||||
/** Set the width for stroking.
|
||||
Pass 0 to stroke in hairline mode.
|
||||
Hairlines always draw 1-pixel wide, regardless of the matrix.
|
||||
@param width set the paint's stroke width, used whenever the paint's
|
||||
style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeWidth(SkScalar width);
|
||||
|
||||
/** Return the paint's stroke miter value. This is used to control the
|
||||
behavior of miter joins when the joins angle is sharp.
|
||||
@return the paint's miter limit, used whenever the paint's style is
|
||||
Stroke or StrokeAndFill.
|
||||
*/
|
||||
SkScalar getStrokeMiter() const { return fMiterLimit; }
|
||||
|
||||
/** Set the paint's stroke miter value. This is used to control the
|
||||
behavior of miter joins when the joins angle is sharp. This value must
|
||||
be >= 0.
|
||||
@param miter set the miter limit on the paint, used whenever the
|
||||
paint's style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeMiter(SkScalar miter);
|
||||
|
||||
/** Cap enum specifies the settings for the paint's strokecap. This is the
|
||||
treatment that is applied to the beginning and end of each non-closed
|
||||
contour (e.g. lines).
|
||||
*/
|
||||
enum Cap {
|
||||
kButt_Cap, //!< begin/end contours with no extension
|
||||
kRound_Cap, //!< begin/end contours with a semi-circle extension
|
||||
kSquare_Cap, //!< begin/end contours with a half square extension
|
||||
|
||||
kCapCount,
|
||||
kDefault_Cap = kButt_Cap
|
||||
};
|
||||
|
||||
/** Join enum specifies the settings for the paint's strokejoin. This is
|
||||
the treatment that is applied to corners in paths and rectangles.
|
||||
*/
|
||||
enum Join {
|
||||
kMiter_Join, //!< connect path segments with a sharp join
|
||||
kRound_Join, //!< connect path segments with a round join
|
||||
kBevel_Join, //!< connect path segments with a flat bevel join
|
||||
|
||||
kJoinCount,
|
||||
kDefault_Join = kMiter_Join
|
||||
};
|
||||
|
||||
/** Return the paint's stroke cap type, controlling how the start and end
|
||||
of stroked lines and paths are treated.
|
||||
@return the line cap style for the paint, used whenever the paint's
|
||||
style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
Cap getStrokeCap() const { return (Cap)fCapType; }
|
||||
|
||||
/** Set the paint's stroke cap type.
|
||||
@param cap set the paint's line cap style, used whenever the paint's
|
||||
style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeCap(Cap cap);
|
||||
|
||||
/** Return the paint's stroke join type.
|
||||
@return the paint's line join style, used whenever the paint's style is
|
||||
Stroke or StrokeAndFill.
|
||||
*/
|
||||
Join getStrokeJoin() const { return (Join)fJoinType; }
|
||||
|
||||
/** Set the paint's stroke join type.
|
||||
@param join set the paint's line join style, used whenever the paint's
|
||||
style is Stroke or StrokeAndFill.
|
||||
*/
|
||||
void setStrokeJoin(Join join);
|
||||
|
||||
/** Applies any/all effects (patheffect, stroking) to src, returning the
|
||||
result in dst. The result is that drawing src with this paint will be
|
||||
the same as drawing dst with a default paint (at least from the
|
||||
geometric perspective).
|
||||
@param src input path
|
||||
@param dst output path (may be the same as src)
|
||||
@return true if the path should be filled, or false if it should be
|
||||
drawn with a hairline (width == 0)
|
||||
*/
|
||||
bool getFillPath(const SkPath& src, SkPath* dst) const;
|
||||
|
||||
/** Returns true if the current paint settings allow for fast computation of
|
||||
bounds (i.e. there is nothing complex like a patheffect that would make
|
||||
the bounds computation expensive.
|
||||
*/
|
||||
bool canComputeFastBounds() const;
|
||||
|
||||
/** Only call this if canComputeFastBounds() returned true. This takes a
|
||||
raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
|
||||
effects in the paint (e.g. stroking). If needed, it uses the storage
|
||||
rect parameter. It returns the adjusted bounds that can then be used
|
||||
for quickReject tests.
|
||||
|
||||
The returned rect will either be orig or storage, thus the caller
|
||||
should not rely on storage being set to the result, but should always
|
||||
use the retured value. It is legal for orig and storage to be the same
|
||||
rect.
|
||||
|
||||
e.g.
|
||||
if (paint.canComputeFastBounds()) {
|
||||
SkRect r, storage;
|
||||
path.computeBounds(&r, SkPath::kFast_BoundsType);
|
||||
const SkRect& fastR = paint.computeFastBounds(r, &storage);
|
||||
if (canvas->quickReject(fastR, ...)) {
|
||||
// don't draw the path
|
||||
}
|
||||
}
|
||||
*/
|
||||
const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const;
|
||||
|
||||
/** Get the paint's shader object.
|
||||
<p />
|
||||
The shader's reference count is not affected.
|
||||
@return the paint's shader (or NULL)
|
||||
*/
|
||||
SkShader* getShader() const { return fShader; }
|
||||
|
||||
/** Set or clear the shader object.
|
||||
<p />
|
||||
Pass NULL to clear any previous shader.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous shader exists, its reference count is decremented.
|
||||
If shader is not NULL, its reference count is incremented.
|
||||
@param shader May be NULL. The shader to be installed in the paint
|
||||
@return shader
|
||||
*/
|
||||
SkShader* setShader(SkShader* shader);
|
||||
|
||||
/** Get the paint's colorfilter. If there is a colorfilter, its reference
|
||||
count is not changed.
|
||||
@return the paint's colorfilter (or NULL)
|
||||
*/
|
||||
SkColorFilter* getColorFilter() const { return fColorFilter; }
|
||||
|
||||
/** Set or clear the paint's colorfilter, returning the parameter.
|
||||
<p />
|
||||
If the paint already has a filter, its reference count is decremented.
|
||||
If filter is not NULL, its reference count is incremented.
|
||||
@param filter May be NULL. The filter to be installed in the paint
|
||||
@return filter
|
||||
*/
|
||||
SkColorFilter* setColorFilter(SkColorFilter* filter);
|
||||
|
||||
/** Get the paint's xfermode object.
|
||||
<p />
|
||||
The xfermode's reference count is not affected.
|
||||
@return the paint's xfermode (or NULL)
|
||||
*/
|
||||
SkXfermode* getXfermode() const { return fXfermode; }
|
||||
|
||||
/** Set or clear the xfermode object.
|
||||
<p />
|
||||
Pass NULL to clear any previous xfermode.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous xfermode exists, its reference count is decremented.
|
||||
If xfermode is not NULL, its reference count is incremented.
|
||||
@param xfermode May be NULL. The new xfermode to be installed in the
|
||||
paint
|
||||
@return xfermode
|
||||
*/
|
||||
SkXfermode* setXfermode(SkXfermode* xfermode);
|
||||
|
||||
/** Helper for setXfermode, passing the corresponding xfermode object
|
||||
returned from the PorterDuff factory.
|
||||
@param mode The porter-duff mode used to create an xfermode for the
|
||||
paint.
|
||||
@return the resulting xfermode object (or NULL if the mode is
|
||||
SrcOver)
|
||||
*/
|
||||
SkXfermode* setPorterDuffXfermode(SkPorterDuff::Mode mode);
|
||||
|
||||
/** Get the paint's patheffect object.
|
||||
<p />
|
||||
The patheffect reference count is not affected.
|
||||
@return the paint's patheffect (or NULL)
|
||||
*/
|
||||
SkPathEffect* getPathEffect() const { return fPathEffect; }
|
||||
|
||||
/** Set or clear the patheffect object.
|
||||
<p />
|
||||
Pass NULL to clear any previous patheffect.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous patheffect exists, its reference count is decremented.
|
||||
If patheffect is not NULL, its reference count is incremented.
|
||||
@param effect May be NULL. The new patheffect to be installed in the
|
||||
paint
|
||||
@return effect
|
||||
*/
|
||||
SkPathEffect* setPathEffect(SkPathEffect* effect);
|
||||
|
||||
/** Get the paint's maskfilter object.
|
||||
<p />
|
||||
The maskfilter reference count is not affected.
|
||||
@return the paint's maskfilter (or NULL)
|
||||
*/
|
||||
SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
|
||||
|
||||
/** Set or clear the maskfilter object.
|
||||
<p />
|
||||
Pass NULL to clear any previous maskfilter.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous maskfilter exists, its reference count is decremented.
|
||||
If maskfilter is not NULL, its reference count is incremented.
|
||||
@param maskfilter May be NULL. The new maskfilter to be installed in
|
||||
the paint
|
||||
@return maskfilter
|
||||
*/
|
||||
SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
|
||||
|
||||
// These attributes are for text/fonts
|
||||
|
||||
/** Get the paint's typeface object.
|
||||
<p />
|
||||
The typeface object identifies which font to use when drawing or
|
||||
measuring text. The typeface reference count is not affected.
|
||||
@return the paint's typeface (or NULL)
|
||||
*/
|
||||
SkTypeface* getTypeface() const { return fTypeface; }
|
||||
|
||||
/** Set or clear the typeface object.
|
||||
<p />
|
||||
Pass NULL to clear any previous typeface.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous typeface exists, its reference count is decremented.
|
||||
If typeface is not NULL, its reference count is incremented.
|
||||
@param typeface May be NULL. The new typeface to be installed in the
|
||||
paint
|
||||
@return typeface
|
||||
*/
|
||||
SkTypeface* setTypeface(SkTypeface* typeface);
|
||||
|
||||
/** Get the paint's rasterizer (or NULL).
|
||||
<p />
|
||||
The raster controls how paths/text are turned into alpha masks.
|
||||
@return the paint's rasterizer (or NULL)
|
||||
*/
|
||||
SkRasterizer* getRasterizer() const { return fRasterizer; }
|
||||
|
||||
/** Set or clear the rasterizer object.
|
||||
<p />
|
||||
Pass NULL to clear any previous rasterizer.
|
||||
As a convenience, the parameter passed is also returned.
|
||||
If a previous rasterizer exists in the paint, its reference count is
|
||||
decremented. If rasterizer is not NULL, its reference count is
|
||||
incremented.
|
||||
@param rasterizer May be NULL. The new rasterizer to be installed in
|
||||
the paint.
|
||||
@return rasterizer
|
||||
*/
|
||||
SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
|
||||
|
||||
SkDrawLooper* getLooper() const { return fLooper; }
|
||||
SkDrawLooper* setLooper(SkDrawLooper*);
|
||||
|
||||
enum Align {
|
||||
kLeft_Align,
|
||||
kCenter_Align,
|
||||
kRight_Align,
|
||||
|
||||
kAlignCount
|
||||
};
|
||||
/** Return the paint's Align value for drawing text.
|
||||
@return the paint's Align value for drawing text.
|
||||
*/
|
||||
Align getTextAlign() const { return (Align)fTextAlign; }
|
||||
/** Set the paint's text alignment.
|
||||
@param align set the paint's Align value for drawing text.
|
||||
*/
|
||||
void setTextAlign(Align align);
|
||||
|
||||
/** Return the paint's text size.
|
||||
@return the paint's text size.
|
||||
*/
|
||||
SkScalar getTextSize() const { return fTextSize; }
|
||||
|
||||
/** Set the paint's text size. This value must be > 0
|
||||
@param textSize set the paint's text size.
|
||||
*/
|
||||
void setTextSize(SkScalar textSize);
|
||||
|
||||
/** Return the paint's horizontal scale factor for text. The default value
|
||||
is 1.0.
|
||||
@return the paint's scale factor in X for drawing/measuring text
|
||||
*/
|
||||
SkScalar getTextScaleX() const { return fTextScaleX; }
|
||||
|
||||
/** Set the paint's horizontal scale factor for text. The default value
|
||||
is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
|
||||
stretch the text narrower.
|
||||
@param scaleX set the paint's scale factor in X for drawing/measuring
|
||||
text.
|
||||
*/
|
||||
void setTextScaleX(SkScalar scaleX);
|
||||
|
||||
/** Return the paint's horizontal skew factor for text. The default value
|
||||
is 0.
|
||||
@return the paint's skew factor in X for drawing text.
|
||||
*/
|
||||
SkScalar getTextSkewX() const { return fTextSkewX; }
|
||||
|
||||
/** Set the paint's horizontal skew factor for text. The default value
|
||||
is 0. For approximating oblique text, use values around -0.25.
|
||||
@param skewX set the paint's skew factor in X for drawing text.
|
||||
*/
|
||||
void setTextSkewX(SkScalar skewX);
|
||||
|
||||
/** Describes how to interpret the text parameters that are passed to paint
|
||||
methods like measureText() and getTextWidths().
|
||||
*/
|
||||
enum TextEncoding {
|
||||
kUTF8_TextEncoding, //!< the text parameters are UTF8
|
||||
kUTF16_TextEncoding, //!< the text parameters are UTF16
|
||||
kGlyphID_TextEncoding //!< the text parameters are glyph indices
|
||||
};
|
||||
|
||||
TextEncoding getTextEncoding() const
|
||||
{
|
||||
return (TextEncoding)fTextEncoding;
|
||||
}
|
||||
|
||||
void setTextEncoding(TextEncoding encoding);
|
||||
|
||||
struct FontMetrics {
|
||||
SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
|
||||
SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
|
||||
SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
|
||||
SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
|
||||
SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
|
||||
};
|
||||
|
||||
/** Return the recommend spacing between lines (which will be
|
||||
fDescent - fAscent + fLeading).
|
||||
If metrics is not null, return in it the font metrics for the
|
||||
typeface/pointsize/etc. currently set in the paint.
|
||||
@param metrics If not null, returns the font metrics for the
|
||||
current typeface/pointsize/etc setting in this
|
||||
paint.
|
||||
@param scale If not 0, return width as if the canvas were scaled
|
||||
by this value
|
||||
@param return the recommended spacing between lines
|
||||
*/
|
||||
SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
|
||||
|
||||
/** Return the recommend line spacing. This will be
|
||||
fDescent - fAscent + fLeading
|
||||
*/
|
||||
SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
|
||||
|
||||
/** Convert the specified text into glyph IDs, returning the number of
|
||||
glyphs ID written. If glyphs is NULL, it is ignore and only the count
|
||||
is returned.
|
||||
*/
|
||||
int textToGlyphs(const void* text, size_t byteLength,
|
||||
uint16_t glyphs[]) const;
|
||||
|
||||
/** Return the number of drawable units in the specified text buffer.
|
||||
This looks at the current TextEncoding field of the paint. If you also
|
||||
want to have the text converted into glyph IDs, call textToGlyphs
|
||||
instead.
|
||||
*/
|
||||
int countText(const void* text, size_t byteLength) const
|
||||
{
|
||||
return this->textToGlyphs(text, byteLength, NULL);
|
||||
}
|
||||
|
||||
/** Return the width of the text.
|
||||
@param text The text to be measured
|
||||
@param length Number of bytes of text to measure
|
||||
@param bounds If not NULL, returns the bounds of the text,
|
||||
relative to (0, 0).
|
||||
@param scale If not 0, return width as if the canvas were scaled
|
||||
by this value
|
||||
@return The advance width of the text
|
||||
*/
|
||||
SkScalar measureText(const void* text, size_t length,
|
||||
SkRect* bounds, SkScalar scale = 0) const;
|
||||
|
||||
/** Return the width of the text.
|
||||
@param text Address of the text
|
||||
@param length Number of bytes of text to measure
|
||||
@return The width of the text
|
||||
*/
|
||||
SkScalar measureText(const void* text, size_t length) const
|
||||
{
|
||||
return this->measureText(text, length, NULL, 0);
|
||||
}
|
||||
|
||||
/** Specify the direction the text buffer should be processed in breakText()
|
||||
*/
|
||||
enum TextBufferDirection {
|
||||
/** When measuring text for breakText(), begin at the start of the text
|
||||
buffer and proceed forward through the data. This is the default.
|
||||
*/
|
||||
kForward_TextBufferDirection,
|
||||
/** When measuring text for breakText(), begin at the end of the text
|
||||
buffer and proceed backwards through the data.
|
||||
*/
|
||||
kBackward_TextBufferDirection
|
||||
};
|
||||
|
||||
/** Return the width of the text.
|
||||
@param text The text to be measured
|
||||
@param length Number of bytes of text to measure
|
||||
@param maxWidth Maximum width. Only the subset of text whose accumulated
|
||||
widths are <= maxWidth are measured.
|
||||
@param measuredWidth Optional. If non-null, this returns the actual
|
||||
width of the measured text.
|
||||
@param tbd Optional. The direction the text buffer should be
|
||||
traversed during measuring.
|
||||
@return The number of bytes of text that were measured. Will be
|
||||
<= length.
|
||||
*/
|
||||
size_t breakText(const void* text, size_t length, SkScalar maxWidth,
|
||||
SkScalar* measuredWidth = NULL,
|
||||
TextBufferDirection tbd = kForward_TextBufferDirection)
|
||||
const;
|
||||
|
||||
/** Return the advance widths for the characters in the string.
|
||||
@param text the text
|
||||
@param byteLength number of bytes to of text
|
||||
@param widths If not null, returns the array of advance widths of
|
||||
the glyphs. If not NULL, must be at least a large
|
||||
as the number of unichars in the specified text.
|
||||
@param bounds If not null, returns the bounds for each of
|
||||
character, relative to (0, 0)
|
||||
@return the number of unichars in the specified text.
|
||||
*/
|
||||
int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
|
||||
SkRect bounds[] = NULL) const;
|
||||
|
||||
/** Return the path (outline) for the specified text.
|
||||
Note: just like SkCanvas::drawText, this will respect the Align setting
|
||||
in the paint.
|
||||
*/
|
||||
void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
|
||||
SkPath* path) const;
|
||||
|
||||
private:
|
||||
SkTypeface* fTypeface;
|
||||
SkScalar fTextSize;
|
||||
SkScalar fTextScaleX;
|
||||
SkScalar fTextSkewX;
|
||||
|
||||
SkPathEffect* fPathEffect;
|
||||
SkShader* fShader;
|
||||
SkXfermode* fXfermode;
|
||||
SkMaskFilter* fMaskFilter;
|
||||
SkColorFilter* fColorFilter;
|
||||
SkRasterizer* fRasterizer;
|
||||
SkDrawLooper* fLooper;
|
||||
|
||||
SkColor fColor;
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
||||
unsigned fFlags : 9;
|
||||
unsigned fTextAlign : 2;
|
||||
unsigned fCapType : 2;
|
||||
unsigned fJoinType : 2;
|
||||
unsigned fStyle : 2;
|
||||
unsigned fTextEncoding : 2; // 3 values
|
||||
|
||||
SkDrawCacheProc getDrawCacheProc() const;
|
||||
SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
|
||||
bool needFullMetrics) const;
|
||||
|
||||
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
|
||||
int* count, SkRect* bounds) const;
|
||||
|
||||
SkGlyphCache* detachCache(const SkMatrix*) const;
|
||||
|
||||
void descriptorProc(const SkMatrix* deviceMatrix,
|
||||
void (*proc)(const SkDescriptor*, void*),
|
||||
void* context) const;
|
||||
|
||||
enum {
|
||||
kCanonicalTextSizeForPaths = 64
|
||||
};
|
||||
friend class SkCanvas;
|
||||
friend class SkDraw;
|
||||
friend class SkAutoGlyphCache;
|
||||
friend class SkTextToPathIter;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkStrokePathEffect
|
||||
|
||||
SkStrokePathEffect simulates stroking inside a patheffect, allowing the
|
||||
caller to have explicit control of when to stroke a path. Typically this is
|
||||
used if the caller wants to stroke before another patheffect is applied
|
||||
(using SkComposePathEffect or SkSumPathEffect).
|
||||
*/
|
||||
class SkStrokePathEffect : public SkPathEffect {
|
||||
public:
|
||||
SkStrokePathEffect(const SkPaint&);
|
||||
SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
|
||||
SkPaint::Cap, SkScalar miterLimit = -1);
|
||||
|
||||
// overrides
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
|
||||
private:
|
||||
SkScalar fWidth, fMiter;
|
||||
uint8_t fStyle, fJoin, fCap;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
SkStrokePathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
|
||||
// illegal
|
||||
SkStrokePathEffect(const SkStrokePathEffect&);
|
||||
SkStrokePathEffect& operator=(const SkStrokePathEffect&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,588 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPath_DEFINED
|
||||
#define SkPath_DEFINED
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
class SkAutoPathBoundsUpdate;
|
||||
class SkString;
|
||||
|
||||
/** \class SkPath
|
||||
|
||||
The SkPath class encapsulates compound (multiple contour) geometric paths
|
||||
consisting of straight line segments, quadratic curves, and cubic curves.
|
||||
*/
|
||||
class SkPath {
|
||||
public:
|
||||
SkPath();
|
||||
SkPath(const SkPath&);
|
||||
~SkPath();
|
||||
|
||||
SkPath& operator=(const SkPath&);
|
||||
|
||||
enum FillType {
|
||||
/** Specifies that "inside" is computed by a non-zero sum of signed
|
||||
edge crossings
|
||||
*/
|
||||
kWinding_FillType,
|
||||
/** Specifies that "inside" is computed by an odd number of edge
|
||||
crossings
|
||||
*/
|
||||
kEvenOdd_FillType,
|
||||
/** Same as Winding, but draws outside of the path, rather than inside
|
||||
*/
|
||||
kInverseWinding_FillType,
|
||||
/** Same as EvenOdd, but draws outside of the path, rather than inside
|
||||
*/
|
||||
kInverseEvenOdd_FillType
|
||||
};
|
||||
|
||||
/** Return the path's fill type. This is used to define how "inside" is
|
||||
computed. The default value is kWinding_FillType.
|
||||
|
||||
@return the path's fill type
|
||||
*/
|
||||
FillType getFillType() const { return (FillType)fFillType; }
|
||||
|
||||
/** Set the path's fill type. This is used to define how "inside" is
|
||||
computed. The default value is kWinding_FillType.
|
||||
|
||||
@param ft The new fill type for this path
|
||||
*/
|
||||
void setFillType(FillType ft) { fFillType = SkToU8(ft); }
|
||||
|
||||
/** Returns true if the filltype is one of the Inverse variants */
|
||||
bool isInverseFillType() const { return (fFillType & 2) != 0; }
|
||||
|
||||
/** Toggle between inverse and normal filltypes. This reverse the return
|
||||
value of isInverseFillType()
|
||||
*/
|
||||
void toggleInverseFillType() { fFillType ^= 2; }
|
||||
|
||||
/** Clear any lines and curves from the path, making it empty. This frees up
|
||||
internal storage associated with those segments.
|
||||
This does NOT change the fill-type setting.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Similar to reset(), in that all lines and curves are removed from the
|
||||
path. However, any internal storage for those lines/curves is retained,
|
||||
making reuse of the path potentially faster.
|
||||
This does NOT change the fill-type setting.
|
||||
*/
|
||||
void rewind();
|
||||
|
||||
/** Returns true if the path is empty (contains no lines or curves)
|
||||
|
||||
@return true if the path is empty (contains no lines or curves)
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
/** Returns true if the path specifies a rectangle. If so, and if rect is
|
||||
not null, set rect to the bounds of the path. If the path does not
|
||||
specify a rectangle, return false and ignore rect.
|
||||
|
||||
@param rect If not null, returns the bounds of the path if it specifies
|
||||
a rectangle
|
||||
@return true if the path specifies a rectangle
|
||||
*/
|
||||
bool isRect(SkRect* rect) const;
|
||||
|
||||
/** Returns the number of points in the path. Up to max points are copied.
|
||||
|
||||
@param points If not null, receives up to max points
|
||||
@param max The maximum number of points to copy into points
|
||||
@return the actual number of points in the path
|
||||
*/
|
||||
int getPoints(SkPoint points[], int max) const;
|
||||
|
||||
//! Swap contents of this and other. Guaranteed not to throw
|
||||
void swap(SkPath& other);
|
||||
|
||||
enum BoundsType {
|
||||
/** compute the bounds of the path's control points, may be larger than
|
||||
with kExact_BoundsType, but may be faster to compute
|
||||
*/
|
||||
kFast_BoundsType,
|
||||
/** compute the exact bounds of the path, may be smaller than with
|
||||
kFast_BoundsType, but may be slower to compute
|
||||
*/
|
||||
kExact_BoundsType
|
||||
};
|
||||
|
||||
/** Compute the bounds of the path, and write the answer into bounds. If the
|
||||
path contains 0 or 1 points, the bounds is set to (0,0,0,0)
|
||||
|
||||
@param bounds Returns the computed bounds of the path
|
||||
@param btype Specifies if the computed bounds should be exact
|
||||
(slower) or approximate (faster)
|
||||
*/
|
||||
void computeBounds(SkRect* bounds, BoundsType btype) const;
|
||||
|
||||
/** Calling this will, if the internal cache of the bounds is out of date,
|
||||
update it so that subsequent calls to computeBounds will be instanteous.
|
||||
This also means that any copies or simple transformations of the path
|
||||
will inherit the cached bounds.
|
||||
*/
|
||||
void updateBoundsCache() const;
|
||||
|
||||
// Construction methods
|
||||
|
||||
/** Hint to the path to prepare for adding more points. This can allow the
|
||||
path to more efficiently grow its storage.
|
||||
|
||||
@param extraPtCount The number of extra points the path should
|
||||
preallocate for.
|
||||
*/
|
||||
void incReserve(unsigned extraPtCount);
|
||||
|
||||
/** Set the beginning of the next contour to the point (x,y).
|
||||
|
||||
@param x The x-coordinate of the start of a new contour
|
||||
@param y The y-coordinate of the start of a new contour
|
||||
*/
|
||||
void moveTo(SkScalar x, SkScalar y);
|
||||
|
||||
/** Set the beginning of the next contour to the point
|
||||
|
||||
@param p The start of a new contour
|
||||
*/
|
||||
void moveTo(const SkPoint& p) {
|
||||
this->moveTo(p.fX, p.fY);
|
||||
}
|
||||
|
||||
/** Set the beginning of the next contour relative to the last point on the
|
||||
previous contour. If there is no previous contour, this is treated the
|
||||
same as moveTo().
|
||||
|
||||
@param dx The amount to add to the x-coordinate of the end of the
|
||||
previous contour, to specify the start of a new contour
|
||||
@param dy The amount to add to the y-coordinate of the end of the
|
||||
previous contour, to specify the start of a new contour
|
||||
*/
|
||||
void rMoveTo(SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Add a line from the last point to the specified point (x,y). If no
|
||||
moveTo() call has been made for this contour, the first point is
|
||||
automatically set to (0,0).
|
||||
|
||||
@param x The x-coordinate of the end of a line
|
||||
@param y The y-coordinate of the end of a line
|
||||
*/
|
||||
void lineTo(SkScalar x, SkScalar y);
|
||||
|
||||
/** Add a line from the last point to the specified point. If no moveTo()
|
||||
call has been made for this contour, the first point is automatically
|
||||
set to (0,0).
|
||||
|
||||
@param p The end of a line
|
||||
*/
|
||||
void lineTo(const SkPoint& p) {
|
||||
this->lineTo(p.fX, p.fY);
|
||||
}
|
||||
|
||||
/** Same as lineTo, but the coordinates are considered relative to the last
|
||||
point on this contour. If there is no previous point, then a moveTo(0,0)
|
||||
is inserted automatically.
|
||||
|
||||
@param dx The amount to add to the x-coordinate of the previous point
|
||||
on this contour, to specify a line
|
||||
@param dy The amount to add to the y-coordinate of the previous point
|
||||
on this contour, to specify a line
|
||||
*/
|
||||
void rLineTo(SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Add a quadratic bezier from the last point, approaching control point
|
||||
(x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
|
||||
this contour, the first point is automatically set to (0,0).
|
||||
|
||||
@param x1 The x-coordinate of the control point on a quadratic curve
|
||||
@param y1 The y-coordinate of the control point on a quadratic curve
|
||||
@param x2 The x-coordinate of the end point on a quadratic curve
|
||||
@param y2 The y-coordinate of the end point on a quadratic curve
|
||||
*/
|
||||
void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
|
||||
|
||||
/** Add a quadratic bezier from the last point, approaching control point
|
||||
p1, and ending at p2. If no moveTo() call has been made for this
|
||||
contour, the first point is automatically set to (0,0).
|
||||
|
||||
@param p1 The control point on a quadratic curve
|
||||
@param p2 The end point on a quadratic curve
|
||||
*/
|
||||
void quadTo(const SkPoint& p1, const SkPoint& p2) {
|
||||
this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
|
||||
}
|
||||
|
||||
/** Same as quadTo, but the coordinates are considered relative to the last
|
||||
point on this contour. If there is no previous point, then a moveTo(0,0)
|
||||
is inserted automatically.
|
||||
|
||||
@param dx1 The amount to add to the x-coordinate of the last point on
|
||||
this contour, to specify the control point of a quadratic curve
|
||||
@param dy1 The amount to add to the y-coordinate of the last point on
|
||||
this contour, to specify the control point of a quadratic curve
|
||||
@param dx2 The amount to add to the x-coordinate of the last point on
|
||||
this contour, to specify the end point of a quadratic curve
|
||||
@param dy2 The amount to add to the y-coordinate of the last point on
|
||||
this contour, to specify the end point of a quadratic curve
|
||||
*/
|
||||
void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
|
||||
|
||||
/** Add a cubic bezier from the last point, approaching control points
|
||||
(x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
|
||||
made for this contour, the first point is automatically set to (0,0).
|
||||
|
||||
@param x1 The x-coordinate of the 1st control point on a cubic curve
|
||||
@param y1 The y-coordinate of the 1st control point on a cubic curve
|
||||
@param x2 The x-coordinate of the 2nd control point on a cubic curve
|
||||
@param y2 The y-coordinate of the 2nd control point on a cubic curve
|
||||
@param x3 The x-coordinate of the end point on a cubic curve
|
||||
@param y3 The y-coordinate of the end point on a cubic curve
|
||||
*/
|
||||
void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
|
||||
/** Add a cubic bezier from the last point, approaching control points p1
|
||||
and p2, and ending at p3. If no moveTo() call has been made for this
|
||||
contour, the first point is automatically set to (0,0).
|
||||
|
||||
@param p1 The 1st control point on a cubic curve
|
||||
@param p2 The 2nd control point on a cubic curve
|
||||
@param p3 The end point on a cubic curve
|
||||
*/
|
||||
void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
|
||||
this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
|
||||
}
|
||||
|
||||
/** Same as cubicTo, but the coordinates are considered relative to the
|
||||
current point on this contour. If there is no previous point, then a
|
||||
moveTo(0,0) is inserted automatically.
|
||||
|
||||
@param dx1 The amount to add to the x-coordinate of the last point on
|
||||
this contour, to specify the 1st control point of a cubic curve
|
||||
@param dy1 The amount to add to the y-coordinate of the last point on
|
||||
this contour, to specify the 1st control point of a cubic curve
|
||||
@param dx2 The amount to add to the x-coordinate of the last point on
|
||||
this contour, to specify the 2nd control point of a cubic curve
|
||||
@param dy2 The amount to add to the y-coordinate of the last point on
|
||||
this contour, to specify the 2nd control point of a cubic curve
|
||||
@param dx3 The amount to add to the x-coordinate of the last point on
|
||||
this contour, to specify the end point of a cubic curve
|
||||
@param dy3 The amount to add to the y-coordinate of the last point on
|
||||
this contour, to specify the end point of a cubic curve
|
||||
*/
|
||||
void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
|
||||
/** Append the specified arc to the path as a new contour. If the start of
|
||||
the path is different from the path's current last point, then an
|
||||
automatic lineTo() is added to connect the current contour to the start
|
||||
of the arc. However, if the path is empty, then we call moveTo() with
|
||||
the first point of the arc. The sweep angle is treated mod 360.
|
||||
|
||||
@param oval The bounding oval defining the shape and size of the arc
|
||||
@param startAngle Starting angle (in degrees) where the arc begins
|
||||
@param sweepAngle Sweep angle (in degrees) measured clockwise. This is
|
||||
treated mod 360.
|
||||
@param forceMoveTo If true, always begin a new contour with the arc
|
||||
*/
|
||||
void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
bool forceMoveTo);
|
||||
|
||||
/** Append a line and arc to the current path. This is the same as the
|
||||
PostScript call "arct".
|
||||
*/
|
||||
void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar radius);
|
||||
|
||||
/** Append a line and arc to the current path. This is the same as the
|
||||
PostScript call "arct".
|
||||
*/
|
||||
void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
|
||||
this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
|
||||
}
|
||||
|
||||
/** Close the current contour. If the current point is not equal to the
|
||||
first point of the contour, a line segment is automatically added.
|
||||
*/
|
||||
void close();
|
||||
|
||||
enum Direction {
|
||||
/** clockwise direction for adding closed contours */
|
||||
kCW_Direction,
|
||||
/** counter-clockwise direction for adding closed contours */
|
||||
kCCW_Direction
|
||||
};
|
||||
|
||||
/** Add a closed rectangle contour to the path
|
||||
@param rect The rectangle to add as a closed contour to the path
|
||||
@param dir The direction to wind the rectangle's contour
|
||||
*/
|
||||
void addRect(const SkRect& rect, Direction dir = kCW_Direction);
|
||||
|
||||
/** Add a closed rectangle contour to the path
|
||||
|
||||
@param left The left side of a rectangle to add as a closed contour
|
||||
to the path
|
||||
@param top The top of a rectangle to add as a closed contour to the
|
||||
path
|
||||
@param right The right side of a rectangle to add as a closed contour
|
||||
to the path
|
||||
@param bottom The bottom of a rectangle to add as a closed contour to
|
||||
the path
|
||||
@param dir The direction to wind the rectangle's contour
|
||||
*/
|
||||
void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Add a closed oval contour to the path
|
||||
|
||||
@param oval The bounding oval to add as a closed contour to the path
|
||||
@param dir The direction to wind the oval's contour
|
||||
*/
|
||||
void addOval(const SkRect& oval, Direction dir = kCW_Direction);
|
||||
|
||||
/** Add a closed circle contour to the path
|
||||
|
||||
@param x The x-coordinate of the center of a circle to add as a
|
||||
closed contour to the path
|
||||
@param y The y-coordinate of the center of a circle to add as a
|
||||
closed contour to the path
|
||||
@param radius The radius of a circle to add as a closed contour to the
|
||||
path
|
||||
@param dir The direction to wind the circle's contour
|
||||
*/
|
||||
void addCircle(SkScalar x, SkScalar y, SkScalar radius,
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Add the specified arc to the path as a new contour.
|
||||
|
||||
@param oval The bounds of oval used to define the size of the arc
|
||||
@param startAngle Starting angle (in degrees) where the arc begins
|
||||
@param sweepAngle Sweep angle (in degrees) measured clockwise
|
||||
*/
|
||||
void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
|
||||
|
||||
/** Add a closed round-rectangle contour to the path
|
||||
@param rect The bounds of a round-rectangle to add as a closed contour
|
||||
@param rx The x-radius of the rounded corners on the round-rectangle
|
||||
@param ry The y-radius of the rounded corners on the round-rectangle
|
||||
@param dir The direction to wind the round-rectangle's contour
|
||||
*/
|
||||
void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Add a closed round-rectangle contour to the path. Each corner receives
|
||||
two radius values [X, Y]. The corners are ordered top-left, top-right,
|
||||
bottom-right, bottom-left.
|
||||
@param rect The bounds of a round-rectangle to add as a closed contour
|
||||
@param radii Array of 8 scalars, 4 [X,Y] pairs for each corner
|
||||
@param dir The direction to wind the round-rectangle's contour
|
||||
*/
|
||||
void addRoundRect(const SkRect& rect, const SkScalar radii[],
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Add a copy of src to the path, offset by (dx,dy)
|
||||
@param src The path to add as a new contour
|
||||
@param dx The amount to translate the path in X as it is added
|
||||
@param dx The amount to translate the path in Y as it is added
|
||||
*/
|
||||
void addPath(const SkPath& src, SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Add a copy of src to the path
|
||||
*/
|
||||
void addPath(const SkPath& src) {
|
||||
SkMatrix m;
|
||||
m.reset();
|
||||
this->addPath(src, m);
|
||||
}
|
||||
|
||||
/** Add a copy of src to the path, transformed by matrix
|
||||
@param src The path to add as a new contour
|
||||
*/
|
||||
void addPath(const SkPath& src, const SkMatrix& matrix);
|
||||
|
||||
/** Offset the path by (dx,dy), returning true on success
|
||||
|
||||
@param dx The amount in the X direction to offset the entire path
|
||||
@param dy The amount in the Y direction to offset the entire path
|
||||
@param dst The translated path is written here
|
||||
*/
|
||||
void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
|
||||
|
||||
/** Offset the path by (dx,dy), returning true on success
|
||||
|
||||
@param dx The amount in the X direction to offset the entire path
|
||||
@param dy The amount in the Y direction to offset the entire path
|
||||
*/
|
||||
void offset(SkScalar dx, SkScalar dy) {
|
||||
this->offset(dx, dy, this);
|
||||
}
|
||||
|
||||
/** Transform the points in this path by matrix, and write the answer into
|
||||
dst.
|
||||
|
||||
@param matrix The matrix to apply to the path
|
||||
@param dst The transformed path is written here
|
||||
*/
|
||||
void transform(const SkMatrix& matrix, SkPath* dst) const;
|
||||
|
||||
/** Transform the points in this path by matrix
|
||||
|
||||
@param matrix The matrix to apply to the path
|
||||
*/
|
||||
void transform(const SkMatrix& matrix) {
|
||||
this->transform(matrix, this);
|
||||
}
|
||||
|
||||
/** Return the last point on the path. If no points have been added, (0,0)
|
||||
is returned.
|
||||
|
||||
@param lastPt The last point on the path is returned here
|
||||
*/
|
||||
void getLastPt(SkPoint* lastPt) const;
|
||||
|
||||
/** Set the last point on the path. If no points have been added,
|
||||
moveTo(x,y) is automatically called.
|
||||
|
||||
@param x The new x-coordinate for the last point
|
||||
@param y The new y-coordinate for the last point
|
||||
*/
|
||||
void setLastPt(SkScalar x, SkScalar y);
|
||||
|
||||
/** Set the last point on the path. If no points have been added, moveTo(p)
|
||||
is automatically called.
|
||||
|
||||
@param p The new location for the last point
|
||||
*/
|
||||
void setLastPt(const SkPoint& p) {
|
||||
this->setLastPt(p.fX, p.fY);
|
||||
}
|
||||
|
||||
enum Verb {
|
||||
kMove_Verb, //!< iter.next returns 1 point
|
||||
kLine_Verb, //!< iter.next returns 2 points
|
||||
kQuad_Verb, //!< iter.next returns 3 points
|
||||
kCubic_Verb, //!< iter.next returns 4 points
|
||||
kClose_Verb, //!< iter.next returns 1 point (the last point)
|
||||
kDone_Verb //!< iter.next returns 0 points
|
||||
};
|
||||
|
||||
/** Iterate through all of the segments (lines, quadratics, cubics) of
|
||||
each contours in a path.
|
||||
*/
|
||||
class Iter {
|
||||
public:
|
||||
Iter();
|
||||
Iter(const SkPath&, bool forceClose);
|
||||
|
||||
void setPath(const SkPath&, bool forceClose);
|
||||
|
||||
/** Return the next verb in this iteration of the path. When all
|
||||
segments have been visited, return kDone_Verb.
|
||||
|
||||
@param pts The points representing the current verb and/or segment
|
||||
@return The verb for the current segment
|
||||
*/
|
||||
Verb next(SkPoint pts[4]);
|
||||
|
||||
/** If next() returns kLine_Verb, then this query returns true if the
|
||||
line was the result of a close() command (i.e. the end point is the
|
||||
initial moveto for this contour). If next() returned a different
|
||||
verb, this returns an undefined value.
|
||||
|
||||
@return If the last call to next() returned kLine_Verb, return true
|
||||
if it was the result of an explicit close command.
|
||||
*/
|
||||
bool isCloseLine() const { return SkToBool(fCloseLine); }
|
||||
|
||||
/** Returns true if the current contour is closed (has a kClose_Verb)
|
||||
@return true if the current contour is closed (has a kClose_Verb)
|
||||
*/
|
||||
bool isClosedContour() const;
|
||||
|
||||
private:
|
||||
const SkPoint* fPts;
|
||||
const uint8_t* fVerbs;
|
||||
const uint8_t* fVerbStop;
|
||||
SkPoint fMoveTo;
|
||||
SkPoint fLastPt;
|
||||
SkBool8 fForceClose;
|
||||
SkBool8 fNeedClose;
|
||||
SkBool8 fNeedMoveTo;
|
||||
SkBool8 fCloseLine;
|
||||
|
||||
bool cons_moveTo(SkPoint pts[1]);
|
||||
Verb autoClose(SkPoint pts[2]);
|
||||
};
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** @cond UNIT_TEST */
|
||||
void dump(bool forceClose, const char title[] = NULL) const;
|
||||
static void UnitTest();
|
||||
/** @endcond */
|
||||
#endif
|
||||
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
void unflatten(SkFlattenableReadBuffer&);
|
||||
|
||||
/** Subdivide the path so that no segment is longer that dist.
|
||||
If bendLines is true, then turn all line segments into curves.
|
||||
If dst == null, then the original path itself is modified (not const!)
|
||||
*/
|
||||
void subdivide(SkScalar dist, bool bendLines, SkPath* dst = NULL) const;
|
||||
|
||||
/** Return an SVG-compatible string of the path.
|
||||
*/
|
||||
void toString(SkString*) const;
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
private:
|
||||
SkTDArray<SkPoint> fPts;
|
||||
SkTDArray<uint8_t> fVerbs;
|
||||
mutable SkRect fFastBounds;
|
||||
mutable uint8_t fFastBoundsIsDirty;
|
||||
uint8_t fFillType;
|
||||
|
||||
friend class Iter;
|
||||
void cons_moveto();
|
||||
|
||||
friend class SkPathStroker;
|
||||
/* Append the first contour of path, ignoring path's initial point. If no
|
||||
moveTo() call has been made for this contour, the first point is
|
||||
automatically set to (0,0).
|
||||
*/
|
||||
void pathTo(const SkPath& path);
|
||||
|
||||
/* Append, in reverse order, the first contour of path, ignoring path's
|
||||
last point. If no moveTo() call has been made for this contour, the
|
||||
first point is automatically set to (0,0).
|
||||
*/
|
||||
void reversePathTo(const SkPath&);
|
||||
|
||||
friend const SkPoint* sk_get_path_points(const SkPath&, int index);
|
||||
friend class SkAutoPathBoundsUpdate;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPathEffect_DEFINED
|
||||
#define SkPathEffect_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkPath;
|
||||
|
||||
/** \class SkPathEffect
|
||||
|
||||
SkPathEffect is the base class for objects in the SkPaint that affect
|
||||
the geometry of a drawing primitive before it is transformed by the
|
||||
canvas' matrix and drawn.
|
||||
|
||||
Dashing is implemented as a subclass of SkPathEffect.
|
||||
*/
|
||||
class SkPathEffect : public SkFlattenable {
|
||||
public:
|
||||
// This method is not exported to java.
|
||||
SkPathEffect() {}
|
||||
|
||||
/** Given a src path and a width value, return true if the patheffect
|
||||
has produced a new path (dst) and a new width value. If false is returned,
|
||||
ignore dst and width.
|
||||
On input, width >= 0 means the src should be stroked
|
||||
On output, width >= 0 means the dst should be stroked
|
||||
*/
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) = 0;
|
||||
|
||||
private:
|
||||
// illegal
|
||||
SkPathEffect(const SkPathEffect&);
|
||||
SkPathEffect& operator=(const SkPathEffect&);
|
||||
};
|
||||
|
||||
/** \class SkPairPathEffect
|
||||
|
||||
Common baseclass for Compose and Sum. This subclass manages two pathEffects,
|
||||
including flattening them. It does nothing in filterPath, and is only useful
|
||||
for managing the lifetimes of its two arguments.
|
||||
*/
|
||||
class SkPairPathEffect : public SkPathEffect {
|
||||
public:
|
||||
SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
|
||||
virtual ~SkPairPathEffect();
|
||||
|
||||
protected:
|
||||
SkPairPathEffect(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
// these are visible to our subclasses
|
||||
SkPathEffect* fPE0, *fPE1;
|
||||
|
||||
private:
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
/** \class SkComposePathEffect
|
||||
|
||||
This subclass of SkPathEffect composes its two arguments, to create
|
||||
a compound pathEffect.
|
||||
*/
|
||||
class SkComposePathEffect : public SkPairPathEffect {
|
||||
public:
|
||||
/** Construct a pathEffect whose effect is to apply first the inner pathEffect
|
||||
and the the outer pathEffect (e.g. outer(inner(path)))
|
||||
The reference counts for outer and inner are both incremented in the constructor,
|
||||
and decremented in the destructor.
|
||||
*/
|
||||
SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
|
||||
: INHERITED(outer, inner) {}
|
||||
|
||||
// overrides
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
protected:
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkComposePathEffect, (buffer));
|
||||
}
|
||||
SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
// illegal
|
||||
SkComposePathEffect(const SkComposePathEffect&);
|
||||
SkComposePathEffect& operator=(const SkComposePathEffect&);
|
||||
|
||||
typedef SkPairPathEffect INHERITED;
|
||||
};
|
||||
|
||||
/** \class SkSumPathEffect
|
||||
|
||||
This subclass of SkPathEffect applies two pathEffects, one after the other.
|
||||
Its filterPath() returns true if either of the effects succeeded.
|
||||
*/
|
||||
class SkSumPathEffect : public SkPairPathEffect {
|
||||
public:
|
||||
/** Construct a pathEffect whose effect is to apply two effects, in sequence.
|
||||
(e.g. first(path) + second(path))
|
||||
The reference counts for first and second are both incremented in the constructor,
|
||||
and decremented in the destructor.
|
||||
*/
|
||||
SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
|
||||
: INHERITED(first, second) {}
|
||||
|
||||
// overrides
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
protected:
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkSumPathEffect, (buffer));
|
||||
}
|
||||
SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
// illegal
|
||||
SkSumPathEffect(const SkSumPathEffect&);
|
||||
SkSumPathEffect& operator=(const SkSumPathEffect&);
|
||||
|
||||
typedef SkPairPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPathMeasure_DEFINED
|
||||
#define SkPathMeasure_DEFINED
|
||||
|
||||
#include "SkPath.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkPathMeasure : SkNoncopyable {
|
||||
public:
|
||||
SkPathMeasure();
|
||||
/** Initialize the pathmeasure with the specified path. The path must remain valid
|
||||
for the lifetime of the measure object, or until setPath() is called with
|
||||
a different path (or null), since the measure object keeps a pointer to the
|
||||
path object (does not copy its data).
|
||||
*/
|
||||
SkPathMeasure(const SkPath& path, bool forceClosed);
|
||||
~SkPathMeasure();
|
||||
|
||||
/** Reset the pathmeasure with the specified path. The path must remain valid
|
||||
for the lifetime of the measure object, or until setPath() is called with
|
||||
a different path (or null), since the measure object keeps a pointer to the
|
||||
path object (does not copy its data).
|
||||
*/
|
||||
void setPath(const SkPath*, bool forceClosed);
|
||||
|
||||
/** Return the total length of the current contour, or 0 if no path
|
||||
is associated (e.g. resetPath(null))
|
||||
*/
|
||||
SkScalar getLength();
|
||||
|
||||
/** Pins distance to 0 <= distance <= getLength(), and then computes
|
||||
the corresponding position and tangent.
|
||||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
position and tangent are unchanged.
|
||||
*/
|
||||
bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent);
|
||||
|
||||
enum MatrixFlags {
|
||||
kGetPosition_MatrixFlag = 0x01,
|
||||
kGetTangent_MatrixFlag = 0x02,
|
||||
kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
|
||||
};
|
||||
/** Pins distance to 0 <= distance <= getLength(), and then computes
|
||||
the corresponding matrix (by calling getPosTan).
|
||||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
matrix is unchanged.
|
||||
*/
|
||||
bool getMatrix(SkScalar distance, SkMatrix* matrix, MatrixFlags flags = kGetPosAndTan_MatrixFlag);
|
||||
/** Given a start and stop distance, return in dst the intervening segment(s).
|
||||
If the segment is zero-length, return false, else return true.
|
||||
startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
|
||||
then return false (and leave dst untouched).
|
||||
Begin the segment with a moveTo if startWithMoveTo is true
|
||||
*/
|
||||
bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
|
||||
|
||||
/** Return true if the current contour is closed()
|
||||
*/
|
||||
bool isClosed();
|
||||
|
||||
/** Move to the next contour in the path. Return true if one exists, or false if
|
||||
we're done with the path.
|
||||
*/
|
||||
bool nextContour();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void dump();
|
||||
static void UnitTest();
|
||||
#endif
|
||||
|
||||
private:
|
||||
SkPath::Iter fIter;
|
||||
const SkPath* fPath;
|
||||
SkScalar fLength; // relative to the current contour
|
||||
int fFirstPtIndex; // relative to the current contour
|
||||
bool fIsClosed; // relative to the current contour
|
||||
bool fForceClosed;
|
||||
|
||||
struct Segment {
|
||||
SkScalar fDistance; // total distance up to this point
|
||||
unsigned fPtIndex : 15;
|
||||
unsigned fTValue : 15;
|
||||
unsigned fType : 2;
|
||||
|
||||
SkScalar getScalarT() const;
|
||||
};
|
||||
SkTDArray<Segment> fSegments;
|
||||
|
||||
static const Segment* NextSegment(const Segment*);
|
||||
|
||||
void buildSegments();
|
||||
SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
|
||||
int mint, int maxt, int ptIndex);
|
||||
SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
|
||||
int mint, int maxt, int ptIndex);
|
||||
const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPerspIter_DEFINED
|
||||
#define SkPerspIter_DEFINED
|
||||
|
||||
#include "SkMatrix.h"
|
||||
|
||||
class SkPerspIter {
|
||||
public:
|
||||
/** Iterate a line through the matrix [x,y] ... [x+count-1, y].
|
||||
@param m The matrix we will be iterating a line through
|
||||
@param x The initial X coordinate to be mapped through the matrix
|
||||
@param y The initial Y coordinate to be mapped through the matrix
|
||||
@param count The number of points (x,y) (x+1,y) (x+2,y) ... we will eventually map
|
||||
*/
|
||||
SkPerspIter(const SkMatrix& m, SkScalar x, SkScalar y, int count);
|
||||
|
||||
/** Return the buffer of [x,y] fixed point values we will be filling.
|
||||
This always returns the same value, so it can be saved across calls to
|
||||
next().
|
||||
*/
|
||||
const SkFixed* getXY() const { return fStorage; }
|
||||
|
||||
/** Return the number of [x,y] pairs that have been filled in the getXY() buffer.
|
||||
When this returns 0, the iterator is finished.
|
||||
*/
|
||||
int next();
|
||||
|
||||
private:
|
||||
enum {
|
||||
kShift = 4,
|
||||
kCount = (1 << kShift)
|
||||
};
|
||||
const SkMatrix& fMatrix;
|
||||
SkFixed fStorage[kCount * 2];
|
||||
SkFixed fX, fY;
|
||||
SkScalar fSX, fSY;
|
||||
int fCount;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPicture_DEFINED
|
||||
#define SkPicture_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkPicturePlayback;
|
||||
class SkPictureRecord;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
/** \class SkPicture
|
||||
|
||||
The SkPicture class records the drawing commands made to a canvas, to
|
||||
be played back at a later time.
|
||||
*/
|
||||
class SkPicture : public SkRefCnt {
|
||||
public:
|
||||
/** The constructor prepares the picture to record.
|
||||
@param width the width of the virtual device the picture records.
|
||||
@param height the height of the virtual device the picture records.
|
||||
*/
|
||||
SkPicture();
|
||||
/** Make a copy of the contents of src. If src records more drawing after
|
||||
this call, those elements will not appear in this picture.
|
||||
*/
|
||||
SkPicture(const SkPicture& src);
|
||||
explicit SkPicture(SkStream*);
|
||||
virtual ~SkPicture();
|
||||
|
||||
/**
|
||||
* Swap the contents of the two pictures. Guaranteed to succeed.
|
||||
*/
|
||||
void swap(SkPicture& other);
|
||||
|
||||
/** Returns the canvas that records the drawing commands.
|
||||
@return the picture canvas.
|
||||
*/
|
||||
SkCanvas* beginRecording(int width, int height);
|
||||
/** Returns the recording canvas if one is active, or NULL if recording is
|
||||
not active. This does not alter the refcnt on the canvas (if present).
|
||||
*/
|
||||
SkCanvas* getRecordingCanvas() const;
|
||||
/** Signal that the caller is done recording. This invalidates the canvas
|
||||
returned by beginRecording/getRecordingCanvas, and prepares the picture
|
||||
for drawing. Note: this happens implicitly the first time the picture
|
||||
is drawn.
|
||||
*/
|
||||
void endRecording();
|
||||
|
||||
/** Replays the drawing commands on the specified canvas. This internally
|
||||
calls endRecording() if that has not already been called.
|
||||
@param surface the canvas receiving the drawing commands.
|
||||
*/
|
||||
void draw(SkCanvas* surface);
|
||||
|
||||
/** Return the width of the picture's recording canvas. This
|
||||
value reflects what was passed to setSize(), and does not necessarily
|
||||
reflect the bounds of what has been recorded into the picture.
|
||||
@return the width of the picture's recording canvas
|
||||
*/
|
||||
int width() const { return fWidth; }
|
||||
|
||||
/** Return the height of the picture's recording canvas. This
|
||||
value reflects what was passed to setSize(), and does not necessarily
|
||||
reflect the bounds of what has been recorded into the picture.
|
||||
@return the height of the picture's recording canvas
|
||||
*/
|
||||
int height() const { return fHeight; }
|
||||
|
||||
void serialize(SkWStream*) const;
|
||||
|
||||
/** Signals that the caller is prematurely done replaying the drawing
|
||||
commands. This can be called from a canvas virtual while the picture
|
||||
is drawing. Has no effect if the picture is not drawing.
|
||||
*/
|
||||
void abortPlayback();
|
||||
|
||||
private:
|
||||
int fWidth, fHeight;
|
||||
SkPictureRecord* fRecord;
|
||||
SkPicturePlayback* fPlayback;
|
||||
|
||||
friend class SkFlatPicture;
|
||||
friend class SkPicturePlayback;
|
||||
};
|
||||
|
||||
class SkAutoPictureRecord : SkNoncopyable {
|
||||
public:
|
||||
SkAutoPictureRecord(SkPicture* pict, int width, int height) {
|
||||
fPicture = pict;
|
||||
fCanvas = pict->beginRecording(width, height);
|
||||
}
|
||||
~SkAutoPictureRecord() {
|
||||
fPicture->endRecording();
|
||||
}
|
||||
|
||||
/** Return the canvas to draw into for recording into the picture.
|
||||
*/
|
||||
SkCanvas* getRecordingCanvas() const { return fCanvas; }
|
||||
|
||||
private:
|
||||
SkPicture* fPicture;
|
||||
SkCanvas* fCanvas;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPixelRef_DEFINED
|
||||
#define SkPixelRef_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
|
||||
class SkColorTable;
|
||||
class SkMutex;
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
|
||||
/** \class SkPixelRef
|
||||
|
||||
This class is the smart container for pixel memory, and is used with
|
||||
SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
|
||||
access the actual pixel memory by calling lockPixels/unlockPixels.
|
||||
|
||||
This class can be shared/accessed between multiple threads.
|
||||
*/
|
||||
class SkPixelRef : public SkRefCnt {
|
||||
public:
|
||||
explicit SkPixelRef(SkMutex* mutex = NULL);
|
||||
|
||||
/** Return the pixel memory returned from lockPixels, or null if the
|
||||
lockCount is 0.
|
||||
*/
|
||||
void* pixels() const { return fPixels; }
|
||||
|
||||
/** Return the current colorTable (if any) if pixels are locked, or null.
|
||||
*/
|
||||
SkColorTable* colorTable() const { return fColorTable; }
|
||||
|
||||
/** Return the current lockcount (defaults to 0)
|
||||
*/
|
||||
int getLockCount() const { return fLockCount; }
|
||||
|
||||
/** Call to access the pixel memory, which is returned. Balance with a call
|
||||
to unlockPixels().
|
||||
*/
|
||||
void lockPixels();
|
||||
/** Call to balanace a previous call to lockPixels(). Returns the pixels
|
||||
(or null) after the unlock. NOTE: lock calls can be nested, but the
|
||||
matching number of unlock calls must be made in order to free the
|
||||
memory (if the subclass implements caching/deferred-decoding.)
|
||||
*/
|
||||
void unlockPixels();
|
||||
|
||||
/** Returns a non-zero, unique value corresponding to the pixels in this
|
||||
pixelref. Each time the pixels are changed (and notifyPixelsChanged is
|
||||
called), a different generation ID will be returned.
|
||||
*/
|
||||
uint32_t getGenerationID() const;
|
||||
|
||||
/** Call this if you have changed the contents of the pixels. This will in-
|
||||
turn cause a different generation ID value to be returned from
|
||||
getGenerationID().
|
||||
*/
|
||||
void notifyPixelsChanged();
|
||||
|
||||
/** Returns true if this pixelref is marked as immutable, meaning that the
|
||||
contents of its pixels will not change for the lifetime of the pixelref.
|
||||
*/
|
||||
bool isImmutable() const { return fIsImmutable; }
|
||||
|
||||
/** Marks this pixelref is immutable, meaning that the contents of its
|
||||
pixels will not change for the lifetime of the pixelref. This state can
|
||||
be set on a pixelref, but it cannot be cleared once it is set.
|
||||
*/
|
||||
void setImmutable();
|
||||
|
||||
/** Return the optional URI string associated with this pixelref. May be
|
||||
null.
|
||||
*/
|
||||
const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
|
||||
|
||||
/** Copy a URI string to this pixelref, or clear the URI if the uri is null
|
||||
*/
|
||||
void setURI(const char uri[]) {
|
||||
fURI.set(uri);
|
||||
}
|
||||
|
||||
/** Copy a URI string to this pixelref
|
||||
*/
|
||||
void setURI(const char uri[], size_t len) {
|
||||
fURI.set(uri, len);
|
||||
}
|
||||
|
||||
/** Assign a URI string to this pixelref.
|
||||
*/
|
||||
void setURI(const SkString& uri) { fURI = uri; }
|
||||
|
||||
// serialization
|
||||
|
||||
typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
|
||||
|
||||
virtual Factory getFactory() const { return NULL; }
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const;
|
||||
|
||||
static Factory NameToFactory(const char name[]);
|
||||
static const char* FactoryToName(Factory);
|
||||
static void Register(const char name[], Factory);
|
||||
|
||||
class Registrar {
|
||||
public:
|
||||
Registrar(const char name[], Factory factory) {
|
||||
SkPixelRef::Register(name, factory);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
/** Called when the lockCount goes from 0 to 1. The caller will have already
|
||||
acquire a mutex for thread safety, so this method need not do that.
|
||||
*/
|
||||
virtual void* onLockPixels(SkColorTable**) = 0;
|
||||
/** Called when the lock count goes from 1 to 0. The caller will have
|
||||
already acquire a mutex for thread safety, so this method need not do
|
||||
that.
|
||||
*/
|
||||
virtual void onUnlockPixels() = 0;
|
||||
|
||||
/** Return the mutex associated with this pixelref. This value is assigned
|
||||
in the constructor, and cannot change during the lifetime of the object.
|
||||
*/
|
||||
SkMutex* mutex() const { return fMutex; }
|
||||
|
||||
SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
|
||||
|
||||
private:
|
||||
SkMutex* fMutex; // must remain in scope for the life of this object
|
||||
void* fPixels;
|
||||
SkColorTable* fColorTable; // we do not track ownership, subclass does
|
||||
int fLockCount;
|
||||
|
||||
mutable uint32_t fGenerationID;
|
||||
|
||||
SkString fURI;
|
||||
|
||||
// can go from false to true, but never from true to false
|
||||
bool fIsImmutable;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPoint_DEFINED
|
||||
#define SkPoint_DEFINED
|
||||
|
||||
#include "SkMath.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
/** \struct SkIPoint
|
||||
|
||||
SkIPoint holds two 32 bit integer coordinates
|
||||
*/
|
||||
struct SkIPoint {
|
||||
int32_t fX, fY;
|
||||
|
||||
/** Set the x and y values of the point. */
|
||||
void set(int32_t x, int32_t y) { fX = x; fY = y; }
|
||||
|
||||
/** Rotate the point clockwise, writing the new point into dst
|
||||
It is legal for dst == this
|
||||
*/
|
||||
void rotateCW(SkIPoint* dst) const;
|
||||
|
||||
/** Rotate the point clockwise, writing the new point back into the point
|
||||
*/
|
||||
|
||||
void rotateCW() { this->rotateCW(this); }
|
||||
|
||||
/** Rotate the point counter-clockwise, writing the new point into dst.
|
||||
It is legal for dst == this
|
||||
*/
|
||||
void rotateCCW(SkIPoint* dst) const;
|
||||
|
||||
/** Rotate the point counter-clockwise, writing the new point back into
|
||||
the point
|
||||
*/
|
||||
void rotateCCW() { this->rotateCCW(this); }
|
||||
|
||||
/** Negate the X and Y coordinates of the point.
|
||||
*/
|
||||
void negate() { fX = -fX; fY = -fY; }
|
||||
|
||||
/** Return a new point whose X and Y coordinates are the negative of the
|
||||
original point's
|
||||
*/
|
||||
SkIPoint operator-() const {
|
||||
SkIPoint neg;
|
||||
neg.fX = -fX;
|
||||
neg.fY = -fY;
|
||||
return neg;
|
||||
}
|
||||
|
||||
/** Add v's coordinates to this point's */
|
||||
void operator+=(const SkIPoint& v) {
|
||||
fX += v.fX;
|
||||
fY += v.fY;
|
||||
}
|
||||
|
||||
/** Subtract v's coordinates from this point's */
|
||||
void operator-=(const SkIPoint& v) {
|
||||
fX -= v.fX;
|
||||
fY -= v.fY;
|
||||
}
|
||||
|
||||
/** Returns true if the point's coordinates equal (x,y) */
|
||||
bool equals(int32_t x, int32_t y) const {
|
||||
return fX == x && fY == y;
|
||||
}
|
||||
|
||||
friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
|
||||
return a.fX == b.fX && a.fY == b.fY;
|
||||
}
|
||||
|
||||
friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
|
||||
return a.fX != b.fX || a.fY != b.fY;
|
||||
}
|
||||
|
||||
/** Returns a new point whose coordinates are the difference between
|
||||
a and b (i.e. a - b)
|
||||
*/
|
||||
friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) {
|
||||
SkIPoint v;
|
||||
v.set(a.fX - b.fX, a.fY - b.fY);
|
||||
return v;
|
||||
}
|
||||
|
||||
/** Returns a new point whose coordinates are the sum of a and b (a + b)
|
||||
*/
|
||||
friend SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) {
|
||||
SkIPoint v;
|
||||
v.set(a.fX + b.fX, a.fY + b.fY);
|
||||
return v;
|
||||
}
|
||||
|
||||
/** Returns the dot product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) {
|
||||
return a.fX * b.fX + a.fY * b.fY;
|
||||
}
|
||||
|
||||
/** Returns the cross product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static int32_t CrossProduct(const SkIPoint& a, const SkIPoint& b) {
|
||||
return a.fX * b.fY - a.fY * b.fX;
|
||||
}
|
||||
};
|
||||
|
||||
struct SkPoint {
|
||||
SkScalar fX, fY;
|
||||
|
||||
/** Set the point's X and Y coordinates */
|
||||
void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
|
||||
|
||||
/** Set the point's X and Y coordinates by automatically promoting (x,y) to
|
||||
SkScalar values.
|
||||
*/
|
||||
void iset(int32_t x, int32_t y) {
|
||||
fX = SkIntToScalar(x);
|
||||
fY = SkIntToScalar(y);
|
||||
}
|
||||
|
||||
/** Set the point's X and Y coordinates by automatically promoting p's
|
||||
coordinates to SkScalar values.
|
||||
*/
|
||||
void iset(const SkIPoint& p) {
|
||||
fX = SkIntToScalar(p.fX);
|
||||
fY = SkIntToScalar(p.fY);
|
||||
}
|
||||
|
||||
/** Return the euclidian distance from (0,0) to the point
|
||||
*/
|
||||
SkScalar length() const { return SkPoint::Length(fX, fY); }
|
||||
|
||||
/** Set the point (vector) to be unit-length in the same direction as it
|
||||
currently is, and return its old length. If the old length is
|
||||
degenerately small (nearly zero), do nothing and return false, otherwise
|
||||
return true.
|
||||
*/
|
||||
bool normalize();
|
||||
|
||||
/** Set the point (vector) to be unit-length in the same direction as the
|
||||
x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0)
|
||||
then return false and do nothing, otherwise return true.
|
||||
*/
|
||||
bool setNormalize(SkScalar x, SkScalar y);
|
||||
|
||||
/** Scale the point (vector) to have the specified length, and return that
|
||||
length. If the original length is degenerately small (nearly zero),
|
||||
do nothing and return false, otherwise return true.
|
||||
*/
|
||||
bool setLength(SkScalar length);
|
||||
|
||||
/** Set the point (vector) to have the specified length in the same
|
||||
direction as (x,y). If the vector (x,y) has a degenerate length
|
||||
(i.e. nearly 0) then return false and do nothing, otherwise return true.
|
||||
*/
|
||||
bool setLength(SkScalar x, SkScalar y, SkScalar length);
|
||||
|
||||
/** Scale the point's coordinates by scale, writing the answer into dst.
|
||||
It is legal for dst == this.
|
||||
*/
|
||||
void scale(SkScalar scale, SkPoint* dst) const;
|
||||
|
||||
/** Scale the point's coordinates by scale, writing the answer back into
|
||||
the point.
|
||||
*/
|
||||
void scale(SkScalar scale) { this->scale(scale, this); }
|
||||
|
||||
/** Rotate the point clockwise by 90 degrees, writing the answer into dst.
|
||||
It is legal for dst == this.
|
||||
*/
|
||||
void rotateCW(SkPoint* dst) const;
|
||||
|
||||
/** Rotate the point clockwise by 90 degrees, writing the answer back into
|
||||
the point.
|
||||
*/
|
||||
void rotateCW() { this->rotateCW(this); }
|
||||
|
||||
/** Rotate the point counter-clockwise by 90 degrees, writing the answer
|
||||
into dst. It is legal for dst == this.
|
||||
*/
|
||||
void rotateCCW(SkPoint* dst) const;
|
||||
|
||||
/** Rotate the point counter-clockwise by 90 degrees, writing the answer
|
||||
back into the point.
|
||||
*/
|
||||
void rotateCCW() { this->rotateCCW(this); }
|
||||
|
||||
/** Negate the point's coordinates
|
||||
*/
|
||||
void negate() {
|
||||
fX = -fX;
|
||||
fY = -fY;
|
||||
}
|
||||
|
||||
/** Returns a new point whose coordinates are the negative of the point's
|
||||
*/
|
||||
SkPoint operator-() const {
|
||||
SkPoint neg;
|
||||
neg.fX = -fX;
|
||||
neg.fY = -fY;
|
||||
return neg;
|
||||
}
|
||||
|
||||
/** Add v's coordinates to the point's
|
||||
*/
|
||||
void operator+=(const SkPoint& v) {
|
||||
fX += v.fX;
|
||||
fY += v.fY;
|
||||
}
|
||||
|
||||
/** Subtract v's coordinates from the point's
|
||||
*/
|
||||
void operator-=(const SkPoint& v) {
|
||||
fX -= v.fX;
|
||||
fY -= v.fY;
|
||||
}
|
||||
|
||||
/** Returns true if the point's coordinates equal (x,y)
|
||||
*/
|
||||
bool equals(SkScalar x, SkScalar y) const { return fX == x && fY == y; }
|
||||
|
||||
friend bool operator==(const SkPoint& a, const SkPoint& b) {
|
||||
return a.fX == b.fX && a.fY == b.fY;
|
||||
}
|
||||
|
||||
friend bool operator!=(const SkPoint& a, const SkPoint& b) {
|
||||
return a.fX != b.fX || a.fY != b.fY;
|
||||
}
|
||||
|
||||
/** Returns a new point whose coordinates are the difference between
|
||||
a's and b's (a - b)
|
||||
*/
|
||||
friend SkPoint operator-(const SkPoint& a, const SkPoint& b) {
|
||||
SkPoint v;
|
||||
v.set(a.fX - b.fX, a.fY - b.fY);
|
||||
return v;
|
||||
}
|
||||
|
||||
/** Returns a new point whose coordinates are the sum of a's and b's (a + b)
|
||||
*/
|
||||
friend SkPoint operator+(const SkPoint& a, const SkPoint& b) {
|
||||
SkPoint v;
|
||||
v.set(a.fX + b.fX, a.fY + b.fY);
|
||||
return v;
|
||||
}
|
||||
|
||||
/** Returns the euclidian distance from (0,0) to (x,y)
|
||||
*/
|
||||
static SkScalar Length(SkScalar x, SkScalar y);
|
||||
|
||||
/** Returns the euclidian distance between a and b
|
||||
*/
|
||||
static SkScalar Distance(const SkPoint& a, const SkPoint& b) {
|
||||
return Length(a.fX - b.fX, a.fY - b.fY);
|
||||
}
|
||||
|
||||
/** Returns the dot product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) {
|
||||
return SkScalarMul(a.fX, b.fX) + SkScalarMul(a.fY, b.fY);
|
||||
}
|
||||
|
||||
/** Returns the cross product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) {
|
||||
return SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX);
|
||||
}
|
||||
};
|
||||
|
||||
typedef SkPoint SkVector;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPorterDuff_DEFINED
|
||||
#define SkPorterDuff_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
|
||||
class SkXfermode;
|
||||
|
||||
class SkPorterDuff {
|
||||
public:
|
||||
/** List of predefined xfermodes. In general, the algebra for the modes
|
||||
uses the following symbols:
|
||||
Sa, Sc - source alpha and color
|
||||
Da, Dc - destination alpha and color (before compositing)
|
||||
[a, c] - Resulting (alpha, color) values
|
||||
For these equations, the colors are in premultiplied state.
|
||||
If no xfermode is specified, kSrcOver is assumed.
|
||||
*/
|
||||
enum Mode {
|
||||
kClear_Mode, //!< [0, 0]
|
||||
kSrc_Mode, //!< [Sa, Sc]
|
||||
kDst_Mode, //!< [Da, Dc]
|
||||
kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Sc + (1 - Sa)*Dc]
|
||||
kDstOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Dc + (1 - Da)*Sc]
|
||||
kSrcIn_Mode, //!< [Sa * Da, Sc * Da]
|
||||
kDstIn_Mode, //!< [Sa * Da, Sa * Dc]
|
||||
kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)]
|
||||
kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
|
||||
kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
|
||||
kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
|
||||
kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
|
||||
kDarken_Mode, //!< [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]
|
||||
kLighten_Mode, //!< [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]
|
||||
kMultiply_Mode, //!< [Sa * Da, Sc * Dc]
|
||||
kScreen_Mode, //!< [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
|
||||
|
||||
kModeCount
|
||||
};
|
||||
/** Return an SkXfermode object for the specified mode.
|
||||
*/
|
||||
static SkXfermode* CreateXfermode(Mode mode);
|
||||
|
||||
/** Return a function pointer to a routine that applies the specified
|
||||
porter-duff transfer mode.
|
||||
*/
|
||||
static SkXfermodeProc GetXfermodeProc(Mode mode);
|
||||
|
||||
/** Return a function pointer to a routine that applies the specified
|
||||
porter-duff transfer mode and srcColor to a 16bit device color. Note,
|
||||
if the mode+srcColor might return a non-opaque color, then there is not
|
||||
16bit proc, and this will return NULL.
|
||||
*/
|
||||
static SkXfermodeProc16 GetXfermodeProc16(Mode mode, SkColor srcColor);
|
||||
|
||||
/** If the specified xfermode advertises itself as one of the porterduff
|
||||
modes (via SkXfermode::Coeff), return true and if not null, set mode
|
||||
to the corresponding porterduff mode. If it is not recognized as a one,
|
||||
return false and ignore the mode parameter.
|
||||
*/
|
||||
static bool IsMode(SkXfermode*, Mode* mode);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPostConfig_DEFINED
|
||||
#define SkPostConfig_DEFINED
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
|
||||
#define SK_BUILD_FOR_WIN
|
||||
#endif
|
||||
|
||||
#if defined(SK_DEBUG) && defined(SK_RELEASE)
|
||||
#error "cannot define both SK_DEBUG and SK_RELEASE"
|
||||
#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
#error "must define either SK_DEBUG or SK_RELEASE"
|
||||
#endif
|
||||
|
||||
#if defined SK_SUPPORT_UNITTEST && !defined(SK_DEBUG)
|
||||
#error "can't have unittests without debug"
|
||||
#endif
|
||||
|
||||
#if defined(SK_SCALAR_IS_FIXED) && defined(SK_SCALAR_IS_FLOAT)
|
||||
#error "cannot define both SK_SCALAR_IS_FIXED and SK_SCALAR_IS_FLOAT"
|
||||
#elif !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#else
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SK_SCALAR_IS_FLOAT) && !defined(SK_CAN_USE_FLOAT)
|
||||
#define SK_CAN_USE_FLOAT
|
||||
// we do nothing in the else case: fixed-scalars can have floats or not
|
||||
#endif
|
||||
|
||||
#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
|
||||
#error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
|
||||
#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
|
||||
#error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
|
||||
#endif
|
||||
|
||||
// ensure the port has defined all of these, or none of them
|
||||
#ifdef SK_A32_SHIFT
|
||||
#if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
|
||||
#error "all or none of the 32bit SHIFT amounts must be defined"
|
||||
#endif
|
||||
#else
|
||||
#if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
|
||||
#error "all or none of the 32bit SHIFT amounts must be defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SkNEW
|
||||
#define SkNEW(type_name) new type_name
|
||||
#define SkNEW_ARGS(type_name, args) new type_name args
|
||||
#define SkNEW_ARRAY(type_name, count) new type_name[count]
|
||||
#define SkDELETE(obj) delete obj
|
||||
#define SkDELETE_ARRAY(array) delete[] array
|
||||
#endif
|
||||
|
||||
#ifndef SK_CRASH
|
||||
#if 1 // set to 0 for infinite loop, which can help connecting gdb
|
||||
#define SK_CRASH() *(int *)(uintptr_t)0xbbadbeef = 0
|
||||
#else
|
||||
#define SK_CRASH() do {} while (true)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(SK_SOFTWARE_FLOAT) && defined(SK_SCALAR_IS_FLOAT)
|
||||
// if this is defined, we convert floats to 2scompliment ints for compares
|
||||
#ifndef SK_SCALAR_SLOW_COMPARES
|
||||
#define SK_SCALAR_SLOW_COMPARES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) do { if (!(cond)) DebugBreak(); } while (false)
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define strcasecmp(a, b) stricmp(a, b)
|
||||
#define strncasecmp(a, b, c) strnicmp(a, b, c)
|
||||
#elif defined(SK_BUILD_FOR_WINCE)
|
||||
#define strcasecmp(a, b) _stricmp(a, b)
|
||||
#define strncasecmp(a, b, c) _strnicmp(a, b, c)
|
||||
#endif
|
||||
#elif defined(SK_BUILD_FOR_MAC)
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) do { if (!(cond)) SK_CRASH(); } while (false)
|
||||
#endif
|
||||
#else
|
||||
#ifdef SK_DEBUG
|
||||
#include <stdio.h>
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) do { if (cond) break; \
|
||||
SkDebugf("%s:%d: failed assertion \"%s\"\n", \
|
||||
__FILE__, __LINE__, #cond); SK_CRASH(); } while (false)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// stdlib macros
|
||||
|
||||
#if 0
|
||||
#if !defined(strlen) && defined(SK_DEBUG)
|
||||
extern size_t sk_strlen(const char*);
|
||||
#define strlen(s) sk_strlen(s)
|
||||
#endif
|
||||
#ifndef sk_strcpy
|
||||
#define sk_strcpy(dst, src) strcpy(dst, src)
|
||||
#endif
|
||||
#ifndef sk_strchr
|
||||
#define sk_strchr(s, c) strchr(s, c)
|
||||
#endif
|
||||
#ifndef sk_strrchr
|
||||
#define sk_strrchr(s, c) strrchr(s, c)
|
||||
#endif
|
||||
#ifndef sk_strcmp
|
||||
#define sk_strcmp(s, t) strcmp(s, t)
|
||||
#endif
|
||||
#ifndef sk_strncmp
|
||||
#define sk_strncmp(s, t, n) strncmp(s, t, n)
|
||||
#endif
|
||||
#ifndef sk_memcpy
|
||||
#define sk_memcpy(dst, src, n) memcpy(dst, src, n)
|
||||
#endif
|
||||
#ifndef memmove
|
||||
#define memmove(dst, src, n) memmove(dst, src, n)
|
||||
#endif
|
||||
#ifndef sk_memset
|
||||
#define sk_memset(dst, val, n) memset(dst, val, n)
|
||||
#endif
|
||||
#ifndef sk_memcmp
|
||||
#define sk_memcmp(s, t, n) memcmp(s, t, n)
|
||||
#endif
|
||||
|
||||
#define sk_strequal(s, t) (!sk_strcmp(s, t))
|
||||
#define sk_strnequal(s, t, n) (!sk_strncmp(s, t, n))
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SK_BUILD_FOR_WINCE
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#define _CMNINTRIN_DECLARE_ONLY
|
||||
#include "cmnintrin.h"
|
||||
#endif
|
||||
|
||||
#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
|
||||
//#define _CRTDBG_MAP_ALLOC
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
#include <crtdbg.h>
|
||||
#undef free
|
||||
|
||||
#ifdef SK_DEBUGx
|
||||
#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
|
||||
void * operator new(
|
||||
size_t cb,
|
||||
int nBlockUse,
|
||||
const char * szFileName,
|
||||
int nLine,
|
||||
int foo
|
||||
);
|
||||
void * operator new[](
|
||||
size_t cb,
|
||||
int nBlockUse,
|
||||
const char * szFileName,
|
||||
int nLine,
|
||||
int foo
|
||||
);
|
||||
void operator delete(
|
||||
void *pUserData,
|
||||
int, const char*, int, int
|
||||
);
|
||||
void operator delete(
|
||||
void *pUserData
|
||||
);
|
||||
void operator delete[]( void * p );
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
|
||||
#else
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
|
||||
#endif
|
||||
#define new DEBUG_CLIENTBLOCK
|
||||
#else
|
||||
#define DEBUG_CLIENTBLOCK
|
||||
#endif // _DEBUG
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPreConfig_DEFINED
|
||||
#define SkPreConfig_DEFINED
|
||||
|
||||
#ifdef ANDROID
|
||||
#define SK_BUILD_FOR_UNIX
|
||||
#define SkLONGLONG int64_t
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC)
|
||||
|
||||
#if defined(PALMOS_SDK_VERSION)
|
||||
#define SK_BUILD_FOR_PALM
|
||||
#elif defined(UNDER_CE)
|
||||
#define SK_BUILD_FOR_WINCE
|
||||
#elif defined(WIN32)
|
||||
#define SK_BUILD_FOR_WIN32
|
||||
#elif defined(__SYMBIAN32__)
|
||||
#define SK_BUILD_FOR_WIN32
|
||||
#elif defined(linux)
|
||||
#define SK_BUILD_FOR_UNIX
|
||||
#else
|
||||
#define SK_BUILD_FOR_MAC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
#ifdef NDEBUG
|
||||
#define SK_RELEASE
|
||||
#else
|
||||
#define SK_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// define to blank or change this in SkUserConfig.h as needed
|
||||
#define SK_RESTRICT __restrict__
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
|
||||
#ifndef SK_CAN_USE_FLOAT
|
||||
#define SK_CAN_USE_FLOAT
|
||||
#endif
|
||||
#if !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
#endif
|
||||
|
||||
#ifndef SkLONGLONG
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define SkLONGLONG __int64
|
||||
#else
|
||||
#define SkLONGLONG long long
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
|
||||
#if defined (__ppc__) || defined(__ppc64__)
|
||||
#define SK_CPU_BENDIAN
|
||||
#else
|
||||
#define SK_CPU_LENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if (defined(__arm__) && !defined(__thumb__)) || defined(SK_BUILD_FOR_BREW) || defined(SK_BUILD_FOR_WINCE) || (defined(SK_BUILD_FOR_SYMBIAN) && !defined(__MARM_THUMB__))
|
||||
/* e.g. the ARM instructions have conditional execution, making tiny branches cheap */
|
||||
#define SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Conditional features based on build target
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
|
||||
#ifndef SK_BUILD_NO_IMAGE_ENCODE
|
||||
#define SK_SUPPORT_IMAGE_ENCODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_SYMBIAN
|
||||
#define SK_USE_RUNTIME_GLOBALS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPtrRecorder_DEFINED
|
||||
#define SkPtrRecorder_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkPtrRecorder : public SkRefCnt {
|
||||
public:
|
||||
uint32_t recordPtr(void*);
|
||||
|
||||
int count() const { return fList.count(); }
|
||||
void getPtrs(void* array[]) const;
|
||||
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
virtual void incPtr(void* ptr) {}
|
||||
virtual void decPtr(void* ptr) {}
|
||||
|
||||
private:
|
||||
struct Pair {
|
||||
void* fPtr;
|
||||
uint32_t fIndex;
|
||||
};
|
||||
SkTDArray<Pair> fList;
|
||||
|
||||
static int Cmp(const Pair& a, const Pair& b);
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkRandom_DEFINED
|
||||
#define SkRandom_DEFINED
|
||||
|
||||
#include "Sk64.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
/** \class SkRandom
|
||||
|
||||
Utility class that implements pseudo random 32bit numbers using a fast
|
||||
linear equation. Unlike rand(), this class holds its own seed (initially
|
||||
set to 0), so that multiple instances can be used with no side-effects.
|
||||
*/
|
||||
class SkRandom {
|
||||
public:
|
||||
SkRandom() : fSeed(0) {}
|
||||
SkRandom(uint32_t seed) : fSeed(seed) {}
|
||||
|
||||
/** Return the next pseudo random number as an unsigned 32bit value.
|
||||
*/
|
||||
uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }
|
||||
|
||||
/** Return the next pseudo random number as a signed 32bit value.
|
||||
*/
|
||||
int32_t nextS() { return (int32_t)this->nextU(); }
|
||||
|
||||
/** Return the next pseudo random number as an unsigned 16bit value.
|
||||
*/
|
||||
U16CPU nextU16() { return this->nextU() >> 16; }
|
||||
|
||||
/** Return the next pseudo random number as a signed 16bit value.
|
||||
*/
|
||||
S16CPU nextS16() { return this->nextS() >> 16; }
|
||||
|
||||
/** Return the next pseudo random number, as an unsigned value of
|
||||
at most bitCount bits.
|
||||
@param bitCount The maximum number of bits to be returned
|
||||
*/
|
||||
uint32_t nextBits(unsigned bitCount) {
|
||||
SkASSERT(bitCount > 0 && bitCount <= 32);
|
||||
return this->nextU() >> (32 - bitCount);
|
||||
}
|
||||
|
||||
/** Return the next pseudo random unsigned number, mapped to lie within
|
||||
[min, max] inclusive.
|
||||
*/
|
||||
uint32_t nextRangeU(uint32_t min, uint32_t max) {
|
||||
SkASSERT(min <= max);
|
||||
return min + this->nextU() % (max - min + 1);
|
||||
}
|
||||
|
||||
/** Return the next pseudo random number expressed as an unsigned SkFixed
|
||||
in the range [0..SK_Fixed1).
|
||||
*/
|
||||
SkFixed nextUFixed1() { return this->nextU() >> 16; }
|
||||
|
||||
/** Return the next pseudo random number expressed as a signed SkFixed
|
||||
in the range (-SK_Fixed1..SK_Fixed1).
|
||||
*/
|
||||
SkFixed nextSFixed1() { return this->nextS() >> 15; }
|
||||
|
||||
/** Return the next pseudo random number expressed as a SkScalar
|
||||
in the range [0..SK_Scalar1).
|
||||
*/
|
||||
SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
|
||||
|
||||
/** Return the next pseudo random number expressed as a SkScalar
|
||||
in the range (-SK_Scalar1..SK_Scalar1).
|
||||
*/
|
||||
SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
|
||||
|
||||
/** Return the next pseudo random number as a signed 64bit value.
|
||||
*/
|
||||
void next64(Sk64* a) {
|
||||
SkASSERT(a);
|
||||
a->set(this->nextS(), this->nextU());
|
||||
}
|
||||
|
||||
/** Set the seed of the random object. The seed is initialized to 0 when the
|
||||
object is first created, and is updated each time the next pseudo random
|
||||
number is requested.
|
||||
*/
|
||||
void setSeed(int32_t seed) { fSeed = (uint32_t)seed; }
|
||||
|
||||
private:
|
||||
// See "Numerical Recipes in C", 1992 page 284 for these constants
|
||||
enum {
|
||||
kMul = 1664525,
|
||||
kAdd = 1013904223
|
||||
};
|
||||
uint32_t fSeed;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkRasterizer_DEFINED
|
||||
#define SkRasterizer_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkMask.h"
|
||||
|
||||
class SkMaskFilter;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
struct SkIRect;
|
||||
|
||||
class SkRasterizer : public SkFlattenable {
|
||||
public:
|
||||
SkRasterizer() {}
|
||||
|
||||
/** Turn the path into a mask, respecting the specified local->device matrix.
|
||||
*/
|
||||
bool rasterize(const SkPath& path, const SkMatrix& matrix,
|
||||
const SkIRect* clipBounds, SkMaskFilter* filter,
|
||||
SkMask* mask, SkMask::CreateMode mode);
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer& ) {}
|
||||
protected:
|
||||
SkRasterizer(SkFlattenableReadBuffer&);
|
||||
|
||||
virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
|
||||
const SkIRect* clipBounds,
|
||||
SkMask* mask, SkMask::CreateMode mode);
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkReader32_DEFINED
|
||||
#define SkReader32_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkReader32 : SkNoncopyable {
|
||||
public:
|
||||
SkReader32() : fCurr(NULL), fStop(NULL), fBase(NULL) {}
|
||||
SkReader32(const void* data, size_t size) {
|
||||
this->setMemory(data, size);
|
||||
}
|
||||
|
||||
void setMemory(const void* data, size_t size) {
|
||||
SkASSERT(ptr_align_4(data));
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
|
||||
fBase = fCurr = (const char*)data;
|
||||
fStop = (const char*)data + size;
|
||||
}
|
||||
|
||||
uint32_t size() const { return fStop - fBase; }
|
||||
uint32_t offset() const { return fCurr - fBase; }
|
||||
bool eof() const { return fCurr >= fStop; }
|
||||
const void* base() const { return fBase; }
|
||||
const void* peek() const { return fCurr; }
|
||||
void rewind() { fCurr = fBase; }
|
||||
|
||||
void setOffset(size_t offset) {
|
||||
SkASSERT(SkAlign4(offset) == offset);
|
||||
SkASSERT(offset <= this->size());
|
||||
fCurr = fBase + offset;
|
||||
}
|
||||
|
||||
bool readBool() { return this->readInt() != 0; }
|
||||
|
||||
int32_t readInt() {
|
||||
SkASSERT(ptr_align_4(fCurr));
|
||||
int32_t value = *(const int32_t*)fCurr;
|
||||
fCurr += sizeof(value);
|
||||
SkASSERT(fCurr <= fStop);
|
||||
return value;
|
||||
}
|
||||
|
||||
SkScalar readScalar() {
|
||||
SkASSERT(ptr_align_4(fCurr));
|
||||
SkScalar value = *(const SkScalar*)fCurr;
|
||||
fCurr += sizeof(value);
|
||||
SkASSERT(fCurr <= fStop);
|
||||
return value;
|
||||
}
|
||||
|
||||
const SkPoint* skipPoint() {
|
||||
return (const SkPoint*)this->skip(sizeof(SkPoint));
|
||||
}
|
||||
|
||||
const SkRect* skipRect() {
|
||||
return (const SkRect*)this->skip(sizeof(SkRect));
|
||||
}
|
||||
|
||||
const void* skip(size_t size) {
|
||||
SkASSERT(ptr_align_4(fCurr));
|
||||
const void* addr = fCurr;
|
||||
fCurr += SkAlign4(size);
|
||||
SkASSERT(fCurr <= fStop);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void read(void* dst, size_t size) {
|
||||
SkASSERT(dst != NULL);
|
||||
SkASSERT(ptr_align_4(fCurr));
|
||||
memcpy(dst, fCurr, size);
|
||||
fCurr += SkAlign4(size);
|
||||
SkASSERT(fCurr <= fStop);
|
||||
}
|
||||
|
||||
uint8_t readU8() { return (uint8_t)this->readInt(); }
|
||||
uint16_t readU16() { return (uint16_t)this->readInt(); }
|
||||
int32_t readS32() { return this->readInt(); }
|
||||
uint32_t readU32() { return this->readInt(); }
|
||||
|
||||
private:
|
||||
// these are always 4-byte aligned
|
||||
const char* fCurr; // current position within buffer
|
||||
const char* fStop; // end of buffer
|
||||
const char* fBase; // beginning of buffer
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static bool ptr_align_4(const void* ptr)
|
||||
{
|
||||
return (((const char*)ptr - (const char*)NULL) & 3) == 0;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkRect_DEFINED
|
||||
#define SkRect_DEFINED
|
||||
|
||||
#include "SkPoint.h"
|
||||
|
||||
/** \struct SkIRect
|
||||
|
||||
SkIRect holds four 32 bit integer coordinates for a rectangle
|
||||
*/
|
||||
struct SkIRect {
|
||||
int32_t fLeft, fTop, fRight, fBottom;
|
||||
|
||||
/** Return true if the rectangle's width or height are <= 0
|
||||
*/
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
|
||||
/** Returns the rectangle's width. This does not check for a valid rectangle (i.e. left <= right)
|
||||
so the result may be negative.
|
||||
*/
|
||||
int width() const { return fRight - fLeft; }
|
||||
|
||||
/** Returns the rectangle's height. This does not check for a valid rectangle (i.e. top <= bottom)
|
||||
so the result may be negative.
|
||||
*/
|
||||
int height() const { return fBottom - fTop; }
|
||||
|
||||
friend int operator==(const SkIRect& a, const SkIRect& b)
|
||||
{
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
friend int operator!=(const SkIRect& a, const SkIRect& b)
|
||||
{
|
||||
return memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
/** Set the rectangle to (0,0,0,0)
|
||||
*/
|
||||
void setEmpty() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
void set(int32_t left, int32_t top, int32_t right, int32_t bottom)
|
||||
{
|
||||
fLeft = left;
|
||||
fTop = top;
|
||||
fRight = right;
|
||||
fBottom = bottom;
|
||||
}
|
||||
|
||||
/** Offset set the rectangle by adding dx to its left and right,
|
||||
and adding dy to its top and bottom.
|
||||
*/
|
||||
void offset(int32_t dx, int32_t dy)
|
||||
{
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight += dx;
|
||||
fBottom += dy;
|
||||
}
|
||||
|
||||
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
|
||||
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
|
||||
making the rectangle wider. The same hods true for dy and the top and bottom.
|
||||
*/
|
||||
void inset(int32_t dx, int32_t dy)
|
||||
{
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight -= dx;
|
||||
fBottom -= dy;
|
||||
}
|
||||
/** Returns true if (x,y) is inside the rectangle and the rectangle is not
|
||||
empty. The left and top are considered to be inside, while the right
|
||||
and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
|
||||
points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not.
|
||||
*/
|
||||
bool contains(int32_t x, int32_t y) const
|
||||
{
|
||||
return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) &&
|
||||
(unsigned)(y - fTop) < (unsigned)(fBottom - fTop);
|
||||
}
|
||||
|
||||
/** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle.
|
||||
If either rectangle is empty, contains() returns false.
|
||||
*/
|
||||
bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const
|
||||
{
|
||||
return left < right && top < bottom && !this->isEmpty() && // check for empties
|
||||
fLeft <= left && fTop <= top &&
|
||||
fRight >= right && fBottom >= bottom;
|
||||
}
|
||||
|
||||
/** Returns true if the specified rectangle r is inside or equal to this rectangle.
|
||||
*/
|
||||
bool contains(const SkIRect& r) const
|
||||
{
|
||||
return !r.isEmpty() && !this->isEmpty() && // check for empties
|
||||
fLeft <= r.fLeft && fTop <= r.fTop &&
|
||||
fRight >= r.fRight && fBottom >= r.fBottom;
|
||||
}
|
||||
|
||||
/** Return true if this rectangle contains the specified rectangle.
|
||||
For speed, this method does not check if either this or the specified
|
||||
rectangles are empty, and if either is, its return value is undefined.
|
||||
In the debugging build however, we assert that both this and the
|
||||
specified rectangles are non-empty.
|
||||
*/
|
||||
bool containsNoEmptyCheck(int32_t left, int32_t top,
|
||||
int32_t right, int32_t bottom) const
|
||||
{
|
||||
SkASSERT(fLeft < fRight && fTop < fBottom);
|
||||
SkASSERT(left < right && top < bottom);
|
||||
|
||||
return fLeft <= left && fTop <= top &&
|
||||
fRight >= right && fBottom >= bottom;
|
||||
}
|
||||
|
||||
/** If r intersects this rectangle, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
*/
|
||||
bool intersect(const SkIRect& r)
|
||||
{
|
||||
SkASSERT(&r);
|
||||
return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
}
|
||||
|
||||
/** If rectangles a and b intersect, return true and set this rectangle to
|
||||
that intersection, otherwise return false and do not change this
|
||||
rectangle. If either rectangle is empty, do nothing and return false.
|
||||
*/
|
||||
bool intersect(const SkIRect& a, const SkIRect& b)
|
||||
{
|
||||
SkASSERT(&a && &b);
|
||||
|
||||
if (!a.isEmpty() && !b.isEmpty() &&
|
||||
a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom)
|
||||
{
|
||||
fLeft = SkMax32(a.fLeft, b.fLeft);
|
||||
fTop = SkMax32(a.fTop, b.fTop);
|
||||
fRight = SkMin32(a.fRight, b.fRight);
|
||||
fBottom = SkMin32(a.fBottom, b.fBottom);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** If rectangles a and b intersect, return true and set this rectangle to
|
||||
that intersection, otherwise return false and do not change this
|
||||
rectangle. For speed, no check to see if a or b are empty is performed.
|
||||
If either is, then the return result is undefined. In the debug build,
|
||||
we assert that both rectangles are non-empty.
|
||||
*/
|
||||
bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b)
|
||||
{
|
||||
SkASSERT(&a && &b);
|
||||
SkASSERT(!a.isEmpty() && !b.isEmpty());
|
||||
|
||||
if (a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom)
|
||||
{
|
||||
fLeft = SkMax32(a.fLeft, b.fLeft);
|
||||
fTop = SkMax32(a.fTop, b.fTop);
|
||||
fRight = SkMin32(a.fRight, b.fRight);
|
||||
fBottom = SkMin32(a.fBottom, b.fBottom);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** If the rectangle specified by left,top,right,bottom intersects this rectangle,
|
||||
return true and set this rectangle to that intersection,
|
||||
otherwise return false and do not change this rectangle.
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
*/
|
||||
bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom)
|
||||
{
|
||||
if (left < right && top < bottom && !this->isEmpty() &&
|
||||
fLeft < right && left < fRight && fTop < bottom && top < fBottom)
|
||||
{
|
||||
if (fLeft < left) fLeft = left;
|
||||
if (fTop < top) fTop = top;
|
||||
if (fRight > right) fRight = right;
|
||||
if (fBottom > bottom) fBottom = bottom;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns true if a and b are not empty, and they intersect
|
||||
*/
|
||||
static bool Intersects(const SkIRect& a, const SkIRect& b)
|
||||
{
|
||||
return !a.isEmpty() && !b.isEmpty() && // check for empties
|
||||
a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
|
||||
/** Update this rectangle to enclose itself and the specified rectangle.
|
||||
If this rectangle is empty, just set it to the specified rectangle. If the specified
|
||||
rectangle is empty, do nothing.
|
||||
*/
|
||||
void join(int32_t left, int32_t top, int32_t right, int32_t bottom);
|
||||
|
||||
/** Update this rectangle to enclose itself and the specified rectangle.
|
||||
If this rectangle is empty, just set it to the specified rectangle. If the specified
|
||||
rectangle is empty, do nothing.
|
||||
*/
|
||||
void join(const SkIRect& r)
|
||||
{
|
||||
this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
}
|
||||
|
||||
/** Swap top/bottom or left/right if there are flipped.
|
||||
This can be called if the edges are computed separately,
|
||||
and may have crossed over each other.
|
||||
When this returns, left <= right && top <= bottom
|
||||
*/
|
||||
void sort();
|
||||
};
|
||||
|
||||
/** \struct SkRect
|
||||
*/
|
||||
struct SkRect {
|
||||
SkScalar fLeft, fTop, fRight, fBottom;
|
||||
|
||||
/** Return true if the rectangle's width or height are <= 0
|
||||
*/
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
SkScalar width() const { return fRight - fLeft; }
|
||||
SkScalar height() const { return fBottom - fTop; }
|
||||
SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); }
|
||||
SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); }
|
||||
|
||||
friend int operator==(const SkRect& a, const SkRect& b)
|
||||
{
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
friend int operator!=(const SkRect& a, const SkRect& b)
|
||||
{
|
||||
return memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
|
||||
/** return the 4 points that enclose the rectangle
|
||||
*/
|
||||
void toQuad(SkPoint quad[4]) const;
|
||||
|
||||
/** Set this rectangle to the empty rectangle (0,0,0,0)
|
||||
*/
|
||||
void setEmpty() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
void set(const SkIRect& src)
|
||||
{
|
||||
fLeft = SkIntToScalar(src.fLeft);
|
||||
fTop = SkIntToScalar(src.fTop);
|
||||
fRight = SkIntToScalar(src.fRight);
|
||||
fBottom = SkIntToScalar(src.fBottom);
|
||||
}
|
||||
|
||||
void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
|
||||
{
|
||||
fLeft = left;
|
||||
fTop = top;
|
||||
fRight = right;
|
||||
fBottom = bottom;
|
||||
}
|
||||
|
||||
/** Initialize the rect with the 4 specified integers. The routine handles
|
||||
converting them to scalars (by calling SkIntToScalar)
|
||||
*/
|
||||
void iset(int left, int top, int right, int bottom) {
|
||||
fLeft = SkIntToScalar(left);
|
||||
fTop = SkIntToScalar(top);
|
||||
fRight = SkIntToScalar(right);
|
||||
fBottom = SkIntToScalar(bottom);
|
||||
}
|
||||
|
||||
/** Set this rectangle to be the bounds of the array of points.
|
||||
If the array is empty (count == 0), then set this rectangle
|
||||
to the empty rectangle (0,0,0,0)
|
||||
*/
|
||||
void set(const SkPoint pts[], int count);
|
||||
|
||||
/** Offset set the rectangle by adding dx to its left and right,
|
||||
and adding dy to its top and bottom.
|
||||
*/
|
||||
void offset(SkScalar dx, SkScalar dy)
|
||||
{
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight += dx;
|
||||
fBottom += dy;
|
||||
}
|
||||
|
||||
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
|
||||
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
|
||||
making the rectangle wider. The same hods true for dy and the top and bottom.
|
||||
*/
|
||||
void inset(SkScalar dx, SkScalar dy)
|
||||
{
|
||||
fLeft += dx;
|
||||
fTop += dy;
|
||||
fRight -= dx;
|
||||
fBottom -= dy;
|
||||
}
|
||||
|
||||
/** If this rectangle intersects r, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
*/
|
||||
bool intersect(const SkRect& r);
|
||||
|
||||
/** If this rectangle intersects the rectangle specified by left, top, right, bottom,
|
||||
return true and set this rectangle to that intersection, otherwise return false
|
||||
and do not change this rectangle.
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
*/
|
||||
bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
|
||||
|
||||
/** Return true if this rectangle is not empty, and the specified sides of
|
||||
a rectangle are not empty, and they intersect.
|
||||
*/
|
||||
bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const
|
||||
{
|
||||
return // first check that both are not empty
|
||||
left < right && top < bottom &&
|
||||
fLeft < fRight && fTop < fBottom &&
|
||||
// now check for intersection
|
||||
fLeft < right && left < fRight &&
|
||||
fTop < bottom && top < fBottom;
|
||||
}
|
||||
|
||||
/** Return true if rectangles a and b are not empty and intersect.
|
||||
*/
|
||||
static bool Intersects(const SkRect& a, const SkRect& b)
|
||||
{
|
||||
return !a.isEmpty() && !b.isEmpty() && // check for empties
|
||||
a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
|
||||
/** Update this rectangle to enclose itself and the specified rectangle.
|
||||
If this rectangle is empty, just set it to the specified rectangle. If the specified
|
||||
rectangle is empty, do nothing.
|
||||
*/
|
||||
void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
|
||||
|
||||
/** Update this rectangle to enclose itself and the specified rectangle.
|
||||
If this rectangle is empty, just set it to the specified rectangle. If the specified
|
||||
rectangle is empty, do nothing.
|
||||
*/
|
||||
void join(const SkRect& r)
|
||||
{
|
||||
this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
}
|
||||
|
||||
/** Returns true if (p.fX,p.fY) is inside the rectangle. The left and top coordinates of
|
||||
the rectangle are considered to be inside, while the right and bottom coordinates
|
||||
are not. Thus for the rectangle (0, 0, 5, 10), the points (0,0) and (0,9) are inside,
|
||||
while (-1,0) and (5,9) are not.
|
||||
If this rectangle is empty, return false.
|
||||
*/
|
||||
bool contains(const SkPoint& p) const
|
||||
{
|
||||
return !this->isEmpty() &&
|
||||
fLeft <= p.fX && p.fX < fRight &&
|
||||
fTop <= p.fY && p.fY < fBottom;
|
||||
}
|
||||
|
||||
/** Returns true if (x,y) is inside the rectangle. The left and top coordinates of
|
||||
the rectangle are considered to be inside, while the right and bottom coordinates
|
||||
are not. Thus for the rectangle (0, 0, 5, 10), the points (0,0) and (0,9) are inside,
|
||||
while (-1,0) and (5,9) are not.
|
||||
If this rectangle is empty, return false.
|
||||
*/
|
||||
bool contains(SkScalar x, SkScalar y) const
|
||||
{
|
||||
return !this->isEmpty() &&
|
||||
fLeft <= x && x < fRight &&
|
||||
fTop <= y && y < fBottom;
|
||||
}
|
||||
|
||||
/** Return true if this rectangle contains r.
|
||||
If either rectangle is empty, return false.
|
||||
*/
|
||||
bool contains(const SkRect& r) const
|
||||
{
|
||||
return !r.isEmpty() && !this->isEmpty() && // check for empties
|
||||
fLeft <= r.fLeft && fTop <= r.fTop &&
|
||||
fRight >= r.fRight && fBottom >= r.fBottom;
|
||||
}
|
||||
|
||||
/** Set the dst integer rectangle by rounding this rectangle's coordinates
|
||||
to their nearest integer values.
|
||||
*/
|
||||
void round(SkIRect* dst) const
|
||||
{
|
||||
SkASSERT(dst);
|
||||
dst->set(SkScalarRound(fLeft), SkScalarRound(fTop), SkScalarRound(fRight), SkScalarRound(fBottom));
|
||||
}
|
||||
|
||||
/** Set the dst integer rectangle by rounding "out" this rectangle, choosing the floor of top and left,
|
||||
and the ceiling of right and bototm.
|
||||
*/
|
||||
void roundOut(SkIRect* dst) const
|
||||
{
|
||||
SkASSERT(dst);
|
||||
dst->set(SkScalarFloor(fLeft), SkScalarFloor(fTop), SkScalarCeil(fRight), SkScalarCeil(fBottom));
|
||||
}
|
||||
|
||||
/** Swap top/bottom or left/right if there are flipped.
|
||||
This can be called if the edges are computed separately,
|
||||
and may have crossed over each other.
|
||||
When this returns, left <= right && top <= bottom
|
||||
*/
|
||||
void sort();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkRefCnt_DEFINED
|
||||
#define SkRefCnt_DEFINED
|
||||
|
||||
#include "SkThread.h"
|
||||
|
||||
/** \class SkRefCnt
|
||||
|
||||
SkRefCnt is the base class for objects that may be shared by multiple
|
||||
objects. When a new owner wants a reference, it calls ref(). When an owner
|
||||
wants to release its reference, it calls unref(). When the shared object's
|
||||
reference count goes to zero as the result of an unref() call, its (virtual)
|
||||
destructor is called. It is an error for the destructor to be called
|
||||
explicitly (or via the object going out of scope on the stack or calling
|
||||
delete) if getRefCnt() > 1.
|
||||
*/
|
||||
class SkRefCnt : SkNoncopyable {
|
||||
public:
|
||||
/** Default construct, initializing the reference count to 1.
|
||||
*/
|
||||
SkRefCnt() : fRefCnt(1) {}
|
||||
|
||||
/** Destruct, asserting that the reference count is 1.
|
||||
*/
|
||||
virtual ~SkRefCnt() { SkASSERT(fRefCnt == 1); }
|
||||
|
||||
/** Return the reference count.
|
||||
*/
|
||||
int32_t getRefCnt() const { return fRefCnt; }
|
||||
|
||||
/** Increment the reference count. Must be balanced by a call to unref().
|
||||
*/
|
||||
void ref() const {
|
||||
SkASSERT(fRefCnt > 0);
|
||||
sk_atomic_inc(&fRefCnt);
|
||||
}
|
||||
|
||||
/** Decrement the reference count. If the reference count is 1 before the
|
||||
decrement, then call delete on the object. Note that if this is the
|
||||
case, then the object needs to have been allocated via new, and not on
|
||||
the stack.
|
||||
*/
|
||||
void unref() const {
|
||||
SkASSERT(fRefCnt > 0);
|
||||
if (sk_atomic_dec(&fRefCnt) == 1) {
|
||||
fRefCnt = 1; // so our destructor won't complain
|
||||
SkDELETE(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper version of ref(), that first checks to see if this is not null.
|
||||
If this is null, then do nothing.
|
||||
*/
|
||||
void safeRef() const {
|
||||
if (this) {
|
||||
this->ref();
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper version of unref(), that first checks to see if this is not null.
|
||||
If this is null, then do nothing.
|
||||
*/
|
||||
void safeUnref() const {
|
||||
if (this) {
|
||||
this->unref();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable int32_t fRefCnt;
|
||||
};
|
||||
|
||||
/** \class SkAutoUnref
|
||||
|
||||
SkAutoUnref is a stack-helper class that will automatically call unref() on
|
||||
the object it points to when the SkAutoUnref object goes out of scope.
|
||||
If obj is null, do nothing.
|
||||
*/
|
||||
class SkAutoUnref : SkNoncopyable {
|
||||
public:
|
||||
SkAutoUnref(SkRefCnt* obj) : fObj(obj) {}
|
||||
~SkAutoUnref();
|
||||
|
||||
SkRefCnt* get() const { return fObj; }
|
||||
|
||||
/** If the hosted object is null, do nothing and return false, else call
|
||||
ref() on it and return true
|
||||
*/
|
||||
bool ref();
|
||||
|
||||
/** If the hosted object is null, do nothing and return false, else call
|
||||
unref() on it, set its reference to null, and return true
|
||||
*/
|
||||
bool unref();
|
||||
|
||||
/** If the hosted object is null, do nothing and return NULL, else call
|
||||
unref() on it, set its reference to null, and return the object
|
||||
*/
|
||||
SkRefCnt* detach();
|
||||
|
||||
private:
|
||||
SkRefCnt* fObj;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for
|
||||
null in on each side of the assignment, and ensuring that ref() is called
|
||||
before unref(), in case the two pointers point to the same object.
|
||||
*/
|
||||
#define SkRefCnt_SafeAssign(dst, src) \
|
||||
do { \
|
||||
if (src) src->ref(); \
|
||||
if (dst) dst->unref(); \
|
||||
dst = src; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkRegion_DEFINED
|
||||
#define SkRegion_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkPath;
|
||||
class SkRgnBuilder;
|
||||
|
||||
namespace android {
|
||||
class Region;
|
||||
}
|
||||
|
||||
#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1)
|
||||
#define SkRegion_gRectRunHeadPtr 0
|
||||
|
||||
/** \class SkRegion
|
||||
|
||||
The SkRegion class encapsulates the geometric region used to specify
|
||||
clipping areas for drawing.
|
||||
*/
|
||||
class SkRegion {
|
||||
public:
|
||||
typedef int32_t RunType;
|
||||
enum {
|
||||
kRunTypeSentinel = 0x7FFFFFFF
|
||||
};
|
||||
|
||||
SkRegion();
|
||||
SkRegion(const SkRegion&);
|
||||
explicit SkRegion(const SkIRect&);
|
||||
~SkRegion();
|
||||
|
||||
SkRegion& operator=(const SkRegion&);
|
||||
|
||||
friend int operator==(const SkRegion& a, const SkRegion& b);
|
||||
friend int operator!=(const SkRegion& a, const SkRegion& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/** Replace this region with the specified region, and return true if the
|
||||
resulting region is non-empty.
|
||||
*/
|
||||
bool set(const SkRegion& src) {
|
||||
SkASSERT(&src);
|
||||
*this = src;
|
||||
return !this->isEmpty();
|
||||
}
|
||||
|
||||
/** Swap the contents of this and the specified region. This operation
|
||||
is gauarenteed to never fail.
|
||||
*/
|
||||
void swap(SkRegion&);
|
||||
|
||||
/** Return true if this region is empty */
|
||||
bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
|
||||
/** Return true if this region is a single, non-empty rectangle */
|
||||
bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
|
||||
/** Return true if this region consists of more than 1 rectangular area */
|
||||
bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
|
||||
/** Return the bounds of this region. If the region is empty, returns an
|
||||
empty rectangle.
|
||||
*/
|
||||
const SkIRect& getBounds() const { return fBounds; }
|
||||
|
||||
/** Returns true if the region is non-empty, and if so, sets the specified
|
||||
path to the boundary(s) of the region.
|
||||
*/
|
||||
bool getBoundaryPath(SkPath* path) const;
|
||||
|
||||
/** Set the region to be empty, and return false, since the resulting
|
||||
region is empty
|
||||
*/
|
||||
bool setEmpty();
|
||||
|
||||
/** If rect is non-empty, set this region to that rectangle and return true,
|
||||
otherwise set this region to empty and return false.
|
||||
*/
|
||||
bool setRect(const SkIRect&);
|
||||
|
||||
/** If left < right and top < bottom, set this region to that rectangle and
|
||||
return true, otherwise set this region to empty and return false.
|
||||
*/
|
||||
bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom);
|
||||
|
||||
/** Set this region to the specified region, and return true if it is
|
||||
non-empty. */
|
||||
bool setRegion(const SkRegion&);
|
||||
|
||||
/** Set this region to the area described by the path, clipped.
|
||||
Return true if the resulting region is non-empty.
|
||||
This produces a region that is identical to the pixels that would be
|
||||
drawn by the path (with no antialiasing) with the specified clip.
|
||||
*/
|
||||
bool setPath(const SkPath&, const SkRegion& clip);
|
||||
|
||||
/** Returns true if the specified rectangle has a non-empty intersection
|
||||
with this region.
|
||||
*/
|
||||
bool intersects(const SkIRect&) const;
|
||||
|
||||
/** Returns true if the specified region has a non-empty intersection
|
||||
with this region.
|
||||
*/
|
||||
bool intersects(const SkRegion&) const;
|
||||
|
||||
/** Return true if the specified x,y coordinate is inside the region.
|
||||
*/
|
||||
bool contains(int32_t x, int32_t y) const;
|
||||
|
||||
/** Return true if the specified rectangle is completely inside the region.
|
||||
This works for simple (rectangular) and complex regions, and always
|
||||
returns the correct result. Note: if either this region or the rectangle
|
||||
is empty, contains() returns false.
|
||||
*/
|
||||
bool contains(const SkIRect&) const;
|
||||
|
||||
/** Return true if the specified region is completely inside the region.
|
||||
This works for simple (rectangular) and complex regions, and always
|
||||
returns the correct result. Note: if either region is empty, contains()
|
||||
returns false.
|
||||
*/
|
||||
bool contains(const SkRegion&) const;
|
||||
|
||||
/** Return true if this region is a single rectangle (not complex) and the
|
||||
specified rectangle is contained by this region. Returning false is not
|
||||
a guarantee that the rectangle is not contained by this region, but
|
||||
return true is a guarantee that the rectangle is contained by this region.
|
||||
*/
|
||||
bool quickContains(const SkIRect& r) const {
|
||||
return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
}
|
||||
|
||||
/** Return true if this region is a single rectangle (not complex) and the
|
||||
specified rectangle is contained by this region. Returning false is not
|
||||
a guarantee that the rectangle is not contained by this region, but
|
||||
return true is a guarantee that the rectangle is contained by this
|
||||
region.
|
||||
*/
|
||||
bool quickContains(int32_t left, int32_t top, int32_t right,
|
||||
int32_t bottom) const {
|
||||
SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
|
||||
|
||||
return left < right && top < bottom &&
|
||||
fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect()
|
||||
/* fBounds.contains(left, top, right, bottom); */
|
||||
fBounds.fLeft <= left && fBounds.fTop <= top &&
|
||||
fBounds.fRight >= right && fBounds.fBottom >= bottom;
|
||||
}
|
||||
|
||||
/** Return true if this region is empty, or if the specified rectangle does
|
||||
not intersect the region. Returning false is not a guarantee that they
|
||||
intersect, but returning true is a guarantee that they do not.
|
||||
*/
|
||||
bool quickReject(const SkIRect& rect) const
|
||||
{
|
||||
return this->isEmpty() || rect.isEmpty() ||
|
||||
!SkIRect::Intersects(fBounds, rect);
|
||||
}
|
||||
|
||||
/** Return true if this region, or rgn, is empty, or if their bounds do not
|
||||
intersect. Returning false is not a guarantee that they intersect, but
|
||||
returning true is a guarantee that they do not.
|
||||
*/
|
||||
bool quickReject(const SkRegion& rgn) const {
|
||||
return this->isEmpty() || rgn.isEmpty() ||
|
||||
!SkIRect::Intersects(fBounds, rgn.fBounds);
|
||||
}
|
||||
|
||||
/** Translate the region by the specified (dx, dy) amount.
|
||||
*/
|
||||
void translate(int dx, int dy) { this->translate(dx, dy, this); }
|
||||
|
||||
/** Translate the region by the specified (dx, dy) amount, writing the
|
||||
resulting region into dst. Note: it is legal to pass this region as the
|
||||
dst parameter, effectively translating the region in place. If dst is
|
||||
null, nothing happens.
|
||||
*/
|
||||
void translate(int dx, int dy, SkRegion* dst) const;
|
||||
|
||||
/** The logical operations that can be performed when combining two regions.
|
||||
*/
|
||||
enum Op {
|
||||
kDifference_Op, //!< subtract the op region from the first region
|
||||
kIntersect_Op, //!< intersect the two regions
|
||||
kUnion_Op, //!< union (inclusive-or) the two regions
|
||||
kXOR_Op, //!< exclusive-or the two regions
|
||||
/** subtract the first region from the op region */
|
||||
kReverseDifference_Op,
|
||||
kReplace_Op //!< replace the dst region with the op region
|
||||
};
|
||||
|
||||
/** Set this region to the result of applying the Op to this region and the
|
||||
specified rectangle: this = (this op rect).
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
|
||||
|
||||
/** Set this region to the result of applying the Op to this region and the
|
||||
specified rectangle: this = (this op rect).
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(int left, int top, int right, int bottom, Op op) {
|
||||
SkIRect rect;
|
||||
rect.set(left, top, right, bottom);
|
||||
return this->op(*this, rect, op);
|
||||
}
|
||||
|
||||
/** Set this region to the result of applying the Op to this region and the
|
||||
specified region: this = (this op rgn).
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
|
||||
/** Set this region to the result of applying the Op to the specified
|
||||
rectangle and region: this = (rect op rgn).
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkIRect& rect, const SkRegion& rgn, Op);
|
||||
/** Set this region to the result of applying the Op to the specified
|
||||
region and rectangle: this = (rgn op rect).
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkRegion& rgn, const SkIRect& rect, Op);
|
||||
/** Set this region to the result of applying the Op to the specified
|
||||
regions: this = (rgna op rgnb).
|
||||
Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
|
||||
|
||||
/** Returns the sequence of rectangles, sorted in Y and X, that make up
|
||||
this region.
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator() : fRgn(NULL), fDone(true) {}
|
||||
Iterator(const SkRegion&);
|
||||
// if we have a region, reset to it and return true, else return false
|
||||
bool rewind();
|
||||
// reset the iterator, using the new region
|
||||
void reset(const SkRegion&);
|
||||
bool done() { return fDone; }
|
||||
void next();
|
||||
const SkIRect& rect() const { return fRect; }
|
||||
|
||||
private:
|
||||
const SkRegion* fRgn;
|
||||
const RunType* fRuns;
|
||||
SkIRect fRect;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
/** Returns the sequence of rectangles, sorted in Y and X, that make up
|
||||
this region intersected with the specified clip rectangle.
|
||||
*/
|
||||
class Cliperator {
|
||||
public:
|
||||
Cliperator(const SkRegion&, const SkIRect& clip);
|
||||
bool done() { return fDone; }
|
||||
void next();
|
||||
const SkIRect& rect() const { return fRect; }
|
||||
|
||||
private:
|
||||
Iterator fIter;
|
||||
SkIRect fClip;
|
||||
SkIRect fRect;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
/** Returns the sequence of runs that make up this region for the specified
|
||||
Y scanline, clipped to the specified left and right X values.
|
||||
*/
|
||||
class Spanerator {
|
||||
public:
|
||||
Spanerator(const SkRegion&, int y, int left, int right);
|
||||
bool next(int* left, int* right);
|
||||
|
||||
private:
|
||||
const SkRegion::RunType* fRuns;
|
||||
int fLeft, fRight;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
/** Write the region to the buffer, and return the number of bytes written.
|
||||
If buffer is NULL, it still returns the number of bytes.
|
||||
*/
|
||||
uint32_t flatten(void* buffer) const;
|
||||
/** Initialized the region from the buffer, returning the number
|
||||
of bytes actually read.
|
||||
*/
|
||||
uint32_t unflatten(const void* buffer);
|
||||
|
||||
SkDEBUGCODE(void dump() const;)
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
|
||||
// expose this to allow for regression test on complex regions
|
||||
SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
|
||||
|
||||
private:
|
||||
enum {
|
||||
kOpCount = kReplace_Op + 1
|
||||
};
|
||||
|
||||
enum {
|
||||
kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S]
|
||||
};
|
||||
|
||||
friend class android::Region; // needed for marshalling efficiently
|
||||
void allocateRuns(int count); // allocate space for count runs
|
||||
|
||||
struct RunHead;
|
||||
|
||||
SkIRect fBounds;
|
||||
RunHead* fRunHead;
|
||||
|
||||
void freeRuns();
|
||||
const RunType* getRuns(RunType tmpStorage[], int* count) const;
|
||||
bool setRuns(RunType runs[], int count);
|
||||
|
||||
int count_runtype_values(int* itop, int* ibot) const;
|
||||
|
||||
static void BuildRectRuns(const SkIRect& bounds,
|
||||
RunType runs[kRectRegionRuns]);
|
||||
// returns true if runs are just a rect
|
||||
static bool ComputeRunBounds(const RunType runs[], int count,
|
||||
SkIRect* bounds);
|
||||
|
||||
friend struct RunHead;
|
||||
friend class Iterator;
|
||||
friend class Spanerator;
|
||||
friend class SkRgnBuilder;
|
||||
friend class SkFlatRegion;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkScalar_DEFINED
|
||||
#define SkScalar_DEFINED
|
||||
|
||||
#include "SkFixed.h"
|
||||
|
||||
/** \file SkScalar.h
|
||||
|
||||
Types and macros for the data type SkScalar. This is the fractional numeric type
|
||||
that, depending on the compile-time flag SK_SCALAR_IS_FLOAT, may be implemented
|
||||
either as an IEEE float, or as a 16.16 SkFixed. The macros in this file are written
|
||||
to allow the calling code to manipulate SkScalar values without knowing which representation
|
||||
is in effect.
|
||||
*/
|
||||
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#include "SkFloatingPoint.h"
|
||||
|
||||
/** SkScalar is our type for fractional values and coordinates. Depending on
|
||||
compile configurations, it is either represented as an IEEE float, or
|
||||
as a 16.16 fixed point integer.
|
||||
*/
|
||||
typedef float SkScalar;
|
||||
extern const uint32_t gIEEENotANumber;
|
||||
extern const uint32_t gIEEEInfinity;
|
||||
|
||||
/** SK_Scalar1 is defined to be 1.0 represented as an SkScalar
|
||||
*/
|
||||
#define SK_Scalar1 (1.0f)
|
||||
/** SK_Scalar1 is defined to be 1/2 represented as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarHalf (0.5f)
|
||||
/** SK_ScalarInfinity is defined to be infinity as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarInfinity (*(const float*)&gIEEEInfinity)
|
||||
/** SK_ScalarMax is defined to be the largest value representable as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarMax (3.4028235e+38f)
|
||||
/** SK_ScalarMin is defined to be the smallest value representable as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarMin (1.1754944e-38f)
|
||||
/** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarNaN (*(const float*)(const void*)&gIEEENotANumber)
|
||||
/** SkScalarIsNaN(n) returns true if argument is not a number
|
||||
*/
|
||||
static inline bool SkScalarIsNaN(float x) { return x != x; }
|
||||
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
||||
*/
|
||||
#define SkIntToScalar(n) ((float)(n))
|
||||
/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar
|
||||
*/
|
||||
#define SkFixedToScalar(x) SkFixedToFloat(x)
|
||||
/** SkScalarToFixed(n) returns its SkScalar argument as an SkFixed
|
||||
*/
|
||||
#define SkScalarToFixed(x) SkFloatToFixed(x)
|
||||
|
||||
#define SkScalarToFloat(n) (n)
|
||||
#define SkFloatToScalar(n) (n)
|
||||
|
||||
#define SkScalarToDouble(n) (double)(n)
|
||||
#define SkDoubleToScalar(n) (float)(n)
|
||||
|
||||
/** SkScalarFraction(x) returns the signed fractional part of the argument
|
||||
*/
|
||||
#define SkScalarFraction(x) sk_float_mod(x, 1.0f)
|
||||
/** Rounds the SkScalar to the nearest integer value
|
||||
*/
|
||||
#define SkScalarRound(x) sk_float_round2int(x)
|
||||
/** Returns the smallest integer that is >= the specified SkScalar
|
||||
*/
|
||||
#define SkScalarCeil(x) sk_float_ceil2int(x)
|
||||
/** Returns the largest integer that is <= the specified SkScalar
|
||||
*/
|
||||
#define SkScalarFloor(x) sk_float_floor2int(x)
|
||||
/** Returns the absolute value of the specified SkScalar
|
||||
*/
|
||||
#define SkScalarAbs(x) sk_float_abs(x)
|
||||
/** Returns the value pinned between 0 and max inclusive
|
||||
*/
|
||||
inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) {
|
||||
return x < 0 ? 0 : x > max ? max : x;
|
||||
}
|
||||
/** Returns the value pinned between min and max inclusive
|
||||
*/
|
||||
inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) {
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
/** Returns the specified SkScalar squared (x*x)
|
||||
*/
|
||||
inline SkScalar SkScalarSquare(SkScalar x) { return x * x; }
|
||||
/** Returns the product of two SkScalars
|
||||
*/
|
||||
#define SkScalarMul(a, b) ((float)(a) * (b))
|
||||
/** Returns the product of two SkScalars plus a third SkScalar
|
||||
*/
|
||||
#define SkScalarMulAdd(a, b, c) ((float)(a) * (b) + (c))
|
||||
/** Returns the product of a SkScalar and an int rounded to the nearest integer value
|
||||
*/
|
||||
#define SkScalarMulRound(a, b) SkScalarRound((float)(a) * (b))
|
||||
/** Returns the product of a SkScalar and an int promoted to the next larger int
|
||||
*/
|
||||
#define SkScalarMulCeil(a, b) SkScalarCeil((float)(a) * (b))
|
||||
/** Returns the product of a SkScalar and an int truncated to the next smaller int
|
||||
*/
|
||||
#define SkScalarMulFloor(a, b) SkScalarFloor((float)(a) * (b))
|
||||
/** Returns the quotient of two SkScalars (a/b)
|
||||
*/
|
||||
#define SkScalarDiv(a, b) ((float)(a) / (b))
|
||||
/** Returns the mod of two SkScalars (a mod b)
|
||||
*/
|
||||
#define SkScalarMod(x,y) sk_float_mod(x,y)
|
||||
/** Returns the product of the first two arguments, divided by the third argument
|
||||
*/
|
||||
#define SkScalarMulDiv(a, b, c) ((float)(a) * (b) / (c))
|
||||
/** Returns the multiplicative inverse of the SkScalar (1/x)
|
||||
*/
|
||||
#define SkScalarInvert(x) (SK_Scalar1 / (x))
|
||||
#define SkScalarFastInvert(x) (SK_Scalar1 / (x))
|
||||
/** Returns the square root of the SkScalar
|
||||
*/
|
||||
#define SkScalarSqrt(x) sk_float_sqrt(x)
|
||||
/** Returns the average of two SkScalars (a+b)/2
|
||||
*/
|
||||
#define SkScalarAve(a, b) (((a) + (b)) * 0.5f)
|
||||
/** Returns the geometric mean of two SkScalars
|
||||
*/
|
||||
#define SkScalarMean(a, b) sk_float_sqrt((float)(a) * (b))
|
||||
/** Returns one half of the specified SkScalar
|
||||
*/
|
||||
#define SkScalarHalf(a) ((a) * 0.5f)
|
||||
|
||||
#define SK_ScalarSqrt2 1.41421356f
|
||||
#define SK_ScalarPI 3.14159265f
|
||||
#define SK_ScalarTanPIOver8 0.414213562f
|
||||
#define SK_ScalarRoot2Over2 0.707106781f
|
||||
|
||||
#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
|
||||
float SkScalarSinCos(SkScalar radians, SkScalar* cosValue);
|
||||
#define SkScalarSin(radians) (float)sk_float_sin(radians)
|
||||
#define SkScalarCos(radians) (float)sk_float_cos(radians)
|
||||
#define SkScalarTan(radians) (float)sk_float_tan(radians)
|
||||
#define SkScalarASin(val) (float)sk_float_asin(val)
|
||||
#define SkScalarACos(val) (float)sk_float_acos(val)
|
||||
#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x)
|
||||
#define SkScalarExp(x) (float)sk_float_exp(x)
|
||||
#define SkScalarLog(x) (float)sk_float_log(x)
|
||||
|
||||
inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; }
|
||||
inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; }
|
||||
|
||||
#else
|
||||
typedef SkFixed SkScalar;
|
||||
|
||||
#define SK_Scalar1 SK_Fixed1
|
||||
#define SK_ScalarHalf SK_FixedHalf
|
||||
#define SK_ScalarInfinity SK_FixedMax
|
||||
#define SK_ScalarMax SK_FixedMax
|
||||
#define SK_ScalarMin SK_FixedMin
|
||||
#define SK_ScalarNaN SK_FixedNaN
|
||||
#define SkScalarIsNaN(x) ((x) == SK_FixedNaN)
|
||||
#define SkIntToScalar(n) SkIntToFixed(n)
|
||||
#define SkFixedToScalar(x) (x)
|
||||
#define SkScalarToFixed(x) (x)
|
||||
#ifdef SK_CAN_USE_FLOAT
|
||||
#define SkScalarToFloat(n) SkFixedToFloat(n)
|
||||
#define SkFloatToScalar(n) SkFloatToFixed(n)
|
||||
|
||||
#define SkScalarToDouble(n) SkFixedToDouble(n)
|
||||
#define SkDoubleToScalar(n) SkDoubleToFixed(n)
|
||||
#endif
|
||||
#define SkScalarFraction(x) SkFixedFraction(x)
|
||||
#define SkScalarRound(x) SkFixedRound(x)
|
||||
#define SkScalarCeil(x) SkFixedCeil(x)
|
||||
#define SkScalarFloor(x) SkFixedFloor(x)
|
||||
#define SkScalarAbs(x) SkFixedAbs(x)
|
||||
#define SkScalarClampMax(x, max) SkClampMax(x, max)
|
||||
#define SkScalarPin(x, min, max) SkPin32(x, min, max)
|
||||
#define SkScalarSquare(x) SkFixedSquare(x)
|
||||
#define SkScalarMul(a, b) SkFixedMul(a, b)
|
||||
#define SkScalarMulAdd(a, b, c) SkFixedMulAdd(a, b, c)
|
||||
#define SkScalarMulRound(a, b) SkFixedMulCommon(a, b, SK_FixedHalf)
|
||||
#define SkScalarMulCeil(a, b) SkFixedMulCommon(a, b, SK_Fixed1 - 1)
|
||||
#define SkScalarMulFloor(a, b) SkFixedMulCommon(a, b, 0)
|
||||
#define SkScalarDiv(a, b) SkFixedDiv(a, b)
|
||||
#define SkScalarMod(a, b) SkFixedMod(a, b)
|
||||
#define SkScalarMulDiv(a, b, c) SkMulDiv(a, b, c)
|
||||
#define SkScalarInvert(x) SkFixedInvert(x)
|
||||
#define SkScalarFastInvert(x) SkFixedFastInvert(x)
|
||||
#define SkScalarSqrt(x) SkFixedSqrt(x)
|
||||
#define SkScalarAve(a, b) SkFixedAve(a, b)
|
||||
#define SkScalarMean(a, b) SkFixedMean(a, b)
|
||||
#define SkScalarHalf(a) ((a) >> 1)
|
||||
|
||||
#define SK_ScalarSqrt2 SK_FixedSqrt2
|
||||
#define SK_ScalarPI SK_FixedPI
|
||||
#define SK_ScalarTanPIOver8 SK_FixedTanPIOver8
|
||||
#define SK_ScalarRoot2Over2 SK_FixedRoot2Over2
|
||||
|
||||
#define SkDegreesToRadians(degrees) SkFractMul(degrees, SK_FractPIOver180)
|
||||
#define SkScalarSinCos(radians, cosPtr) SkFixedSinCos(radians, cosPtr)
|
||||
#define SkScalarSin(radians) SkFixedSin(radians)
|
||||
#define SkScalarCos(radians) SkFixedCos(radians)
|
||||
#define SkScalarTan(val) SkFixedTan(val)
|
||||
#define SkScalarASin(val) SkFixedASin(val)
|
||||
#define SkScalarACos(val) SkFixedACos(val)
|
||||
#define SkScalarATan2(y, x) SkFixedATan2(y,x)
|
||||
#define SkScalarExp(x) SkFixedExp(x)
|
||||
#define SkScalarLog(x) SkFixedLog(x)
|
||||
|
||||
#define SkMaxScalar(a, b) SkMax32(a, b)
|
||||
#define SkMinScalar(a, b) SkMin32(a, b)
|
||||
#endif
|
||||
|
||||
#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
|
||||
|
||||
/* <= is slower than < for floats, so we use < for our tolerance test
|
||||
*/
|
||||
|
||||
inline bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance = SK_ScalarNearlyZero)
|
||||
{
|
||||
SkASSERT(tolerance > 0);
|
||||
return SkScalarAbs(x) < tolerance;
|
||||
}
|
||||
|
||||
/** Linearly interpolate between A and B, based on t.
|
||||
If t is 0, return A
|
||||
If t is 1, return B
|
||||
else interpolate.
|
||||
t must be [0..SK_Scalar1]
|
||||
*/
|
||||
inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t)
|
||||
{
|
||||
SkASSERT(t >= 0 && t <= SK_Scalar1);
|
||||
return A + SkScalarMul(B - A, t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkScalarCompare_DEFINED
|
||||
#define SkScalarCompare_DEFINED
|
||||
|
||||
#include "SkFloatBits.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
#ifdef SK_SCALAR_SLOW_COMPARES
|
||||
typedef int32_t SkScalarCompareType;
|
||||
typedef SkIRect SkRectCompareType;
|
||||
#define SkScalarToCompareType(x) SkScalarAs2sCompliment(x)
|
||||
#else
|
||||
typedef SkScalar SkScalarCompareType;
|
||||
typedef SkRect SkRectCompareType;
|
||||
#define SkScalarToCompareType(x) (x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkScalerContext_DEFINED
|
||||
#define SkScalerContext_DEFINED
|
||||
|
||||
#include "SkMask.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
class SkDescriptor;
|
||||
class SkMaskFilter;
|
||||
class SkPathEffect;
|
||||
class SkRasterizer;
|
||||
|
||||
// needs to be != to any valid SkMask::Format
|
||||
#define MASK_FORMAT_JUST_ADVANCE (0xFF)
|
||||
|
||||
struct SkGlyph {
|
||||
void* fImage;
|
||||
SkPath* fPath;
|
||||
SkFixed fAdvanceX, fAdvanceY;
|
||||
|
||||
uint32_t fID;
|
||||
uint16_t fWidth, fHeight;
|
||||
int16_t fTop, fLeft;
|
||||
|
||||
uint8_t fMaskFormat;
|
||||
int8_t fRsbDelta, fLsbDelta; // used by auto-kerning
|
||||
|
||||
unsigned rowBytes() const {
|
||||
unsigned rb = fWidth;
|
||||
if (SkMask::kBW_Format == fMaskFormat) {
|
||||
rb = (rb + 7) >> 3;
|
||||
} else {
|
||||
rb = SkAlign4(rb);
|
||||
}
|
||||
return rb;
|
||||
}
|
||||
|
||||
bool isJustAdvance() const {
|
||||
return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
|
||||
}
|
||||
|
||||
bool isFullMetrics() const {
|
||||
return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
|
||||
}
|
||||
|
||||
uint16_t getGlyphID() const {
|
||||
return ID2Code(fID);
|
||||
}
|
||||
|
||||
unsigned getGlyphID(unsigned baseGlyphCount) const {
|
||||
unsigned code = ID2Code(fID);
|
||||
SkASSERT(code >= baseGlyphCount);
|
||||
return code - baseGlyphCount;
|
||||
}
|
||||
|
||||
unsigned getSubX() const {
|
||||
return ID2SubX(fID);
|
||||
}
|
||||
|
||||
SkFixed getSubXFixed() const {
|
||||
return SubToFixed(ID2SubX(fID));
|
||||
}
|
||||
|
||||
SkFixed getSubYFixed() const {
|
||||
return SubToFixed(ID2SubY(fID));
|
||||
}
|
||||
|
||||
size_t computeImageSize() const;
|
||||
|
||||
enum {
|
||||
kSubBits = 2,
|
||||
kSubMask = ((1 << kSubBits) - 1),
|
||||
kSubShift = 24, // must be large enough for glyphs and unichars
|
||||
kCodeMask = ((1 << kSubShift) - 1),
|
||||
// relative offsets for X and Y subpixel bits
|
||||
kSubShiftX = kSubBits,
|
||||
kSubShiftY = 0
|
||||
};
|
||||
|
||||
static unsigned ID2Code(uint32_t id) {
|
||||
return id & kCodeMask;
|
||||
}
|
||||
|
||||
static unsigned ID2SubX(uint32_t id) {
|
||||
return id >> (kSubShift + kSubShiftX);
|
||||
}
|
||||
|
||||
static unsigned ID2SubY(uint32_t id) {
|
||||
return (id >> (kSubShift + kSubShiftY)) & kSubMask;
|
||||
}
|
||||
|
||||
static unsigned FixedToSub(SkFixed n) {
|
||||
return (n >> (16 - kSubBits)) & kSubMask;
|
||||
}
|
||||
|
||||
static SkFixed SubToFixed(unsigned sub) {
|
||||
SkASSERT(sub <= kSubMask);
|
||||
return sub << (16 - kSubBits);
|
||||
}
|
||||
|
||||
static uint32_t MakeID(unsigned code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) {
|
||||
SkASSERT(code <= kCodeMask);
|
||||
x = FixedToSub(x);
|
||||
y = FixedToSub(y);
|
||||
return (x << (kSubShift + kSubShiftX)) |
|
||||
(y << (kSubShift + kSubShiftY)) |
|
||||
code;
|
||||
}
|
||||
|
||||
void toMask(SkMask* mask) const;
|
||||
};
|
||||
|
||||
class SkScalerContext {
|
||||
public:
|
||||
enum Hints {
|
||||
kNo_Hints,
|
||||
kSubpixel_Hints,
|
||||
kNormal_Hints
|
||||
};
|
||||
enum Flags {
|
||||
kFrameAndFill_Flag = 0x01,
|
||||
kDevKernText_Flag = 0x02,
|
||||
kGammaForBlack_Flag = 0x04, // illegal to set both Gamma flags
|
||||
kGammaForWhite_Flag = 0x08 // illegal to set both Gamma flags
|
||||
};
|
||||
struct Rec {
|
||||
uint32_t fFontID;
|
||||
SkScalar fTextSize, fPreScaleX, fPreSkewX;
|
||||
SkScalar fPost2x2[2][2];
|
||||
SkScalar fFrameWidth, fMiterLimit;
|
||||
uint8_t fHints;
|
||||
uint8_t fMaskFormat;
|
||||
uint8_t fStrokeJoin;
|
||||
uint8_t fFlags;
|
||||
|
||||
void getMatrixFrom2x2(SkMatrix*) const;
|
||||
void getLocalMatrix(SkMatrix*) const;
|
||||
void getSingleMatrix(SkMatrix*) const;
|
||||
};
|
||||
|
||||
SkScalerContext(const SkDescriptor* desc);
|
||||
virtual ~SkScalerContext();
|
||||
|
||||
void setBaseGlyphCount(unsigned baseGlyphCount) {
|
||||
fBaseGlyphCount = baseGlyphCount;
|
||||
}
|
||||
|
||||
uint16_t charToGlyphID(SkUnichar uni);
|
||||
|
||||
unsigned getGlyphCount() const { return this->generateGlyphCount(); }
|
||||
void getAdvance(SkGlyph*);
|
||||
void getMetrics(SkGlyph*);
|
||||
void getImage(const SkGlyph&);
|
||||
void getPath(const SkGlyph&, SkPath*);
|
||||
void getFontMetrics(SkPaint::FontMetrics* mX,
|
||||
SkPaint::FontMetrics* mY);
|
||||
|
||||
static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
|
||||
static SkScalerContext* Create(const SkDescriptor*);
|
||||
|
||||
protected:
|
||||
Rec fRec;
|
||||
unsigned fBaseGlyphCount;
|
||||
|
||||
virtual unsigned generateGlyphCount() const = 0;
|
||||
virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
|
||||
virtual void generateAdvance(SkGlyph*) = 0;
|
||||
virtual void generateMetrics(SkGlyph*) = 0;
|
||||
virtual void generateImage(const SkGlyph&) = 0;
|
||||
virtual void generatePath(const SkGlyph&, SkPath*) = 0;
|
||||
virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
|
||||
SkPaint::FontMetrics* mY) = 0;
|
||||
|
||||
private:
|
||||
SkPathEffect* fPathEffect;
|
||||
SkMaskFilter* fMaskFilter;
|
||||
SkRasterizer* fRasterizer;
|
||||
SkScalar fDevFrameWidth;
|
||||
|
||||
void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
|
||||
SkPath* devPath, SkMatrix* fillToDevMatrix);
|
||||
|
||||
mutable SkScalerContext* fAuxScalerContext;
|
||||
|
||||
SkScalerContext* getGlyphContext(const SkGlyph& glyph) const;
|
||||
|
||||
// return loaded fAuxScalerContext or NULL
|
||||
SkScalerContext* loadAuxContext() const;
|
||||
};
|
||||
|
||||
#define kRec_SkDescriptorTag SkSetFourByteTag('s', 'r', 'e', 'c')
|
||||
#define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e')
|
||||
#define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f')
|
||||
#define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't')
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkShader_DEFINED
|
||||
#define SkShader_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkMask.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPaint.h"
|
||||
|
||||
class SkPath;
|
||||
|
||||
/** \class SkShader
|
||||
|
||||
SkShader is the based class for objects that return horizontal spans of colors during drawing.
|
||||
A subclass of SkShader is installed in a SkPaint calling paint.setShader(shader). After that
|
||||
any object (other than a bitmap) that is drawn with that paint will get its color(s) from the
|
||||
shader.
|
||||
*/
|
||||
class SkShader : public SkFlattenable {
|
||||
public:
|
||||
SkShader();
|
||||
virtual ~SkShader();
|
||||
|
||||
/** Return true if the shader has a non-identity local matrix.
|
||||
@param localM Optional: If not null, return the shader's local matrix
|
||||
@return true if the shader has a non-identity local matrix.
|
||||
*/
|
||||
bool getLocalMatrix(SkMatrix* localM) const;
|
||||
/** Set the shader's local matrix.
|
||||
@param localM The shader's new local matrix.
|
||||
*/
|
||||
void setLocalMatrix(const SkMatrix& localM);
|
||||
/** Reset the shader's local matrix to identity.
|
||||
*/
|
||||
void resetLocalMatrix();
|
||||
|
||||
enum TileMode {
|
||||
kClamp_TileMode, //!< replicate the edge color if the shader draws outside of its original bounds
|
||||
kRepeat_TileMode, //!< repeat the shader's image horizontally and vertically
|
||||
kMirror_TileMode, //!< repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam
|
||||
|
||||
kTileModeCount
|
||||
};
|
||||
|
||||
// override these in your subclass
|
||||
|
||||
enum Flags {
|
||||
//!< set if all of the colors will be opaque
|
||||
kOpaqueAlpha_Flag = 0x01,
|
||||
//! set if this shader's shadeSpan16() method can be called
|
||||
kHasSpan16_Flag = 0x02,
|
||||
/** Set this bit if the shader's native data type is instrinsically 16
|
||||
bit, meaning that calling the 32bit shadeSpan() entry point will
|
||||
mean the the impl has to up-sample 16bit data into 32bit. Used as a
|
||||
a means of clearing a dither request if the it will have no effect
|
||||
*/
|
||||
kIntrinsicly16_Flag = 0x04
|
||||
};
|
||||
|
||||
/** Called sometimes before drawing with this shader.
|
||||
Return the type of alpha your shader will return.
|
||||
The default implementation returns 0. Your subclass should override if it can
|
||||
(even sometimes) report a non-zero value, since that will enable various blitters
|
||||
to perform faster.
|
||||
*/
|
||||
virtual uint32_t getFlags() { return 0; }
|
||||
|
||||
/** Return the alpha associated with the data returned by shadeSpan16(). If
|
||||
kHasSpan16_Flag is not set, this value is meaningless.
|
||||
*/
|
||||
virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
|
||||
|
||||
/** Called once before drawing, with the current paint and
|
||||
device matrix. Return true if your shader supports these
|
||||
parameters, or false if not. If false is returned, nothing
|
||||
will be drawn.
|
||||
*/
|
||||
virtual bool setContext( const SkBitmap& device,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix& matrix);
|
||||
|
||||
/** Called for each span of the object being drawn. Your subclass
|
||||
should set the appropriate colors (with premultiplied alpha) that
|
||||
correspond to the specified device coordinates.
|
||||
*/
|
||||
virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
|
||||
/** Called only for 16bit devices when getFlags() returns kOpaqueAlphaFlag | kHasSpan16_Flag
|
||||
*/
|
||||
virtual void shadeSpan16(int x, int y, uint16_t[], int count);
|
||||
/** Similar to shadeSpan, but only returns the alpha-channel for a span.
|
||||
The default implementation calls shadeSpan() and then extracts the alpha
|
||||
values from the returned colors.
|
||||
*/
|
||||
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
|
||||
|
||||
/** Helper function that returns true if this shader's shadeSpan16() method can
|
||||
be called.
|
||||
*/
|
||||
bool canCallShadeSpan16()
|
||||
{
|
||||
return SkShader::CanCallShadeSpan16(this->getFlags());
|
||||
}
|
||||
|
||||
/** Helper to check the flags to know if it is legal to call shadeSpan16()
|
||||
*/
|
||||
static bool CanCallShadeSpan16(uint32_t flags) {
|
||||
return (flags & kHasSpan16_Flag) != 0;
|
||||
}
|
||||
|
||||
/** Called before a session using the shader begins. Some shaders override
|
||||
this to defer some of their work (like calling bitmap.lockPixels()).
|
||||
Must be balanced by a call to endSession.
|
||||
*/
|
||||
virtual void beginSession();
|
||||
virtual void endSession();
|
||||
|
||||
/** Optional methods for shaders that can pretend to be a bitmap/texture
|
||||
to play along with opengl. Default just returns false and ignores
|
||||
the out parameters.
|
||||
*/
|
||||
virtual bool asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
|
||||
TileMode xy[2]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Factory methods for stock shaders
|
||||
|
||||
/** Call this to create a new shader that will draw with the specified bitmap.
|
||||
@param src The bitmap to use inside the shader
|
||||
@param tmx The tiling mode to use when sampling the bitmap in the x-direction.
|
||||
@param tmy The tiling mode to use when sampling the bitmap in the y-direction.
|
||||
@return Returns a new shader object. Note: this function never returns null.
|
||||
*/
|
||||
static SkShader* CreateBitmapShader(const SkBitmap& src,
|
||||
TileMode tmx, TileMode tmy);
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer& );
|
||||
protected:
|
||||
enum MatrixClass {
|
||||
kLinear_MatrixClass, // no perspective
|
||||
kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each scanline
|
||||
kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
|
||||
};
|
||||
static MatrixClass ComputeMatrixClass(const SkMatrix&);
|
||||
|
||||
// These can be called by your subclass after setContext() has been called
|
||||
uint8_t getPaintAlpha() const { return fPaintAlpha; }
|
||||
SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
|
||||
const SkMatrix& getTotalInverse() const { return fTotalInverse; }
|
||||
MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
|
||||
|
||||
SkShader(SkFlattenableReadBuffer& );
|
||||
private:
|
||||
SkMatrix* fLocalMatrix;
|
||||
SkMatrix fTotalInverse;
|
||||
uint8_t fPaintAlpha;
|
||||
uint8_t fDeviceConfig;
|
||||
uint8_t fTotalInverseClass;
|
||||
SkDEBUGCODE(SkBool8 fInSession;)
|
||||
|
||||
static SkShader* CreateBitmapShader(const SkBitmap& src,
|
||||
TileMode, TileMode,
|
||||
void* storage, size_t storageSize);
|
||||
friend class SkAutoBitmapShaderInstall;
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkStream_DEFINED
|
||||
#define SkStream_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkStream : public SkRefCnt {
|
||||
public:
|
||||
virtual ~SkStream();
|
||||
/** Called to rewind to the beginning of the stream. If this cannot be
|
||||
done, return false.
|
||||
*/
|
||||
virtual bool rewind() = 0;
|
||||
/** If this stream represents a file, this method returns the file's name.
|
||||
If it does not, it returns NULL (the default behavior).
|
||||
*/
|
||||
virtual const char* getFileName();
|
||||
/** Called to read or skip size number of bytes.
|
||||
If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped.
|
||||
If buffer is NULL and size == 0, return the total length of the stream.
|
||||
If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied.
|
||||
@param buffer If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer
|
||||
@param size The number of bytes to skip or copy
|
||||
@return bytes read on success
|
||||
*/
|
||||
virtual size_t read(void* buffer, size_t size) = 0;
|
||||
|
||||
/** Return the total length of the stream.
|
||||
*/
|
||||
size_t getLength() { return this->read(NULL, 0); }
|
||||
|
||||
/** Skip the specified number of bytes, returning the actual number
|
||||
of bytes that could be skipped.
|
||||
*/
|
||||
size_t skip(size_t bytes);
|
||||
|
||||
/** If the stream is backed by RAM, this method returns the starting
|
||||
address for the data. If not (i.e. it is backed by a file or other
|
||||
structure), this method returns NULL.
|
||||
The default implementation returns NULL.
|
||||
*/
|
||||
virtual const void* getMemoryBase();
|
||||
|
||||
int8_t readS8();
|
||||
int16_t readS16();
|
||||
int32_t readS32();
|
||||
|
||||
uint8_t readU8() { return (uint8_t)this->readS8(); }
|
||||
uint16_t readU16() { return (uint16_t)this->readS16(); }
|
||||
uint32_t readU32() { return (uint32_t)this->readS32(); }
|
||||
|
||||
bool readBool() { return this->readU8() != 0; }
|
||||
SkScalar readScalar();
|
||||
size_t readPackedUInt();
|
||||
|
||||
static void UnitTest();
|
||||
};
|
||||
|
||||
class SkWStream : SkNoncopyable {
|
||||
public:
|
||||
virtual ~SkWStream();
|
||||
|
||||
/** Called to write bytes to a SkWStream. Returns true on success
|
||||
@param buffer the address of at least size bytes to be written to the stream
|
||||
@param size The number of bytes in buffer to write to the stream
|
||||
@return true on success
|
||||
*/
|
||||
virtual bool write(const void* buffer, size_t size) = 0;
|
||||
virtual void newline();
|
||||
virtual void flush();
|
||||
|
||||
// helpers
|
||||
|
||||
bool write8(U8CPU);
|
||||
bool write16(U16CPU);
|
||||
bool write32(uint32_t);
|
||||
|
||||
bool writeText(const char text[]);
|
||||
bool writeDecAsText(int32_t);
|
||||
bool writeHexAsText(uint32_t, int minDigits = 0);
|
||||
bool writeScalarAsText(SkScalar);
|
||||
|
||||
bool writeBool(bool v) { return this->write8(v); }
|
||||
bool writeScalar(SkScalar);
|
||||
bool writePackedUInt(size_t);
|
||||
|
||||
bool writeStream(SkStream* input, size_t length);
|
||||
|
||||
static void UnitTest();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkString.h"
|
||||
|
||||
struct SkFILE;
|
||||
|
||||
/** A stream that reads from a FILE*, which is opened in the constructor and
|
||||
closed in the destructor
|
||||
*/
|
||||
class SkFILEStream : public SkStream {
|
||||
public:
|
||||
/** Initialize the stream by calling fopen on the specified path. Will be
|
||||
closed in the destructor.
|
||||
*/
|
||||
explicit SkFILEStream(const char path[] = NULL);
|
||||
virtual ~SkFILEStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFILE != NULL; }
|
||||
/** Close the current file, and open a new file with the specified
|
||||
path. If path is NULL, just close the current file.
|
||||
*/
|
||||
void setPath(const char path[]);
|
||||
|
||||
virtual bool rewind();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
virtual const char* getFileName();
|
||||
|
||||
private:
|
||||
SkFILE* fFILE;
|
||||
SkString fName;
|
||||
};
|
||||
|
||||
/** A stream that reads from a file descriptor
|
||||
*/
|
||||
class SkFDStream : public SkStream {
|
||||
public:
|
||||
/** Initialize the stream with a dup() of the specified file descriptor.
|
||||
If closeWhenDone is true, then the descriptor will be closed in the
|
||||
destructor.
|
||||
*/
|
||||
SkFDStream(int fileDesc, bool closeWhenDone);
|
||||
virtual ~SkFDStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFD >= 0; }
|
||||
|
||||
virtual bool rewind();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
virtual const char* getFileName() { return NULL; }
|
||||
|
||||
private:
|
||||
int fFD;
|
||||
bool fCloseWhenDone;
|
||||
};
|
||||
|
||||
class SkMemoryStream : public SkStream {
|
||||
public:
|
||||
SkMemoryStream();
|
||||
/** We allocate (and free) the memory. Write to it via getMemoryBase()
|
||||
*/
|
||||
SkMemoryStream(size_t length);
|
||||
/** if copyData is true, the stream makes a private copy of the data
|
||||
*/
|
||||
SkMemoryStream(const void* data, size_t length, bool copyData = false);
|
||||
virtual ~SkMemoryStream();
|
||||
|
||||
/** Resets the stream to the specified data and length,
|
||||
just like the constructor.
|
||||
if copyData is true, the stream makes a private copy of the data
|
||||
*/
|
||||
virtual void setMemory(const void* data, size_t length,
|
||||
bool copyData = false);
|
||||
void skipToAlign4();
|
||||
virtual bool rewind();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
virtual const void* getMemoryBase();
|
||||
const void* getAtPos();
|
||||
size_t seek(size_t offset);
|
||||
size_t peek() const { return fOffset; }
|
||||
|
||||
private:
|
||||
const void* fSrc;
|
||||
size_t fSize, fOffset;
|
||||
SkBool8 fWeOwnTheData;
|
||||
};
|
||||
|
||||
/** \class SkBufferStream
|
||||
This is a wrapper class that adds buffering to another stream.
|
||||
The caller can provide the buffer, or ask SkBufferStream to allocated/free
|
||||
it automatically.
|
||||
*/
|
||||
class SkBufferStream : public SkStream {
|
||||
public:
|
||||
/** Provide the stream to be buffered (proxy), and the size of the buffer that
|
||||
should be used. This will be allocated and freed automatically. If bufferSize is 0,
|
||||
a default buffer size will be used.
|
||||
The proxy stream is referenced, and will be unreferenced in when the
|
||||
bufferstream is destroyed.
|
||||
*/
|
||||
SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
|
||||
/** Provide the stream to be buffered (proxy), and a buffer and size to be used.
|
||||
This buffer is owned by the caller, and must be at least bufferSize bytes big.
|
||||
Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
|
||||
If buffer is not NULL, it is an error for bufferSize to be 0.
|
||||
The proxy stream is referenced, and will be unreferenced in when the
|
||||
bufferstream is destroyed.
|
||||
*/
|
||||
SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
|
||||
virtual ~SkBufferStream();
|
||||
|
||||
virtual bool rewind();
|
||||
virtual const char* getFileName();
|
||||
virtual size_t read(void* buffer, size_t size);
|
||||
virtual const void* getMemoryBase();
|
||||
|
||||
private:
|
||||
enum {
|
||||
kDefaultBufferSize = 128
|
||||
};
|
||||
// illegal
|
||||
SkBufferStream(const SkBufferStream&);
|
||||
SkBufferStream& operator=(const SkBufferStream&);
|
||||
|
||||
SkStream* fProxy;
|
||||
char* fBuffer;
|
||||
size_t fOrigBufferSize, fBufferSize, fBufferOffset;
|
||||
bool fWeOwnTheBuffer;
|
||||
|
||||
void init(void*, size_t);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkFILEWStream : public SkWStream {
|
||||
public:
|
||||
SkFILEWStream(const char path[]);
|
||||
virtual ~SkFILEWStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFILE != NULL; }
|
||||
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
virtual void flush();
|
||||
private:
|
||||
SkFILE* fFILE;
|
||||
};
|
||||
|
||||
class SkMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SkMemoryWStream(void* buffer, size_t size);
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
char* fBuffer;
|
||||
size_t fMaxLength;
|
||||
size_t fBytesWritten;
|
||||
};
|
||||
|
||||
class SkDynamicMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SkDynamicMemoryWStream();
|
||||
virtual ~SkDynamicMemoryWStream();
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
// random access write
|
||||
// modifies stream and returns true if offset + size is less than or equal to getOffset()
|
||||
bool write(const void* buffer, size_t offset, size_t size);
|
||||
bool read(void* buffer, size_t offset, size_t size);
|
||||
size_t getOffset() { return fBytesWritten; }
|
||||
|
||||
// copy what has been written to the stream into dst
|
||||
void copyTo(void* dst) const;
|
||||
/* return a cache of the flattened data returned by copyTo().
|
||||
This copy is only valid until the next call to write().
|
||||
The memory is managed by the stream class.
|
||||
*/
|
||||
const char* getStream() const;
|
||||
|
||||
// same as getStream, but additionally detach the flattened datat
|
||||
const char* detach();
|
||||
|
||||
// reset the stream to its original state
|
||||
void reset();
|
||||
void padToAlign4();
|
||||
private:
|
||||
struct Block;
|
||||
Block* fHead;
|
||||
Block* fTail;
|
||||
size_t fBytesWritten;
|
||||
mutable char* fCopyToCache;
|
||||
};
|
||||
|
||||
|
||||
class SkDebugWStream : public SkWStream {
|
||||
public:
|
||||
// overrides
|
||||
virtual bool write(const void* buffer, size_t size);
|
||||
virtual void newline();
|
||||
};
|
||||
|
||||
// for now
|
||||
typedef SkFILEStream SkURLStream;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkString_DEFINED
|
||||
#define SkString_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
/* Some helper functions for C strings
|
||||
*/
|
||||
|
||||
bool SkStrStartsWith(const char string[], const char prefix[]);
|
||||
bool SkStrEndsWith(const char string[], const char suffix[]);
|
||||
int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
|
||||
|
||||
#define SkStrAppendS32_MaxSize 11
|
||||
char* SkStrAppendS32(char buffer[], int32_t);
|
||||
#define SkStrAppendScalar_MaxSize 11
|
||||
char* SkStrAppendScalar(char buffer[], SkScalar);
|
||||
|
||||
/** \class SkString
|
||||
|
||||
Light weight class for managing strings. Uses reference
|
||||
counting to make string assignments and copies very fast
|
||||
with no extra RAM cost. Assumes UTF8 encoding.
|
||||
*/
|
||||
class SkString {
|
||||
public:
|
||||
SkString();
|
||||
explicit SkString(size_t len);
|
||||
explicit SkString(const char text[]);
|
||||
SkString(const char text[], size_t len);
|
||||
explicit SkString(const SkString&);
|
||||
~SkString();
|
||||
|
||||
bool isEmpty() const { return fRec->fLength == 0; }
|
||||
size_t size() const { return (size_t) fRec->fLength; }
|
||||
const char* c_str() const { return fRec->data(); }
|
||||
|
||||
bool equals(const SkString&) const;
|
||||
bool equals(const char text[]) const;
|
||||
bool equals(const char text[], size_t len) const;
|
||||
|
||||
bool startsWith(const char prefix[]) const
|
||||
{
|
||||
return SkStrStartsWith(fRec->data(), prefix);
|
||||
}
|
||||
bool endsWith(const char suffix[]) const
|
||||
{
|
||||
return SkStrEndsWith(fRec->data(), suffix);
|
||||
}
|
||||
|
||||
friend int operator==(const SkString& a, const SkString& b)
|
||||
{
|
||||
return a.equals(b);
|
||||
}
|
||||
friend int operator!=(const SkString& a, const SkString& b)
|
||||
{
|
||||
return !a.equals(b);
|
||||
}
|
||||
|
||||
// these methods edit the string
|
||||
|
||||
SkString& operator=(const SkString&);
|
||||
|
||||
char* writable_str();
|
||||
|
||||
void reset();
|
||||
void resize(size_t len) { this->set(NULL, len); }
|
||||
void set(const SkString& src) { *this = src; }
|
||||
void set(const char text[]);
|
||||
void set(const char text[], size_t len);
|
||||
void setUTF16(const uint16_t[]);
|
||||
void setUTF16(const uint16_t[], size_t len);
|
||||
|
||||
void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
|
||||
void insert(size_t offset, const char text[]);
|
||||
void insert(size_t offset, const char text[], size_t len);
|
||||
void insertUnichar(size_t offset, SkUnichar);
|
||||
void insertS32(size_t offset, int32_t value);
|
||||
void insertHex(size_t offset, uint32_t value, int minDigits = 0);
|
||||
void insertScalar(size_t offset, SkScalar);
|
||||
|
||||
void append(const SkString& str) { this->insert((size_t)-1, str); }
|
||||
void append(const char text[]) { this->insert((size_t)-1, text); }
|
||||
void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
|
||||
void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
|
||||
void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
|
||||
void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
|
||||
void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
|
||||
|
||||
void prepend(const SkString& str) { this->insert(0, str); }
|
||||
void prepend(const char text[]) { this->insert(0, text); }
|
||||
void prepend(const char text[], size_t len) { this->insert(0, text, len); }
|
||||
void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
|
||||
void prependS32(int32_t value) { this->insertS32(0, value); }
|
||||
void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
|
||||
void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
|
||||
|
||||
void printf(const char format[], ...);
|
||||
void appendf(const char format[], ...);
|
||||
void prependf(const char format[], ...);
|
||||
|
||||
void remove(size_t offset, size_t length);
|
||||
|
||||
/** Swap contents between this and other. This function is guaranteed
|
||||
to never fail or throw.
|
||||
*/
|
||||
void swap(SkString& other);
|
||||
|
||||
/** @cond UNIT_TEST */
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
/** @endcond */
|
||||
|
||||
private:
|
||||
struct Rec {
|
||||
public:
|
||||
uint16_t fLength;
|
||||
uint16_t fRefCnt;
|
||||
char fBeginningOfData;
|
||||
|
||||
char* data() { return &fBeginningOfData; }
|
||||
const char* data() const { return &fBeginningOfData; }
|
||||
};
|
||||
Rec* fRec;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
const char* fStr;
|
||||
void validate() const;
|
||||
#else
|
||||
void validate() const {}
|
||||
#endif
|
||||
|
||||
static const Rec gEmptyRec;
|
||||
static Rec* AllocRec(const char text[], U16CPU len);
|
||||
static Rec* RefRec(Rec*);
|
||||
};
|
||||
|
||||
class SkAutoUCS2 {
|
||||
public:
|
||||
SkAutoUCS2(const char utf8[]);
|
||||
~SkAutoUCS2();
|
||||
|
||||
/** This returns the number of ucs2 characters
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
/** This returns a null terminated ucs2 string
|
||||
*/
|
||||
const uint16_t* getUCS2() const { return fUCS2; }
|
||||
|
||||
private:
|
||||
int fCount;
|
||||
uint16_t* fUCS2;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkStroke_DEFINED
|
||||
#define SkStroke_DEFINED
|
||||
|
||||
#include "SkPoint.h"
|
||||
#include "SkPaint.h"
|
||||
|
||||
struct SkRect;
|
||||
class SkPath;
|
||||
|
||||
#define SK_DefaultStrokeWidth SK_Scalar1
|
||||
#define SK_DefaultMiterLimit SkIntToScalar(4)
|
||||
|
||||
|
||||
/** \class SkStroke
|
||||
SkStroke is the utility class that constructs paths by stroking
|
||||
geometries (lines, rects, ovals, roundrects, paths). This is
|
||||
invoked when a geometry or text is drawn in a canvas with the
|
||||
kStroke_Mask bit set in the paint.
|
||||
*/
|
||||
class SkStroke {
|
||||
public:
|
||||
SkStroke();
|
||||
SkStroke(const SkPaint&);
|
||||
SkStroke(const SkPaint&, SkScalar width); // width overrides paint.getStrokeWidth()
|
||||
|
||||
SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
|
||||
void setCap(SkPaint::Cap);
|
||||
|
||||
SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; }
|
||||
void setJoin(SkPaint::Join);
|
||||
|
||||
void setMiterLimit(SkScalar);
|
||||
void setWidth(SkScalar);
|
||||
|
||||
bool getDoFill() const { return SkToBool(fDoFill); }
|
||||
void setDoFill(bool doFill) { fDoFill = SkToU8(doFill); }
|
||||
|
||||
void strokeLine(const SkPoint& start, const SkPoint& end, SkPath*) const;
|
||||
void strokeRect(const SkRect& rect, SkPath*) const;
|
||||
void strokeOval(const SkRect& oval, SkPath*) const;
|
||||
void strokeRRect(const SkRect& rect, SkScalar rx, SkScalar ry, SkPath*) const;
|
||||
void strokePath(const SkPath& path, SkPath*) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
SkScalar fWidth, fMiterLimit;
|
||||
uint8_t fCap, fJoin;
|
||||
SkBool8 fDoFill;
|
||||
|
||||
friend class SkPaint;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTDArray_DEFINED
|
||||
#define SkTDArray_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
template <typename T> class SkTDArray {
|
||||
public:
|
||||
SkTDArray() {
|
||||
fReserve = fCount = 0;
|
||||
fArray = NULL;
|
||||
#ifdef SK_DEBUG
|
||||
fData = NULL;
|
||||
#endif
|
||||
}
|
||||
SkTDArray(const T src[], size_t count) {
|
||||
SkASSERT(src || count == 0);
|
||||
|
||||
fReserve = fCount = 0;
|
||||
fArray = NULL;
|
||||
#ifdef SK_DEBUG
|
||||
fData = NULL;
|
||||
#endif
|
||||
if (count) {
|
||||
fArray = (T*)sk_malloc_throw(count * sizeof(T));
|
||||
#ifdef SK_DEBUG
|
||||
fData = (ArrayT*)fArray;
|
||||
#endif
|
||||
memcpy(fArray, src, sizeof(T) * count);
|
||||
fReserve = fCount = count;
|
||||
}
|
||||
}
|
||||
SkTDArray(const SkTDArray<T>& src) {
|
||||
fReserve = fCount = 0;
|
||||
fArray = NULL;
|
||||
#ifdef SK_DEBUG
|
||||
fData = NULL;
|
||||
#endif
|
||||
SkTDArray<T> tmp(src.fArray, src.fCount);
|
||||
this->swap(tmp);
|
||||
}
|
||||
~SkTDArray() {
|
||||
sk_free(fArray);
|
||||
}
|
||||
|
||||
SkTDArray<T>& operator=(const SkTDArray<T>& src) {
|
||||
if (this != &src) {
|
||||
if (src.fCount > fReserve) {
|
||||
SkTDArray<T> tmp(src.fArray, src.fCount);
|
||||
this->swap(tmp);
|
||||
} else {
|
||||
memcpy(fArray, src.fArray, sizeof(T) * src.fCount);
|
||||
fCount = src.fCount;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend int operator==(const SkTDArray<T>& a, const SkTDArray<T>& b) {
|
||||
return a.fCount == b.fCount &&
|
||||
(a.fCount == 0 ||
|
||||
!memcmp(a.fArray, b.fArray, a.fCount * sizeof(T)));
|
||||
}
|
||||
|
||||
void swap(SkTDArray<T>& other) {
|
||||
SkTSwap(fArray, other.fArray);
|
||||
#ifdef SK_DEBUG
|
||||
SkTSwap(fData, other.fData);
|
||||
#endif
|
||||
SkTSwap(fReserve, other.fReserve);
|
||||
SkTSwap(fCount, other.fCount);
|
||||
}
|
||||
|
||||
bool isEmpty() const { return fCount == 0; }
|
||||
int count() const { return fCount; }
|
||||
T* begin() const { return fArray; }
|
||||
T* end() const { return fArray ? fArray + fCount : NULL; }
|
||||
T& operator[](int index) const {
|
||||
SkASSERT((unsigned)index < fCount);
|
||||
return fArray[index];
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if (fArray) {
|
||||
sk_free(fArray);
|
||||
fArray = NULL;
|
||||
#ifdef SK_DEBUG
|
||||
fData = NULL;
|
||||
#endif
|
||||
fReserve = fCount = 0;
|
||||
} else {
|
||||
SkASSERT(fReserve == 0 && fCount == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void rewind() {
|
||||
// same as setCount(0)
|
||||
fCount = 0;
|
||||
}
|
||||
|
||||
void setCount(size_t count) {
|
||||
if (count > fReserve) {
|
||||
this->growBy(count - fCount);
|
||||
} else {
|
||||
fCount = count;
|
||||
}
|
||||
}
|
||||
|
||||
void setReserve(size_t reserve) {
|
||||
if (reserve > fReserve) {
|
||||
SkASSERT(reserve > fCount);
|
||||
size_t count = fCount;
|
||||
this->growBy(reserve - fCount);
|
||||
fCount = count;
|
||||
}
|
||||
}
|
||||
|
||||
T* prepend() {
|
||||
this->growBy(1);
|
||||
memmove(fArray + 1, fArray, (fCount - 1) * sizeof(T));
|
||||
return fArray;
|
||||
}
|
||||
|
||||
T* append() {
|
||||
return this->append(1, NULL);
|
||||
}
|
||||
T* append(size_t count, const T* src = NULL) {
|
||||
unsigned oldCount = fCount;
|
||||
if (count) {
|
||||
SkASSERT(src == NULL || fArray == NULL ||
|
||||
src + count <= fArray || fArray + oldCount <= src);
|
||||
|
||||
this->growBy(count);
|
||||
if (src) {
|
||||
memcpy(fArray + oldCount, src, sizeof(T) * count);
|
||||
}
|
||||
}
|
||||
return fArray + oldCount;
|
||||
}
|
||||
|
||||
T* appendClear() {
|
||||
T* result = this->append();
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
T* insert(size_t index) {
|
||||
return this->insert(index, 1, NULL);
|
||||
}
|
||||
T* insert(size_t index, size_t count, const T* src = NULL) {
|
||||
SkASSERT(count);
|
||||
SkASSERT(index <= fCount);
|
||||
int oldCount = fCount;
|
||||
this->growBy(count);
|
||||
T* dst = fArray + index;
|
||||
memmove(dst + count, dst, sizeof(T) * (oldCount - index));
|
||||
if (src) {
|
||||
memcpy(dst, src, sizeof(T) * count);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
void remove(size_t index, size_t count = 1) {
|
||||
SkASSERT(index + count <= fCount);
|
||||
fCount = fCount - count;
|
||||
memmove(fArray + index, fArray + index + count, sizeof(T) * (fCount - index));
|
||||
}
|
||||
|
||||
void removeShuffle(size_t index) {
|
||||
SkASSERT(index < fCount);
|
||||
unsigned newCount = fCount - 1;
|
||||
fCount = newCount;
|
||||
if (index != newCount) {
|
||||
memcpy(fArray + index, fArray + newCount, sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
int find(const T& elem) const {
|
||||
const T* iter = fArray;
|
||||
const T* stop = fArray + fCount;
|
||||
|
||||
for (; iter < stop; iter++) {
|
||||
if (*iter == elem) {
|
||||
return (int) (iter - fArray);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rfind(const T& elem) const {
|
||||
const T* iter = fArray + fCount;
|
||||
const T* stop = fArray;
|
||||
|
||||
while (iter > stop) {
|
||||
if (*--iter == elem) {
|
||||
return iter - stop;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// routines to treat the array like a stack
|
||||
T* push() { return this->append(); }
|
||||
void push(const T& elem) { *this->append() = elem; }
|
||||
const T& top() const { return (*this)[fCount - 1]; }
|
||||
T& top() { return (*this)[fCount - 1]; }
|
||||
void pop(T* elem) { if (elem) *elem = (*this)[fCount - 1]; --fCount; }
|
||||
void pop() { --fCount; }
|
||||
|
||||
void deleteAll() {
|
||||
T* iter = fArray;
|
||||
T* stop = fArray + fCount;
|
||||
while (iter < stop) {
|
||||
delete (*iter);
|
||||
iter += 1;
|
||||
}
|
||||
this->reset();
|
||||
}
|
||||
|
||||
void freeAll() {
|
||||
T* iter = fArray;
|
||||
T* stop = fArray + fCount;
|
||||
while (iter < stop) {
|
||||
sk_free(*iter);
|
||||
iter += 1;
|
||||
}
|
||||
this->reset();
|
||||
}
|
||||
|
||||
void unrefAll() {
|
||||
T* iter = fArray;
|
||||
T* stop = fArray + fCount;
|
||||
while (iter < stop) {
|
||||
(*iter)->unref();
|
||||
iter += 1;
|
||||
}
|
||||
this->reset();
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const {
|
||||
SkASSERT((fReserve == 0 && fArray == NULL) ||
|
||||
(fReserve > 0 && fArray != NULL));
|
||||
SkASSERT(fCount <= fReserve);
|
||||
SkASSERT(fData == (ArrayT*)fArray);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
#ifdef SK_DEBUG
|
||||
enum {
|
||||
kDebugArraySize = 16
|
||||
};
|
||||
typedef T ArrayT[kDebugArraySize];
|
||||
ArrayT* fData;
|
||||
#endif
|
||||
T* fArray;
|
||||
size_t fReserve, fCount;
|
||||
|
||||
void growBy(size_t extra) {
|
||||
SkASSERT(extra);
|
||||
|
||||
if (fCount + extra > fReserve) {
|
||||
size_t size = fCount + extra + 4;
|
||||
size += size >> 2;
|
||||
|
||||
fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T));
|
||||
#ifdef SK_DEBUG
|
||||
fData = (ArrayT*)fArray;
|
||||
#endif
|
||||
fReserve = size;
|
||||
}
|
||||
fCount += extra;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTDStack_DEFINED
|
||||
#define SkTDStack_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
template <typename T> class SkTDStack : SkNoncopyable {
|
||||
public:
|
||||
SkTDStack() : fCount(0), fTotalCount(0)
|
||||
{
|
||||
fInitialRec.fNext = NULL;
|
||||
fRec = &fInitialRec;
|
||||
|
||||
// fCount = kSlotCount;
|
||||
}
|
||||
~SkTDStack()
|
||||
{
|
||||
Rec* rec = fRec;
|
||||
while (rec != &fInitialRec)
|
||||
{
|
||||
Rec* next = rec->fNext;
|
||||
sk_free(rec);
|
||||
rec = next;
|
||||
}
|
||||
}
|
||||
|
||||
int count() const { return fTotalCount; }
|
||||
|
||||
T* push()
|
||||
{
|
||||
SkASSERT(fCount <= kSlotCount);
|
||||
if (fCount == kSlotCount)
|
||||
{
|
||||
Rec* rec = (Rec*)sk_malloc_throw(sizeof(Rec));
|
||||
rec->fNext = fRec;
|
||||
fRec = rec;
|
||||
fCount = 0;
|
||||
}
|
||||
++fTotalCount;
|
||||
return &fRec->fSlots[fCount++];
|
||||
}
|
||||
void push(const T& elem) { *this->push() = elem; }
|
||||
const T& index(int idx) const
|
||||
{
|
||||
SkASSERT(fRec && fCount > idx);
|
||||
return fRec->fSlots[fCount - idx - 1];
|
||||
}
|
||||
T& index(int idx)
|
||||
{
|
||||
SkASSERT(fRec && fCount > idx);
|
||||
return fRec->fSlots[fCount - idx - 1];
|
||||
}
|
||||
const T& top() const
|
||||
{
|
||||
SkASSERT(fRec && fCount > 0);
|
||||
return fRec->fSlots[fCount - 1];
|
||||
}
|
||||
T& top()
|
||||
{
|
||||
SkASSERT(fRec && fCount > 0);
|
||||
return fRec->fSlots[fCount - 1];
|
||||
}
|
||||
void pop(T* elem)
|
||||
{
|
||||
if (elem)
|
||||
*elem = fRec->fSlots[fCount - 1];
|
||||
this->pop();
|
||||
}
|
||||
void pop()
|
||||
{
|
||||
SkASSERT(fCount > 0 && fRec);
|
||||
--fTotalCount;
|
||||
if (--fCount == 0)
|
||||
{
|
||||
if (fRec != &fInitialRec)
|
||||
{
|
||||
Rec* rec = fRec->fNext;
|
||||
sk_free(fRec);
|
||||
fCount = kSlotCount;
|
||||
fRec = rec;
|
||||
}
|
||||
else
|
||||
SkASSERT(fTotalCount == 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
kSlotCount = 8
|
||||
};
|
||||
|
||||
struct Rec;
|
||||
friend struct Rec;
|
||||
|
||||
struct Rec {
|
||||
Rec* fNext;
|
||||
T fSlots[kSlotCount];
|
||||
};
|
||||
Rec fInitialRec;
|
||||
Rec* fRec;
|
||||
int fCount, fTotalCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTDict_DEFINED
|
||||
#define SkTDict_DEFINED
|
||||
|
||||
#include "SkChunkAlloc.h"
|
||||
#include "SkTSearch.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
template <typename T> class SkTDict : SkNoncopyable {
|
||||
public:
|
||||
SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {}
|
||||
|
||||
void reset()
|
||||
{
|
||||
fArray.reset();
|
||||
fStrings.reset();
|
||||
}
|
||||
|
||||
int count() const { return fArray.count(); }
|
||||
|
||||
bool set(const char name[], const T& value)
|
||||
{
|
||||
return set(name, strlen(name), value);
|
||||
}
|
||||
|
||||
bool set(const char name[], size_t len, const T& value)
|
||||
{
|
||||
SkASSERT(name);
|
||||
|
||||
int index = this->find_index(name, len);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
fArray[index].fValue = value;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pair* pair = fArray.insert(~index);
|
||||
char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
|
||||
memcpy(copy, name, len);
|
||||
copy[len] = '\0';
|
||||
pair->fName = copy;
|
||||
pair->fValue = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool find(const char name[]) const
|
||||
{
|
||||
return this->find_index(name) >= 0;
|
||||
}
|
||||
|
||||
bool find(const char name[], size_t len) const
|
||||
{
|
||||
return this->find_index(name, len) >= 0;
|
||||
}
|
||||
|
||||
bool find(const char name[], T* value) const
|
||||
{
|
||||
return find(name, strlen(name), value);
|
||||
}
|
||||
|
||||
bool find(const char name[], size_t len, T* value) const
|
||||
{
|
||||
int index = this->find_index(name, len);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
if (value)
|
||||
*value = fArray[index].fValue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findKey(T& value, const char** name) const
|
||||
{
|
||||
Pair* end = fArray.end();
|
||||
for (Pair* pair = fArray.begin(); pair < end; pair++) {
|
||||
if (pair->fValue != value)
|
||||
continue;
|
||||
*name = pair->fName;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
struct Pair {
|
||||
const char* fName;
|
||||
T fValue;
|
||||
|
||||
friend int operator<(const Pair& a, const Pair& b)
|
||||
{
|
||||
return strcmp(a.fName, b.fName);
|
||||
}
|
||||
friend int operator!=(const Pair& a, const Pair& b)
|
||||
{
|
||||
return strcmp(a.fName, b.fName);
|
||||
}
|
||||
};
|
||||
friend class Iter;
|
||||
|
||||
public:
|
||||
class Iter {
|
||||
public:
|
||||
Iter(const SkTDict<T>& dict)
|
||||
{
|
||||
fIter = dict.fArray.begin();
|
||||
fStop = dict.fArray.end();
|
||||
}
|
||||
const char* next(T* value)
|
||||
{
|
||||
const char* name = NULL;
|
||||
if (fIter < fStop)
|
||||
{
|
||||
name = fIter->fName;
|
||||
if (value)
|
||||
*value = fIter->fValue;
|
||||
fIter += 1;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
private:
|
||||
Pair* fIter;
|
||||
Pair* fStop;
|
||||
};
|
||||
|
||||
private:
|
||||
SkTDArray<Pair> fArray;
|
||||
SkChunkAlloc fStrings;
|
||||
|
||||
int find_index(const char name[]) const
|
||||
{
|
||||
return find_index(name, strlen(name));
|
||||
}
|
||||
|
||||
int find_index(const char name[], size_t len) const
|
||||
{
|
||||
SkASSERT(name);
|
||||
|
||||
int count = fArray.count();
|
||||
int index = ~0;
|
||||
|
||||
if (count)
|
||||
index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair));
|
||||
return index;
|
||||
}
|
||||
friend class Iter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTSearch_DEFINED
|
||||
#define SkTSearch_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
template <typename T>
|
||||
int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0)
|
||||
return ~0;
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi)
|
||||
{
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = (const T*)((const char*)base + mid * elemSize);
|
||||
|
||||
if (*elem < target)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = (const T*)((const char*)base + hi * elemSize);
|
||||
if (*elem != target)
|
||||
{
|
||||
if (*elem < target)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int SkTSearch(const T* base, int count, const T& target, size_t elemSize,
|
||||
int (*compare)(const T&, const T&))
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0) {
|
||||
return ~0;
|
||||
}
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi) {
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = (const T*)((const char*)base + mid * elemSize);
|
||||
|
||||
if ((*compare)(*elem, target) < 0)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = (const T*)((const char*)base + hi * elemSize);
|
||||
int pred = (*compare)(*elem, target);
|
||||
if (pred != 0) {
|
||||
if (pred < 0)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int SkTSearch(const T** base, int count, const T* target, size_t elemSize,
|
||||
int (*compare)(const T*, const T*))
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0)
|
||||
return ~0;
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi)
|
||||
{
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = *(const T**)((const char*)base + mid * elemSize);
|
||||
|
||||
if ((*compare)(elem, target) < 0)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = *(const T**)((const char*)base + hi * elemSize);
|
||||
int pred = (*compare)(elem, target);
|
||||
if (pred != 0)
|
||||
{
|
||||
if (pred < 0)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
int SkStrSearch(const char*const* base, int count, const char target[],
|
||||
size_t target_len, size_t elemSize);
|
||||
int SkStrSearch(const char*const* base, int count, const char target[],
|
||||
size_t elemSize);
|
||||
|
||||
/** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
|
||||
base points to a table of lower-case strings.
|
||||
*/
|
||||
int SkStrLCSearch(const char*const* base, int count, const char target[],
|
||||
size_t target_len, size_t elemSize);
|
||||
int SkStrLCSearch(const char*const* base, int count, const char target[],
|
||||
size_t elemSize);
|
||||
|
||||
/** Helper class to convert a string to lower-case, but only modifying the ascii
|
||||
characters. This makes the routine very fast and never changes the string
|
||||
length, but it is not suitable for linguistic purposes. Normally this is
|
||||
used for buiding and searching string tables.
|
||||
*/
|
||||
class SkAutoAsciiToLC {
|
||||
public:
|
||||
SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
|
||||
~SkAutoAsciiToLC();
|
||||
|
||||
const char* lc() const { return fLC; }
|
||||
size_t length() const { return fLength; }
|
||||
|
||||
private:
|
||||
char* fLC; // points to either the heap or fStorage
|
||||
size_t fLength;
|
||||
enum {
|
||||
STORAGE = 64
|
||||
};
|
||||
char fStorage[STORAGE+1];
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
typedef int (*SkQSortCompareProc)(const void*, const void*);
|
||||
void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc);
|
||||
}
|
||||
|
||||
SkDEBUGCODE(void SkQSort_UnitTest();)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTemplates_DEFINED
|
||||
#define SkTemplates_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkTemplates.h
|
||||
|
||||
This file contains light-weight template classes for type-safe and exception-safe
|
||||
resource management.
|
||||
*/
|
||||
|
||||
/** \class SkAutoTCallVProc
|
||||
|
||||
Call a function when this goes out of scope. The template uses two
|
||||
parameters, the object, and a function that is to be called in the destructor.
|
||||
If detach() is called, the object reference is set to null. If the object
|
||||
reference is null when the destructor is called, we do not call the
|
||||
function.
|
||||
*/
|
||||
template <typename T, void (*P)(T*)> class SkAutoTCallVProc : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTCallVProc(T* obj): fObj(obj) {}
|
||||
~SkAutoTCallVProc() { if (fObj) P(fObj); }
|
||||
T* detach() { T* obj = fObj; fObj = NULL; return obj; }
|
||||
private:
|
||||
T* fObj;
|
||||
};
|
||||
|
||||
/** \class SkAutoTCallIProc
|
||||
|
||||
Call a function when this goes out of scope. The template uses two
|
||||
parameters, the object, and a function that is to be called in the destructor.
|
||||
If detach() is called, the object reference is set to null. If the object
|
||||
reference is null when the destructor is called, we do not call the
|
||||
function.
|
||||
*/
|
||||
template <typename T, int (*P)(T*)> class SkAutoTCallIProc : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTCallIProc(T* obj): fObj(obj) {}
|
||||
~SkAutoTCallIProc() { if (fObj) P(fObj); }
|
||||
T* detach() { T* obj = fObj; fObj = NULL; return obj; }
|
||||
private:
|
||||
T* fObj;
|
||||
};
|
||||
|
||||
template <typename T> class SkAutoTDelete : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTDelete(T* obj) : fObj(obj) {}
|
||||
~SkAutoTDelete() { delete fObj; }
|
||||
|
||||
T* get() const { return fObj; }
|
||||
void free() { delete fObj; fObj = NULL; }
|
||||
T* detach() { T* obj = fObj; fObj = NULL; return obj; }
|
||||
|
||||
private:
|
||||
T* fObj;
|
||||
};
|
||||
|
||||
template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTDeleteArray(T array[]) : fArray(array) {}
|
||||
~SkAutoTDeleteArray() { delete[] fArray; }
|
||||
|
||||
T* get() const { return fArray; }
|
||||
void free() { delete[] fArray; fArray = NULL; }
|
||||
T* detach() { T* array = fArray; fArray = NULL; return array; }
|
||||
|
||||
private:
|
||||
T* fArray;
|
||||
};
|
||||
|
||||
/** Allocate an array of T elements, and free the array in the destructor
|
||||
*/
|
||||
template <typename T> class SkAutoTArray : SkNoncopyable {
|
||||
public:
|
||||
/** Allocate count number of T elements
|
||||
*/
|
||||
SkAutoTArray(size_t count) {
|
||||
fArray = NULL;
|
||||
if (count) {
|
||||
fArray = new T[count];
|
||||
}
|
||||
SkDEBUGCODE(fCount = count;)
|
||||
}
|
||||
|
||||
~SkAutoTArray() {
|
||||
delete[] fArray;
|
||||
}
|
||||
|
||||
/** Return the array of T elements. Will be NULL if count == 0
|
||||
*/
|
||||
T* get() const { return fArray; }
|
||||
|
||||
/** Return the nth element in the array
|
||||
*/
|
||||
T& operator[](int index) const {
|
||||
SkASSERT((unsigned)index < fCount);
|
||||
return fArray[index];
|
||||
}
|
||||
|
||||
private:
|
||||
T* fArray;
|
||||
SkDEBUGCODE(size_t fCount;)
|
||||
};
|
||||
|
||||
/** Wraps SkAutoTArray, with room for up to N elements preallocated
|
||||
*/
|
||||
template <size_t N, typename T> class SkAutoSTArray : SkNoncopyable {
|
||||
public:
|
||||
/** Allocate count number of T elements
|
||||
*/
|
||||
SkAutoSTArray(size_t count) {
|
||||
if (count > N) {
|
||||
fArray = new T[count];
|
||||
} else if (count) {
|
||||
fArray = new (fStorage) T[count];
|
||||
} else {
|
||||
fArray = NULL;
|
||||
}
|
||||
fCount = count;
|
||||
}
|
||||
|
||||
~SkAutoSTArray() {
|
||||
if (fCount > N) {
|
||||
delete[] fArray;
|
||||
} else {
|
||||
T* start = fArray;
|
||||
T* iter = start + fCount;
|
||||
while (iter > start) {
|
||||
(--iter)->~T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the number of T elements in the array
|
||||
*/
|
||||
size_t count() const { return fCount; }
|
||||
|
||||
/** Return the array of T elements. Will be NULL if count == 0
|
||||
*/
|
||||
T* get() const { return fArray; }
|
||||
|
||||
/** Return the nth element in the array
|
||||
*/
|
||||
T& operator[](int index) const {
|
||||
SkASSERT((unsigned)index < fCount);
|
||||
return fArray[index];
|
||||
}
|
||||
|
||||
private:
|
||||
size_t fCount;
|
||||
T* fArray;
|
||||
// since we come right after fArray, fStorage should be properly aligned
|
||||
char fStorage[N * sizeof(T)];
|
||||
};
|
||||
|
||||
/** Allocate a temp array on the stack/heap.
|
||||
Does NOT call any constructors/destructors on T (i.e. T must be POD)
|
||||
*/
|
||||
template <typename T> class SkAutoTMalloc : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTMalloc(size_t count)
|
||||
{
|
||||
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
|
||||
}
|
||||
~SkAutoTMalloc()
|
||||
{
|
||||
sk_free(fPtr);
|
||||
}
|
||||
T* get() const { return fPtr; }
|
||||
|
||||
private:
|
||||
T* fPtr;
|
||||
};
|
||||
|
||||
template <size_t N, typename T> class SkAutoSTMalloc : SkNoncopyable {
|
||||
public:
|
||||
SkAutoSTMalloc(size_t count)
|
||||
{
|
||||
if (count <= N)
|
||||
fPtr = fTStorage;
|
||||
else
|
||||
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
|
||||
}
|
||||
~SkAutoSTMalloc()
|
||||
{
|
||||
if (fPtr != fTStorage)
|
||||
sk_free(fPtr);
|
||||
}
|
||||
T* get() const { return fPtr; }
|
||||
|
||||
private:
|
||||
T* fPtr;
|
||||
union {
|
||||
uint32_t fStorage32[(N*sizeof(T) + 3) >> 2];
|
||||
T fTStorage[1]; // do NOT want to invoke T::T()
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkThread_DEFINED
|
||||
#define SkThread_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include "SkThread_platform.h"
|
||||
|
||||
/****** SkThread_platform needs to define the following...
|
||||
|
||||
int32_t sk_atomic_inc(int32_t*);
|
||||
int32_t sk_atomic_dec(int32_t*);
|
||||
|
||||
class SkMutex {
|
||||
public:
|
||||
SkMutex();
|
||||
~SkMutex();
|
||||
|
||||
void acquire();
|
||||
void release();
|
||||
};
|
||||
|
||||
****************/
|
||||
|
||||
class SkAutoMutexAcquire : SkNoncopyable {
|
||||
public:
|
||||
explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(&mutex)
|
||||
{
|
||||
SkASSERT(fMutex != NULL);
|
||||
mutex.acquire();
|
||||
}
|
||||
/** If the mutex has not been release, release it now.
|
||||
*/
|
||||
~SkAutoMutexAcquire()
|
||||
{
|
||||
if (fMutex)
|
||||
fMutex->release();
|
||||
}
|
||||
/** If the mutex has not been release, release it now.
|
||||
*/
|
||||
void release()
|
||||
{
|
||||
if (fMutex)
|
||||
{
|
||||
fMutex->release();
|
||||
fMutex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SkMutex* fMutex;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkThread_platform_DEFINED
|
||||
#define SkThread_platform_DEFINED
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Atomic.h>
|
||||
|
||||
#define sk_atomic_inc(addr) android_atomic_inc(addr)
|
||||
#define sk_atomic_dec(addr) android_atomic_dec(addr)
|
||||
|
||||
class SkMutex : android::Mutex {
|
||||
public:
|
||||
// if isGlobal is true, then ignore any errors in the platform-specific
|
||||
// destructor
|
||||
SkMutex(bool isGlobal = true) {}
|
||||
~SkMutex() {}
|
||||
|
||||
void acquire() { this->lock(); }
|
||||
void release() { this->unlock(); }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
/** Implemented by the porting layer, this function adds 1 to the int specified
|
||||
by the address (in a thread-safe manner), and returns the previous value.
|
||||
*/
|
||||
int32_t sk_atomic_inc(int32_t* addr);
|
||||
/** Implemented by the porting layer, this function subtracts 1 to the int
|
||||
specified by the address (in a thread-safe manner), and returns the previous
|
||||
value.
|
||||
*/
|
||||
int32_t sk_atomic_dec(int32_t* addr);
|
||||
|
||||
class SkMutex {
|
||||
public:
|
||||
// if isGlobal is true, then ignore any errors in the platform-specific
|
||||
// destructor
|
||||
SkMutex(bool isGlobal = true);
|
||||
~SkMutex();
|
||||
|
||||
void acquire();
|
||||
void release();
|
||||
|
||||
private:
|
||||
bool fIsGlobal;
|
||||
enum {
|
||||
kStorageIntCount = 12
|
||||
};
|
||||
uint32_t fStorage[kStorageIntCount];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTime_DEFINED
|
||||
#define SkTime_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \class SkTime
|
||||
Platform-implemented utilities to return time of day, and millisecond counter.
|
||||
*/
|
||||
class SkTime {
|
||||
public:
|
||||
struct DateTime {
|
||||
uint16_t fYear; //!< e.g. 2005
|
||||
uint8_t fMonth; //!< 1..12
|
||||
uint8_t fDayOfWeek; //!< 0..6, 0==Sunday
|
||||
uint8_t fDay; //!< 1..31
|
||||
uint8_t fHour; //!< 0..23
|
||||
uint8_t fMinute; //!< 0..59
|
||||
uint8_t fSecond; //!< 0..59
|
||||
};
|
||||
static void GetDateTime(DateTime*);
|
||||
|
||||
static SkMSec GetMSecs();
|
||||
};
|
||||
|
||||
#if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN32)
|
||||
extern SkMSec gForceTickCount;
|
||||
#endif
|
||||
|
||||
#define SK_TIME_FACTOR 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkAutoTime {
|
||||
public:
|
||||
// The label is not deep-copied, so its address must remain valid for the
|
||||
// lifetime of this object
|
||||
SkAutoTime(const char* label = NULL, SkMSec minToDump = 0) : fLabel(label)
|
||||
{
|
||||
fNow = SkTime::GetMSecs();
|
||||
fMinToDump = minToDump;
|
||||
}
|
||||
~SkAutoTime()
|
||||
{
|
||||
SkMSec dur = SkTime::GetMSecs() - fNow;
|
||||
if (dur >= fMinToDump) {
|
||||
SkDebugf("%s %d\n", fLabel ? fLabel : "", dur);
|
||||
}
|
||||
}
|
||||
private:
|
||||
const char* fLabel;
|
||||
SkMSec fNow;
|
||||
SkMSec fMinToDump;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTypeface_DEFINED
|
||||
#define SkTypeface_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
/** \class SkTypeface
|
||||
|
||||
The SkTypeface class specifies the typeface and intrinsic style of a font.
|
||||
This is used in the paint, along with optionally algorithmic settings like
|
||||
textSize, textSkewX, textScaleX, kFakeBoldText_Mask, to specify
|
||||
how text appears when drawn (and measured).
|
||||
|
||||
Typeface objects are immutable, and so they can be shred between threads.
|
||||
To enable this, Typeface inherits from the thread-safe version of SkRefCnt.
|
||||
*/
|
||||
class SkTypeface : public SkRefCnt {
|
||||
public:
|
||||
/** Style specifies the intrinsic style attributes of a given typeface
|
||||
*/
|
||||
enum Style {
|
||||
kNormal = 0,
|
||||
kBold = 0x01,
|
||||
kItalic = 0x02,
|
||||
|
||||
// helpers
|
||||
kBoldItalic = 0x03
|
||||
};
|
||||
|
||||
/** Returns the typeface's intrinsic style attributes
|
||||
*/
|
||||
Style style() const { return fStyle; }
|
||||
|
||||
/** DEPRECATED */
|
||||
Style getStyle() const { return this->style(); }
|
||||
|
||||
/** Returns true if getStyle() has the kBold bit set.
|
||||
*/
|
||||
bool isBold() const { return (fStyle & kBold) != 0; }
|
||||
|
||||
/** Returns true if getStyle() has the kItalic bit set.
|
||||
*/
|
||||
bool isItalic() const { return (fStyle & kItalic) != 0; }
|
||||
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
|
||||
/** Return the uniqueID for the specified typeface. If the face is null,
|
||||
resolve it to the default font and return its uniqueID.
|
||||
*/
|
||||
static uint32_t UniqueID(const SkTypeface* face);
|
||||
|
||||
/** Return a new reference to the typeface that most closely matches the
|
||||
requested familyName and style. Pass null as the familyName to return
|
||||
the default font for the requested style. Will never return null
|
||||
|
||||
@param familyName May be NULL. The name of the font family.
|
||||
@param style The style (normal, bold, italic) of the typeface.
|
||||
@return reference to the closest-matching typeface. Call must call
|
||||
unref() when they are done.
|
||||
*/
|
||||
static SkTypeface* Create(const char familyName[], Style style = kNormal);
|
||||
|
||||
/** Return a new reference to the typeface that most closely matches the
|
||||
requested typeface and specified Style. Use this call if you want to
|
||||
pick a new style from the same family of the existing typeface.
|
||||
If family is NULL, this selects from the default font's family.
|
||||
|
||||
@param family May be NULL. The name of the existing type face.
|
||||
@param s The style (normal, bold, italic) of the type face.
|
||||
@return reference to the closest-matching typeface. Call must call
|
||||
unref() when they are done.
|
||||
*/
|
||||
static SkTypeface* CreateFromTypeface(const SkTypeface* family, Style s);
|
||||
|
||||
/** Returns true if the two typefaces reference the same underlying font,
|
||||
even if one is null (which maps to the default font).
|
||||
*/
|
||||
static bool Equal(const SkTypeface* facea, const SkTypeface* faceb);
|
||||
|
||||
/** Returns a 32bit hash value for the typeface. Takes care of mapping null
|
||||
to the default typeface.
|
||||
*/
|
||||
static uint32_t Hash(const SkTypeface* face);
|
||||
|
||||
/** Return a new typeface given a file. If the file does not exist, or is
|
||||
not a valid font file, returns null.
|
||||
*/
|
||||
static SkTypeface* CreateFromFile(const char path[]);
|
||||
|
||||
/** Return a new typeface given a stream. If the stream is
|
||||
not a valid font file, returns null. Ownership of the stream is
|
||||
transferred, so the caller must not reference it again.
|
||||
*/
|
||||
static SkTypeface* CreateFromStream(SkStream* stream);
|
||||
|
||||
// Serialization
|
||||
void serialize(SkWStream*) const;
|
||||
static SkTypeface* Deserialize(SkStream*);
|
||||
|
||||
protected:
|
||||
/** uniqueID must be unique (please!) and non-zero
|
||||
*/
|
||||
SkTypeface(Style style, uint32_t uniqueID)
|
||||
: fUniqueID(uniqueID), fStyle(style) {}
|
||||
|
||||
private:
|
||||
uint32_t fUniqueID;
|
||||
Style fStyle;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTypes_DEFINED
|
||||
#define SkTypes_DEFINED
|
||||
|
||||
#include "SkPreConfig.h"
|
||||
#include "SkUserConfig.h"
|
||||
#include "SkPostConfig.h"
|
||||
|
||||
#ifndef SK_IGNORE_STDINT_DOT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/** \file SkTypes.h
|
||||
*/
|
||||
|
||||
/*
|
||||
memory wrappers to be implemented by the porting layer (platform)
|
||||
*/
|
||||
|
||||
/** Called internally if we run out of memory. The platform implementation must
|
||||
not return, but should either throw an exception or otherwise exit.
|
||||
*/
|
||||
extern void sk_out_of_memory(void);
|
||||
/** Called internally if we hit an unrecoverable error.
|
||||
The platform implementation must not return, but should either throw
|
||||
an exception or otherwise exit.
|
||||
*/
|
||||
extern void sk_throw(void);
|
||||
|
||||
enum {
|
||||
SK_MALLOC_TEMP = 0x01, //!< hint to sk_malloc that the requested memory will be freed in the scope of the stack frame
|
||||
SK_MALLOC_THROW = 0x02 //!< instructs sk_malloc to call sk_throw if the memory cannot be allocated.
|
||||
};
|
||||
/** Return a block of memory (at least 4-byte aligned) of at least the
|
||||
specified size. If the requested memory cannot be returned, either
|
||||
return null (if SK_MALLOC_TEMP bit is clear) or call sk_throw()
|
||||
(if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free().
|
||||
*/
|
||||
extern void* sk_malloc_flags(size_t size, unsigned flags);
|
||||
/** Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag
|
||||
*/
|
||||
extern void* sk_malloc_throw(size_t size);
|
||||
/** Same as standard realloc(), but this one never returns null on failure. It will throw
|
||||
an exception if it fails.
|
||||
*/
|
||||
extern void* sk_realloc_throw(void* buffer, size_t size);
|
||||
/** Free memory returned by sk_malloc(). It is safe to pass null.
|
||||
*/
|
||||
extern void sk_free(void*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SK_INIT_TO_AVOID_WARNING = 0
|
||||
|
||||
#ifndef SkDebugf
|
||||
void SkDebugf(const char format[], ...);
|
||||
#endif
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#define SkASSERT(cond) SK_DEBUGBREAK(cond)
|
||||
#define SkDEBUGCODE(code) code
|
||||
#define SkDECLAREPARAM(type, var) , type var
|
||||
#define SkPARAM(var) , var
|
||||
// #define SkDEBUGF(args ) SkDebugf##args
|
||||
#define SkDEBUGF(args ) SkDebugf args
|
||||
#define SkAssertResult(cond) SkASSERT(cond)
|
||||
#else
|
||||
#define SkASSERT(cond)
|
||||
#define SkDEBUGCODE(code)
|
||||
#define SkDEBUGF(args)
|
||||
#define SkDECLAREPARAM(type, var)
|
||||
#define SkPARAM(var)
|
||||
|
||||
// unlike SkASSERT, this guy executes its condition in the non-debug build
|
||||
#define SkAssertResult(cond) cond
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Fast type for signed 8 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef int S8CPU;
|
||||
/** Fast type for unsigned 8 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef int S16CPU;
|
||||
/** Fast type for signed 16 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef unsigned U8CPU;
|
||||
/** Fast type for unsigned 16 bits. Use for parameter passing and local variables, not for storage
|
||||
*/
|
||||
typedef unsigned U16CPU;
|
||||
|
||||
/** Meant to be faster than bool (doesn't promise to be 0 or 1, just 0 or non-zero
|
||||
*/
|
||||
typedef int SkBool;
|
||||
/** Meant to be a small version of bool, for storage purposes. Will be 0 or 1
|
||||
*/
|
||||
typedef uint8_t SkBool8;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
int8_t SkToS8(long);
|
||||
uint8_t SkToU8(size_t);
|
||||
int16_t SkToS16(long);
|
||||
uint16_t SkToU16(size_t);
|
||||
int32_t SkToS32(long);
|
||||
uint32_t SkToU32(size_t);
|
||||
#else
|
||||
#define SkToS8(x) ((int8_t)(x))
|
||||
#define SkToU8(x) ((uint8_t)(x))
|
||||
#define SkToS16(x) ((int16_t)(x))
|
||||
#define SkToU16(x) ((uint16_t)(x))
|
||||
#define SkToS32(x) ((int32_t)(x))
|
||||
#define SkToU32(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
/** Returns 0 or 1 based on the condition
|
||||
*/
|
||||
#define SkToBool(cond) ((cond) != 0)
|
||||
|
||||
#define SK_MaxS16 32767
|
||||
#define SK_MinS16 -32767
|
||||
#define SK_MaxU16 0xFFFF
|
||||
#define SK_MinU16 0
|
||||
#define SK_MaxS32 0x7FFFFFFF
|
||||
#define SK_MinS32 0x80000001
|
||||
#define SK_MaxU32 0xFFFFFFFF
|
||||
#define SK_MinU32 0
|
||||
#define SK_NaN32 0x80000000
|
||||
|
||||
#ifndef SK_OFFSETOF
|
||||
#define SK_OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1)
|
||||
#endif
|
||||
|
||||
/** Returns the number of entries in an array (not a pointer)
|
||||
*/
|
||||
#define SK_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
/** Returns x rounded up to a multiple of 2
|
||||
*/
|
||||
#define SkAlign2(x) (((x) + 1) >> 1 << 1)
|
||||
/** Returns x rounded up to a multiple of 4
|
||||
*/
|
||||
#define SkAlign4(x) (((x) + 3) >> 2 << 2)
|
||||
|
||||
typedef uint32_t SkFourByteTag;
|
||||
#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
|
||||
/** 32 bit integer to hold a unicode value
|
||||
*/
|
||||
typedef int32_t SkUnichar;
|
||||
/** 32 bit value to hold a millisecond count
|
||||
*/
|
||||
typedef uint32_t SkMSec;
|
||||
/** 1 second measured in milliseconds
|
||||
*/
|
||||
#define SK_MSec1 1000
|
||||
/** maximum representable milliseconds
|
||||
*/
|
||||
#define SK_MSecMax 0x7FFFFFFF
|
||||
/** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
|
||||
*/
|
||||
#define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0)
|
||||
/** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
|
||||
*/
|
||||
#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
The rest of these only build with C++
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
|
||||
/** Faster than SkToBool for integral conditions. Returns 0 or 1
|
||||
*/
|
||||
inline int Sk32ToBool(uint32_t n)
|
||||
{
|
||||
return (n | (0-n)) >> 31;
|
||||
}
|
||||
|
||||
template <typename T> inline void SkTSwap(T& a, T& b)
|
||||
{
|
||||
T c(a);
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
|
||||
inline int32_t SkAbs32(int32_t value)
|
||||
{
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value < 0)
|
||||
value = -value;
|
||||
return value;
|
||||
#else
|
||||
int32_t mask = value >> 31;
|
||||
return (value ^ mask) - mask;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int32_t SkMax32(int32_t a, int32_t b)
|
||||
{
|
||||
if (a < b)
|
||||
a = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int32_t SkMin32(int32_t a, int32_t b)
|
||||
{
|
||||
if (a > b)
|
||||
a = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline int32_t SkSign32(int32_t a)
|
||||
{
|
||||
return (a >> 31) | ((unsigned) -a >> 31);
|
||||
}
|
||||
|
||||
inline int32_t SkFastMin32(int32_t value, int32_t max)
|
||||
{
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value > max)
|
||||
value = max;
|
||||
return value;
|
||||
#else
|
||||
int diff = max - value;
|
||||
// clear diff if it is negative (clear if value > max)
|
||||
diff &= (diff >> 31);
|
||||
return value + diff;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Returns signed 32 bit value pinned between min and max, inclusively
|
||||
*/
|
||||
inline int32_t SkPin32(int32_t value, int32_t min, int32_t max)
|
||||
{
|
||||
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
if (value < min)
|
||||
value = min;
|
||||
if (value > max)
|
||||
value = max;
|
||||
#else
|
||||
if (value < min)
|
||||
value = min;
|
||||
else if (value > max)
|
||||
value = max;
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
inline uint32_t SkSetClearShift(uint32_t bits, bool cond, unsigned shift)
|
||||
{
|
||||
SkASSERT((int)cond == 0 || (int)cond == 1);
|
||||
return (bits & ~(1 << shift)) | ((int)cond << shift);
|
||||
}
|
||||
|
||||
inline uint32_t SkSetClearMask(uint32_t bits, bool cond, uint32_t mask)
|
||||
{
|
||||
return cond ? bits | mask : bits & ~mask;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** \class SkNoncopyable
|
||||
|
||||
SkNoncopyable is the base class for objects that may do not want to
|
||||
be copied. It hides its copy-constructor and its assignment-operator.
|
||||
*/
|
||||
class SkNoncopyable {
|
||||
public:
|
||||
SkNoncopyable() {}
|
||||
|
||||
private:
|
||||
SkNoncopyable(const SkNoncopyable&);
|
||||
SkNoncopyable& operator=(const SkNoncopyable&);
|
||||
};
|
||||
|
||||
class SkAutoFree : SkNoncopyable {
|
||||
public:
|
||||
SkAutoFree() : fPtr(NULL) {}
|
||||
explicit SkAutoFree(void* ptr) : fPtr(ptr) {}
|
||||
~SkAutoFree() { sk_free(fPtr); }
|
||||
|
||||
/** Return the currently allocate buffer, or null
|
||||
*/
|
||||
void* get() const { return fPtr; }
|
||||
|
||||
/** Assign a new ptr allocated with sk_malloc (or null), and return the
|
||||
previous ptr. Note it is the caller's responsibility to sk_free the
|
||||
returned ptr.
|
||||
*/
|
||||
void* set(void* ptr) {
|
||||
void* prev = fPtr;
|
||||
fPtr = ptr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/** Transfer ownership of the current ptr to the caller, setting the
|
||||
internal reference to null. Note the caller is reponsible for calling
|
||||
sk_free on the returned address.
|
||||
*/
|
||||
void* detach() { return this->set(NULL); }
|
||||
|
||||
/** Free the current buffer, and set the internal reference to NULL. Same
|
||||
as calling sk_free(detach())
|
||||
*/
|
||||
void free() {
|
||||
sk_free(fPtr);
|
||||
fPtr = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
void* fPtr;
|
||||
// illegal
|
||||
SkAutoFree(const SkAutoFree&);
|
||||
SkAutoFree& operator=(const SkAutoFree&);
|
||||
};
|
||||
|
||||
class SkAutoMalloc : public SkAutoFree {
|
||||
public:
|
||||
explicit SkAutoMalloc(size_t size)
|
||||
: SkAutoFree(sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP)) {}
|
||||
|
||||
SkAutoMalloc(size_t size, unsigned flags)
|
||||
: SkAutoFree(sk_malloc_flags(size, flags)) {}
|
||||
SkAutoMalloc() {}
|
||||
|
||||
void* alloc(size_t size,
|
||||
unsigned flags = (SK_MALLOC_THROW | SK_MALLOC_TEMP)) {
|
||||
sk_free(set(sk_malloc_flags(size, flags)));
|
||||
return get();
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t kSize> class SkAutoSMalloc : SkNoncopyable {
|
||||
public:
|
||||
explicit SkAutoSMalloc(size_t size)
|
||||
{
|
||||
if (size <= kSize)
|
||||
fPtr = fStorage;
|
||||
else
|
||||
fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
|
||||
}
|
||||
~SkAutoSMalloc()
|
||||
{
|
||||
if (fPtr != (void*)fStorage)
|
||||
sk_free(fPtr);
|
||||
}
|
||||
void* get() const { return fPtr; }
|
||||
private:
|
||||
void* fPtr;
|
||||
uint32_t fStorage[(kSize + 3) >> 2];
|
||||
// illegal
|
||||
SkAutoSMalloc(const SkAutoSMalloc&);
|
||||
SkAutoSMalloc& operator=(const SkAutoSMalloc&);
|
||||
};
|
||||
|
||||
#endif /* C++ */
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef SkUnPreMultiply_DEFINED
|
||||
#define SkUnPreMultiply_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
|
||||
class SkUnPreMultiply {
|
||||
public:
|
||||
typedef uint32_t Scale;
|
||||
|
||||
// index this table with alpha [0..255]
|
||||
static const Scale* GetScaleTable() {
|
||||
return gTable;
|
||||
}
|
||||
|
||||
static Scale GetScale(U8CPU alpha) {
|
||||
SkASSERT(alpha <= 255);
|
||||
return gTable[alpha];
|
||||
}
|
||||
|
||||
/** Usage:
|
||||
|
||||
const Scale* table = SkUnPreMultiply::GetScaleTable();
|
||||
|
||||
for (...) {
|
||||
unsigned a = ...
|
||||
SkUnPreMultiply::Scale scale = table[a];
|
||||
|
||||
red = SkUnPreMultiply::ApplyScale(scale, red);
|
||||
...
|
||||
// now red is unpremultiplied
|
||||
}
|
||||
*/
|
||||
static U8CPU ApplyScale(Scale scale, U8CPU component) {
|
||||
SkASSERT(component <= 255);
|
||||
return (scale * component + (1 << 23)) >> 24;
|
||||
}
|
||||
|
||||
static SkColor PMColorToColor(SkPMColor c);
|
||||
|
||||
private:
|
||||
static const uint32_t gTable[256];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkUnitMapper_DEFINED
|
||||
#define SkUnitMapper_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkUnitMapper : public SkFlattenable {
|
||||
public:
|
||||
SkUnitMapper() {}
|
||||
|
||||
/** Given a value in [0..0xFFFF], return a value in the same range.
|
||||
*/
|
||||
virtual uint16_t mapUnit16(uint16_t x) = 0;
|
||||
|
||||
protected:
|
||||
SkUnitMapper(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkUserConfig_DEFINED
|
||||
#define SkUserConfig_DEFINED
|
||||
|
||||
// for floats
|
||||
#ifdef SK_SCALAR_IS_FIXED
|
||||
#undef SK_SCALAR_IS_FIXED
|
||||
#endif
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
|
||||
// remove the x if you want to force us into SK_DEBUG mode
|
||||
#ifdef SK_RELEASE
|
||||
#undef SK_RELEASE
|
||||
#define SK_DEBUG
|
||||
#endif
|
||||
|
||||
// remove the x if you want to force us into SK_RELEASE mode
|
||||
#ifdef SK_DEBUGx
|
||||
#undef SK_DEBUG
|
||||
#define SK_RELEASE
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <utils/misc.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define SK_CRASH() *(int *)(uintptr_t)0 = 0
|
||||
// #define SK_CRASH() assert(0)
|
||||
|
||||
#if 0
|
||||
// force fixed
|
||||
#define SK_SCALAR_IS_FIXED
|
||||
#undef SK_SCALAR_IS_FLOAT
|
||||
#else
|
||||
// force floats
|
||||
#ifdef SK_SCALAR_IS_FIXED
|
||||
#undef SK_SCALAR_IS_FIXED
|
||||
#endif
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#endif
|
||||
|
||||
#define SK_CAN_USE_FLOAT
|
||||
#define SK_SOFTWARE_FLOAT
|
||||
#define SkLONGLONG int64_t
|
||||
|
||||
// replace some sw float routines (floor, ceil, etc.)
|
||||
#define SK_USE_FLOATBITS
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define SK_CPU_BENDIAN
|
||||
#undef SK_CPU_LENDIAN
|
||||
#else
|
||||
#define SK_CPU_LENDIAN
|
||||
#undef SK_CPU_BENDIAN
|
||||
#endif
|
||||
|
||||
// define SkDebugf to record file/line
|
||||
#define SkDebugf(...) Android_SkDebugf(__FILE__, __LINE__, \
|
||||
__FUNCTION__, __VA_ARGS__)
|
||||
void Android_SkDebugf(const char* file, int line,
|
||||
const char* function, const char* format, ...);
|
||||
#endif
|
||||
|
||||
/* This file is included before all other headers, except for SkPreConfig.h.
|
||||
That file uses various heuristics to make a "best guess" at settings for
|
||||
the following build defines.
|
||||
|
||||
However, in this file you can override any of those decisions by either
|
||||
defining new symbols, or #undef symbols that were already set.
|
||||
*/
|
||||
|
||||
// experimental for now
|
||||
#define SK_SUPPORT_MIPMAP
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#define SK_SUPPORT_UNITTEST
|
||||
/* Define SK_SIMULATE_FAILED_MALLOC to have
|
||||
* sk_malloc throw an exception. Use this to
|
||||
* detect unhandled memory leaks. */
|
||||
//#define SK_SIMULATE_FAILED_MALLOC
|
||||
//#define SK_FIND_MEMORY_LEAKS
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_BREW
|
||||
#include "SkBrewUserConfig.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkUtils_DEFINED
|
||||
#define SkUtils_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Similar to memset(), but it assigns a 16bit value into the buffer.
|
||||
@param buffer The memory to have value copied into it
|
||||
@param value The 16bit value to be copied into buffer
|
||||
@param count The number of times value should be copied into the buffer.
|
||||
*/
|
||||
void sk_memset16_portable(uint16_t dst[], uint16_t value, int count);
|
||||
|
||||
/** Similar to memset(), but it assigns a 32bit value into the buffer.
|
||||
@param buffer The memory to have value copied into it
|
||||
@param value The 32bit value to be copied into buffer
|
||||
@param count The number of times value should be copied into the buffer.
|
||||
*/
|
||||
void sk_memset32_portable(uint32_t dst[], uint32_t value, int count);
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "cutils/memory.h"
|
||||
|
||||
#define sk_memset16(dst, value, count) android_memset16(dst, value, (count) << 1)
|
||||
#define sk_memset32(dst, value, count) android_memset32(dst, value, (count) << 2)
|
||||
#endif
|
||||
|
||||
#ifndef sk_memset16
|
||||
#define sk_memset16(dst, value, count) sk_memset16_portable(dst, value, count)
|
||||
#endif
|
||||
|
||||
#ifndef sk_memset32
|
||||
#define sk_memset32(dst, value, count) sk_memset32_portable(dst, value, count)
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define kMaxBytesInUTF8Sequence 4
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
int SkUTF8_LeadByteToCount(unsigned c);
|
||||
#else
|
||||
#define SkUTF8_LeadByteToCount(c) ((((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1)
|
||||
#endif
|
||||
|
||||
inline int SkUTF8_CountUTF8Bytes(const char utf8[])
|
||||
{
|
||||
SkASSERT(utf8);
|
||||
return SkUTF8_LeadByteToCount(*(const uint8_t*)utf8);
|
||||
}
|
||||
|
||||
int SkUTF8_CountUnichars(const char utf8[]);
|
||||
int SkUTF8_CountUnichars(const char utf8[], size_t byteLength);
|
||||
SkUnichar SkUTF8_ToUnichar(const char utf8[]);
|
||||
SkUnichar SkUTF8_NextUnichar(const char**);
|
||||
SkUnichar SkUTF8_PrevUnichar(const char**);
|
||||
|
||||
/** Return the number of bytes need to convert a unichar
|
||||
into a utf8 sequence. Will be 1..kMaxBytesInUTF8Sequence,
|
||||
or 0 if uni is illegal.
|
||||
*/
|
||||
size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[] = NULL);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SkUTF16_IsHighSurrogate(c) (((c) & 0xFC00) == 0xD800)
|
||||
#define SkUTF16_IsLowSurrogate(c) (((c) & 0xFC00) == 0xDC00)
|
||||
|
||||
int SkUTF16_CountUnichars(const uint16_t utf16[]);
|
||||
int SkUTF16_CountUnichars(const uint16_t utf16[],
|
||||
int numberOf16BitValues);
|
||||
// returns the current unichar and then moves past it (*p++)
|
||||
SkUnichar SkUTF16_NextUnichar(const uint16_t**);
|
||||
// this guy backs up to the previus unichar value, and returns it (*--p)
|
||||
SkUnichar SkUTF16_PrevUnichar(const uint16_t**);
|
||||
size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t utf16[] = NULL);
|
||||
|
||||
size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues,
|
||||
char utf8[] = NULL);
|
||||
|
||||
class SkUtils {
|
||||
public:
|
||||
#ifdef SK_DEBUG
|
||||
static void UnitTest();
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkAutoTrace {
|
||||
public:
|
||||
/** NOTE: label contents are not copied, just the ptr is
|
||||
retained, so DON'T DELETE IT.
|
||||
*/
|
||||
SkAutoTrace(const char label[]) : fLabel(label) {
|
||||
SkDebugf("--- trace: %s Enter\n", fLabel);
|
||||
}
|
||||
~SkAutoTrace() {
|
||||
SkDebugf("--- trace: %s Leave\n", fLabel);
|
||||
}
|
||||
private:
|
||||
const char* fLabel;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkAutoMemoryUsageProbe {
|
||||
public:
|
||||
/** Record memory usage in constructor, and dump the result
|
||||
(delta and current total) in the destructor, with the optional
|
||||
label. NOTE: label contents are not copied, just the ptr is
|
||||
retained, so DON'T DELETE IT.
|
||||
*/
|
||||
SkAutoMemoryUsageProbe(const char label[]);
|
||||
~SkAutoMemoryUsageProbe();
|
||||
private:
|
||||
const char* fLabel;
|
||||
size_t fBytesAllocated;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkWriter32_DEFINED
|
||||
#define SkWriter32_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
class SkWriter32 : SkNoncopyable {
|
||||
public:
|
||||
SkWriter32(size_t minSize) {
|
||||
fMinSize = minSize;
|
||||
fSize = 0;
|
||||
fHead = fTail = NULL;
|
||||
}
|
||||
~SkWriter32();
|
||||
|
||||
bool writeBool(bool value) {
|
||||
this->writeInt(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void writeInt(int32_t value) {
|
||||
*(int32_t*)this->reserve(sizeof(value)) = value;
|
||||
}
|
||||
|
||||
void write8(int32_t value) {
|
||||
*(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
|
||||
}
|
||||
|
||||
void write16(int32_t value) {
|
||||
*(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
|
||||
}
|
||||
|
||||
void write32(int32_t value) {
|
||||
*(int32_t*)this->reserve(sizeof(value)) = value;
|
||||
}
|
||||
|
||||
void writeScalar(SkScalar value) {
|
||||
*(SkScalar*)this->reserve(sizeof(value)) = value;
|
||||
}
|
||||
|
||||
void writePoint(const SkPoint& pt) {
|
||||
*(SkPoint*)this->reserve(sizeof(pt)) = pt;
|
||||
}
|
||||
|
||||
void writeRect(const SkRect& rect) {
|
||||
*(SkRect*)this->reserve(sizeof(rect)) = rect;
|
||||
}
|
||||
|
||||
// write count bytes (must be a multiple of 4)
|
||||
void writeMul4(const void* values, size_t size) {
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
// if we could query how much is avail in the current block, we might
|
||||
// copy that much, and then alloc the rest. That would reduce the waste
|
||||
// in the current block
|
||||
memcpy(this->reserve(size), values, size);
|
||||
}
|
||||
|
||||
void writePad(const void* src, size_t size);
|
||||
|
||||
// return the current offset (will always be a multiple of 4)
|
||||
uint32_t size() const { return fSize; }
|
||||
void reset();
|
||||
uint32_t* reserve(size_t size); // size MUST be multiple of 4
|
||||
|
||||
// return the address of the 4byte int at the specified offset (which must
|
||||
// be a multiple of 4. This does not allocate any new space, so the returned
|
||||
// address is only valid for 1 int.
|
||||
uint32_t* peek32(size_t offset);
|
||||
|
||||
// copy into a single buffer (allocated by caller). Must be at least size()
|
||||
void flatten(void* dst) const;
|
||||
|
||||
// read from the stream, and write up to length bytes. Return the actual
|
||||
// number of bytes written.
|
||||
size_t readFromStream(SkStream*, size_t length);
|
||||
|
||||
bool writeToStream(SkWStream*);
|
||||
|
||||
private:
|
||||
size_t fMinSize;
|
||||
uint32_t fSize;
|
||||
|
||||
struct Block;
|
||||
Block* fHead;
|
||||
Block* fTail;
|
||||
|
||||
Block* newBlock(size_t bytes);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkXfermode_DEFINED
|
||||
#define SkXfermode_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkColor.h"
|
||||
|
||||
/** \class SkXfermode
|
||||
|
||||
SkXfermode is the base class for objects that are called to implement custom
|
||||
"transfer-modes" in the drawing pipeline. The static function Create(Modes)
|
||||
can be called to return an instance of any of the predefined subclasses as
|
||||
specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
|
||||
then objects drawn with that paint have the xfermode applied.
|
||||
*/
|
||||
class SkXfermode : public SkFlattenable {
|
||||
public:
|
||||
SkXfermode() {}
|
||||
|
||||
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
|
||||
enum Coeff {
|
||||
kZero_Coeff,
|
||||
kOne_Coeff,
|
||||
kSC_Coeff,
|
||||
kISC_Coeff,
|
||||
kDC_Coeff,
|
||||
kIDC_Coeff,
|
||||
kSA_Coeff,
|
||||
kISA_Coeff,
|
||||
kDA_Coeff,
|
||||
kIDA_Coeff,
|
||||
|
||||
kCoeffCount
|
||||
};
|
||||
virtual bool asCoeff(Coeff* src, Coeff* dst);
|
||||
|
||||
protected:
|
||||
SkXfermode(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}
|
||||
|
||||
/** The default implementation of xfer32/xfer16/xferA8 in turn call this
|
||||
method, 1 color at a time (upscaled to a SkPMColor). The default
|
||||
implmentation of this method just returns dst. If performance is
|
||||
important, your subclass should override xfer32/xfer16/xferA8 directly.
|
||||
|
||||
This method will not be called directly by the client, so it need not
|
||||
be implemented if your subclass has overridden xfer32/xfer16/xferA8
|
||||
*/
|
||||
virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst);
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** \class SkProcXfermode
|
||||
|
||||
SkProcXfermode is a xfermode that applies the specified proc to its colors.
|
||||
This class is not exported to java.
|
||||
*/
|
||||
class SkProcXfermode : public SkXfermode {
|
||||
public:
|
||||
SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {}
|
||||
|
||||
// overrides from SkXfermode
|
||||
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
SkProcXfermode(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkXfermodeProc fProc;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkProcXfermode, (buffer)); }
|
||||
|
||||
typedef SkXfermode INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef Sk1DPathEffect_DEFINED
|
||||
#define Sk1DPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
#include "SkPath.h"
|
||||
|
||||
class SkPathMeasure;
|
||||
|
||||
// This class is not exported to java.
|
||||
class Sk1DPathEffect : public SkPathEffect {
|
||||
public:
|
||||
// override from SkPathEffect
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
protected:
|
||||
/** Called at the start of each contour, returns the initial offset
|
||||
into that contour.
|
||||
*/
|
||||
virtual SkScalar begin(SkScalar contourLength) = 0;
|
||||
/** Called with the current distance along the path, with the current matrix
|
||||
for the point/tangent at the specified distance.
|
||||
Return the distance to travel for the next call. If return <= 0, then that
|
||||
contour is done.
|
||||
*/
|
||||
virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&) = 0;
|
||||
|
||||
private:
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
class SkPath1DPathEffect : public Sk1DPathEffect {
|
||||
public:
|
||||
enum Style {
|
||||
kTranslate_Style, // translate the shape to each position
|
||||
kRotate_Style, // rotate the shape about its center
|
||||
kMorph_Style, // transform each point, and turn lines into curves
|
||||
|
||||
kStyleCount
|
||||
};
|
||||
|
||||
/** Dash by replicating the specified path.
|
||||
@param path The path to replicate (dash)
|
||||
@param advance The space between instances of path
|
||||
@param phase distance (mod advance) along path for its initial position
|
||||
@param style how to transform path at each point (based on the current
|
||||
position and tangent)
|
||||
*/
|
||||
SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
|
||||
|
||||
// override from SkPathEffect
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
protected:
|
||||
SkPath1DPathEffect(SkFlattenableReadBuffer& buffer);
|
||||
|
||||
// overrides from Sk1DPathEffect
|
||||
virtual SkScalar begin(SkScalar contourLength);
|
||||
virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&);
|
||||
// overrides from SkFlattenable
|
||||
virtual void flatten(SkFlattenableWriteBuffer& );
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
SkPath fPath; // copied from constructor
|
||||
SkScalar fAdvance; // copied from constructor
|
||||
SkScalar fInitialOffset; // computed from phase
|
||||
Style fStyle; // copied from constructor
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkPath1DPathEffect, (buffer));
|
||||
}
|
||||
|
||||
typedef Sk1DPathEffect INHERITED;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef Sk2DPathEffect_DEFINED
|
||||
#define Sk2DPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
#include "SkMatrix.h"
|
||||
|
||||
// This class is not exported to java.
|
||||
class Sk2DPathEffect : public SkPathEffect {
|
||||
public:
|
||||
Sk2DPathEffect(const SkMatrix& mat);
|
||||
|
||||
// overrides
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
|
||||
protected:
|
||||
/** New virtual, to be overridden by subclasses.
|
||||
This is called once from filterPath, and provides the
|
||||
uv parameter bounds for the path. Subsequent calls to
|
||||
next() will receive u and v values within these bounds,
|
||||
and then a call to end() will signal the end of processing.
|
||||
*/
|
||||
virtual void begin(const SkIRect& uvBounds, SkPath* dst);
|
||||
virtual void next(const SkPoint& loc, int u, int v, SkPath* dst);
|
||||
virtual void end(SkPath* dst);
|
||||
|
||||
/** Low-level virtual called per span of locations in the u-direction.
|
||||
The default implementation calls next() repeatedly with each
|
||||
location.
|
||||
*/
|
||||
virtual void nextSpan(int u, int v, int ucount, SkPath* dst);
|
||||
|
||||
const SkMatrix& getMatrix() const { return fMatrix; }
|
||||
|
||||
// protected so that subclasses can call this during unflattening
|
||||
Sk2DPathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkMatrix fMatrix, fInverse;
|
||||
// illegal
|
||||
Sk2DPathEffect(const Sk2DPathEffect&);
|
||||
Sk2DPathEffect& operator=(const Sk2DPathEffect&);
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
friend class Sk2DPathEffectBlitter;
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkAvoidXfermode_DEFINED
|
||||
#define SkAvoidXfermode_DEFINED
|
||||
|
||||
#include "SkXfermode.h"
|
||||
|
||||
/** \class SkAvoidXfermode
|
||||
|
||||
This xfermode will draw the src everywhere except on top of the specified
|
||||
color.
|
||||
*/
|
||||
class SkAvoidXfermode : public SkXfermode {
|
||||
public:
|
||||
enum Mode {
|
||||
kAvoidColor_Mode, //!< draw everywhere except on the opColor
|
||||
kTargetColor_Mode //!< draw only on top of the opColor
|
||||
};
|
||||
|
||||
/** This xfermode will draw the src everywhere except on top of the opColor
|
||||
or, depending on the Mode, draw only on top of the opColor.
|
||||
@param opColor the color to avoid (or to target depending on Mode).
|
||||
note: the alpha in opColor is ignored
|
||||
@param tolerance How closely we compare a pixel to the opColor.
|
||||
0 - only operate if exact match
|
||||
255 - maximum gradation (blending) based on how
|
||||
similar the pixel is to our opColor (max tolerance)
|
||||
@param mode If we should avoid or target the opColor
|
||||
*/
|
||||
SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
|
||||
|
||||
// overrides from SkXfermode
|
||||
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
|
||||
const SkAlpha aa[]);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual Factory getFactory();
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
SkAvoidXfermode(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkColor fOpColor;
|
||||
uint32_t fDistMul; // x.14
|
||||
Mode fMode;
|
||||
|
||||
static SkFlattenable* Create(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkXfermode INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkBlurDrawLooper_DEFINED
|
||||
#define SkBlurDrawLooper_DEFINED
|
||||
|
||||
#include "SkDrawLooper.h"
|
||||
#include "SkColor.h"
|
||||
|
||||
class SkMaskFilter;
|
||||
|
||||
/** \class SkBlurDrawLooper
|
||||
This class draws a shadow of the object (possibly offset), and then draws
|
||||
the original object in its original position.
|
||||
should there be an option to just draw the shadow/blur layer? webkit?
|
||||
*/
|
||||
class SkBlurDrawLooper : public SkDrawLooper {
|
||||
public:
|
||||
SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color);
|
||||
virtual ~SkBlurDrawLooper();
|
||||
|
||||
// overrides from SkDrawLooper
|
||||
virtual void init(SkCanvas*, SkPaint*);
|
||||
virtual bool next();
|
||||
virtual void restore();
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
|
||||
}
|
||||
|
||||
protected:
|
||||
SkBlurDrawLooper(SkFlattenableReadBuffer&);
|
||||
// overrides from SkFlattenable
|
||||
virtual void flatten(SkFlattenableWriteBuffer& );
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
SkCanvas* fCanvas;
|
||||
SkPaint* fPaint;
|
||||
SkMaskFilter* fBlur;
|
||||
SkScalar fDx, fDy;
|
||||
SkColor fBlurColor;
|
||||
SkColor fSavedColor; // remember the original
|
||||
int fSaveCount;
|
||||
|
||||
enum State {
|
||||
kBeforeEdge,
|
||||
kAfterEdge,
|
||||
kDone
|
||||
};
|
||||
State fState;
|
||||
|
||||
typedef SkDrawLooper INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkBlurMaskFilter_DEFINED
|
||||
#define SkBlurMaskFilter_DEFINED
|
||||
|
||||
// we include this since our callers will need to at least be able to ref/unref
|
||||
#include "SkMaskFilter.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkBlurMaskFilter {
|
||||
public:
|
||||
enum BlurStyle {
|
||||
kNormal_BlurStyle, //!< fuzzy inside and outside
|
||||
kSolid_BlurStyle, //!< solid inside, fuzzy outside
|
||||
kOuter_BlurStyle, //!< nothing inside, fuzzy outside
|
||||
kInner_BlurStyle, //!< fuzzy inside, nothing outside
|
||||
|
||||
kBlurStyleCount
|
||||
};
|
||||
|
||||
/** Create a blur maskfilter.
|
||||
@param radius The radius to extend the blur from the original mask. Must be > 0.
|
||||
@param style The BlurStyle to use
|
||||
@return The new blur maskfilter
|
||||
*/
|
||||
static SkMaskFilter* Create(SkScalar radius, BlurStyle style);
|
||||
|
||||
/** Create an emboss maskfilter
|
||||
@param direction array of 3 scalars [x, y, z] specifying the direction of the light source
|
||||
@param ambient 0...1 amount of ambient light
|
||||
@param specular coefficient for specular highlights (e.g. 8)
|
||||
@param blurRadius amount to blur before applying lighting (e.g. 3)
|
||||
@return the emboss maskfilter
|
||||
*/
|
||||
static SkMaskFilter* CreateEmboss( const SkScalar direction[3],
|
||||
SkScalar ambient, SkScalar specular,
|
||||
SkScalar blurRadius);
|
||||
|
||||
private:
|
||||
SkBlurMaskFilter(); // can't be instantiated
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkColorMatrix_DEFINED
|
||||
#define SkColorMatrix_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkColorMatrix {
|
||||
public:
|
||||
SkScalar fMat[20];
|
||||
|
||||
void setIdentity();
|
||||
void setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
|
||||
SkScalar aScale = SK_Scalar1);
|
||||
void preScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
|
||||
SkScalar aScale = SK_Scalar1);
|
||||
void postScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
|
||||
SkScalar aScale = SK_Scalar1);
|
||||
|
||||
enum Axis {
|
||||
kR_Axis = 0,
|
||||
kG_Axis = 1,
|
||||
kB_Axis = 2
|
||||
};
|
||||
void setRotate(Axis, SkScalar degrees);
|
||||
void setSinCos(Axis, SkScalar sine, SkScalar cosine);
|
||||
void preRotate(Axis, SkScalar degrees);
|
||||
void postRotate(Axis, SkScalar degrees);
|
||||
|
||||
void setConcat(const SkColorMatrix& a, const SkColorMatrix& b);
|
||||
void preConcat(const SkColorMatrix& mat) { this->setConcat(*this, mat); }
|
||||
void postConcat(const SkColorMatrix& mat) { this->setConcat(mat, *this); }
|
||||
|
||||
void setSaturation(SkScalar sat);
|
||||
void setRGB2YUV();
|
||||
void setYUV2RGB();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkColorMatrixFilter_DEFINED
|
||||
#define SkColorMatrixFilter_DEFINED
|
||||
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkColorMatrix.h"
|
||||
|
||||
class SkColorMatrixFilter : public SkColorFilter {
|
||||
public:
|
||||
SkColorMatrixFilter();
|
||||
explicit SkColorMatrixFilter(const SkColorMatrix&);
|
||||
SkColorMatrixFilter(const SkScalar array[20]);
|
||||
|
||||
void setMatrix(const SkColorMatrix&);
|
||||
void setArray(const SkScalar array[20]);
|
||||
|
||||
// overrides from SkColorFilter
|
||||
virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]);
|
||||
virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]);
|
||||
virtual uint32_t getFlags();
|
||||
|
||||
// overrides for SkFlattenable
|
||||
virtual void flatten(SkFlattenableWriteBuffer& buffer);
|
||||
|
||||
struct State {
|
||||
int32_t fArray[20];
|
||||
int fShift;
|
||||
int32_t fResult[4];
|
||||
};
|
||||
|
||||
protected:
|
||||
// overrides for SkFlattenable
|
||||
virtual Factory getFactory();
|
||||
|
||||
SkColorMatrixFilter(SkFlattenableReadBuffer& buffer);
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer);
|
||||
|
||||
typedef void (*Proc)(State*, unsigned r, unsigned g, unsigned b,
|
||||
unsigned a);
|
||||
|
||||
Proc fProc;
|
||||
State fState;
|
||||
uint32_t fFlags;
|
||||
|
||||
void setup(const SkScalar array[20]);
|
||||
|
||||
typedef SkColorFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkCornerPathEffect_DEFINED
|
||||
#define SkCornerPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkCornerPathEffect
|
||||
|
||||
SkCornerPathEffect is a subclass of SkPathEffect that can turn sharp corners
|
||||
into various treatments (e.g. rounded corners)
|
||||
*/
|
||||
class SkCornerPathEffect : public SkPathEffect {
|
||||
public:
|
||||
/** radius must be > 0 to have an effect. It specifies the distance from each corner
|
||||
that should be "rounded".
|
||||
*/
|
||||
SkCornerPathEffect(SkScalar radius);
|
||||
virtual ~SkCornerPathEffect();
|
||||
|
||||
// overrides for SkPathEffect
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
SkCornerPathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar fRadius;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
// illegal
|
||||
SkCornerPathEffect(const SkCornerPathEffect&);
|
||||
SkCornerPathEffect& operator=(const SkCornerPathEffect&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDashPathEffect_DEFINED
|
||||
#define SkDashPathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkDashPathEffect
|
||||
|
||||
SkDashPathEffect is a subclass of SkPathEffect that implements dashing
|
||||
*/
|
||||
class SkDashPathEffect : public SkPathEffect {
|
||||
public:
|
||||
/** The intervals array must contain an even number of entries (>=2), with the even
|
||||
indices specifying the "on" intervals, and the odd indices specifying the "off"
|
||||
intervals. phase is an offset into the intervals array (mod the sum of all of the
|
||||
intervals).
|
||||
Note: only affects framed paths
|
||||
*/
|
||||
SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase, bool scaleToFit = false);
|
||||
virtual ~SkDashPathEffect();
|
||||
|
||||
// overrides for SkPathEffect
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
SkDashPathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar* fIntervals;
|
||||
int32_t fCount;
|
||||
// computed from phase
|
||||
SkScalar fInitialDashLength;
|
||||
int32_t fInitialDashIndex;
|
||||
SkScalar fIntervalLength;
|
||||
bool fScaleToFit;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkDiscretePathEffect_DEFINED
|
||||
#define SkDiscretePathEffect_DEFINED
|
||||
|
||||
#include "SkPathEffect.h"
|
||||
|
||||
/** \class SkDiscretePathEffect
|
||||
|
||||
This path effect chops a path into discrete segments, and randomly displaces them.
|
||||
*/
|
||||
class SkDiscretePathEffect : public SkPathEffect {
|
||||
public:
|
||||
/** Break the path into segments of segLength length, and randomly move the endpoints
|
||||
away from the original path by a maximum of deviation.
|
||||
Note: works on filled or framed paths
|
||||
*/
|
||||
SkDiscretePathEffect(SkScalar segLength, SkScalar deviation);
|
||||
|
||||
// overrides for SkPathEffect
|
||||
// This method is not exported to java.
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
SkDiscretePathEffect(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkScalar fSegLength, fPerterb;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SK_DRAW_EXTRA_PATH_EFFECT_H
|
||||
#define SK_DRAW_EXTRA_PATH_EFFECT_H
|
||||
class SkAnimator;
|
||||
void InitializeSkExtraPathEffects(SkAnimator* animator);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkEmbossMaskFilter_DEFINED
|
||||
#define SkEmbossMaskFilter_DEFINED
|
||||
|
||||
#include "SkMaskFilter.h"
|
||||
|
||||
/** \class SkEmbossMaskFilter
|
||||
|
||||
This mask filter creates a 3D emboss look, by specifying a light and blur amount.
|
||||
*/
|
||||
class SkEmbossMaskFilter : public SkMaskFilter {
|
||||
public:
|
||||
struct Light {
|
||||
SkScalar fDirection[3]; // x,y,z
|
||||
uint16_t fPad;
|
||||
uint8_t fAmbient;
|
||||
uint8_t fSpecular; // exponent, 4.4 right now
|
||||
};
|
||||
|
||||
SkEmbossMaskFilter(const Light& light, SkScalar blurRadius);
|
||||
|
||||
// overrides from SkMaskFilter
|
||||
// This method is not exported to java.
|
||||
virtual SkMask::Format getFormat();
|
||||
// This method is not exported to java.
|
||||
virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
|
||||
// This method is not exported to java.
|
||||
virtual Factory getFactory();
|
||||
// This method is not exported to java.
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
SkEmbossMaskFilter(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
Light fLight;
|
||||
SkScalar fBlurRadius;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkMaskFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkGradientShader_DEFINED
|
||||
#define SkGradientShader_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkUnitMapper;
|
||||
|
||||
/** \class SkGradientShader
|
||||
|
||||
SkGradientShader hosts factories for creating subclasses of SkShader that
|
||||
render linear and radial gradients.
|
||||
*/
|
||||
class SkGradientShader {
|
||||
public:
|
||||
/** Returns a shader that generates a linear gradient between the two
|
||||
specified points.
|
||||
<p />
|
||||
CreateLinear returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for count to be < 2.
|
||||
@param pts The start and end points for the gradient.
|
||||
@param colors The array[count] of colors, to be distributed between the two points
|
||||
@param pos May be NULL. array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the start and end point.
|
||||
If this is not null, the values must begin with 0, end with 1.0, and
|
||||
intermediate values must be strictly increasing.
|
||||
@param count Must be >=2. The number of colors (and pos if not NULL) entries.
|
||||
@param mode The tiling mode
|
||||
@param mapper May be NULL. Callback to modify the spread of the colors.
|
||||
*/
|
||||
static SkShader* CreateLinear( const SkPoint pts[2],
|
||||
const SkColor colors[], const SkScalar pos[], int count,
|
||||
SkShader::TileMode mode,
|
||||
SkUnitMapper* mapper = NULL);
|
||||
|
||||
/** Returns a shader that generates a radial gradient given the center and radius.
|
||||
<p />
|
||||
CreateRadial returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for colorCount to be < 2, or for radius to be <= 0.
|
||||
@param center The center of the circle for this gradient
|
||||
@param radius Must be positive. The radius of the circle for this gradient
|
||||
@param colors The array[count] of colors, to be distributed between the center and edge of the circle
|
||||
@param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the center and edge of the circle.
|
||||
If this is not null, the values must begin with 0, end with 1.0, and
|
||||
intermediate values must be strictly increasing.
|
||||
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
|
||||
@param mode The tiling mode
|
||||
@param mapper May be NULL. Callback to modify the spread of the colors.
|
||||
*/
|
||||
static SkShader* CreateRadial( const SkPoint& center, SkScalar radius,
|
||||
const SkColor colors[], const SkScalar pos[], int count,
|
||||
SkShader::TileMode mode,
|
||||
SkUnitMapper* mapper = NULL);
|
||||
|
||||
/** Returns a shader that generates a sweep gradient given a center.
|
||||
<p />
|
||||
CreateRadial returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for colorCount to be < 2.
|
||||
@param cx The X coordinate of the center of the sweep
|
||||
@param cx The Y coordinate of the center of the sweep
|
||||
@param colors The array[count] of colors, to be distributed around the center.
|
||||
@param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the center and edge of the circle.
|
||||
If this is not null, the values must begin with 0, end with 1.0, and
|
||||
intermediate values must be strictly increasing.
|
||||
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
|
||||
@param mapper May be NULL. Callback to modify the spread of the colors.
|
||||
*/
|
||||
static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
|
||||
const SkColor colors[], const SkScalar pos[],
|
||||
int count, SkUnitMapper* mapper = NULL);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkKernel33MaskFilter_DEFINED
|
||||
#define SkKernel33MaskFilter_DEFINED
|
||||
|
||||
#include "SkMaskFilter.h"
|
||||
|
||||
class SkKernel33ProcMaskFilter : public SkMaskFilter {
|
||||
public:
|
||||
SkKernel33ProcMaskFilter(unsigned percent256 = 256)
|
||||
: fPercent256(percent256) {}
|
||||
|
||||
virtual uint8_t computeValue(uint8_t* const* srcRows) = 0;
|
||||
|
||||
// overrides from SkMaskFilter
|
||||
virtual SkMask::Format getFormat();
|
||||
virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&, SkIPoint*);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual void flatten(SkFlattenableWriteBuffer& wb);
|
||||
|
||||
protected:
|
||||
SkKernel33ProcMaskFilter(SkFlattenableReadBuffer& rb);
|
||||
|
||||
private:
|
||||
int fPercent256;
|
||||
|
||||
typedef SkMaskFilter INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkKernel33MaskFilter : public SkKernel33ProcMaskFilter {
|
||||
public:
|
||||
SkKernel33MaskFilter(const int coeff[3][3], int shift, int percent256 = 256)
|
||||
: SkKernel33ProcMaskFilter(percent256)
|
||||
{
|
||||
memcpy(fKernel, coeff, 9 * sizeof(int));
|
||||
fShift = shift;
|
||||
}
|
||||
|
||||
// override from SkKernel33ProcMaskFilter
|
||||
virtual uint8_t computeValue(uint8_t* const* srcRows);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual void flatten(SkFlattenableWriteBuffer& wb);
|
||||
virtual Factory getFactory();
|
||||
|
||||
private:
|
||||
int fKernel[3][3];
|
||||
int fShift;
|
||||
|
||||
SkKernel33MaskFilter(SkFlattenableReadBuffer& rb);
|
||||
static SkFlattenable* Create(SkFlattenableReadBuffer& rb);
|
||||
|
||||
typedef SkKernel33ProcMaskFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
#ifndef SkLayerDrawLooper_DEFINED
|
||||
#define SkLayerDrawLooper_DEFINED
|
||||
|
||||
#include "SkDrawLooper.h"
|
||||
|
||||
struct SkPoint;
|
||||
|
||||
class SkLayerDrawLooper : public SkDrawLooper {
|
||||
public:
|
||||
SkLayerDrawLooper();
|
||||
virtual ~SkLayerDrawLooper();
|
||||
|
||||
/** Call for each layer you want to add (from top to bottom).
|
||||
This returns a paint you can modify, but that ptr is only valid until
|
||||
the next call made to this object.
|
||||
*/
|
||||
SkPaint* addLayer(SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Helper for addLayer() which passes (0, 0) for the offset parameters
|
||||
*/
|
||||
SkPaint* addLayer() {
|
||||
return this->addLayer(0, 0);
|
||||
}
|
||||
|
||||
// overrides from SkDrawLooper
|
||||
virtual void init(SkCanvas*, SkPaint*);
|
||||
virtual bool next();
|
||||
virtual void restore();
|
||||
|
||||
// must be public for Registrar :(
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
|
||||
}
|
||||
|
||||
protected:
|
||||
SkLayerDrawLooper(SkFlattenableReadBuffer&);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual void flatten(SkFlattenableWriteBuffer& );
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
struct Rec {
|
||||
Rec* fNext;
|
||||
SkPaint fPaint;
|
||||
SkPoint fOffset;
|
||||
|
||||
static Rec* Reverse(Rec*);
|
||||
};
|
||||
Rec* fRecs;
|
||||
int fCount;
|
||||
|
||||
struct Iter {
|
||||
SkPaint fSavedPaint;
|
||||
SkPaint* fPaint;
|
||||
SkCanvas* fCanvas;
|
||||
Rec* fRec;
|
||||
};
|
||||
Iter fIter;
|
||||
|
||||
class MyRegistrar : public SkFlattenable::Registrar {
|
||||
public:
|
||||
MyRegistrar();
|
||||
};
|
||||
|
||||
typedef SkDrawLooper INHERITED;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkLayerRasterizer_DEFINED
|
||||
#define SkLayerRasterizer_DEFINED
|
||||
|
||||
#include "SkRasterizer.h"
|
||||
#include "SkDeque.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkPaint;
|
||||
|
||||
class SkLayerRasterizer : public SkRasterizer {
|
||||
public:
|
||||
SkLayerRasterizer();
|
||||
virtual ~SkLayerRasterizer();
|
||||
|
||||
void addLayer(const SkPaint& paint)
|
||||
{
|
||||
this->addLayer(paint, 0, 0);
|
||||
}
|
||||
|
||||
/** Add a new layer (above any previous layers) to the rasterizer.
|
||||
The layer will extract those fields that affect the mask from
|
||||
the specified paint, but will not retain a reference to the paint
|
||||
object itself, so it may be reused without danger of side-effects.
|
||||
*/
|
||||
void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy);
|
||||
|
||||
// overrides from SkFlattenable
|
||||
virtual Factory getFactory();
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
SkLayerRasterizer(SkFlattenableReadBuffer&);
|
||||
|
||||
// override from SkRasterizer
|
||||
virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
|
||||
const SkIRect* clipBounds,
|
||||
SkMask* mask, SkMask::CreateMode mode);
|
||||
|
||||
private:
|
||||
SkDeque fLayers;
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkRasterizer INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPaintFlagsDrawFilter_DEFINED
|
||||
#define SkPaintFlagsDrawFilter_DEFINED
|
||||
|
||||
#include "SkDrawFilter.h"
|
||||
|
||||
class SkPaintFlagsDrawFilter : public SkDrawFilter {
|
||||
public:
|
||||
SkPaintFlagsDrawFilter(uint32_t clearFlags, uint32_t setFlags);
|
||||
|
||||
// overrides
|
||||
virtual bool filter(SkCanvas*, SkPaint*, Type);
|
||||
virtual void restore(SkCanvas*, SkPaint*, Type);
|
||||
|
||||
private:
|
||||
uint32_t fPrevFlags; // local cache for filter/restore
|
||||
uint16_t fClearFlags; // user specified
|
||||
uint16_t fSetFlags; // user specified
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkPixelXorXfermode_DEFINED
|
||||
#define SkPixelXorXfermode_DEFINED
|
||||
|
||||
#include "SkXfermode.h"
|
||||
|
||||
/** SkPixelXorXfermode implements a simple pixel xor (op ^ src ^ dst).
|
||||
This transformation does not follow premultiplied conventions, therefore
|
||||
this proc *always* returns an opaque color (alpha == 255). Thus it is
|
||||
not really usefull for operating on blended colors.
|
||||
*/
|
||||
class SkPixelXorXfermode : public SkXfermode {
|
||||
public:
|
||||
SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {}
|
||||
|
||||
// override from SkFlattenable
|
||||
virtual Factory getFactory();
|
||||
virtual void flatten(SkFlattenableWriteBuffer&);
|
||||
|
||||
protected:
|
||||
// override from SkXfermode
|
||||
virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst);
|
||||
|
||||
private:
|
||||
SkColor fOpColor;
|
||||
|
||||
SkPixelXorXfermode(SkFlattenableReadBuffer& rb);
|
||||
// our private factory
|
||||
static SkFlattenable* Create(SkFlattenableReadBuffer&);
|
||||
|
||||
typedef SkXfermode INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkTransparentShader_DEFINED
|
||||
#define SkTransparentShader_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkTransparentShader : public SkShader {
|
||||
public:
|
||||
SkTransparentShader() {}
|
||||
virtual uint32_t getFlags();
|
||||
virtual bool setContext( const SkBitmap& device,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix& matrix);
|
||||
virtual void shadeSpan(int x, int y, SkPMColor[], int count);
|
||||
virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
|
||||
|
||||
// overrides for SkFlattenable
|
||||
virtual Factory getFactory() { return Create; }
|
||||
virtual void flatten(SkFlattenableWriteBuffer& buffer)
|
||||
{
|
||||
this->INHERITED::flatten(buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
// these are a cache from the call to setContext()
|
||||
const SkBitmap* fDevice;
|
||||
uint8_t fAlpha;
|
||||
|
||||
SkTransparentShader(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
static SkFlattenable* Create(SkFlattenableReadBuffer& buffer)
|
||||
{
|
||||
return SkNEW_ARGS(SkTransparentShader, (buffer));
|
||||
}
|
||||
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SkFlipPixelRef_DEFINED
|
||||
#define SkFlipPixelRef_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkPageFlipper.h"
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkThread.h"
|
||||
|
||||
class SkRegion;
|
||||
|
||||
class SkFlipPixelRef : public SkPixelRef {
|
||||
public:
|
||||
SkFlipPixelRef(SkBitmap::Config, int width, int height);
|
||||
virtual ~SkFlipPixelRef();
|
||||
|
||||
bool isDirty() const { return fFlipper.isDirty(); }
|
||||
const SkRegion& dirtyRgn() const { return fFlipper.dirtyRgn(); }
|
||||
|
||||
void inval() { fFlipper.inval(); }
|
||||
void inval(const SkIRect& rect) { fFlipper.inval(rect); }
|
||||
void inval(const SkRegion& rgn) { fFlipper.inval(rgn); }
|
||||
void inval(const SkRect& r, bool doAA) { fFlipper.inval(r, doAA); }
|
||||
|
||||
const SkRegion& beginUpdate(SkBitmap* device);
|
||||
void endUpdate();
|
||||
|
||||
private:
|
||||
void getFrontBack(const void** front, void** back) const {
|
||||
if (front) {
|
||||
*front = fPage0;
|
||||
}
|
||||
if (back) {
|
||||
*back = fPage1;
|
||||
}
|
||||
}
|
||||
|
||||
void swapPages();
|
||||
|
||||
// Helper to copy pixels from srcAddr to the dst bitmap, clipped to clip.
|
||||
// srcAddr points to memory with the same config as dst.
|
||||
static void CopyBitsFromAddr(const SkBitmap& dst, const SkRegion& clip,
|
||||
const void* srcAddr);
|
||||
|
||||
// serialization
|
||||
|
||||
public:
|
||||
virtual Factory getFactory() const { return Create; }
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const;
|
||||
static SkPixelRef* Create(SkFlattenableReadBuffer& buffer);
|
||||
|
||||
protected:
|
||||
virtual void* onLockPixels(SkColorTable**);
|
||||
virtual void onUnlockPixels();
|
||||
|
||||
SkFlipPixelRef(SkFlattenableReadBuffer&);
|
||||
|
||||
private:
|
||||
SkMutex fMutex;
|
||||
SkPageFlipper fFlipper;
|
||||
|
||||
void* fStorage;
|
||||
void* fPage0; // points into fStorage;
|
||||
void* fPage1; // points into fStorage;
|
||||
size_t fSize; // size of 1 page. fStorage holds 2 pages
|
||||
SkBitmap::Config fConfig;
|
||||
|
||||
typedef SkPixelRef INHERITED;
|
||||
};
|
||||
|
||||
class SkAutoFlipUpdate : SkNoncopyable {
|
||||
public:
|
||||
SkAutoFlipUpdate(SkFlipPixelRef* ref) : fRef(ref) {
|
||||
fDirty = &ref->beginUpdate(&fBitmap);
|
||||
}
|
||||
~SkAutoFlipUpdate() {
|
||||
if (fRef) {
|
||||
fRef->endUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
const SkBitmap& bitmap() const { return fBitmap; }
|
||||
const SkRegion& dirty() const { return *fDirty; }
|
||||
|
||||
// optional. This gets automatically called in the destructor (only once)
|
||||
void endUpdate() {
|
||||
if (fRef) {
|
||||
fRef->endUpdate();
|
||||
fRef = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SkFlipPixelRef* fRef;
|
||||
SkBitmap fBitmap;
|
||||
const SkRegion* fDirty;
|
||||
};
|
||||
|
||||
#endif
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче