aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/config/SkUserConfig.h3
-rw-r--r--include/core/SkClipStack.h1
-rw-r--r--include/core/SkColorPriv.h20
-rw-r--r--include/core/SkComposeShader.h2
-rw-r--r--include/core/SkDevice.h27
-rw-r--r--include/core/SkMath.h2
-rw-r--r--include/core/SkMatrix.h21
-rw-r--r--include/core/SkPath.h38
-rw-r--r--include/core/SkPostConfig.h19
-rw-r--r--include/core/SkPreConfig.h10
-rw-r--r--include/core/SkReader32.h9
-rw-r--r--include/core/SkRect.h2
-rw-r--r--include/core/SkScalar.h39
-rw-r--r--include/core/SkScalerContext.h3
-rw-r--r--include/core/SkWriter32.h17
-rw-r--r--include/core/SkXfermode.h10
-rw-r--r--include/gpu/SkGpuDevice.h13
-rw-r--r--include/gpu/SkGr.h33
-rw-r--r--include/pdf/SkPDFCatalog.h102
-rw-r--r--include/pdf/SkPDFDevice.h227
-rw-r--r--include/pdf/SkPDFDocument.h84
-rw-r--r--include/pdf/SkPDFFont.h151
-rw-r--r--include/pdf/SkPDFFormXObject.h73
-rw-r--r--include/pdf/SkPDFGraphicState.h106
-rw-r--r--include/pdf/SkPDFImage.h95
-rw-r--r--include/pdf/SkPDFPage.h101
-rw-r--r--include/pdf/SkPDFShader.h110
-rw-r--r--include/pdf/SkPDFStream.h55
-rw-r--r--include/pdf/SkPDFTypes.h332
-rw-r--r--include/pdf/SkPDFUtils.h61
-rw-r--r--include/pipe/SkGPipe.h96
-rw-r--r--include/utils/SkEGLContext.h43
-rw-r--r--include/utils/android/AndroidKeyToSkKey.h40
-rw-r--r--include/utils/unix/XkeysToSkKeys.h8
-rw-r--r--include/views/SkApplication.h26
-rw-r--r--include/views/SkBGViewArtist.h41
-rw-r--r--include/views/SkBorderView.h48
-rw-r--r--include/views/SkEvent.h257
-rw-r--r--include/views/SkEventSink.h103
-rw-r--r--include/views/SkImageView.h75
-rw-r--r--include/views/SkKey.h63
-rw-r--r--include/views/SkOSMenu.h55
-rw-r--r--include/views/SkOSWindow_Android.h41
-rw-r--r--include/views/SkOSWindow_Mac.h62
-rw-r--r--include/views/SkOSWindow_SDL.h52
-rw-r--r--include/views/SkOSWindow_Unix.h79
-rw-r--r--include/views/SkOSWindow_Win.h79
-rw-r--r--include/views/SkOSWindow_wxwidgets.h52
-rw-r--r--include/views/SkProgressBarView.h57
-rw-r--r--include/views/SkScrollBarView.h52
-rw-r--r--include/views/SkStackViewLayout.h96
-rw-r--r--include/views/SkSystemEventTypes.h32
-rw-r--r--include/views/SkTouchGesture.h72
-rw-r--r--include/views/SkView.h370
-rw-r--r--include/views/SkViewInflate.h79
-rw-r--r--include/views/SkWidget.h476
-rw-r--r--include/views/SkWidgetViews.h312
-rw-r--r--include/views/SkWindow.h125
58 files changed, 4550 insertions, 107 deletions
diff --git a/include/config/SkUserConfig.h b/include/config/SkUserConfig.h
index aa2e6cf..c56d8cf 100644
--- a/include/config/SkUserConfig.h
+++ b/include/config/SkUserConfig.h
@@ -54,7 +54,7 @@
/* Somewhat independent of how SkScalar is implemented, Skia also wants to know
if it can use floats at all. Naturally, if SK_SCALAR_IS_FLOAT is defined,
- then so muse SK_CAN_USE_FLOAT, but if scalars are fixed, SK_CAN_USE_FLOAT
+ SK_CAN_USE_FLOAT must be too; but if scalars are fixed, SK_CAN_USE_FLOAT
can go either way.
*/
//#define SK_CAN_USE_FLOAT
@@ -151,4 +151,3 @@
#endif
#endif
-
diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h
index ae0b974..6e8da76 100644
--- a/include/core/SkClipStack.h
+++ b/include/core/SkClipStack.h
@@ -43,6 +43,7 @@ public:
struct Clip {
friend bool operator==(const Clip& a, const Clip& b);
+ friend bool operator!=(const Clip& a, const Clip& b);
const SkRect* fRect; // if non-null, this is a rect clip
const SkPath* fPath; // if non-null, this is a path clip
SkRegion::Op fOp;
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h
index f9e02a2..6fa9df3 100644
--- a/include/core/SkColorPriv.h
+++ b/include/core/SkColorPriv.h
@@ -155,31 +155,13 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[],
#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)
diff --git a/include/core/SkComposeShader.h b/include/core/SkComposeShader.h
index 0b198f6..ea37549 100644
--- a/include/core/SkComposeShader.h
+++ b/include/core/SkComposeShader.h
@@ -27,7 +27,7 @@ class SkXfermode;
This subclass of shader returns the coposition of two other shaders, combined by
a xfermode.
*/
-class SkComposeShader : public SkShader {
+class SK_API SkComposeShader : public SkShader {
public:
/** Create a new compose shader, given shaders A, B, and a combining xfermode mode.
When the xfermode is called, it will be given the result from shader A as its
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 46bcf1a..d9a4fde 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -155,31 +155,6 @@ public:
virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
const SkClipStack&);
- /**
- * Observer interface for listening to the calls to
- * SkDevice::setMatrixClip(...). Users of SkDevice instances should
- * implement matrixClipChanged(...) to receive notifications.
- */
- class SkMatrixClipObserver : public SkRefCnt {
- public:
- virtual void matrixClipChanged(const SkMatrix&, const SkRegion&,
- const SkClipStack&) = 0;
- };
-
- /** Assign the clip observer. Note that an extra reference is added to the
- * observer, and removed at SkDevice construction, or re-assignment of a
- * different observer.
- */
- void setMatrixClipObserver(SkMatrixClipObserver* observer);
-
- /** Return the device's associated SkMatrixClipObserver, or NULL.
- * If non-null is returned, the reference count of the object is not
- * modified.
- */
- SkMatrixClipObserver* getMatrixClipObserver() const {
- return fMatrixClipObserver;
- }
-
/** Called when this device gains focus (i.e becomes the current device
for drawing).
*/
@@ -306,8 +281,6 @@ private:
SkIPoint fOrigin;
SkMetaData* fMetaData;
- SkMatrixClipObserver* fMatrixClipObserver;
-
SkDeviceFactory* fCachedDeviceFactory;
};
diff --git a/include/core/SkMath.h b/include/core/SkMath.h
index 3e72904..efe378a 100644
--- a/include/core/SkMath.h
+++ b/include/core/SkMath.h
@@ -115,7 +115,7 @@ static inline unsigned SkClampUMax(unsigned value, unsigned max) {
///////////////////////////////////////////////////////////////////////////////
-#if defined(__arm__) && !defined(__thumb__)
+#if defined(__arm__)
#define SkCLZ(x) __builtin_clz(x)
#endif
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
index 7c77902..480e077 100644
--- a/include/core/SkMatrix.h
+++ b/include/core/SkMatrix.h
@@ -438,6 +438,7 @@ public:
*/
bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;
+#ifdef SK_SCALAR_IS_FIXED
friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) == 0;
}
@@ -445,6 +446,12 @@ public:
friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
}
+#else
+ friend bool operator==(const SkMatrix& a, const SkMatrix& b);
+ friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
+ return !(a == b);
+ }
+#endif
enum {
// flatten/unflatten will never return a value larger than this
@@ -488,7 +495,12 @@ private:
kRectStaysRect_Mask = 0x10,
kUnknown_Mask = 0x80,
-
+
+ kORableMasks = kTranslate_Mask |
+ kScale_Mask |
+ kAffine_Mask |
+ kPerspective_Mask,
+
kAllMasks = kTranslate_Mask |
kScale_Mask |
kAffine_Mask |
@@ -506,7 +518,12 @@ private:
SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask);
fTypeMask = SkToU8(mask);
}
-
+
+ void orTypeMask(int mask) {
+ SkASSERT((mask & kORableMasks) == mask);
+ fTypeMask = SkToU8(fTypeMask | mask);
+ }
+
void clearTypeMask(int mask) {
// only allow a valid mask
SkASSERT((mask & kAllMasks) == mask);
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index 18dcd11..7120d3f 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -88,9 +88,10 @@ public:
/** 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()
- */
+ /**
+ * Toggle between inverse and normal filltypes. This reverse the return
+ * value of isInverseFillType()
+ */
void toggleInverseFillType() {
fFillType ^= 2;
GEN_ID_INC;
@@ -103,14 +104,33 @@ public:
};
/**
- * Return the path's convexity, as stored in the path.
+ * Return the path's convexity, as stored in the path. If it is currently
+ * unknown, and the computeIfUnknown bool is true, then this will first
+ * call ComputeConvexity() and then return that (cached) value.
+ */
+ Convexity getConvexity() const {
+ if (kUnknown_Convexity == fConvexity) {
+ fConvexity = (uint8_t)ComputeConvexity(*this);
+ }
+ return (Convexity)fConvexity;
+ }
+
+ /**
+ * Return the currently cached value for convexity, even if that is set to
+ * kUnknown_Convexity. Note: getConvexity() will automatically call
+ * ComputeConvexity and cache its return value if the current setting is
+ * kUnknown.
*/
- Convexity getConvexity() const { return (Convexity)fConvexity; }
+ Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; }
/**
* Store a convexity setting in the path. There is no automatic check to
* see if this value actually agress with the return value from
* ComputeConvexity().
+ *
+ * Note: even if this is set to a "known" value, if the path is later
+ * changed (e.g. lineTo(), addRect(), etc.) then the cached value will be
+ * reset to kUnknown_Convexity.
*/
void setConvexity(Convexity);
@@ -118,9 +138,11 @@ public:
* Compute the convexity of the specified path. This does not look at the
* value stored in the path, but computes it directly from the path's data.
*
+ * This never returns kUnknown_Convexity.
+ *
* If there is more than one contour, this returns kConcave_Convexity.
- * If the contour is degenerate (i.e. all segements are colinear,
- * then this returns kUnknown_Convexity.
+ * If the contour is degenerate (e.g. there are fewer than 3 non-degenerate
+ * segments), then this returns kConvex_Convexity.
* The contour is treated as if it were closed, even if there is no kClose
* verb.
*/
@@ -635,7 +657,7 @@ private:
mutable SkRect fBounds;
mutable uint8_t fBoundsIsDirty;
uint8_t fFillType;
- uint8_t fConvexity;
+ mutable uint8_t fConvexity;
#ifdef ANDROID
uint32_t fGenerationID;
#endif
diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h
index 57cc368..23ce02b 100644
--- a/include/core/SkPostConfig.h
+++ b/include/core/SkPostConfig.h
@@ -132,6 +132,25 @@
#endif
#endif
+/*
+ * We check to see if the SHIFT value has already been defined.
+ * if not, we define it ourself to some default values. We default to OpenGL
+ * order (in memory: r,g,b,a)
+ */
+#ifndef SK_A32_SHIFT
+ #ifdef SK_CPU_BENDIAN
+ #define SK_R32_SHIFT 24
+ #define SK_G32_SHIFT 16
+ #define SK_B32_SHIFT 8
+ #define SK_A32_SHIFT 0
+ #else
+ #define SK_R32_SHIFT 0
+ #define SK_G32_SHIFT 8
+ #define SK_B32_SHIFT 16
+ #define SK_A32_SHIFT 24
+ #endif
+#endif
+
// stdlib macros
#if 0
diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h
index 8d47d46..6ec73ce 100644
--- a/include/core/SkPreConfig.h
+++ b/include/core/SkPreConfig.h
@@ -41,14 +41,16 @@
#define SK_BUILD_FOR_UNIX
#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define SK_BUILD_FOR_IOS
- #elif defined(ANDROID_NDK)
- #define SK_BUILD_FOR_ANDROID_NDK
- #elif defined(ANROID)
- #define SK_BUILD_FOR_ANDROID
#else
#define SK_BUILD_FOR_MAC
#endif
+ #if defined(ANDROID)
+ #define SK_BUILD_FOR_ANDROID
+ #endif
+ #if defined(ANDROID_NDK)
+ #define SK_BUILD_FOR_ANDROID_NDK
+ #endif
#endif
//////////////////////////////////////////////////////////////////////
diff --git a/include/core/SkReader32.h b/include/core/SkReader32.h
index 03a34c7..654ebd5 100644
--- a/include/core/SkReader32.h
+++ b/include/core/SkReader32.h
@@ -101,7 +101,14 @@ public:
uint16_t readU16() { return (uint16_t)this->readInt(); }
int32_t readS32() { return this->readInt(); }
uint32_t readU32() { return this->readInt(); }
-
+
+ /**
+ * Read the length of a string written by SkWriter32::writeString()
+ * (if len is not NULL) and return the null-ternimated address of the
+ * string.
+ */
+ const char* readString(size_t* len = NULL);
+
private:
// these are always 4-byte aligned
const char* fCurr; // current position within buffer
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 550c5d1..19ee12a 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -290,7 +290,7 @@ struct SK_API SkIRect {
void sort();
static const SkIRect& EmptyIRect() {
- static const SkIRect gEmpty = {0,0,0,0};
+ static const SkIRect gEmpty = { 0, 0, 0, 0 };
return gEmpty;
}
};
diff --git a/include/core/SkScalar.h b/include/core/SkScalar.h
index ebe621b..5dbf684 100644
--- a/include/core/SkScalar.h
+++ b/include/core/SkScalar.h
@@ -66,9 +66,47 @@
int exponent = bits << 1 >> 24;
return exponent != 0xFF;
}
+#ifdef SK_DEBUG
+ /** SkIntToScalar(n) returns its integer argument as an SkScalar
+ *
+ * If we're compiling in DEBUG mode, and can thus afford some extra runtime
+ * cycles, check to make sure that the parameter passed in has not already
+ * been converted to SkScalar. (A double conversion like this is harmless
+ * for SK_SCALAR_IS_FLOAT, but for SK_SCALAR_IS_FIXED this causes trouble.)
+ *
+ * Note that we need all of these method signatures to properly handle the
+ * various types that we pass into SkIntToScalar() to date:
+ * int, size_t, U8CPU, etc., even though what we really mean is "anything
+ * but a float".
+ */
+ static inline float SkIntToScalar(signed int param) {
+ return (float)param;
+ }
+ static inline float SkIntToScalar(unsigned int param) {
+ return (float)param;
+ }
+ static inline float SkIntToScalar(signed long param) {
+ return (float)param;
+ }
+ static inline float SkIntToScalar(unsigned long param) {
+ return (float)param;
+ }
+ static inline float SkIntToScalar(float param) {
+ /* If the parameter passed into SkIntToScalar is a float,
+ * one of two things has happened:
+ * 1. the parameter was an SkScalar (which is typedef'd to float)
+ * 2. the parameter was a float instead of an int
+ *
+ * Either way, it's not good.
+ */
+ SkASSERT(!"looks like you passed an SkScalar into SkIntToScalar");
+ return (float)0;
+ }
+#else // not SK_DEBUG
/** SkIntToScalar(n) returns its integer argument as an SkScalar
*/
#define SkIntToScalar(n) ((float)(n))
+#endif // not SK_DEBUG
/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar
*/
#define SkFixedToScalar(x) SkFixedToFloat(x)
@@ -282,4 +320,3 @@ SkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[],
const SkScalar values[], int length);
#endif
-
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h
index 55dfcef..3f818a3 100644
--- a/include/core/SkScalerContext.h
+++ b/include/core/SkScalerContext.h
@@ -179,6 +179,9 @@ public:
kEmbolden_Flag = 0x80,
kSubpixelPositioning_Flag = 0x100,
kAutohinting_Flag = 0x200,
+ // these should only ever be set if fMaskFormat is LCD
+ kLCD_Vertical_Flag = 0x400, // else Horizontal
+ kLCD_BGROrder_Flag = 0x800, // else RGB order
};
private:
enum {
diff --git a/include/core/SkWriter32.h b/include/core/SkWriter32.h
index 8e133c2..c8ebb6a 100644
--- a/include/core/SkWriter32.h
+++ b/include/core/SkWriter32.h
@@ -100,7 +100,22 @@ public:
}
void writePad(const void* src, size_t size);
-
+
+ /**
+ * Writes a string to the writer, which can be retrieved with
+ * SkReader32::readString().
+ * The length can be specified, or if -1 is passed, it will be computed by
+ * calling strlen(). The length must be < 0xFFFF
+ */
+ void writeString(const char* str, size_t len = (size_t)-1);
+
+ /**
+ * Computes the size (aligned to multiple of 4) need to write the string
+ * in a call to writeString(). If the length is not specified, it will be
+ * computed by calling strlen().
+ */
+ static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
+
// return the current offset (will always be a multiple of 4)
uint32_t size() const { return fSize; }
void reset();
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index 4d46bb9..6ab9d6d 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -103,11 +103,15 @@ public:
kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
- // these modes are defined in the SVG Compositing standard
+ // all remaining modes are defined in the SVG Compositing standard
// http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/
kPlus_Mode,
- kMultiply_Mode,
- kScreen_Mode,
+ kMultiply_Mode,
+
+ // all above modes can be expressed as pair of src/dst Coeffs
+ kCoeffModesCnt,
+
+ kScreen_Mode = kCoeffModesCnt,
kOverlay_Mode,
kDarken_Mode,
kLighten_Mode,
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 15def87..601da09 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -163,17 +163,26 @@ private:
// doesn't set the texture/sampler/matrix state
// caller needs to null out GrPaint's texture if
// non-textured drawing is desired.
+ // Set constantColor to true if a constant color
+ // will be used. This is an optimization, and can
+ // always be set to false. constantColor should
+ // never be true if justAlpha is true.
bool skPaint2GrPaintNoShader(const SkPaint& skPaint,
bool justAlpha,
- GrPaint* grPaint);
+ GrPaint* grPaint,
+ bool constantColor);
// uses the SkShader to setup paint, act used to
// hold lock on cached texture and free it when
// destroyed.
+ // If there is no shader, constantColor will
+ // be passed to skPaint2GrPaintNoShader. Otherwise
+ // it is ignored.
bool skPaint2GrPaintShader(const SkPaint& skPaint,
SkAutoCachedTexture* act,
const SkMatrix& ctm,
- GrPaint* grPaint);
+ GrPaint* grPaint,
+ bool constantColor);
SkDrawProcs* initDrawForText(GrTextContext*);
bool bindDeviceAsTexture(GrPaint* paint);
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 75099b2..65565c9 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -24,8 +24,8 @@
#include "GrConfig.h"
#include "GrContext.h"
#include "GrFontScaler.h"
-#include "GrPathIter.h"
#include "GrClipIterator.h"
+#include "GrPath.h"
// skia headers
#include "SkBitmap.h"
@@ -130,29 +130,6 @@ public:
////////////////////////////////////////////////////////////////////////////////
// Classes
-class SkGrPathIter : public GrPathIter {
-public:
- SkGrPathIter() { fPath = NULL; }
- SkGrPathIter(const SkPath& path) { reset(path); }
- virtual GrPathCmd next(GrPoint pts[]);
- virtual GrPathCmd next();
- virtual void rewind();
- virtual GrConvexHint convexHint() const;
- virtual bool getConservativeBounds(GrRect* rect) const;
-
- void reset(const SkPath& path) {
- fPath = &path;
- fIter.setPath(path, false);
- }
-private:
-
-#if !SK_SCALAR_IS_GR_SCALAR
- SkPoint fPoints[4];
-#endif
- SkPath::Iter fIter;
- const SkPath* fPath;
-};
-
class SkGrClipIterator : public GrClipIterator {
public:
SkGrClipIterator() { fClipStack = NULL; fCurr = NULL; }
@@ -176,9 +153,8 @@ public:
}
}
- virtual GrPathIter* getPathIter() {
- fPathIter.reset(*fCurr->fPath);
- return &fPathIter;
+ virtual const GrPath* getPath() {
+ return fCurr->fPath;
}
virtual GrPathFill getPathFill() const;
@@ -186,7 +162,6 @@ public:
private:
const SkClipStack* fClipStack;
SkClipStack::B2FIter fIter;
- SkGrPathIter fPathIter;
// SkClipStack's auto advances on each get
// so we store the current pos here.
const SkClipStack::B2FIter::Clip* fCurr;
@@ -218,7 +193,7 @@ public:
rect->fBottom = GrIntToScalar(r.fBottom);
}
- virtual GrPathIter* getPathIter() {
+ virtual const GrPath* getPath() {
SkASSERT(0);
return NULL;
}
diff --git a/include/pdf/SkPDFCatalog.h b/include/pdf/SkPDFCatalog.h
new file mode 100644
index 0000000..e02ffa1
--- /dev/null
+++ b/include/pdf/SkPDFCatalog.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFCatalog_DEFINED
+#define SkPDFCatalog_DEFINED
+
+#include <sys/types.h>
+
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+/** \class SkPDFCatalog
+
+ The PDF catalog manages object numbers and file offsets. It is used
+ to create the PDF cross reference table.
+*/
+class SK_API SkPDFCatalog {
+public:
+ /** Create a PDF catalog.
+ */
+ SkPDFCatalog();
+ ~SkPDFCatalog();
+
+ /** Add the passed object to the catalog. Refs obj.
+ * @param obj The object to add.
+ * @param onFirstPage Is the object on the first page.
+ * @return The obj argument is returned.
+ */
+ SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage);
+
+ /** Inform the catalog of the object's position in the final stream.
+ * The object should already have been added to the catalog. Returns
+ * the object's size.
+ * @param obj The object to add.
+ * @param offset The byte offset in the output stream of this object.
+ */
+ size_t setFileOffset(SkPDFObject* obj, size_t offset);
+
+ /** Output the object number for the passed object.
+ * @param obj The object of interest.
+ * @param stream The writable output stream to send the output to.
+ */
+ void emitObjectNumber(SkWStream* stream, SkPDFObject* obj);
+
+ /** Return the number of bytes that would be emitted for the passed
+ * object's object number.
+ * @param obj The object of interest
+ */
+ size_t getObjectNumberSize(SkPDFObject* obj);
+
+ /** Output the cross reference table for objects in the catalog.
+ * Returns the total number of objects.
+ * @param stream The writable output stream to send the output to.
+ * @param firstPage If true, include first page objects only, otherwise
+ * include all objects not on the first page.
+ */
+ int32_t emitXrefTable(SkWStream* stream, bool firstPage);
+
+private:
+ struct Rec {
+ Rec(SkPDFObject* object, bool onFirstPage)
+ : fObject(object),
+ fFileOffset(0),
+ fObjNumAssigned(false),
+ fOnFirstPage(onFirstPage) {
+ }
+ SkPDFObject* fObject;
+ off_t fFileOffset;
+ bool fObjNumAssigned;
+ bool fOnFirstPage;
+ };
+
+ // TODO(vandebo) Make this a hash if it's a performance problem.
+ SkTDArray<struct Rec> fCatalog;
+
+ // Number of objects on the first page.
+ uint32_t fFirstPageCount;
+ // Next object number to assign (on page > 1).
+ uint32_t fNextObjNum;
+ // Next object number to assign on the first page.
+ uint32_t fNextFirstPageObjNum;
+
+ int findObjectIndex(SkPDFObject* obj) const;
+
+ int assignObjNum(SkPDFObject* obj);
+};
+
+#endif
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
new file mode 100644
index 0000000..6e4d8db
--- /dev/null
+++ b/include/pdf/SkPDFDevice.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFDevice_DEFINED
+#define SkPDFDevice_DEFINED
+
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkTScopedPtr.h"
+
+class SkPDFArray;
+class SkPDFDevice;
+class SkPDFDict;
+class SkPDFFont;
+class SkPDFFormXObject;
+class SkPDFGraphicState;
+class SkPDFObject;
+class SkPDFShader;
+class SkPDFStream;
+
+// Private classes.
+struct ContentEntry;
+struct GraphicStateEntry;
+
+class SkPDFDeviceFactory : public SkDeviceFactory {
+public:
+ virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
+ int height, bool isOpaque, bool isForLayer);
+};
+
+/** \class SkPDFDevice
+
+ The drawing context for the PDF backend.
+*/
+class SkPDFDevice : public SkDevice {
+public:
+ /** Create a PDF drawing context with the given width and height.
+ * 72 points/in means letter paper is 612x792.
+ * @param pageSize Page size in points.
+ * @param contentSize The content size of the page in points. This will be
+ * combined with the initial transform to determine the drawing area
+ * (as reported by the width and height methods). Anything outside
+ * of the drawing area will be clipped.
+ * @param initialTransform The initial transform to apply to the page.
+ * This may be useful to, for example, move the origin in and
+ * over a bit to account for a margin, scale the canvas,
+ * or apply a rotation. Note1: the SkPDFDevice also applies
+ * a scale+translate transform to move the origin from the
+ * bottom left (PDF default) to the top left. Note2: drawDevice
+ * (used by layer restore) draws the device after this initial
+ * transform is applied, so the PDF device factory does an
+ * inverse scale+translate to accommodate the one that SkPDFDevice
+ * always does.
+ */
+ // TODO(vandebo) The sizes should be SkSize and not SkISize.
+ SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
+ const SkMatrix& initialTransform);
+ SK_API virtual ~SkPDFDevice();
+
+ virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
+
+ virtual void clear(SkColor color);
+
+ virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
+ return false;
+ }
+
+ /** 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& origpath,
+ const SkPaint& paint, const SkMatrix* prePathMatrix,
+ bool pathIsMutable);
+ virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkIRect* srcRectOrNull,
+ const SkMatrix& matrix, const SkPaint& paint);
+ virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
+ const SkPaint& paint);
+ 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&);
+
+ // PDF specific methods.
+
+ /** Returns a reference to the resource dictionary for this device.
+ */
+ SK_API const SkRefPtr<SkPDFDict>& getResourceDict();
+
+ /** Get the list of resources (PDF objects) used on this page.
+ * @param resourceList A list to append the resources to.
+ */
+ SK_API void getResources(SkTDArray<SkPDFObject*>* resourceList) const;
+
+ /** Get the fonts used on this device.
+ */
+ SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;
+
+ /** Returns the media box for this device.
+ */
+ SK_API SkRefPtr<SkPDFArray> getMediaBox() const;
+
+ /** Returns a SkStream with the page contents. The caller is responsible
+ for a reference to the returned value.
+ */
+ SK_API SkStream* content() const;
+
+ SK_API const SkMatrix& initialTransform() const {
+ return fInitialTransform;
+ }
+
+protected:
+ // override
+ virtual SkDeviceFactory* onNewDeviceFactory();
+
+private:
+ friend class SkPDFDeviceFactory;
+ // TODO(vandebo) push most of SkPDFDevice's state into a core object in
+ // order to get the right access levels without using friend.
+ friend class ScopedContentEntry;
+
+ SkISize fPageSize;
+ SkISize fContentSize;
+ SkMatrix fInitialTransform;
+ SkClipStack fExistingClipStack;
+ SkRegion fExistingClipRegion;
+ SkRefPtr<SkPDFDict> fResourceDict;
+
+ SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
+ SkTDArray<SkPDFObject*> fXObjectResources;
+ SkTDArray<SkPDFFont*> fFontResources;
+ SkTDArray<SkPDFShader*> fShaderResources;
+
+ SkTScopedPtr<ContentEntry> fContentEntries;
+ ContentEntry* fLastContentEntry;
+
+ // For use by the DeviceFactory.
+ SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
+ const SkRegion& existingClipRegion);
+
+ void init();
+ void cleanUp();
+ void createFormXObjectFromDevice(SkRefPtr<SkPDFFormXObject>* xobject);
+
+ // Clear the passed clip from all existing content entries.
+ void clearClipFromContent(const SkClipStack* clipStack,
+ const SkRegion& clipRegion);
+ void drawFormXObjectWithClip(SkPDFFormXObject* form,
+ const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ bool invertClip);
+
+ // If the paint or clip is such that we shouldn't draw anything, this
+ // returns NULL and does not create a content entry.
+ // setUpContentEntry and finishContentEntry can be used directly, but
+ // the preferred method is to use the ScopedContentEntry helper class.
+ ContentEntry* setUpContentEntry(const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ const SkMatrix& matrix,
+ const SkPaint& paint,
+ bool hasText,
+ SkRefPtr<SkPDFFormXObject>* dst);
+ void finishContentEntry(SkXfermode::Mode xfermode,
+ SkPDFFormXObject* dst);
+ bool isContentEmpty();
+
+ void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
+ const SkClipStack& clipStack,
+ const SkRegion& clipRegion,
+ const SkPaint& paint,
+ bool hasText,
+ GraphicStateEntry* entry);
+ int addGraphicStateResource(SkPDFGraphicState* gs);
+
+ void updateFont(const SkPaint& paint, uint16_t glyphID,
+ ContentEntry* contentEntry);
+ int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
+
+ void internalDrawPaint(const SkPaint& paint, ContentEntry* contentEntry);
+ void internalDrawBitmap(const SkMatrix& matrix,
+ const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ const SkBitmap& bitmap,
+ const SkIRect* srcRect,
+ const SkPaint& paint);
+
+ // Disable the default copy and assign implementation.
+ SkPDFDevice(const SkPDFDevice&);
+ void operator=(const SkPDFDevice&);
+};
+
+#endif
diff --git a/include/pdf/SkPDFDocument.h b/include/pdf/SkPDFDocument.h
new file mode 100644
index 0000000..0a76ea2
--- /dev/null
+++ b/include/pdf/SkPDFDocument.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFDocument_DEFINED
+#define SkPDFDocument_DEFINED
+
+#include "SkPDFCatalog.h"
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+class SkPDFDevice;
+class SkPDFPage;
+class SkWSteam;
+
+/** \class SkPDFDocument
+
+ A SkPDFDocument assembles pages together and generates the final PDF file.
+*/
+class SkPDFDocument {
+public:
+ /** Create a PDF document.
+ */
+ SK_API SkPDFDocument();
+ SK_API ~SkPDFDocument();
+
+ /** Output the PDF to the passed stream.
+ * @param stream The writable output stream to send the PDF to.
+ */
+ SK_API bool emitPDF(SkWStream* stream);
+
+ /** Append the passed pdf device to the document as a new page. Returns
+ * true if successful. Will fail if the document has already been emitted.
+ *
+ * @param pdfDevice The page to add to this document.
+ */
+ SK_API bool appendPage(const SkRefPtr<SkPDFDevice>& pdfDevice);
+
+ /** Get the list of pages in this document.
+ */
+ SK_API const SkTDArray<SkPDFPage*>& getPages();
+
+private:
+ SkPDFCatalog fCatalog;
+ int64_t fXRefFileOffset;
+
+ SkTDArray<SkPDFPage*> fPages;
+ SkTDArray<SkPDFDict*> fPageTree;
+ SkRefPtr<SkPDFDict> fDocCatalog;
+ SkTDArray<SkPDFObject*> fPageResources;
+ int fSecondPageFirstResourceIndex;
+
+ SkRefPtr<SkPDFDict> fTrailerDict;
+
+ /** Output the PDF header to the passed stream.
+ * @param stream The writable output stream to send the header to.
+ */
+ void emitHeader(SkWStream* stream);
+
+ /** Get the size of the header.
+ */
+ size_t headerSize();
+
+ /** Output the PDF footer to the passed stream.
+ * @param stream The writable output stream to send the footer to.
+ * @param objCount The number of objects in the PDF.
+ */
+ void emitFooter(SkWStream* stream, int64_t objCount);
+};
+
+#endif
diff --git a/include/pdf/SkPDFFont.h b/include/pdf/SkPDFFont.h
new file mode 100644
index 0000000..93a72f1
--- /dev/null
+++ b/include/pdf/SkPDFFont.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFFont_DEFINED
+#define SkPDFFont_DEFINED
+
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkPDFTypes.h"
+#include "SkTDArray.h"
+#include "SkThread.h"
+
+class SkPaint;
+
+/** \class SkPDFFont
+ A PDF Object class representing a font. The font may have resources
+ attached to it in order to embed the font. SkPDFFonts are canonicalized
+ so that resource deduplication will only include one copy of a font.
+ This class uses the same pattern as SkPDFGraphicState, a static weak
+ reference to each instantiated class.
+*/
+class SkPDFFont : public SkPDFDict {
+public:
+ SK_API virtual ~SkPDFFont();
+
+ SK_API virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ /** Returns the typeface represented by this class. Returns NULL for the
+ * default typeface.
+ */
+ SK_API SkTypeface* typeface();
+
+ /** Returns the font type represented in this font. For Type0 fonts,
+ * returns the type of the decendant font.
+ */
+ SK_API SkAdvancedTypefaceMetrics::FontType getType();
+
+ /** Return true if this font has an encoding for the passed glyph id.
+ */
+ SK_API bool hasGlyph(uint16_t glyphID);
+
+ /** Returns true if this font encoding supports glyph IDs above 255.
+ */
+ SK_API bool multiByteGlyphs();
+
+ /** Convert (in place) the input glyph IDs into the font encoding. If the
+ * font has more glyphs than can be encoded (like a type 1 font with more
+ * than 255 glyphs) this method only converts up to the first out of range
+ * glyph ID.
+ * @param glyphIDs The input text as glyph IDs.
+ * @param numGlyphs The number of input glyphs.
+ * @return Returns the number of glyphs consumed.
+ */
+ SK_API size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs);
+
+ /** Get the font resource for the passed typeface and glyphID. The
+ * reference count of the object is incremented and it is the caller's
+ * responsibility to unreference it when done. This is needed to
+ * accommodate the weak reference pattern used when the returned object
+ * is new and has no other references.
+ * @param typeface The typeface to find.
+ * @param glyphID Specify which section of a large font is of interest.
+ */
+ SK_API static SkPDFFont* getFontResource(SkTypeface* typeface,
+ uint16_t glyphID);
+
+private:
+ SkRefPtr<SkTypeface> fTypeface;
+ SkAdvancedTypefaceMetrics::FontType fType;
+#ifdef SK_DEBUG
+ bool fDescendant;
+#endif
+ bool fMultiByteGlyphs;
+
+ // The glyph IDs accessible with this font. For Type1 (non CID) fonts,
+ // this will be a subset if the font has more than 255 glyphs.
+ uint16_t fFirstGlyphID;
+ uint16_t fLastGlyphID;
+ // The font info is only kept around after construction for large
+ // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs.
+ SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
+ SkTDArray<SkPDFObject*> fResources;
+ SkRefPtr<SkPDFDict> fDescriptor;
+
+ class FontRec {
+ public:
+ SkPDFFont* fFont;
+ uint32_t fFontID;
+ uint16_t fGlyphID;
+
+ // A fGlyphID of 0 with no fFont always matches.
+ bool operator==(const FontRec& b) const;
+ FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
+ };
+
+ // This should be made a hash table if performance is a problem.
+ static SkTDArray<FontRec>& canonicalFonts();
+ static SkMutex& canonicalFontsMutex();
+
+ /** Construct a new font dictionary and support objects.
+ * @param fontInfo Information about the to create.
+ * @param typeface The typeface for the font.
+ * @param glyphID The glyph ID the caller is interested in. This
+ * is important only for Type1 fonts, which have
+ * more than 255 glyphs.
+ * @param descendantFont If this is the descendant (true) or root
+ * (Type 0 font - false) font dictionary. Only True
+ * Type and CID encoded fonts will use a true value.
+ * @param fontDescriptor If the font descriptor has already have generated
+ * for this font, pass it in here, otherwise pass
+ * NULL.
+ */
+ SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
+ uint16_t glyphID, bool descendantFont, SkPDFDict* fontDescriptor);
+
+ void populateType0Font();
+ void populateCIDFont();
+ bool populateType1Font(int16_t glyphID);
+
+ /** Populate the PDF font dictionary as Type3 font which includes glyph
+ * descriptions with instructions for painting the glyphs. This function
+ * doesn't use any fields from SkAdvancedTypefaceMetrics (fFontInfo). Font
+ * information including glyph paths are queried from the platform
+ * dependent SkGlyphCache.
+ */
+ void populateType3Font(int16_t glyphID);
+ bool addFontDescriptor(int16_t defaultWidth);
+ void populateToUnicodeTable();
+ void addWidthInfoFromRange(int16_t defaultWidth,
+ const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry);
+ /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
+ * including the passed glyphID.
+ */
+ void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
+
+ static bool find(uint32_t fontID, uint16_t glyphID, int* index);
+};
+
+#endif
diff --git a/include/pdf/SkPDFFormXObject.h b/include/pdf/SkPDFFormXObject.h
new file mode 100644
index 0000000..41719f0
--- /dev/null
+++ b/include/pdf/SkPDFFormXObject.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFFormXObject_DEFINED
+#define SkPDFFormXObject_DEFINED
+
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+class SkMatrix;
+class SkPDFDevice;
+class SkPDFCatalog;
+
+/** \class SkPDFFormXObject
+
+ A form XObject; a self contained description of graphics objects. A form
+ XObject is basically a page object with slightly different syntax, that
+ can be drawn onto a page.
+*/
+
+// The caller could keep track of the form XObjects it creates and
+// canonicalize them, but the Skia API doesn't provide enough context to
+// automatically do it (trivially).
+class SkPDFFormXObject : public SkPDFObject {
+public:
+ /** Create a PDF form XObject. Entries for the dictionary entries are
+ * automatically added.
+ * @param device The set of graphical elements on this form.
+ */
+ explicit SkPDFFormXObject(SkPDFDevice* device);
+ virtual ~SkPDFFormXObject();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ /** Add the value to the stream dictionary with the given key. Refs value.
+ * @param key The key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);
+
+ /** Add the value to the stream dictionary with the given key. Refs value.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(const char key[], SkPDFObject* value);
+
+private:
+ SkRefPtr<SkPDFStream> fStream;
+ SkTDArray<SkPDFObject*> fResources;
+};
+
+#endif
diff --git a/include/pdf/SkPDFGraphicState.h b/include/pdf/SkPDFGraphicState.h
new file mode 100644
index 0000000..49809a4
--- /dev/null
+++ b/include/pdf/SkPDFGraphicState.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFGraphicState_DEFINED
+#define SkPDFGraphicState_DEFINED
+
+#include "SkPaint.h"
+#include "SkPDFTypes.h"
+#include "SkTemplates.h"
+#include "SkThread.h"
+
+class SkPDFFormXObject;
+
+/** \class SkPDFGraphicState
+ SkPaint objects roughly correspond to graphic state dictionaries that can
+ be installed. So that a given dictionary is only output to the pdf file
+ once, we want to canonicalize them. Static methods in this class manage
+ a weakly referenced set of SkPDFGraphicState objects: when the last
+ reference to a SkPDFGraphicState is removed, it removes itself from the
+ static set of objects.
+
+*/
+class SkPDFGraphicState : public SkPDFDict {
+public:
+ virtual ~SkPDFGraphicState();
+
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ // Override emitObject and getOutputSize so that we can populate
+ // the dictionary on demand.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** Get the graphic state for the passed SkPaint. The reference count of
+ * the object is incremented and it is the caller's responsibility to
+ * unreference it when done. This is needed to accommodate the weak
+ * reference pattern used when the returned object is new and has no
+ * other references.
+ * @param paint The SkPaint to emulate.
+ */
+ static SkPDFGraphicState* getGraphicStateForPaint(const SkPaint& paint);
+
+ /** Make a graphic state that only sets the passed soft mask. The
+ * reference count of the object is incremented and it is the caller's
+ * responsibility to unreference it when done.
+ * @param sMask The form xobject to use as a soft mask.
+ * @param invert Indicates if the alpha of the sMask should be inverted.
+ */
+ static SkPDFGraphicState* getSMaskGraphicState(SkPDFFormXObject* sMask,
+ bool invert);
+
+ /** Get a graphic state that only unsets the soft mask. The reference
+ * count of the object is incremented and it is the caller's responsibility
+ * to unreference it when done. This is needed to accommodate the weak
+ * reference pattern used when the returned object is new and has no
+ * other references.
+ */
+ static SkPDFGraphicState* getNoSMaskGraphicState();
+
+private:
+ const SkPaint fPaint;
+ SkTDArray<SkPDFObject*> fResources;
+ bool fPopulated;
+ bool fSMask;
+
+ class GSCanonicalEntry {
+ public:
+ SkPDFGraphicState* fGraphicState;
+ const SkPaint* fPaint;
+
+ bool operator==(const GSCanonicalEntry& b) const;
+ explicit GSCanonicalEntry(SkPDFGraphicState* gs)
+ : fGraphicState(gs),
+ fPaint(&gs->fPaint) {}
+ explicit GSCanonicalEntry(const SkPaint* paint) : fPaint(paint) {}
+ };
+
+ // This should be made a hash table if performance is a problem.
+ static SkTDArray<GSCanonicalEntry>& canonicalPaints();
+ static SkMutex& canonicalPaintsMutex();
+
+ SkPDFGraphicState();
+ explicit SkPDFGraphicState(const SkPaint& paint);
+
+ void populateDict();
+
+ static SkPDFObject* GetInvertFunction();
+
+ static int find(const SkPaint& paint);
+};
+
+#endif
diff --git a/include/pdf/SkPDFImage.h b/include/pdf/SkPDFImage.h
new file mode 100644
index 0000000..945ff9e
--- /dev/null
+++ b/include/pdf/SkPDFImage.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFImage_DEFINED
+#define SkPDFImage_DEFINED
+
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+
+class SkBitmap;
+class SkPaint;
+class SkPDFCatalog;
+struct SkIRect;
+
+/** \class SkPDFImage
+
+ An image XObject.
+*/
+
+// We could play the same trick here as is done in SkPDFGraphicState, storing
+// a copy of the Bitmap object (not the pixels), the pixel generation number,
+// and settings used from the paint to canonicalize image objects.
+class SkPDFImage : public SkPDFObject {
+public:
+ /** Create a new Image XObject to represent the passed bitmap.
+ * @param bitmap The image to encode.
+ * @param srcRect The rectangle to cut out of bitmap.
+ * @param paint Used to calculate alpha, masks, etc.
+ * @return The image XObject or NUll if there is nothing to draw for
+ * the given parameters.
+ */
+ static SkPDFImage* CreateImage(const SkBitmap& bitmap,
+ const SkIRect& srcRect,
+ const SkPaint& paint);
+
+ virtual ~SkPDFImage();
+
+ /** Add a Soft Mask (alpha or shape channel) to the image. Refs mask.
+ * @param mask A gray scale image representing the mask.
+ * @return The mask argument is returned.
+ */
+ SkPDFImage* addSMask(SkPDFImage* mask);
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+private:
+ SkRefPtr<SkPDFStream> fStream;
+ SkTDArray<SkPDFObject*> fResources;
+
+ /** Create a PDF image XObject. Entries for the image properties are
+ * automatically added to the stream dictionary.
+ * @param imageData The final raw bits representing the image.
+ * @param bitmap The image parameters to use (Config, etc).
+ * @param srcRect The clipping applied to bitmap before generating
+ * imageData.
+ * @param alpha Is this the alpha channel of the bitmap.
+ * @param paint Used to calculate alpha, masks, etc.
+ */
+ SkPDFImage(SkStream* imageData, const SkBitmap& bitmap,
+ const SkIRect& srcRect, bool alpha, const SkPaint& paint);
+
+ /** Add the value to the stream dictionary with the given key. Refs value.
+ * @param key The key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);
+
+ /** Add the value to the stream dictionary with the given key. Refs value.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(const char key[], SkPDFObject* value);
+};
+
+#endif
diff --git a/include/pdf/SkPDFPage.h b/include/pdf/SkPDFPage.h
new file mode 100644
index 0000000..0e30028
--- /dev/null
+++ b/include/pdf/SkPDFPage.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFPage_DEFINED
+#define SkPDFPage_DEFINED
+
+#include "SkPDFTypes.h"
+#include "SkPDFStream.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+class SkPDFCatalog;
+class SkPDFDevice;
+class SkWStream;
+
+/** \class SkPDFPage
+
+ A SkPDFPage contains meta information about a page, is used in the page
+ tree and points to the content of the page.
+*/
+class SkPDFPage : public SkPDFDict {
+public:
+ /** Create a PDF page with the passed PDF device. The device need not
+ * have content on it yet.
+ * @param content The page content.
+ */
+ explicit SkPDFPage(const SkRefPtr<SkPDFDevice>& content);
+ ~SkPDFPage();
+
+ /** Before a page and its contents can be sized and emitted, it must
+ * be finalized. No changes to the PDFDevice will be honored after
+ * finalizePage has been called. This function adds the page content
+ * to the passed catalog, so it must be called for each document
+ * that the page is part of.
+ * @param catalog The catalog to add page content objects to.
+ * @param firstPage Indicate if this is the first page of a document.
+ * @param resourceObjects The resource objects used on the page are added
+ * to this array. This gives the caller a chance
+ * to deduplicate resources across pages.
+ */
+ void finalizePage(SkPDFCatalog* catalog, bool firstPage,
+ SkTDArray<SkPDFObject*>* resourceObjects);
+
+ /** Determine the size of the page content and store to the catalog
+ * the offsets of all nonresource-indirect objects that make up the page
+ * content. This must be called before emitPage(), but after finalizePage.
+ * @param catalog The catalog to add the object offsets to.
+ * @param fileOffset The file offset where the page content will be
+ * emitted.
+ */
+ off_t getPageSize(SkPDFCatalog* catalog, off_t fileOffset);
+
+ /** Output the page content to the passed stream.
+ * @param stream The writable output stream to send the content to.
+ * @param catalog The active object catalog.
+ */
+ void emitPage(SkWStream* stream, SkPDFCatalog* catalog);
+
+ /** Generate a page tree for the passed vector of pages. New objects are
+ * added to the catalog. The pageTree vector is populated with all of
+ * the 'Pages' dictionaries as well as the 'Page' objects. Page trees
+ * have both parent and children links, creating reference cycles, so
+ * it must be torn down explicitly. The first page is not added to
+ * the pageTree dictionary array so the caller can handle it specially.
+ * @param pages The ordered vector of page objects.
+ * @param catalog The catalog to add new objects into.
+ * @param pageTree An output vector with all of the internal and leaf
+ * nodes of the pageTree.
+ * @param rootNode An output parameter set to the root node.
+ */
+ static void generatePageTree(const SkTDArray<SkPDFPage*>& pages,
+ SkPDFCatalog* catalog,
+ SkTDArray<SkPDFDict*>* pageTree,
+ SkPDFDict** rootNode);
+
+ /** Get the fonts used on this page.
+ */
+ SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;
+
+private:
+ // Multiple pages may reference the content.
+ SkRefPtr<SkPDFDevice> fDevice;
+
+ // Once the content is finalized, put it into a stream for output.
+ SkRefPtr<SkPDFStream> fContentStream;
+};
+
+#endif
diff --git a/include/pdf/SkPDFShader.h b/include/pdf/SkPDFShader.h
new file mode 100644
index 0000000..17f7f03
--- /dev/null
+++ b/include/pdf/SkPDFShader.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFShader_DEFINED
+#define SkPDFShader_DEFINED
+
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkMatrix.h"
+#include "SkRefCnt.h"
+#include "SkShader.h"
+
+class SkObjRef;
+class SkPDFCatalog;
+
+/** \class SkPDFShader
+
+ In PDF parlance, this is a pattern, used in place of a color when the
+ pattern color space is selected.
+*/
+
+class SkPDFShader : public SkPDFObject {
+public:
+ virtual ~SkPDFShader();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ /** Get the PDF shader for the passed SkShader. If the SkShader is
+ * invalid in some way, returns NULL. The reference count of
+ * the object is incremented and it is the caller's responsibility to
+ * unreference it when done. This is needed to accommodate the weak
+ * reference pattern used when the returned object is new and has no
+ * other references.
+ * @param shader The SkShader to emulate.
+ * @param matrix The current transform. (PDF shaders are absolutely
+ * positioned, relative to where the page is drawn.)
+ * @param surfceBBox The bounding box of the drawing surface (with matrix
+ * already applied).
+ */
+ static SkPDFShader* getPDFShader(const SkShader& shader,
+ const SkMatrix& matrix,
+ const SkIRect& surfaceBBox);
+
+private:
+ class State {
+ public:
+ SkShader::GradientType fType;
+ SkShader::GradientInfo fInfo;
+ SkAutoFree fColorData;
+ SkMatrix fCanvasTransform;
+ SkMatrix fShaderTransform;
+ SkIRect fBBox;
+
+ SkBitmap fImage;
+ uint32_t fPixelGeneration;
+ SkShader::TileMode fImageTileModes[2];
+
+ explicit State(const SkShader& shader, const SkMatrix& canvasTransform,
+ const SkIRect& bbox);
+ bool operator==(const State& b) const;
+ };
+
+ SkRefPtr<SkPDFDict> fContent;
+ SkTDArray<SkPDFObject*> fResources;
+ SkAutoTDelete<const State> fState;
+
+ class ShaderCanonicalEntry {
+ public:
+ SkPDFShader* fPDFShader;
+ const State* fState;
+
+ bool operator==(const ShaderCanonicalEntry& b) const {
+ return fPDFShader == b.fPDFShader || *fState == *b.fState;
+ }
+ ShaderCanonicalEntry(SkPDFShader* pdfShader, const State* state)
+ : fPDFShader(pdfShader),
+ fState(state) {
+ }
+ };
+ // This should be made a hash table if performance is a problem.
+ static SkTDArray<ShaderCanonicalEntry>& canonicalShaders();
+ static SkMutex& canonicalShadersMutex();
+
+ static SkPDFObject* rangeObject();
+
+ SkPDFShader(State* state);
+
+ void doFunctionShader();
+ void doImageShader();
+ SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
+};
+
+#endif
diff --git a/include/pdf/SkPDFStream.h b/include/pdf/SkPDFStream.h
new file mode 100644
index 0000000..a975ad6
--- /dev/null
+++ b/include/pdf/SkPDFStream.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFStream_DEFINED
+#define SkPDFStream_DEFINED
+
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+
+class SkPDFCatalog;
+
+/** \class SkPDFStream
+
+ A stream object in a PDF. Note, all streams must be indirect objects (via
+ SkObjRef).
+*/
+class SkPDFStream : public SkPDFDict {
+public:
+ /** Create a PDF stream. A Length entry is automatically added to the
+ * stream dictionary.
+ * @param stream The data part of the stream.
+ */
+ explicit SkPDFStream(SkStream* stream);
+ virtual ~SkPDFStream();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+private:
+ size_t fLength;
+ // Only one of the two streams will be valid.
+ SkRefPtr<SkStream> fPlainData;
+ SkDynamicMemoryWStream fCompressedData;
+
+ typedef SkPDFDict INHERITED;
+};
+
+#endif
diff --git a/include/pdf/SkPDFTypes.h b/include/pdf/SkPDFTypes.h
new file mode 100644
index 0000000..6b5146a
--- /dev/null
+++ b/include/pdf/SkPDFTypes.h
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFTypes_DEFINED
+#define SkPDFTypes_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+#include "SkString.h"
+#include "SkTDArray.h"
+#include "SkTypes.h"
+
+class SkPDFCatalog;
+class SkWStream;
+
+/** \class SkPDFObject
+
+ A PDF Object is the base class for primitive elements in a PDF file. A
+ common subtype is used to ease the use of indirect object references,
+ which are common in the PDF format.
+*/
+class SkPDFObject : public SkRefCnt {
+public:
+ /** Create a PDF object.
+ */
+ SkPDFObject();
+ virtual ~SkPDFObject();
+
+ /** Subclasses must implement this method to print the object to the
+ * PDF file.
+ * @param catalog The object catalog to use.
+ * @param indirect If true, output an object identifier with the object.
+ * @param stream The writable output stream to send the output to.
+ */
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect) = 0;
+
+ /** Return the size (number of bytes) of this object in the final output
+ * file. Compound objects or objects that are computationally intensive
+ * to output should override this method.
+ * @param catalog The object catalog to use.
+ * @param indirect If true, output an object identifier with the object.
+ */
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** If this object explicitly depends on other objects, add them to the
+ * end of the list. This only applies to higher level object, where
+ * the depenency is explicit and introduced by the class. i.e. an
+ * SkPDFImage added to an SkPDFDevice, but not an SkPDFObjRef added to
+ * an SkPDFArray.
+ * @param resourceList The list to append dependant resources to.
+ */
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ /** Helper function to output an indirect object.
+ * @param catalog The object catalog to use.
+ * @param stream The writable output stream to send the output to.
+ */
+ void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog);
+
+ /** Helper function to find the size of an indirect object.
+ * @param catalog The object catalog to use.
+ */
+ size_t getIndirectOutputSize(SkPDFCatalog* catalog);
+};
+
+/** \class SkPDFObjRef
+
+ An indirect reference to a PDF object.
+*/
+class SkPDFObjRef : public SkPDFObject {
+public:
+ /** Create a reference to an existing SkPDFObject.
+ * @param obj The object to reference.
+ */
+ explicit SkPDFObjRef(SkPDFObject* obj);
+ virtual ~SkPDFObjRef();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+private:
+ SkRefPtr<SkPDFObject> fObj;
+};
+
+/** \class SkPDFInt
+
+ An integer object in a PDF.
+*/
+class SkPDFInt : public SkPDFObject {
+public:
+ /** Create a PDF integer (usually for indirect reference purposes).
+ * @param value An integer value between 2^31 - 1 and -2^31.
+ */
+ explicit SkPDFInt(int32_t value);
+ virtual ~SkPDFInt();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+
+private:
+ int32_t fValue;
+};
+
+/** \class SkPDFBool
+
+ An boolean value in a PDF.
+*/
+class SkPDFBool : public SkPDFObject {
+public:
+ /** Create a PDF boolean.
+ * @param value true or false.
+ */
+ explicit SkPDFBool(bool value);
+ virtual ~SkPDFBool();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+private:
+ bool fValue;
+};
+
+/** \class SkPDFScalar
+
+ A real number object in a PDF.
+*/
+class SkPDFScalar : public SkPDFObject {
+public:
+ /** Create a PDF real number.
+ * @param value A real value.
+ */
+ explicit SkPDFScalar(SkScalar value);
+ virtual ~SkPDFScalar();
+
+ static void Append(SkScalar value, SkWStream* stream);
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+
+private:
+ SkScalar fValue;
+};
+
+/** \class SkPDFString
+
+ A string object in a PDF.
+*/
+class SkPDFString : public SkPDFObject {
+public:
+ /** Create a PDF string. Maximum length (in bytes) is 65,535.
+ * @param value A string value.
+ */
+ explicit SkPDFString(const char value[]);
+ explicit SkPDFString(const SkString& value);
+
+ /** Create a PDF string. Maximum length (in bytes) is 65,535.
+ * @param value A string value.
+ * @param len The length of value.
+ * @param wideChars Indicates if the top byte in value is significant and
+ * should be encoded (true) or not (false).
+ */
+ SkPDFString(const uint16_t* value, size_t len, bool wideChars);
+ virtual ~SkPDFString();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ static SkString formatString(const char* input, size_t len);
+ static SkString formatString(const uint16_t* input, size_t len,
+ bool wideChars);
+private:
+ static const size_t kMaxLen = 65535;
+
+ const SkString fValue;
+
+ static SkString doFormatString(const void* input, size_t len,
+ bool wideInput, bool wideOutput);
+};
+
+/** \class SkPDFName
+
+ A name object in a PDF.
+*/
+class SkPDFName : public SkPDFObject {
+public:
+ /** Create a PDF name object. Maximum length is 127 bytes.
+ * @param value The name.
+ */
+ explicit SkPDFName(const char name[]);
+ explicit SkPDFName(const SkString& name);
+ virtual ~SkPDFName();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+private:
+ static const size_t kMaxLen = 127;
+
+ const SkString fValue;
+
+ static SkString formatName(const SkString& input);
+};
+
+/** \class SkPDFArray
+
+ An array object in a PDF.
+*/
+class SkPDFArray : public SkPDFObject {
+public:
+ /** Create a PDF array. Maximum length is 8191.
+ */
+ SkPDFArray();
+ virtual ~SkPDFArray();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** The size of the array.
+ */
+ int size() { return fValue.count(); }
+
+ /** Preallocate space for the given number of entries.
+ * @param length The number of array slots to preallocate.
+ */
+ void reserve(int length);
+
+ /** Returns the object at the given offset in the array.
+ * @param index The index into the array to retrieve.
+ */
+ SkPDFObject* getAt(int index) { return fValue[index]; }
+
+ /** Set the object at the given offset in the array. Ref's value.
+ * @param index The index into the array to set.
+ * @param value The value to add to the array.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* setAt(int index, SkPDFObject* value);
+
+ /** Append the object to the end of the array and increments its ref count.
+ * @param value The value to add to the array.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* append(SkPDFObject* value);
+
+private:
+ static const int kMaxLen = 8191;
+ SkTDArray<SkPDFObject*> fValue;
+};
+
+/** \class SkPDFDict
+
+ A dictionary object in a PDF.
+*/
+class SkPDFDict : public SkPDFObject {
+public:
+ /** Create a PDF dictionary. Maximum number of entries is 4095.
+ */
+ SkPDFDict();
+
+ /** Create a PDF dictionary with a Type entry.
+ * @param type The value of the Type entry.
+ */
+ explicit SkPDFDict(const char type[]);
+
+ virtual ~SkPDFDict();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** The size of the dictionary.
+ */
+ int size() { return fValue.count(); }
+
+ /** Add the value to the dictionary with the given key. Refs value.
+ * @param key The key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);
+
+ /** Add the value to the dictionary with the given key. Refs value. The
+ * method will create the SkPDFName object.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(const char key[], SkPDFObject* value);
+
+ /** Remove all entries from the dictionary.
+ */
+ void clear();
+
+private:
+ static const int kMaxLen = 4095;
+
+ struct Rec {
+ SkPDFName* key;
+ SkPDFObject* value;
+ };
+
+ SkTDArray<struct Rec> fValue;
+};
+
+#endif
diff --git a/include/pdf/SkPDFUtils.h b/include/pdf/SkPDFUtils.h
new file mode 100644
index 0000000..50da28c
--- /dev/null
+++ b/include/pdf/SkPDFUtils.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFUtils_DEFINED
+#define SkPDFUtils_DEFINED
+
+#include "SkPath.h"
+
+class SkMatrix;
+class SkPath;
+class SkPDFArray;
+struct SkRect;
+
+#if 0
+#define PRINT_NOT_IMPL(str) fprintf(stderr, str)
+#else
+#define PRINT_NOT_IMPL(str)
+#endif
+
+#define NOT_IMPLEMENTED(condition, assert) \
+ do { \
+ if (condition) { \
+ PRINT_NOT_IMPL("NOT_IMPLEMENTED: " #condition "\n"); \
+ SkDEBUGCODE(SkASSERT(!assert);) \
+ } \
+ } while(0)
+
+class SkPDFUtils {
+public:
+ static SkPDFArray* MatrixToArray(const SkMatrix& matrix);
+ static void AppendTransform(const SkMatrix& matrix, SkWStream* content);
+
+ static void MoveTo(SkScalar x, SkScalar y, SkWStream* content);
+ static void AppendLine(SkScalar x, SkScalar y, SkWStream* content);
+ static void AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
+ SkScalar ctl2X, SkScalar ctl2Y,
+ SkScalar dstX, SkScalar dstY, SkWStream* content);
+ static void AppendRectangle(const SkRect& rect, SkWStream* content);
+ static void EmitPath(const SkPath& path, SkWStream* content);
+ static void ClosePath(SkWStream* content);
+ static void PaintPath(SkPaint::Style style, SkPath::FillType fill,
+ SkWStream* content);
+ static void StrokePath(SkWStream* content);
+ static void DrawFormXObject(int objectIndex, SkWStream* content);
+ static void ApplyGraphicState(int objectIndex, SkWStream* content);
+};
+
+#endif
diff --git a/include/pipe/SkGPipe.h b/include/pipe/SkGPipe.h
new file mode 100644
index 0000000..897766f
--- /dev/null
+++ b/include/pipe/SkGPipe.h
@@ -0,0 +1,96 @@
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef SkGPipe_DEFINED
+#define SkGPipe_DEFINED
+
+#include "SkWriter32.h"
+#include "SkFlattenable.h"
+
+class SkCanvas;
+
+class SkGPipeReader {
+public:
+ SkGPipeReader(SkCanvas* target);
+ ~SkGPipeReader();
+
+ enum Status {
+ kDone_Status, //!< no more data expected from reader
+ kEOF_Status, //!< need more data from reader
+ kError_Status //!< encountered error
+ };
+
+ // data must be 4-byte aligned
+ // length must be a multiple of 4
+ Status playback(const void* data, size_t length, size_t* bytesRead = NULL);
+
+private:
+ SkCanvas* fCanvas;
+ class SkGPipeState* fState;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkGPipeController {
+public:
+ /**
+ * Called periodically by the writer, to get a working buffer of RAM to
+ * write into. The actual size of the block is also returned, and must be
+ * actual >= minRequest. If NULL is returned, then actual is ignored and
+ * writing will stop.
+ *
+ * The returned block must be 4-byte aligned, and actual must be a
+ * multiple of 4.
+ * minRequest will always be a multiple of 4.
+ */
+ virtual void* requestBlock(size_t minRequest, size_t* actual) = 0;
+
+ /**
+ * This is called each time some atomic portion of the data has been
+ * written to the block (most recently returned by requestBlock()).
+ * If bytes == 0, then the writer has finished.
+ *
+ * bytes will always be a multiple of 4.
+ */
+ virtual void notifyWritten(size_t bytes) = 0;
+};
+
+class SkGPipeWriter {
+public:
+ SkGPipeWriter();
+ ~SkGPipeWriter();
+
+ bool isRecording() const { return NULL != fCanvas; }
+
+ enum Flags {
+ kCrossProcess_Flag = 1 << 0,
+ };
+
+ SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0);
+
+ // called in destructor, but can be called sooner once you know there
+ // should be no more drawing calls made into the recording canvas.
+ void endRecording();
+
+private:
+ class SkGPipeCanvas* fCanvas;
+ SkGPipeController* fController;
+ SkFactorySet fFactorySet;
+ SkWriter32 fWriter;
+};
+
+#endif
diff --git a/include/utils/SkEGLContext.h b/include/utils/SkEGLContext.h
index 4b17be1..ced31a5 100644
--- a/include/utils/SkEGLContext.h
+++ b/include/utils/SkEGLContext.h
@@ -1,20 +1,53 @@
#ifndef SkEGLContext_DEFINED
#define SkEGLContext_DEFINED
-#include "SkTypes.h"
+#if defined(SK_MESA)
+ #include "GL/osmesa.h"
+#elif defined(SK_BUILD_FOR_MAC)
+ #include <AGL/agl.h>
+#elif defined(SK_BUILD_FOR_ANDROID)
+ #include "GLES2/gl2.h"
+ #include "EGL/egl.h"
+#elif defined(SK_BUILD_FOR_UNIX)
+ #include <X11/Xlib.h>
+ #include <GL/glx.h>
+#elif defined(SK_BUILD_FOR_WIN32)
+ #include <Windows.h>
+ #include <GL/GL.h>
+#else
+
+#endif
/**
* Create an offscreen opengl context
*/
class SkEGLContext {
public:
- SkEGLContext();
- ~SkEGLContext();
+ SkEGLContext();
+ ~SkEGLContext();
- bool init(int width, int height);
+ bool init(const int width, const int height);
private:
- void* fContext;
+#if defined(SK_MESA)
+ OSMesaContext context;
+ GLfloat *image;
+#elif defined(SK_BUILD_FOR_MAC)
+ AGLContext context;
+#elif defined(SK_BUILD_FOR_ANDROID)
+
+#elif defined(SK_BUILD_FOR_UNIX)
+ GLXContext context;
+ Display *display;
+ Pixmap pixmap;
+ GLXPixmap glxPixmap;
+#elif defined(SK_BUILD_FOR_WIN32)
+ HWND fWindow;
+ HDC fDeviceContext;
+ HGLRC fGlRenderContext;
+#else
+
+#endif
};
#endif
diff --git a/include/utils/android/AndroidKeyToSkKey.h b/include/utils/android/AndroidKeyToSkKey.h
new file mode 100644
index 0000000..7b0a035
--- /dev/null
+++ b/include/utils/android/AndroidKeyToSkKey.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 Skia
+ *
+ * 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 _ANDROID_TO_SKIA_KEYCODES_H
+#define _ANDROID_TO_SKIA_KEYCODES_H
+
+#include "keycodes.h"
+#include "SkKey.h"
+
+// Convert an Android keycode to an SkKey. This is an incomplete list, only
+// including keys used by the sample app.
+SkKey AndroidKeycodeToSkKey(int keycode) {
+ switch (keycode) {
+ case AKEYCODE_DPAD_LEFT:
+ return kLeft_SkKey;
+ case AKEYCODE_DPAD_RIGHT:
+ return kRight_SkKey;
+ case AKEYCODE_DPAD_UP:
+ return kUp_SkKey;
+ case AKEYCODE_DPAD_DOWN:
+ return kDown_SkKey;
+ default:
+ return kNONE_SkKey;
+ }
+}
+
+#endif
diff --git a/include/utils/unix/XkeysToSkKeys.h b/include/utils/unix/XkeysToSkKeys.h
index 3d41a22..1852d99 100644
--- a/include/utils/unix/XkeysToSkKeys.h
+++ b/include/utils/unix/XkeysToSkKeys.h
@@ -8,6 +8,14 @@
SkKey XKeyToSkKey(KeySym keysym) {
switch (keysym) {
+ case XK_BackSpace:
+ return kBack_SkKey;
+ case XK_Return:
+ return kOK_SkKey;
+ case XK_Home:
+ return kHome_SkKey;
+ case XK_End:
+ return kEnd_SkKey;
case XK_Right:
return kRight_SkKey;
case XK_Left:
diff --git a/include/views/SkApplication.h b/include/views/SkApplication.h
new file mode 100644
index 0000000..4c4a4fb
--- /dev/null
+++ b/include/views/SkApplication.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkApplication_DEFINED
+#define SkApplication_DEFINED
+
+class SkOSWindow;
+
+extern SkOSWindow* create_sk_window(void* hwnd);
+extern void application_init();
+extern void application_term();
+
+#endif // SkApplication_DEFINED
diff --git a/include/views/SkBGViewArtist.h b/include/views/SkBGViewArtist.h
new file mode 100644
index 0000000..1bca42f
--- /dev/null
+++ b/include/views/SkBGViewArtist.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkBGViewArtist_DEFINED
+#define SkBGViewArtist_DEFINED
+
+#include "SkView.h"
+#include "SkPaint.h"
+
+class SkBGViewArtist : public SkView::Artist {
+public:
+ SkBGViewArtist(SkColor c = SK_ColorWHITE);
+ virtual ~SkBGViewArtist();
+
+ const SkPaint& paint() const { return fPaint; }
+ SkPaint& paint() { return fPaint; }
+
+protected:
+ // overrides
+ virtual void onDraw(SkView*, SkCanvas*);
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+
+private:
+ SkPaint fPaint;
+};
+
+#endif
+
diff --git a/include/views/SkBorderView.h b/include/views/SkBorderView.h
new file mode 100644
index 0000000..94ccc1f
--- /dev/null
+++ b/include/views/SkBorderView.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkBorderView_DEFINED
+#define SkBorderView_DEFINED
+
+#include "SkView.h"
+#include "SkWidgetViews.h"
+#include "SkAnimator.h"
+
+class SkBorderView : public SkWidgetView {
+public:
+ SkBorderView();
+ ~SkBorderView();
+ void setSkin(const char skin[]);
+ SkScalar getLeft() const { return fLeft; }
+ SkScalar getRight() const { return fRight; }
+ SkScalar getTop() const { return fTop; }
+ SkScalar getBottom() const { return fBottom; }
+protected:
+ //overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual void onSizeChange();
+ virtual void onDraw(SkCanvas* canvas);
+ virtual bool onEvent(const SkEvent& evt);
+private:
+ SkAnimator fAnim;
+ SkScalar fLeft, fRight, fTop, fBottom; //margin on each side
+ SkRect fMargin;
+
+ typedef SkWidgetView INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkEvent.h b/include/views/SkEvent.h
new file mode 100644
index 0000000..f6719d6
--- /dev/null
+++ b/include/views/SkEvent.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkEvent_DEFINED
+#define SkEvent_DEFINED
+
+#include "SkDOM.h"
+#include "SkMetaData.h"
+#include "SkString.h"
+
+/** Unique 32bit id used to identify an instance of SkEventSink. When events are
+ posted, they are posted to a specific sinkID. When it is time to dispatch the
+ event, the sinkID is used to find the specific SkEventSink object. If it is found,
+ its doEvent() method is called with the event.
+*/
+typedef uint32_t SkEventSinkID;
+
+/** \class SkEvent
+
+ SkEvents are used to communicate type-safe information to SkEventSinks.
+ SkEventSinks (including SkViews) each have a unique ID, which is stored
+ in an event. This ID is used to target the event once it has been "posted".
+*/
+class SkEvent {
+public:
+ /** Default construct, creating an empty event.
+ */
+ SkEvent();
+ /** Construct a new event with the specified type.
+ */
+ explicit SkEvent(const SkString& type);
+ /** Construct a new event with the specified type.
+ */
+ explicit SkEvent(const char type[]);
+ /** Construct a new event by copying the fields from the src event.
+ */
+ SkEvent(const SkEvent& src);
+ ~SkEvent();
+
+// /** Return the event's type (will never be null) */
+// const char* getType() const;
+ /** Copy the event's type into the specified SkString parameter */
+ void getType(SkString* str) const;
+ /** Returns true if the event's type matches exactly the specified type (case sensitive) */
+ bool isType(const SkString& str) const;
+ /** Returns true if the event's type matches exactly the specified type (case sensitive) */
+ bool isType(const char type[], size_t len = 0) const;
+ /** Set the event's type to the specified string.
+ In XML, use the "type" attribute.
+ */
+ void setType(const SkString&);
+ /** Set the event's type to the specified string.
+ In XML, use the "type" attribute.
+ */
+ void setType(const char type[], size_t len = 0);
+
+ /** Return the event's unnamed 32bit field. Default value is 0 */
+ uint32_t getFast32() const { return f32; }
+ /** Set the event's unnamed 32bit field. In XML, use
+ the subelement <data fast32=... />
+ */
+ void setFast32(uint32_t x) { f32 = x; }
+
+ /** Return true if the event contains the named 32bit field, and return the field
+ in value (if value is non-null). If there is no matching named field, return false
+ and ignore the value parameter.
+ */
+ bool findS32(const char name[], int32_t* value = NULL) const { return fMeta.findS32(name, value); }
+ /** Return true if the event contains the named SkScalar field, and return the field
+ in value (if value is non-null). If there is no matching named field, return false
+ and ignore the value parameter.
+ */
+ bool findScalar(const char name[], SkScalar* value = NULL) const { return fMeta.findScalar(name, value); }
+ /** Return true if the event contains the named SkScalar field, and return the fields
+ in value[] (if value is non-null), and return the number of SkScalars in count (if count is non-null).
+ If there is no matching named field, return false and ignore the value and count parameters.
+ */
+ const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const { return fMeta.findScalars(name, count, values); }
+ /** Return the value of the named string field, or if no matching named field exists, return null.
+ */
+ const char* findString(const char name[]) const { return fMeta.findString(name); }
+ /** Return true if the event contains the named pointer field, and return the field
+ in value (if value is non-null). If there is no matching named field, return false
+ and ignore the value parameter.
+ */
+ bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); }
+ bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); }
+ const void* findData(const char name[], size_t* byteCount = NULL) const {
+ return fMeta.findData(name, byteCount);
+ }
+
+ /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */
+ bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); }
+ /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */
+ bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); }
+ /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */
+ bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); }
+ /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */
+ bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); }
+ bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); }
+ bool hasData(const char name[], const void* data, size_t byteCount) const {
+ return fMeta.hasData(name, data, byteCount);
+ }
+
+ /** Add/replace the named 32bit field to the event. In XML use the subelement <data name=... s32=... /> */
+ void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); }
+ /** Add/replace the named SkScalar field to the event. In XML use the subelement <data name=... scalar=... /> */
+ void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); }
+ /** Add/replace the named SkScalar[] field to the event. */
+ SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL) { return fMeta.setScalars(name, count, values); }
+ /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
+ void setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); }
+ /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
+ void setString(const char name[], const char value[]) { fMeta.setString(name, value); }
+ /** Add/replace the named pointer field to the event. There is no XML equivalent for this call */
+ void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); }
+ void setBool(const char name[], bool value) { fMeta.setBool(name, value); }
+ void setData(const char name[], const void* data, size_t byteCount) {
+ fMeta.setData(name, data, byteCount);
+ }
+
+ /** Return the underlying metadata object */
+ SkMetaData& getMetaData() { return fMeta; }
+ /** Return the underlying metadata object */
+ const SkMetaData& getMetaData() const { return fMeta; }
+
+ void tron() { SkDEBUGCODE(fDebugTrace = true;) }
+ void troff() { SkDEBUGCODE(fDebugTrace = false;) }
+ bool isDebugTrace() const
+ {
+#ifdef SK_DEBUG
+ return fDebugTrace;
+#else
+ return false;
+#endif
+ }
+
+ /** Call this to initialize the event from the specified XML node */
+ void inflate(const SkDOM&, const SkDOM::Node*);
+
+ SkDEBUGCODE(void dump(const char title[] = NULL);)
+
+ /** Post the specified event to the event queue, targeting the specified eventsink, with an optional
+ delay. The event must be dynamically allocated for this. It cannot be a global or on the stack.
+ After this call, ownership is transfered to the system, so the caller must not retain
+ the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
+ */
+ static bool Post(SkEvent* evt, SkEventSinkID targetID, SkMSec delay = 0);
+ /** Post the specified event to the event queue, targeting the specified eventsink, to be delivered on/after the
+ specified millisecond time. The event must be dynamically allocated for this. It cannot be a global or on the stack.
+ After this call, ownership is transfered to the system, so the caller must not retain
+ the event's ptr. Returns false if the event could not be posted (which means it will have been deleted).
+ */
+ static bool PostTime(SkEvent* evt, SkEventSinkID targetID, SkMSec time);
+
+ /** Helper method for calling SkEvent::PostTime(this, ...), where the caller specifies a delay.
+ The real "time" will be computed automatically by sampling the clock and adding its value
+ to delay.
+ */
+ bool post(SkEventSinkID sinkID, SkMSec delay = 0)
+ {
+ return SkEvent::Post(this, sinkID, delay);
+ }
+
+ void postTime(SkEventSinkID sinkID, SkMSec time)
+ {
+ SkEvent::PostTime(this, sinkID, time);
+ }
+
+ ///////////////////////////////////////////////
+ /** Porting layer must call these functions **/
+ ///////////////////////////////////////////////
+
+ /** Global initialization function for the SkEvent system. Should be called exactly
+ once before any other event method is called, and should be called after the
+ call to SkGraphics::Init().
+ */
+ static void Init();
+ /** Global cleanup function for the SkEvent system. Should be called exactly once after
+ all event methods have been called, and should be called before calling SkGraphics::Term().
+ */
+ static void Term();
+
+ /** Call this to process one event from the queue. If it returns true, there are more events
+ to process.
+ */
+ static bool ProcessEvent();
+ /** Call this whenever the requested timer has expired (requested by a call to SetQueueTimer).
+ It will post any delayed events whose time as "expired" onto the event queue.
+ It may also call SignalQueueTimer() and SignalNonEmptyQueue().
+ */
+ static void ServiceQueueTimer();
+
+ /** Return the number of queued events. note that this value may be obsolete
+ upon return, since another thread may have called ProcessEvent() or
+ Post() after the count was made.
+ */
+ static int CountEventsOnQueue();
+
+ ////////////////////////////////////////////////////
+ /** Porting layer must implement these functions **/
+ ////////////////////////////////////////////////////
+
+ /** Called whenever an SkEvent is posted to an empty queue, so that the OS
+ can be told to later call Dequeue().
+ */
+ static void SignalNonEmptyQueue();
+ /** Called whenever the delay until the next delayed event changes. If zero is
+ passed, then there are no more queued delay events.
+ */
+ static void SignalQueueTimer(SkMSec delay);
+
+#ifndef SK_USE_WXWIDGETS
+#ifdef SK_BUILD_FOR_WIN
+ static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+#elif defined(SK_BUILD_FOR_UNIXx)
+ static uint32_t HandleTimer(uint32_t, void*);
+ static bool WndProc(Display*, Window, XEvent&);
+#endif
+#else
+ // Don't know yet what this will be
+ //static bool CustomEvent();
+#endif
+
+private:
+ SkMetaData fMeta;
+ mutable char* fType; // may be characters with low bit set to know that it is not a pointer
+ uint32_t f32;
+ SkDEBUGCODE(bool fDebugTrace;)
+
+ // these are for our implementation of the event queue
+ SkEventSinkID fTargetID;
+ SkMSec fTime;
+ SkEvent* fNextEvent; // either in the delay or normal event queue
+ void initialize(const char* type, size_t typeLen);
+
+ static bool Enqueue(SkEvent* evt);
+ static SkMSec EnqueueTime(SkEvent* evt, SkMSec time);
+ static SkEvent* Dequeue(SkEventSinkID* targetID);
+ static bool QHasEvents();
+};
+
+#endif
+
diff --git a/include/views/SkEventSink.h b/include/views/SkEventSink.h
new file mode 100644
index 0000000..27a6743
--- /dev/null
+++ b/include/views/SkEventSink.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkEventSink_DEFINED
+#define SkEventSink_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkEvent.h"
+
+struct SkTagList;
+
+/** \class SkEventSink
+
+ SkEventSink is the base class for all objects that receive SkEvents.
+*/
+class SkEventSink : public SkRefCnt {
+public:
+ SkEventSink();
+ virtual ~SkEventSink();
+
+ /** Returns this eventsink's unique ID. Use this to post SkEvents to
+ this eventsink.
+ */
+ SkEventSinkID getSinkID() const { return fID; }
+
+ /** Call this to pass an event to this object for processing. Returns true if the
+ event was handled.
+ */
+ bool doEvent(const SkEvent&);
+ /** Returns true if the sink (or one of its subclasses) understands the event as a query.
+ If so, the sink may modify the event to communicate its "answer".
+ */
+ bool doQuery(SkEvent* query);
+
+ /** Add sinkID to the list of listeners, to receive events from calls to sendToListeners()
+ and postToListeners(). If sinkID already exists in the listener list, no change is made.
+ */
+ void addListenerID(SkEventSinkID sinkID);
+ /** Copy listeners from one event sink to another, typically from parent to child.
+ @param from the event sink to copy the listeners from
+ */
+ void copyListeners(const SkEventSink& from);
+ /** Remove sinkID from the list of listeners. If sinkID does not appear in the list,
+ no change is made.
+ */
+ void removeListenerID(SkEventSinkID);
+ /** Returns true if there are 1 or more listeners attached to this eventsink
+ */
+ bool hasListeners() const;
+ /** Posts a copy of evt to each of the eventsinks in the lisener list.
+ */
+ void postToListeners(const SkEvent& evt, SkMSec delay = 0);
+
+ enum EventResult {
+ kHandled_EventResult, //!< the eventsink returned true from its doEvent method
+ kNotHandled_EventResult, //!< the eventsink returned false from its doEvent method
+ kSinkNotFound_EventResult //!< no matching eventsink was found for the event's getSink().
+ };
+ /** DoEvent handles searching for an eventsink object that matches the targetID.
+ If one is found, it calls the sink's doEvent method, returning
+ either kHandled_EventResult or kNotHandled_EventResult. If no matching
+ eventsink is found, kSinkNotFound_EventResult is returned.
+ */
+ static EventResult DoEvent(const SkEvent&, SkEventSinkID targetID);
+
+ /** Returns the matching eventsink, or null if not found
+ */
+ static SkEventSink* FindSink(SkEventSinkID);
+
+protected:
+ /** Override this to handle events in your subclass. Be sure to call the inherited version
+ for events that you don't handle.
+ */
+ virtual bool onEvent(const SkEvent&);
+ virtual bool onQuery(SkEvent*);
+
+ SkTagList* findTagList(U8CPU tag) const;
+ void addTagList(SkTagList*);
+ void removeTagList(U8CPU tag);
+
+private:
+ SkEventSinkID fID;
+ SkTagList* fTagHead;
+
+ // for our private link-list
+ SkEventSink* fNextSink;
+};
+
+#endif
+
diff --git a/include/views/SkImageView.h b/include/views/SkImageView.h
new file mode 100644
index 0000000..57215c9
--- /dev/null
+++ b/include/views/SkImageView.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkImageView_DEFINED
+#define SkImageView_DEFINED
+
+#include "SkView.h"
+#include "SkString.h"
+
+class SkAnimator;
+class SkBitmap;
+class SkMatrix;
+
+class SkImageView : public SkView {
+public:
+ SkImageView();
+ virtual ~SkImageView();
+
+ void getUri(SkString*) const;
+ void setUri(const char []);
+ void setUri(const SkString&);
+
+
+ enum ScaleType {
+ kMatrix_ScaleType,
+ kFitXY_ScaleType,
+ kFitStart_ScaleType,
+ kFitCenter_ScaleType,
+ kFitEnd_ScaleType
+ };
+ ScaleType getScaleType() const { return (ScaleType)fScaleType; }
+ void setScaleType(ScaleType);
+
+ bool getImageMatrix(SkMatrix*) const;
+ void setImageMatrix(const SkMatrix*);
+
+protected:
+ // overrides
+ virtual bool onEvent(const SkEvent&);
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM&, const SkDOMNode*);
+
+private:
+ SkString fUri;
+ SkMatrix* fMatrix; // null or copy of caller's matrix ,,,,,
+ union {
+ SkAnimator* fAnim;
+ SkBitmap* fBitmap;
+ } fData;
+ uint8_t fScaleType;
+ SkBool8 fDataIsAnim; // as opposed to bitmap
+ SkBool8 fUriIsValid;
+
+ void onUriChange();
+ bool getDataBounds(SkRect* bounds);
+ bool freeData();
+ bool ensureUriIsLoaded();
+
+ typedef SkView INHERITED;
+};
+
+#endif
diff --git a/include/views/SkKey.h b/include/views/SkKey.h
new file mode 100644
index 0000000..3fd5114
--- /dev/null
+++ b/include/views/SkKey.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkKey_DEFINED
+#define SkKey_DEFINED
+
+#include "SkTypes.h"
+
+enum SkKey {
+ //reordering these to match android.app.KeyEvent
+ kNONE_SkKey, //corresponds to android's UNKNOWN
+
+ kLeftSoftKey_SkKey,
+ kRightSoftKey_SkKey,
+
+ kHome_SkKey, //!< the home key - added to match android
+ kBack_SkKey, //!< (CLR)
+ kSend_SkKey, //!< the green (talk) key
+ kEnd_SkKey, //!< the red key
+
+ k0_SkKey,
+ k1_SkKey,
+ k2_SkKey,
+ k3_SkKey,
+ k4_SkKey,
+ k5_SkKey,
+ k6_SkKey,
+ k7_SkKey,
+ k8_SkKey,
+ k9_SkKey,
+ kStar_SkKey, //!< the * key
+ kHash_SkKey, //!< the # key
+
+ kUp_SkKey,
+ kDown_SkKey,
+ kLeft_SkKey,
+ kRight_SkKey,
+
+ kOK_SkKey, //!< the center key
+
+ kVolUp_SkKey, //!< volume up - match android
+ kVolDown_SkKey, //!< volume down - same
+ kPower_SkKey, //!< power button - same
+ kCamera_SkKey, //!< camera - same
+
+ kSkKeyCount
+};
+
+#endif
+
diff --git a/include/views/SkOSMenu.h b/include/views/SkOSMenu.h
new file mode 100644
index 0000000..433a601
--- /dev/null
+++ b/include/views/SkOSMenu.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSMenu_DEFINED
+#define SkOSMenu_DEFINED
+
+#include "SkEvent.h"
+#include "SkTDArray.h"
+
+class SkOSMenu {
+public:
+ explicit SkOSMenu(const char title[]);
+ ~SkOSMenu();
+
+ const char* getTitle() const { return fTitle; }
+
+ void appendItem(const char title[], const char eventType[], int32_t eventData);
+
+ // called by SkOSWindow when it receives an OS menu event
+ int countItems() const;
+ const char* getItem(int index, uint32_t* cmdID) const;
+
+ SkEvent* createEvent(uint32_t os_cmd);
+
+private:
+ const char* fTitle;
+
+ struct Item {
+ const char* fTitle;
+ const char* fEventType;
+ uint32_t fEventData;
+ uint32_t fOSCmd; // internal
+ };
+ SkTDArray<Item> fItems;
+
+ // illegal
+ SkOSMenu(const SkOSMenu&);
+ SkOSMenu& operator=(const SkOSMenu&);
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_Android.h b/include/views/SkOSWindow_Android.h
new file mode 100644
index 0000000..38a4cf8
--- /dev/null
+++ b/include/views/SkOSWindow_Android.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 Skia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_Android_DEFINED
+#define SkOSWindow_Android_DEFINED
+
+#include "SkWindow.h"
+#include "SkEvent.h"
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void*) {}
+ ~SkOSWindow() {}
+ bool attachGL() { return false; }
+ void detachGL() {}
+ void presentGL() {}
+
+protected:
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ virtual void onSetTitle(const char title[]);
+
+private:
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_Mac.h b/include/views/SkOSWindow_Mac.h
new file mode 100644
index 0000000..232a202
--- /dev/null
+++ b/include/views/SkOSWindow_Mac.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_Mac_DEFINED
+#define SkOSWindow_Mac_DEFINED
+
+#include <Carbon/Carbon.h>
+#include "SkWindow.h"
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void* hwnd);
+
+ void* getHWND() const { return fHWND; }
+ void* getHVIEW() const { return fHVIEW; }
+ void updateSize();
+
+ static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+ static OSStatus EventHandler(EventHandlerCallRef inHandler,
+ EventRef inEvent, void* userData);
+
+ void doPaint(void* ctx);
+
+
+ bool attachGL();
+ void detachGL();
+ void presentGL();
+
+protected:
+ // overrides from SkEventSink
+ virtual bool onEvent(const SkEvent& evt);
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+ virtual void onSetTitle(const char[]);
+
+
+private:
+ void* fHWND;
+ void* fHVIEW;
+ void* fAGLCtx;
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_SDL.h b/include/views/SkOSWindow_SDL.h
new file mode 100644
index 0000000..0ff24f3
--- /dev/null
+++ b/include/views/SkOSWindow_SDL.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_SDL_DEFINED
+#define SkOSWindow_SDL_DEFINED
+
+#include "SDL.h"
+#include "SkWindow.h"
+
+class SkGLCanvas;
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void* screen);
+ virtual ~SkOSWindow();
+
+ static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+ void handleSDLEvent(const SDL_Event& event);
+
+protected:
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+ virtual void onSetTitle(const char[]);
+
+private:
+ SDL_Surface* fScreen;
+ SDL_Surface* fSurface;
+ SkGLCanvas* fGLCanvas;
+
+ void doDraw();
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_Unix.h b/include/views/SkOSWindow_Unix.h
new file mode 100644
index 0000000..803ca13
--- /dev/null
+++ b/include/views/SkOSWindow_Unix.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_Unix_DEFINED
+#define SkOSWindow_Unix_DEFINED
+
+#include "SkWindow.h"
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+class SkBitmap;
+class SkEvent;
+
+struct SkUnixWindow {
+ Display* fDisplay;
+ Window fWin;
+ size_t fOSWin;
+ GC fGc;
+ GLXContext fGLContext;
+ bool fGLCreated;
+};
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void*);
+ ~SkOSWindow();
+
+ void* getHWND() const { return (void*)fUnixWindow.fWin; }
+ void* getDisplay() const { return (void*)fUnixWindow.fDisplay; }
+ void* getUnixWindow() const { return (void*)&fUnixWindow; }
+ void loop();
+ void post_linuxevent();
+ bool attachGL();
+ void detachGL();
+ void presentGL();
+
+ //static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+ //static bool WndProc(SkUnixWindow* w, XEvent &e);
+
+protected:
+ // overrides from SkWindow
+ virtual bool onEvent(const SkEvent&);
+ virtual void onHandleInval(const SkIRect&);
+ virtual bool onHandleChar(SkUnichar);
+ virtual bool onHandleKey(SkKey);
+ virtual bool onHandleKeyUp(SkKey);
+ virtual void onSetTitle(const char title[]);
+
+private:
+ SkUnixWindow fUnixWindow;
+ bool fGLAttached;
+ bool fRestart;
+
+ // Needed for GL
+ XVisualInfo* fVi;
+
+ void doPaint();
+ void restartLoop();
+ void mapWindowAndWait();
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_Win.h b/include/views/SkOSWindow_Win.h
new file mode 100644
index 0000000..4b3e916
--- /dev/null
+++ b/include/views/SkOSWindow_Win.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkOSWindow_Win_DEFINED
+#define SkOSWindow_Win_DEFINED
+
+#include "SkWindow.h"
+
+class SkOSWindow : public SkWindow {
+public:
+ SkOSWindow(void* hwnd);
+ virtual ~SkOSWindow();
+
+ void* getHWND() const { return fHWND; }
+ void setSize(int width, int height);
+ void updateSize();
+
+ static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
+
+ bool attachGL();
+ void detachGL();
+ void presentGL();
+
+ bool attachD3D9();
+ void detachD3D9();
+ void presentD3D9();
+
+ void* d3d9Device() { return fD3D9Device; }
+
+ bool wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static bool QuitOnDeactivate(HWND hWnd);
+
+ enum {
+ SK_WM_SkEvent = WM_APP + 1000,
+ SK_WM_SkTimerID = 0xFFFF // just need a non-zero value
+ };
+
+protected:
+ virtual bool quitOnDeactivate() { return true; }
+
+ // overrides from SkWindow
+ virtual void onHandleInval(const SkIRect&);
+ // overrides from SkView
+ virtual void onAddMenu(const SkOSMenu*);
+
+ virtual void onSetTitle(const char title[]);
+
+private:
+ void* fHWND;
+
+ void doPaint(void* ctx);
+
+ void* fHGLRC;
+
+ bool fGLAttached;
+
+ void* fD3D9Device;
+ bool fD3D9Attached;
+
+ HMENU fMBar;
+
+ typedef SkWindow INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkOSWindow_wxwidgets.h b/include/views/SkOSWindow_wxwidgets.h
new file mode 100644
index 0000000..c5dfc7c
--- /dev/null
+++ b/include/views/SkOSWindow_wxwidgets.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * SkOSWindow_wxwidgets.h
+ * wxwidgets
+ *
+ * Copyright 2005 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef SkOSWindow_wxwidgets_DEFINED
+#define SkOSWindow_wxwidgets_DEFINED
+
+#include "SkWindow.h"
+#include "wx/frame.h"
+
+class SkOSWindow: public SkWindow
+{
+public:
+ SkOSWindow();
+ SkOSWindow(const wxString& title, int x, int y, int width, int height);
+ ~SkOSWindow();
+
+ wxFrame* getWXFrame() const { return fFrame; }
+
+ void updateSize();
+
+protected:
+ virtual void onHandleInval(const SkIRect&);
+ virtual void onAddMenu(const SkOSMenu*);
+
+private:
+ wxFrame* fFrame;
+ typedef SkWindow INHERITED;
+
+};
+
+#endifpedef SkWindow INHERITED;
diff --git a/include/views/SkProgressBarView.h b/include/views/SkProgressBarView.h
new file mode 100644
index 0000000..6341fcb
--- /dev/null
+++ b/include/views/SkProgressBarView.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkProgressBarView_DEFINED
+#define SkProgressBarView_DEFINED
+
+#include "SkView.h"
+#include "SkWidgetViews.h"
+#include "SkAnimator.h"
+
+class SkProgressBarView : public SkWidgetView {
+ public:
+ SkProgressBarView();
+ //SkProgressBarView(int max);
+
+ //inflate: "sk-progress"
+
+ void reset(); //reset progress to zero
+ void setProgress(int progress);
+ void changeProgress(int diff);
+ void setMax(int max);
+
+ int getProgress() const { return fProgress; }
+ int getMax() const { return fMax; }
+
+ protected:
+ //overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual void onSizeChange();
+ virtual void onDraw(SkCanvas* canvas);
+ virtual bool onEvent(const SkEvent& evt);
+
+ private:
+ SkAnimator fAnim;
+ int fProgress;
+ int fMax;
+
+ typedef SkWidgetView INHERITED;
+};
+
+
+
+
+#endif
diff --git a/include/views/SkScrollBarView.h b/include/views/SkScrollBarView.h
new file mode 100644
index 0000000..b8a5209
--- /dev/null
+++ b/include/views/SkScrollBarView.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkScrollBarView_DEFINED
+#define SkScrollBarView_DEFINED
+
+#include "SkView.h"
+#include "SkWidgetViews.h"
+#include "SkAnimator.h"
+
+class SkScrollBarView : public SkWidgetView {
+public:
+ SkScrollBarView();
+
+ unsigned getStart() const { return fStartPoint; }
+ unsigned getShown() const { return fShownLength; }
+ unsigned getTotal() const { return fTotalLength; }
+
+ void setStart(unsigned start);
+ void setShown(unsigned shown);
+ void setTotal(unsigned total);
+
+protected:
+ //overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual void onSizeChange();
+ virtual void onDraw(SkCanvas* canvas);
+ virtual bool onEvent(const SkEvent& evt);
+
+private:
+ SkAnimator fAnim;
+ unsigned fTotalLength, fStartPoint, fShownLength;
+
+ void adjust();
+
+ typedef SkWidgetView INHERITED;
+};
+#endif
+
diff --git a/include/views/SkStackViewLayout.h b/include/views/SkStackViewLayout.h
new file mode 100644
index 0000000..8000319
--- /dev/null
+++ b/include/views/SkStackViewLayout.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkStackViewLayout_DEFINED
+#define SkStackViewLayout_DEFINED
+
+#include "SkView.h"
+
+class SkStackViewLayout : public SkView::Layout {
+public:
+ SkStackViewLayout();
+
+ enum Orient {
+ kHorizontal_Orient,
+ kVertical_Orient,
+
+ kOrientCount
+ };
+ Orient getOrient() const { return (Orient)fOrient; }
+ void setOrient(Orient);
+
+ void getMargin(SkRect*) const;
+ void setMargin(const SkRect&);
+
+ SkScalar getSpacer() const { return fSpacer; }
+ void setSpacer(SkScalar);
+
+ /** Controls the posititioning in the same direction as the orientation
+ */
+ enum Pack {
+ kStart_Pack,
+ kCenter_Pack,
+ kEnd_Pack,
+
+ kPackCount
+ };
+ Pack getPack() const { return (Pack)fPack; }
+ void setPack(Pack);
+
+ /** Controls the posititioning at right angles to the orientation
+ */
+ enum Align {
+ kStart_Align,
+ kCenter_Align,
+ kEnd_Align,
+ kStretch_Align,
+
+ kAlignCount
+ };
+ Align getAlign() const { return (Align)fAlign; }
+ void setAlign(Align);
+
+ bool getRound() const { return SkToBool(fRound); }
+ void setRound(bool);
+
+protected:
+ virtual void onLayoutChildren(SkView* parent);
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+
+private:
+ SkRect fMargin;
+ SkScalar fSpacer;
+ uint8_t fOrient, fPack, fAlign, fRound;
+};
+
+class SkFillViewLayout : public SkView::Layout {
+public:
+ SkFillViewLayout();
+ void getMargin(SkRect*) const;
+ void setMargin(const SkRect&);
+
+protected:
+ // overrides;
+ virtual void onLayoutChildren(SkView* parent);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkRect fMargin;
+ typedef SkView::Layout INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkSystemEventTypes.h b/include/views/SkSystemEventTypes.h
new file mode 100644
index 0000000..8dfe8be
--- /dev/null
+++ b/include/views/SkSystemEventTypes.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkSystemEventTypes_DEFINED
+#define SkSystemEventTypes_DEFINED
+
+/*
+ The goal of these strings is two-fold:
+ 1) make funny strings (containing at least one char < 32) to avoid colliding with "user" strings
+ 2) keep them <= 4 bytes, so we can avoid an allocation in SkEvent::setType()
+*/
+#define SK_EventType_Delay "\xd" "lay"
+#define SK_EventType_Inval "nv" "\xa" "l"
+#define SK_EventType_Key "key" "\x1"
+#define SK_EventType_OnEnd "on" "\xe" "n"
+#define SK_EventType_Unichar "\xc" "har"
+#define SK_EventType_KeyUp "key" "\xf"
+
+#endif
diff --git a/include/views/SkTouchGesture.h b/include/views/SkTouchGesture.h
new file mode 100644
index 0000000..79d4e28
--- /dev/null
+++ b/include/views/SkTouchGesture.h
@@ -0,0 +1,72 @@
+#ifndef SkTouchGesture_DEFINED
+#define SkTouchGesture_DEFINED
+
+#include "SkTDArray.h"
+#include "SkMatrix.h"
+
+struct SkFlingState {
+ SkFlingState() : fActive(false) {}
+
+ bool isActive() const { return fActive; }
+ void stop() { fActive = false; }
+
+ void reset(float sx, float sy);
+ bool evaluateMatrix(SkMatrix* matrix);
+
+private:
+ SkPoint fDirection;
+ SkScalar fSpeed0;
+ double fTime0;
+ bool fActive;
+};
+
+class SkTouchGesture {
+public:
+ SkTouchGesture();
+ ~SkTouchGesture();
+
+ void touchBegin(void* owner, float x, float y);
+ void touchMoved(void* owner, float x, float y);
+ void touchEnd(void* owner);
+ void reset();
+
+ bool isActive() { return fFlinger.isActive(); }
+ void stop() { fFlinger.stop(); }
+
+ const SkMatrix& localM();
+ const SkMatrix& globalM() const { return fGlobalM; }
+
+private:
+ enum State {
+ kEmpty_State,
+ kTranslate_State,
+ kZoom_State,
+ };
+
+ struct Rec {
+ void* fOwner;
+ float fStartX, fStartY;
+ float fPrevX, fPrevY;
+ float fLastX, fLastY;
+ SkMSec fPrevT, fLastT;
+ };
+ SkTDArray<Rec> fTouches;
+
+ State fState;
+ SkMatrix fLocalM, fGlobalM;
+ SkFlingState fFlinger;
+ SkMSec fLastUpT;
+ SkPoint fLastUpP;
+
+
+ void flushLocalM();
+ int findRec(void* owner) const;
+ void appendNewRec(void* owner, float x, float y);
+ float computePinch(const Rec&, const Rec&);
+ float limitTotalZoom(float scale) const;
+ bool handleDblTap(float, float);
+};
+
+#endif
+
+
diff --git a/include/views/SkView.h b/include/views/SkView.h
new file mode 100644
index 0000000..d3633db
--- /dev/null
+++ b/include/views/SkView.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkView_DEFINED
+#define SkView_DEFINED
+
+#include "SkEventSink.h"
+#include "SkRect.h"
+#include "SkDOM.h"
+#include "SkTDict.h"
+
+class SkCanvas;
+class SkLayerView;
+
+/** \class SkView
+
+ SkView is the base class for screen management. All widgets and controls inherit
+ from SkView.
+*/
+class SkView : public SkEventSink {
+public:
+ enum Flag_Shift {
+ kVisible_Shift,
+ kEnabled_Shift,
+ kFocusable_Shift,
+ kFlexH_Shift,
+ kFlexV_Shift,
+ kNoClip_Shift,
+
+ kFlagShiftCount
+ };
+ enum Flag_Mask {
+ kVisible_Mask = 1 << kVisible_Shift, //!< set if the view is visible
+ kEnabled_Mask = 1 << kEnabled_Shift, //!< set if the view is enabled
+ kFocusable_Mask = 1 << kFocusable_Shift, //!< set if the view can receive focus
+ kFlexH_Mask = 1 << kFlexH_Shift, //!< set if the view's width is stretchable
+ kFlexV_Mask = 1 << kFlexV_Shift, //!< set if the view's height is stretchable
+ kNoClip_Mask = 1 << kNoClip_Shift, //!< set if the view is not clipped to its bounds
+
+ kAllFlagMasks = (uint32_t)(0 - 1) >> (32 - kFlagShiftCount)
+ };
+
+ SkView(uint32_t flags = 0);
+ virtual ~SkView();
+
+ /** Return the flags associated with the view
+ */
+ uint32_t getFlags() const { return fFlags; }
+ /** Set the flags associated with the view
+ */
+ void setFlags(uint32_t flags);
+
+ /** Helper that returns non-zero if the kVisible_Mask bit is set in the view's flags
+ */
+ int isVisible() const { return fFlags & kVisible_Mask; }
+ int isEnabled() const { return fFlags & kEnabled_Mask; }
+ int isFocusable() const { return fFlags & kFocusable_Mask; }
+ int isClipToBounds() const { return !(fFlags & kNoClip_Mask); }
+ /** Helper to set/clear the view's kVisible_Mask flag */
+ void setVisibleP(bool);
+ void setEnabledP(bool);
+ void setFocusableP(bool);
+ void setClipToBounds(bool);
+
+ /** Return the view's width */
+ SkScalar width() const { return fWidth; }
+ /** Return the view's height */
+ SkScalar height() const { return fHeight; }
+ /** Set the view's width and height. These must both be >= 0. This does not affect the view's loc */
+ void setSize(SkScalar width, SkScalar height);
+ void setSize(const SkPoint& size) { this->setSize(size.fX, size.fY); }
+ void setWidth(SkScalar width) { this->setSize(width, fHeight); }
+ void setHeight(SkScalar height) { this->setSize(fWidth, height); }
+ /** Return a rectangle set to [0, 0, width, height] */
+ void getLocalBounds(SkRect* bounds) const;
+
+ /** Return the view's left edge */
+ SkScalar locX() const { return fLoc.fX; }
+ /** Return the view's top edge */
+ SkScalar locY() const { return fLoc.fY; }
+ /** Set the view's left and top edge. This does not affect the view's size */
+ void setLoc(SkScalar x, SkScalar y);
+ void setLoc(const SkPoint& loc) { this->setLoc(loc.fX, loc.fY); }
+ void setLocX(SkScalar x) { this->setLoc(x, fLoc.fY); }
+ void setLocY(SkScalar y) { this->setLoc(fLoc.fX, y); }
+ /** Offset (move) the view by the specified dx and dy. This does not affect the view's size */
+ void offset(SkScalar dx, SkScalar dy);
+
+ /** Call this to have the view draw into the specified canvas. */
+ virtual void draw(SkCanvas* canvas);
+
+ /** Call this to invalidate part of all of a view, requesting that the view's
+ draw method be called. The rectangle parameter specifies the part of the view
+ that should be redrawn. If it is null, it specifies the entire view bounds.
+ */
+ void inval(SkRect* rectOrNull);
+
+ // Focus management
+
+ SkView* getFocusView() const;
+ bool hasFocus() const;
+
+ enum FocusDirection {
+ kNext_FocusDirection,
+ kPrev_FocusDirection,
+
+ kFocusDirectionCount
+ };
+ bool acceptFocus();
+ SkView* moveFocus(FocusDirection);
+
+ // Click handling
+
+ class Click {
+ public:
+ Click(SkView* target);
+ virtual ~Click();
+
+ const char* getType() const { return fType; }
+ bool isType(const char type[]) const;
+ void setType(const char type[]); // does NOT make a copy of the string
+ void copyType(const char type[]); // makes a copy of the string
+
+ enum State {
+ kDown_State,
+ kMoved_State,
+ kUp_State
+ };
+ SkPoint fOrig, fPrev, fCurr;
+ SkIPoint fIOrig, fIPrev, fICurr;
+ State fState;
+ private:
+ SkEventSinkID fTargetID;
+ char* fType;
+ bool fWeOwnTheType;
+
+ void resetType();
+
+ friend class SkView;
+ };
+ Click* findClickHandler(SkScalar x, SkScalar y);
+
+ static void DoClickDown(Click*, int x, int y);
+ static void DoClickMoved(Click*, int x, int y);
+ static void DoClickUp(Click*, int x, int y);
+
+ /** Send the event to the view's parent, and its parent etc. until one of them
+ returns true from its onEvent call. This view is returned. If no parent handles
+ the event, null is returned.
+ */
+ SkView* sendEventToParents(const SkEvent&);
+ /** Send the query to the view's parent, and its parent etc. until one of them
+ returns true from its onQuery call. This view is returned. If no parent handles
+ the query, null is returned.
+ */
+ SkView* sendQueryToParents(SkEvent*);
+
+ /** Depricated helper function. Just call event->post(sinkID, delay);
+ */
+ bool postEvent(SkEvent* evt, SkEventSinkID sinkID, SkMSec delay) { return evt->post(sinkID, delay); }
+
+ // View hierarchy management
+
+ /** Return the view's parent, or null if it has none. This does not affect the parent's reference count. */
+ SkView* getParent() const { return fParent; }
+ SkView* attachChildToFront(SkView* child);
+ /** Attach the child view to this view, and increment the child's reference count. The child view is added
+ such that it will be drawn before all other child views.
+ The child view parameter is returned.
+ */
+ SkView* attachChildToBack(SkView* child);
+ /** If the view has a parent, detach the view from its parent and decrement the view's reference count.
+ If the parent was the only owner of the view, this will cause the view to be deleted.
+ */
+ void detachFromParent();
+ /** Attach the child view to this view, and increment the child's reference count. The child view is added
+ such that it will be drawn after all other child views.
+ The child view parameter is returned.
+ */
+ /** Detach all child views from this view. */
+ void detachAllChildren();
+
+ /** Convert the specified point from global coordinates into view-local coordinates
+ */
+ void globalToLocal(SkPoint* pt) const { if (pt) this->globalToLocal(pt->fX, pt->fY, pt); }
+ /** Convert the specified x,y from global coordinates into view-local coordinates, returning
+ the answer in the local parameter.
+ */
+ void globalToLocal(SkScalar globalX, SkScalar globalY, SkPoint* local) const;
+
+ /** \class F2BIter
+
+ Iterator that will return each of this view's children, in
+ front-to-back order (the order used for clicking). The first
+ call to next() returns the front-most child view. When
+ next() returns null, there are no more child views.
+ */
+ class F2BIter {
+ public:
+ F2BIter(const SkView* parent);
+ SkView* next();
+ private:
+ SkView* fFirstChild, *fChild;
+ };
+
+ /** \class B2FIter
+
+ Iterator that will return each of this view's children, in
+ back-to-front order (the order they are drawn). The first
+ call to next() returns the back-most child view. When
+ next() returns null, there are no more child views.
+ */
+ class B2FIter {
+ public:
+ B2FIter(const SkView* parent);
+ SkView* next();
+ private:
+ SkView* fFirstChild, *fChild;
+ };
+
+ /** \class Artist
+
+ Install a subclass of this in a view (calling setArtist()), and then the
+ default implementation of that view's onDraw() will invoke this object
+ automatically.
+ */
+ class Artist : public SkRefCnt {
+ public:
+ void draw(SkView*, SkCanvas*);
+ void inflate(const SkDOM&, const SkDOM::Node*);
+ protected:
+ virtual void onDraw(SkView*, SkCanvas*) = 0;
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+ };
+ /** Return the artist attached to this view (or null). The artist's reference
+ count is not affected.
+ */
+ Artist* getArtist() const;
+ /** Attach the specified artist (or null) to the view, replacing any existing
+ artist. If the new artist is not null, its reference count is incremented.
+ The artist parameter is returned.
+ */
+ Artist* setArtist(Artist* artist);
+
+ /** \class Layout
+
+ Install a subclass of this in a view (calling setLayout()), and then the
+ default implementation of that view's onLayoutChildren() will invoke
+ this object automatically.
+ */
+ class Layout : public SkRefCnt {
+ public:
+ void layoutChildren(SkView* parent);
+ void inflate(const SkDOM&, const SkDOM::Node*);
+ protected:
+ virtual void onLayoutChildren(SkView* parent) = 0;
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+ };
+
+ /** Return the layout attached to this view (or null). The layout's reference
+ count is not affected.
+ */
+ Layout* getLayout() const;
+ /** Attach the specified layout (or null) to the view, replacing any existing
+ layout. If the new layout is not null, its reference count is incremented.
+ The layout parameter is returned.
+ */
+ Layout* setLayout(Layout*, bool invokeLayoutNow = true);
+ /** If a layout is attached to this view, call its layoutChildren() method
+ */
+ void invokeLayout();
+
+ /** Call this to initialize this view based on the specified XML node
+ */
+ void inflate(const SkDOM& dom, const SkDOM::Node* node);
+ /** After a view hierarchy is inflated, this may be called with a dictionary
+ containing pairs of <name, view*>, where the name string was the view's
+ "id" attribute when it was inflated.
+
+ This will call the virtual onPostInflate for this view, and the recursively
+ call postInflate on all of the view's children.
+ */
+ void postInflate(const SkTDict<SkView*>& ids);
+
+ SkDEBUGCODE(void dump(bool recurse) const;)
+
+protected:
+ /** Override this to draw inside the view. Be sure to call the inherited version too */
+ virtual void onDraw(SkCanvas*);
+ /** Override this to be notified when the view's size changes. Be sure to call the inherited version too */
+ virtual void onSizeChange();
+ /** Override this if you want to handle an inval request from this view or one of its children.
+ Tyically this is only overridden by the by the "window". If your subclass does handle the
+ request, return true so the request will not continue to propogate to the parent.
+ */
+ virtual bool handleInval(const SkRect*);
+ //! called once before all of the children are drawn (or clipped/translated)
+ virtual SkCanvas* beforeChildren(SkCanvas* c) { return c; }
+ //! called once after all of the children are drawn (or clipped/translated)
+ virtual void afterChildren(SkCanvas* orig) {}
+
+ //! called right before this child's onDraw is called
+ virtual void beforeChild(SkView* child, SkCanvas* canvas) {}
+ //! called right after this child's onDraw is called
+ virtual void afterChild(SkView* child, SkCanvas* canvas) {}
+
+ /** Override this if you might handle the click
+ */
+ virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
+ /** Override this to decide if your children are targets for a click.
+ The default returns true, in which case your children views will be
+ candidates for onFindClickHandler. Returning false wil skip the children
+ and just call your onFindClickHandler.
+ */
+ virtual bool onSendClickToChildren(SkScalar x, SkScalar y);
+ /** Override this to track clicks, returning true as long as you want to track
+ the pen/mouse.
+ */
+ virtual bool onClick(Click*);
+ /** Override this to initialize your subclass from the XML node. Be sure to call the inherited version too */
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ /** Override this if you want to perform post initialization work based on the ID dictionary built
+ during XML parsing. Be sure to call the inherited version too.
+ */
+ virtual void onPostInflate(const SkTDict<SkView*>&);
+
+public:
+ // default action is to inval the view
+ virtual void onFocusChange(bool gainFocusP);
+protected:
+
+ // override these if you're acting as a layer/host
+ virtual bool onGetFocusView(SkView**) const { return false; }
+ virtual bool onSetFocusView(SkView*) { return false; }
+
+private:
+ SkScalar fWidth, fHeight;
+ SkPoint fLoc;
+ SkView* fParent;
+ SkView* fFirstChild;
+ SkView* fNextSibling;
+ SkView* fPrevSibling;
+ uint8_t fFlags;
+ uint8_t fContainsFocus;
+
+ friend class B2FIter;
+ friend class F2BIter;
+
+ friend class SkLayerView;
+
+ bool setFocusView(SkView* fvOrNull);
+ SkView* acceptFocus(FocusDirection);
+ void detachFromParent_NoLayout();
+};
+
+#endif
+
diff --git a/include/views/SkViewInflate.h b/include/views/SkViewInflate.h
new file mode 100644
index 0000000..3ec65a6
--- /dev/null
+++ b/include/views/SkViewInflate.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkViewInflate_DEFINED
+#define SkViewInflate_DEFINED
+
+#include "SkDOM.h"
+#include "SkTDict.h"
+#include "SkEvent.h"
+
+class SkView;
+
+class SkViewInflate {
+public:
+ SkViewInflate();
+ virtual ~SkViewInflate();
+
+ /** Return the tree of inflated views. If root is null, create the root element
+ as a view, otherwise assume root is that view, and just "inflate" it.
+
+ Returns null if the tree cannot be built.
+ */
+ SkView* inflate(const SkDOM& dom, const SkDOM::Node* node, SkView* root = NULL);
+ SkView* inflate(const char xml[], size_t len, SkView* root = NULL);
+
+ /** Given an id attribute value, return the corresponding view, or null
+ if no match is found.
+ */
+ SkView* findViewByID(const char id[]) const;
+
+ SkDEBUGCODE(void dump() const;)
+
+protected:
+ /* Override this in your subclass to handle instantiating views
+ Call the inherited version for nodes you don't recognize.
+
+ Do not call "inflate" on the view, just return it. This will
+ get called automatically after createView returns.
+ */
+ virtual SkView* createView(const SkDOM& dom, const SkDOM::Node* node);
+ /** Base implementation calls view->inflate(dom, node). Subclasses may override this
+ to perform additional initializations to view, either before or after calling
+ the inherited version.
+ */
+ virtual void inflateView(SkView* view, const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ enum {
+ kMinIDStrAlloc = 64
+ };
+ SkTDict<SkView*> fIDs;
+
+ struct IDStr {
+ SkView* fView;
+ char* fStr;
+ };
+ SkTDArray<IDStr> fListenTo, fBroadcastTo;
+ SkChunkAlloc fStrings;
+
+ void addIDStr(SkTDArray<IDStr>* list, SkView*, const char* str);
+
+ void rInflate(const SkDOM& dom, const SkDOM::Node* node, SkView* parent);
+};
+
+#endif
+
diff --git a/include/views/SkWidget.h b/include/views/SkWidget.h
new file mode 100644
index 0000000..db85f01
--- /dev/null
+++ b/include/views/SkWidget.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkWidget_DEFINED
+#define SkWidget_DEFINED
+
+#include "SkView.h"
+#include "SkBitmap.h"
+#include "SkDOM.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkTDArray.h"
+
+//////////////////////////////////////////////////////////////////////////////
+
+class SkWidget : public SkView {
+public:
+ SkWidget(uint32_t flags = 0) : SkView(flags | kFocusable_Mask | kEnabled_Mask) {}
+
+ /** Call this to post the widget's event to its listeners */
+ void postWidgetEvent();
+
+ static void Init();
+ static void Term();
+protected:
+ // override to add slots to an event before posting
+ virtual void prepareWidgetEvent(SkEvent*);
+ virtual void onEnabledChange();
+
+ // <event ...> to initialize the event from XML
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkEvent fEvent;
+ typedef SkView INHERITED;
+};
+
+class SkHasLabelWidget : public SkWidget {
+public:
+ SkHasLabelWidget(uint32_t flags = 0) : SkWidget(flags) {}
+
+ size_t getLabel(SkString* label = NULL) const;
+ size_t getLabel(char lable[] = NULL) const;
+ void setLabel(const SkString&);
+ void setLabel(const char label[]);
+ void setLabel(const char label[], size_t len);
+
+protected:
+ // called when the label changes
+ virtual void onLabelChange();
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkString fLabel;
+ typedef SkWidget INHERITED;
+};
+
+class SkButtonWidget : public SkHasLabelWidget {
+public:
+ SkButtonWidget(uint32_t flags = 0) : SkHasLabelWidget(flags), fState(kOff_State) {}
+
+ enum State {
+ kOff_State, //!< XML: buttonState="off"
+ kOn_State, //!< XML: buttonState="on"
+ kUnknown_State //!< XML: buttonState="unknown"
+ };
+ State getButtonState() const { return fState; }
+ void setButtonState(State);
+
+protected:
+ /** called when the label changes. default behavior is to inval the widget */
+ virtual void onButtonStateChange();
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ State fState;
+ typedef SkHasLabelWidget INHERITED;
+};
+
+class SkPushButtonWidget : public SkButtonWidget {
+public:
+ SkPushButtonWidget(uint32_t flags = 0) : SkButtonWidget(flags) {}
+
+protected:
+ virtual bool onEvent(const SkEvent&);
+ virtual void onDraw(SkCanvas*);
+ virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
+ virtual bool onClick(Click* click);
+
+private:
+ typedef SkButtonWidget INHERITED;
+};
+
+class SkCheckBoxWidget : public SkButtonWidget {
+public:
+ SkCheckBoxWidget(uint32_t flags = 0);
+
+protected:
+ virtual bool onEvent(const SkEvent&);
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ typedef SkButtonWidget INHERITED;
+};
+
+#include "SkTextBox.h"
+
+class SkStaticTextView : public SkView {
+public:
+ SkStaticTextView(uint32_t flags = 0);
+ virtual ~SkStaticTextView();
+
+ enum Mode {
+ kFixedSize_Mode,
+ kAutoWidth_Mode,
+ kAutoHeight_Mode,
+
+ kModeCount
+ };
+ Mode getMode() const { return (Mode)fMode; }
+ void setMode(Mode);
+
+ SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
+ void setSpacingAlign(SkTextBox::SpacingAlign);
+
+ void getMargin(SkPoint* margin) const;
+ void setMargin(SkScalar dx, SkScalar dy);
+
+ size_t getText(SkString* text = NULL) const;
+ size_t getText(char text[] = NULL) const;
+ void setText(const SkString&);
+ void setText(const char text[]);
+ void setText(const char text[], size_t len);
+
+ void getPaint(SkPaint*) const;
+ void setPaint(const SkPaint&);
+
+protected:
+ // overrides
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkPoint fMargin;
+ SkString fText;
+ SkPaint fPaint;
+ uint8_t fMode;
+ uint8_t fSpacingAlign;
+
+ void computeSize();
+
+ typedef SkView INHERITED;
+};
+
+class SkBitmapView : public SkView {
+public:
+ SkBitmapView(uint32_t flags = 0);
+ virtual ~SkBitmapView();
+
+ bool getBitmap(SkBitmap*) const;
+ void setBitmap(const SkBitmap*, bool viewOwnsPixels);
+ bool loadBitmapFromFile(const char path[]);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM&, const SkDOM::Node*);
+
+private:
+ SkBitmap fBitmap;
+ typedef SkView INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class SkShader;
+class SkInterpolator;
+
+class SkWidgetView : public SkView {
+public:
+ SkWidgetView(uint32_t flags = 0);
+ virtual ~SkWidgetView();
+
+ static const char* GetEventType();
+};
+
+class SkSliderView : public SkWidgetView {
+public:
+ SkSliderView(uint32_t flags = 0);
+
+ uint16_t getValue() const { return fValue; }
+ uint16_t getMax() const { return fMax; }
+
+ void setMax(U16CPU max);
+ void setValue(U16CPU value);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
+ virtual bool onClick(Click*);
+
+private:
+ uint16_t fValue, fMax;
+
+ typedef SkWidgetView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+class SkHasLabelView : public SkView {
+public:
+ void getLabel(SkString*) const;
+ void setLabel(const SkString&);
+ void setLabel(const char label[]);
+
+protected:
+ SkString fLabel;
+
+ // called when the label changes
+ virtual void onLabelChange();
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+};
+
+class SkPushButtonView : public SkHasLabelView {
+public:
+ SkPushButtonView(uint32_t flags = 0);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+};
+
+class SkCheckBoxView : public SkHasLabelView {
+public:
+ SkCheckBoxView(uint32_t flags = 0);
+
+ enum State {
+ kOff_State,
+ kOn_State,
+ kMaybe_State
+ };
+ State getState() const { return fState; }
+ void setState(State);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ State fState;
+};
+
+class SkProgressView : public SkView {
+public:
+ SkProgressView(uint32_t flags = 0);
+ virtual ~SkProgressView();
+
+ uint16_t getValue() const { return fValue; }
+ uint16_t getMax() const { return fMax; }
+
+ void setMax(U16CPU max);
+ void setValue(U16CPU value);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ uint16_t fValue, fMax;
+ SkShader* fOnShader, *fOffShader;
+ SkInterpolator* fInterp;
+ bool fDoInterp;
+
+ typedef SkView INHERITED;
+};
+
+class SkTextView : public SkView {
+public:
+ SkTextView(uint32_t flags = 0);
+ virtual ~SkTextView();
+
+ enum AnimaDir {
+ kNeutral_AnimDir,
+ kForward_AnimDir,
+ kBackward_AnimDir,
+ kAnimDirCount
+ };
+
+ void getText(SkString*) const;
+ void setText(const SkString&, AnimaDir dir = kNeutral_AnimDir);
+ void setText(const char text[], AnimaDir dir = kNeutral_AnimDir);
+ void setText(const char text[], size_t len, AnimaDir dir = kNeutral_AnimDir);
+
+ void getMargin(SkPoint* margin) const;
+ void setMargin(const SkPoint&);
+
+ SkPaint& paint() { return fPaint; }
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkString fText;
+ SkPaint fPaint;
+ SkPoint fMargin;
+
+ class Interp;
+ Interp* fInterp;
+ bool fDoInterp;
+ // called by the other setText methods. This guy does not check for !=
+ // before doing the assign, so the caller must check for us
+ void privSetText(const SkString&, AnimaDir dir);
+
+ typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////
+
+class SkEvent;
+
+class SkListSource : public SkEventSink {
+public:
+ virtual int countRows() = 0;
+ virtual void getRow(int index, SkString* left, SkString* right) = 0;
+ virtual SkEvent* getEvent(int index);
+
+ static SkListSource* CreateFromDir(const char path[], const char suffix[],
+ const char targetPrefix[]);
+ static SkListSource* CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node);
+};
+
+class SkListView : public SkWidgetView {
+public:
+ SkListView(uint32_t flags = 0);
+ virtual ~SkListView();
+
+ SkScalar getRowHeight() const { return fRowHeight; }
+ void setRowHeight(SkScalar);
+
+ /** Return the index of the selected row, or -1 if none
+ */
+ int getSelection() const { return fCurrIndex; }
+ /** Set the index of the selected row, or -1 for none
+ */
+ void setSelection(int);
+
+ void moveSelectionUp();
+ void moveSelectionDown();
+
+ enum Attr {
+ kBG_Attr,
+ kNormalText_Attr,
+ kHiliteText_Attr,
+ kHiliteCell_Attr,
+ kAttrCount
+ };
+ SkPaint& paint(Attr);
+
+ SkListSource* getListSource() const { return fSource; }
+ SkListSource* setListSource(SkListSource*);
+
+#if 0
+ enum Action {
+ kSelectionChange_Action,
+ kSelectionPicked_Action,
+ kActionCount
+ };
+ /** If event is not null, it is retained by the view, and a copy
+ of the event will be posted to its listeners when the specified
+ action occurs. If event is null, then no event will be posted for
+ the specified action.
+ */
+ void setActionEvent(Action, SkEvent* event);
+#endif
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onSizeChange();
+ virtual bool onEvent(const SkEvent&);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkPaint fPaint[kAttrCount];
+ SkListSource* fSource;
+ SkScalar fRowHeight;
+ int fCurrIndex; // logical index
+ int fScrollIndex; // logical index of top-most visible row
+ int fVisibleRowCount;
+ SkString* fStrCache;
+
+ void dirtyStrCache();
+ void ensureStrCache(int visibleCount);
+
+ int logicalToVisualIndex(int index) const { return index - fScrollIndex; }
+ void invalSelection();
+ bool getRowRect(int index, SkRect*) const;
+ void ensureSelectionIsVisible();
+
+ typedef SkWidgetView INHERITED;
+};
+
+//////////////////////////////////////////////////////////
+
+class SkGridView : public SkWidgetView {
+public:
+ SkGridView(uint32_t flags = 0);
+ virtual ~SkGridView();
+
+ void getCellSize(SkPoint*) const;
+ void setCellSize(SkScalar x, SkScalar y);
+
+ /** Return the index of the selected item, or -1 if none
+ */
+ int getSelection() const { return fCurrIndex; }
+ /** Set the index of the selected row, or -1 for none
+ */
+ void setSelection(int);
+
+ void moveSelectionUp();
+ void moveSelectionDown();
+
+ enum Attr {
+ kBG_Attr,
+ kHiliteCell_Attr,
+ kAttrCount
+ };
+ SkPaint& paint(Attr);
+
+ SkListSource* getListSource() const { return fSource; }
+ SkListSource* setListSource(SkListSource*);
+
+protected:
+ virtual void onDraw(SkCanvas*);
+ virtual void onSizeChange();
+ virtual bool onEvent(const SkEvent&);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+
+private:
+ SkView* fScrollBar;
+ SkPaint fPaint[kAttrCount];
+ SkListSource* fSource;
+ int fCurrIndex; // logical index
+
+ SkPoint fCellSize;
+ SkIPoint fVisibleCount;
+
+ int logicalToVisualIndex(int index) const { return index; }
+ void invalSelection();
+ bool getCellRect(int index, SkRect*) const;
+ void ensureSelectionIsVisible();
+
+ typedef SkWidgetView INHERITED;
+};
+
+#endif
+
diff --git a/include/views/SkWidgetViews.h b/include/views/SkWidgetViews.h
new file mode 100644
index 0000000..9b3a816
--- /dev/null
+++ b/include/views/SkWidgetViews.h
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkWidgetViews_DEFINED
+#define SkWidgetViews_DEFINED
+
+#include "SkView.h"
+
+
+enum SkWidgetEnum {
+ kBorder_WidgetEnum, //!< <sk-border>
+ kButton_WidgetEnum, //!< <sk-button>
+ kImage_WidgetEnum, //!< <sk-image>
+ kList_WidgetEnum, //!< <sk-list>
+ kProgress_WidgetEnum, //!< <sk-progress>
+ kScroll_WidgetEnum, //!< <sk-scroll>
+ kText_WidgetEnum, //!< <sk-text>
+
+ kWidgetEnumCount
+};
+
+//determines which skin to use
+enum SkinEnum {
+ kBorder_SkinEnum,
+ kButton_SkinEnum,
+ kProgress_SkinEnum,
+ kScroll_SkinEnum,
+ kStaticText_SkinEnum,
+
+ kSkinEnumCount
+};
+
+#include "SkAnimator.h"
+//used for inflates
+const char* get_skin_enum_path(SkinEnum se);
+void init_skin_anim(const char path[], SkAnimator* anim);
+void init_skin_anim(SkinEnum se, SkAnimator* anim);
+void init_skin_paint(SkinEnum se, SkPaint* paint);
+void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint);
+
+/** Given an enum value, return an instance of the specified widget.
+ If the enum is out of range, returns null
+*/
+SkView* SkWidgetFactory(SkWidgetEnum);
+/** Given the inflate/element name of a widget, return an instance of
+ the specified widget, or null if name does not match any known
+ widget type.
+*/
+SkView* SkWidgetFactory(const char name[]);
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkWidgetView : public SkView {
+public:
+ SkWidgetView();
+
+ const char* getLabel() const;
+ void getLabel(SkString* label) const;
+
+ void setLabel(const char[]);
+ void setLabel(const char[], size_t len);
+ void setLabel(const SkString&);
+
+ SkEvent& event() { return fEvent; }
+ const SkEvent& event() const { return fEvent; }
+
+ /** Returns true if the widget can post its event to its listeners.
+ */
+ bool postWidgetEvent();
+
+ /** Returns the sinkID of the widgetview that posted the event, or 0
+ */
+ static SkEventSinkID GetWidgetEventSinkID(const SkEvent&);
+
+protected:
+ /** called when the label changes. override in subclasses. default action invals the view's bounds.
+ called with the old and new labels, before the label has actually changed.
+ */
+ virtual void onLabelChange(const char oldLabel[], const char newLabel[]);
+ /** called before posting the event to our listeners. Override to add slots to the event
+ before posting. Return true to proceed with posting, or false to not post the event to any
+ listener. Note: the event passed in may not be the same as calling this->event().
+ Be sure to call your INHERITED method as well, so that all classes in the hierarchy get a shot
+ at modifying the event (and possibly returning false to abort).
+ */
+ virtual bool onPrepareWidgetEvent(SkEvent* evt);
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkString fLabel;
+ SkEvent fEvent;
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkButtonView : public SkWidgetView {
+public:
+ // inflate: "sk-button"
+
+protected:
+ // overrides
+ virtual bool onEvent(const SkEvent&);
+private:
+ typedef SkWidgetView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkCheckButtonView : public SkWidgetView {
+public:
+ SkCheckButtonView();
+
+ // inflate: "sk-checkbutton"
+
+ enum CheckState {
+ kOff_CheckState, //!< inflate: check-state="off"
+ kOn_CheckState, //!< inflate: check-state="on"
+ kUnknown_CheckState //!< inflate: check-state="unknown"
+ };
+ CheckState getCheckState() const { return (CheckState)fCheckState; }
+ void setCheckState(CheckState);
+
+ /** use this to extract the CheckState from an event (i.e. one that as posted
+ by a SkCheckButtonView). Returns true if the proper slot was present in the event,
+ and sets state to that value. If no proper slot is found, returns false and does not
+ modify state.
+ */
+ static bool GetWidgetEventCheckState(const SkEvent&, CheckState* state);
+
+protected:
+ // called when the check-state is about to change, but before it actually has
+ virtual void onCheckStateChange(CheckState oldState, CheckState newState);
+
+ // overrides
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+ virtual bool onPrepareWidgetEvent(SkEvent* evt);
+
+private:
+ uint8_t fCheckState;
+
+ typedef SkWidgetView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkTextBox.h"
+
+class SkStaticTextView : public SkView {
+public:
+ SkStaticTextView();
+ virtual ~SkStaticTextView();
+
+ enum Mode {
+ kFixedSize_Mode,
+ kAutoWidth_Mode,
+ kAutoHeight_Mode,
+
+ kModeCount
+ };
+ Mode getMode() const { return (Mode)fMode; }
+ void setMode(Mode);
+
+ SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
+ void setSpacingAlign(SkTextBox::SpacingAlign);
+
+ void getMargin(SkPoint* margin) const;
+ void setMargin(SkScalar dx, SkScalar dy);
+
+ size_t getText(SkString* text = NULL) const;
+ size_t getText(char text[] = NULL) const;
+ void setText(const SkString&);
+ void setText(const char text[]);
+ void setText(const char text[], size_t len);
+
+ void getPaint(SkPaint*) const;
+ void setPaint(const SkPaint&);
+
+protected:
+ // overrides
+ virtual void onDraw(SkCanvas*);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+ SkPoint fMargin;
+ SkString fText;
+ SkPaint fPaint;
+ uint8_t fMode;
+ uint8_t fSpacingAlign;
+
+ void computeSize();
+
+ typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkAnimator;
+class SkListSource;
+class SkScrollBarView;
+
+class SkListView : public SkWidgetView {
+public:
+ SkListView();
+ virtual ~SkListView();
+
+ bool hasScrollBar() const { return fScrollBar != NULL; }
+ void setHasScrollBar(bool);
+
+ /** Return the number of visible rows
+ */
+ int getVisibleRowCount() const { return fVisibleRowCount; }
+ /** Return the index of the selected row, or -1 if none
+ */
+ int getSelection() const { return fCurrIndex; }
+ /** Set the index of the selected row, or -1 for none
+ */
+ void setSelection(int);
+ /** If possible, move the selection up and return true,
+ else do nothing and return false
+ If nothing is selected, select the last item (unless there are no items).
+ */
+ bool moveSelectionUp();
+ /** If possible, move the selection down and return true,
+ else do nothing and return false.
+ If nothing is selected, select the first item (unless there are no items).
+ */
+ bool moveSelectionDown();
+
+ SkListSource* getListSource() const { return fSource; }
+ SkListSource* setListSource(SkListSource*);
+
+ /** Call this in your event handler. If the specified event is from a SkListView,
+ then it returns the index of the selected item in this list, otherwise it
+ returns -1
+ */
+ static int GetWidgetEventListIndex(const SkEvent&);
+
+protected:
+ // overrides
+ virtual void onDraw(SkCanvas*);
+ virtual void onSizeChange();
+ virtual bool onEvent(const SkEvent&);
+ virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+ virtual bool onPrepareWidgetEvent(SkEvent*);
+
+private:
+ enum DirtyFlags {
+ kAnimCount_DirtyFlag = 0x01,
+ kAnimContent_DirtyFlag = 0x02
+ };
+ void dirtyCache(unsigned dirtyFlags);
+ bool ensureCache();
+
+ int logicalToVisualIndex(int index) const { return index - fScrollIndex; }
+ void invalSelection();
+ SkScalar getContentWidth() const;
+ bool getRowRect(int index, SkRect*) const;
+ void ensureSelectionIsVisible();
+ void ensureVisibleRowCount();
+
+ struct BindingRec;
+
+ enum Heights {
+ kNormal_Height,
+ kSelected_Height
+ };
+ SkListSource* fSource;
+ SkScrollBarView* fScrollBar;
+ SkAnimator* fAnims;
+ BindingRec* fBindings;
+ SkString fSkinName;
+ SkScalar fHeights[2];
+ int16_t fScrollIndex, fCurrIndex;
+ uint16_t fVisibleRowCount, fBindingCount;
+ SkBool8 fAnimContentDirty;
+ SkBool8 fAnimFocusDirty;
+
+ typedef SkWidgetView INHERITED;
+};
+
+class SkListSource : public SkRefCnt {
+public:
+ virtual int countFields();
+ virtual void getFieldName(int index, SkString* field);
+ /** Return the index of the named field, or -1 if not found */
+ virtual int findFieldIndex(const char field[]);
+
+ virtual int countRecords();
+ virtual void getRecord(int rowIndex, int fieldIndex, SkString* data);
+
+ virtual bool prepareWidgetEvent(SkEvent*, int rowIndex);
+
+ static SkListSource* Factory(const char name[]);
+};
+
+#endif
diff --git a/include/views/SkWindow.h b/include/views/SkWindow.h
new file mode 100644
index 0000000..fd4ce0a
--- /dev/null
+++ b/include/views/SkWindow.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkWindow_DEFINED
+#define SkWindow_DEFINED
+
+#include "SkView.h"
+#include "SkBitmap.h"
+#include "SkMatrix.h"
+#include "SkRegion.h"
+#include "SkEvent.h"
+#include "SkKey.h"
+#include "SkTDArray.h"
+
+#ifdef SK_BUILD_FOR_WINCEx
+ #define SHOW_FPS
+#endif
+//#define USE_GX_SCREEN
+
+class SkCanvas;
+
+class SkOSMenu;
+
+class SkWindow : public SkView {
+public:
+ SkWindow();
+ virtual ~SkWindow();
+
+ const SkBitmap& getBitmap() const { return fBitmap; }
+
+ void setConfig(SkBitmap::Config);
+ void resize(int width, int height, SkBitmap::Config config = SkBitmap::kNo_Config);
+ void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
+ void eraseRGB(U8CPU r, U8CPU g, U8CPU b);
+
+ bool isDirty() const { return !fDirtyRgn.isEmpty(); }
+ bool update(SkIRect* updateArea, SkCanvas* = NULL);
+ // does not call through to onHandleInval(), but does force the fDirtyRgn
+ // to be wide open. Call before update() to ensure we redraw everything.
+ void forceInvalAll();
+ // return the bounds of the dirty/inval rgn, or [0,0,0,0] if none
+ const SkIRect& getDirtyBounds() const { return fDirtyRgn.getBounds(); }
+
+ bool handleClick(int x, int y, Click::State);
+ bool handleChar(SkUnichar);
+ bool handleKey(SkKey);
+ bool handleKeyUp(SkKey);
+ bool handleMenu(uint32_t os_cmd);
+
+ void addMenu(SkOSMenu*);
+
+ const char* getTitle() const { return fTitle.c_str(); }
+ void setTitle(const char title[]);
+
+ const SkMatrix& getMatrix() const { return fMatrix; }
+ void setMatrix(const SkMatrix&);
+ void preConcat(const SkMatrix&);
+ void postConcat(const SkMatrix&);
+
+protected:
+ virtual bool onEvent(const SkEvent&);
+ virtual bool onDispatchClick(int x, int y, Click::State);
+ // called if part of our bitmap is invalidated
+ virtual void onHandleInval(const SkIRect&);
+ virtual bool onHandleChar(SkUnichar);
+ virtual bool onHandleKey(SkKey);
+ virtual bool onHandleKeyUp(SkKey);
+ virtual void onAddMenu(const SkOSMenu*) {}
+ virtual void onSetTitle(const char title[]) {}
+
+ // overrides from SkView
+ virtual bool handleInval(const SkRect*);
+ virtual bool onGetFocusView(SkView** focus) const;
+ virtual bool onSetFocusView(SkView* focus);
+
+private:
+ SkBitmap::Config fConfig;
+ SkBitmap fBitmap;
+ SkRegion fDirtyRgn;
+ Click* fClick; // to track clicks
+
+ SkTDArray<SkOSMenu*> fMenus;
+
+ SkView* fFocusView;
+ bool fWaitingOnInval;
+
+ SkString fTitle;
+ SkMatrix fMatrix;
+
+ typedef SkView INHERITED;
+};
+
+///////////////////////////////////////////////////////////
+
+#ifdef SK_USE_WXWIDGETS
+ #include "SkOSWindow_wxwidgets.h"
+#elif defined(SK_BUILD_FOR_MAC)
+ #include "SkOSWindow_Mac.h"
+#elif defined(SK_BUILD_FOR_WIN)
+ #include "SkOSWindow_Win.h"
+#elif defined(ANDROID)
+ #include "SkOSWindow_Android.h"
+#elif defined(SK_BUILD_FOR_UNIX)
+ #include "SkOSWindow_Unix.h"
+#elif defined(SK_BUILD_FOR_SDL)
+ #include "SkOSWindow_SDL.h"
+#elif defined(SK_BUILD_FOR_IOS)
+ #include "SkOSWindow_iOS.h"
+#endif
+
+#endif
+