From 0b15698a8c76bb8abc1b555c1d91892669b4118f Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 6 Jun 2011 17:02:24 -0400 Subject: Skia Merge (revision 1510) This CL includes bug fixes and closely mirrors the version of Skia used in Chrome M13, which is likely to be our baseline for ICS. The CL also adds source files for the SampleApp which will allow us to execute basic skia tests. The SampleApp requires the utils/views directory in order to run. Finally, we have included the PDF backend for Skia in order to experiment with using it to generate PDF files for certain applications. Note: The SampleApp and PDF code are not built as part of libskia. Change-Id: I1895ccfbd8074e25f19148cc7bd1b4af571fb307 --- include/config/SkUserConfig.h | 3 +- include/core/SkClipStack.h | 1 + include/core/SkColorPriv.h | 20 +- include/core/SkComposeShader.h | 2 +- include/core/SkDevice.h | 27 -- include/core/SkMath.h | 2 +- include/core/SkMatrix.h | 21 +- include/core/SkPath.h | 38 ++- include/core/SkPostConfig.h | 19 ++ include/core/SkPreConfig.h | 10 +- include/core/SkReader32.h | 9 +- include/core/SkRect.h | 2 +- include/core/SkScalar.h | 39 ++- include/core/SkScalerContext.h | 3 + include/core/SkWriter32.h | 17 +- include/core/SkXfermode.h | 10 +- include/gpu/SkGpuDevice.h | 13 +- include/gpu/SkGr.h | 33 +-- include/pdf/SkPDFCatalog.h | 102 +++++++ include/pdf/SkPDFDevice.h | 227 ++++++++++++++ include/pdf/SkPDFDocument.h | 84 ++++++ include/pdf/SkPDFFont.h | 151 ++++++++++ include/pdf/SkPDFFormXObject.h | 73 +++++ include/pdf/SkPDFGraphicState.h | 106 +++++++ include/pdf/SkPDFImage.h | 95 ++++++ include/pdf/SkPDFPage.h | 101 +++++++ include/pdf/SkPDFShader.h | 110 +++++++ include/pdf/SkPDFStream.h | 55 ++++ include/pdf/SkPDFTypes.h | 332 +++++++++++++++++++++ include/pdf/SkPDFUtils.h | 61 ++++ include/pipe/SkGPipe.h | 96 ++++++ include/utils/SkEGLContext.h | 43 ++- include/utils/android/AndroidKeyToSkKey.h | 40 +++ include/utils/unix/XkeysToSkKeys.h | 8 + include/views/SkApplication.h | 26 ++ include/views/SkBGViewArtist.h | 41 +++ include/views/SkBorderView.h | 48 +++ include/views/SkEvent.h | 257 ++++++++++++++++ include/views/SkEventSink.h | 103 +++++++ include/views/SkImageView.h | 75 +++++ include/views/SkKey.h | 63 ++++ include/views/SkOSMenu.h | 55 ++++ include/views/SkOSWindow_Android.h | 41 +++ include/views/SkOSWindow_Mac.h | 62 ++++ include/views/SkOSWindow_SDL.h | 52 ++++ include/views/SkOSWindow_Unix.h | 79 +++++ include/views/SkOSWindow_Win.h | 79 +++++ include/views/SkOSWindow_wxwidgets.h | 52 ++++ include/views/SkProgressBarView.h | 57 ++++ include/views/SkScrollBarView.h | 52 ++++ include/views/SkStackViewLayout.h | 96 ++++++ include/views/SkSystemEventTypes.h | 32 ++ include/views/SkTouchGesture.h | 72 +++++ include/views/SkView.h | 370 +++++++++++++++++++++++ include/views/SkViewInflate.h | 79 +++++ include/views/SkWidget.h | 476 ++++++++++++++++++++++++++++++ include/views/SkWidgetViews.h | 312 ++++++++++++++++++++ include/views/SkWindow.h | 125 ++++++++ 58 files changed, 4550 insertions(+), 107 deletions(-) create mode 100644 include/pdf/SkPDFCatalog.h create mode 100644 include/pdf/SkPDFDevice.h create mode 100644 include/pdf/SkPDFDocument.h create mode 100644 include/pdf/SkPDFFont.h create mode 100644 include/pdf/SkPDFFormXObject.h create mode 100644 include/pdf/SkPDFGraphicState.h create mode 100644 include/pdf/SkPDFImage.h create mode 100644 include/pdf/SkPDFPage.h create mode 100644 include/pdf/SkPDFShader.h create mode 100644 include/pdf/SkPDFStream.h create mode 100644 include/pdf/SkPDFTypes.h create mode 100644 include/pdf/SkPDFUtils.h create mode 100644 include/pipe/SkGPipe.h create mode 100644 include/utils/android/AndroidKeyToSkKey.h create mode 100644 include/views/SkApplication.h create mode 100644 include/views/SkBGViewArtist.h create mode 100644 include/views/SkBorderView.h create mode 100644 include/views/SkEvent.h create mode 100644 include/views/SkEventSink.h create mode 100644 include/views/SkImageView.h create mode 100644 include/views/SkKey.h create mode 100644 include/views/SkOSMenu.h create mode 100644 include/views/SkOSWindow_Android.h create mode 100644 include/views/SkOSWindow_Mac.h create mode 100644 include/views/SkOSWindow_SDL.h create mode 100644 include/views/SkOSWindow_Unix.h create mode 100644 include/views/SkOSWindow_Win.h create mode 100644 include/views/SkOSWindow_wxwidgets.h create mode 100644 include/views/SkProgressBarView.h create mode 100644 include/views/SkScrollBarView.h create mode 100644 include/views/SkStackViewLayout.h create mode 100644 include/views/SkSystemEventTypes.h create mode 100644 include/views/SkTouchGesture.h create mode 100644 include/views/SkView.h create mode 100644 include/views/SkViewInflate.h create mode 100644 include/views/SkWidget.h create mode 100644 include/views/SkWidgetViews.h create mode 100644 include/views/SkWindow.h (limited to 'include') 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 + +#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 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& 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* resourceList) const; + + /** Get the fonts used on this device. + */ + SK_API const SkTDArray& getFontResources() const; + + /** Returns the media box for this device. + */ + SK_API SkRefPtr 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 fResourceDict; + + SkTDArray fGraphicStateResources; + SkTDArray fXObjectResources; + SkTDArray fFontResources; + SkTDArray fShaderResources; + + SkTScopedPtr 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* 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* 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& pdfDevice); + + /** Get the list of pages in this document. + */ + SK_API const SkTDArray& getPages(); + +private: + SkPDFCatalog fCatalog; + int64_t fXRefFileOffset; + + SkTDArray fPages; + SkTDArray fPageTree; + SkRefPtr fDocCatalog; + SkTDArray fPageResources; + int fSecondPageFirstResourceIndex; + + SkRefPtr 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* 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 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 fFontInfo; + SkTDArray fResources; + SkRefPtr 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& 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* 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 fStream; + SkTDArray 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* 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 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& 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* resourceList); + +private: + SkRefPtr fStream; + SkTDArray 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& 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* 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& pages, + SkPDFCatalog* catalog, + SkTDArray* pageTree, + SkPDFDict** rootNode); + + /** Get the fonts used on this page. + */ + SK_API const SkTDArray& getFontResources() const; + +private: + // Multiple pages may reference the content. + SkRefPtr fDevice; + + // Once the content is finalized, put it into a stream for output. + SkRefPtr 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* 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 fContent; + SkTDArray fResources; + SkAutoTDelete 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& 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 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* 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 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 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 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 +#elif defined(SK_BUILD_FOR_ANDROID) + #include "GLES2/gl2.h" + #include "EGL/egl.h" +#elif defined(SK_BUILD_FOR_UNIX) + #include + #include +#elif defined(SK_BUILD_FOR_WIN32) + #include + #include +#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 + */ + 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 */ + 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 */ + 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 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 +#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 +#include + +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 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 , 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& 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&); + +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 fIDs; + + struct IDStr { + SkView* fView; + char* fStr; + }; + SkTDArray fListenTo, fBroadcastTo; + SkChunkAlloc fStrings; + + void addIDStr(SkTDArray* 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(); + + // 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, //!< + kButton_WidgetEnum, //!< + kImage_WidgetEnum, //!< + kList_WidgetEnum, //!< + kProgress_WidgetEnum, //!< + kScroll_WidgetEnum, //!< + kText_WidgetEnum, //!< + + 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 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 + -- cgit v1.1