diff options
Diffstat (limited to 'WebKit/android/nav/FindCanvas.h')
-rw-r--r-- | WebKit/android/nav/FindCanvas.h | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/WebKit/android/nav/FindCanvas.h b/WebKit/android/nav/FindCanvas.h new file mode 100644 index 0000000..5d79b4c --- /dev/null +++ b/WebKit/android/nav/FindCanvas.h @@ -0,0 +1,207 @@ +/* + * Copyright 2008, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Find_Canvas_h +#define Find_Canvas_h + +#include "SkBounder.h" +#include "SkCanvas.h" +#include "SkPicture.h" +#include "SkRegion.h" +#include "SkTDArray.h" +#include "icu/unicode/umachine.h" +#include "wtf/Vector.h" + +class SkRect; +class SkTypeface; + +// Stores both region information and an SkPicture of the match, so that the +// region can be drawn, followed by drawing the matching text on top of it. +// This class owns its SkPicture +class MatchInfo { +public: + MatchInfo(); + ~MatchInfo(); + MatchInfo(const MatchInfo& src); + const SkRegion& getLocation() const { return m_location; } + // Return a pointer to our picture, representing the matching text. Does + // not transfer ownership of the picture. + SkPicture* getPicture() const { return m_picture; } + // This will make a copy of the region, and increase the ref count on the + // SkPicture. If this MatchInfo already had one, unref it. + void set(const SkRegion& region, SkPicture* pic); +private: + MatchInfo& operator=(MatchInfo& src); + SkRegion m_location; + SkPicture* m_picture; +}; + +// A class containing a typeface for reference, the length in glyphs, and +// the upper and lower case representations of the search string. +class GlyphSet { +public: + GlyphSet(const SkPaint& paint, const UChar* lower, const UChar* upper, + size_t byteLength); + ~GlyphSet(); + GlyphSet& operator=(GlyphSet& src); + + // Return true iff c matches one of our glyph arrays at index + bool characterMatches(uint16_t c, int index); + + int getCount() const { return mCount; } + + const SkTypeface* getTypeface() const { return mTypeface; } + +private: + // Disallow copy constructor + GlyphSet(GlyphSet& src) { } + + // mTypeface is used for comparison only + const SkTypeface* mTypeface; + // mLowerGlyphs points to all of our storage space: the lower set followed + // by the upper set. mUpperGlyphs is purely a convenience pointer to the + // start of the upper case glyphs. + uint16_t* mLowerGlyphs; + uint16_t* mUpperGlyphs; + // mCount is the number of glyphs of the search string. Must be the same + // for both the lower case set and the upper case set. + int mCount; + + // Arbitrarily chose the maximum storage to use in the GlyphSet. This is + // based on the length of the word being searched. If users are always + // searching for 3 letter words (for example), an ideal number would be 3. + // Each time the user searches for a word longer than (in this case, 3) that + // will result in calling new/delete. + enum Storage { + MAX_STORAGE_COUNT = 16 + }; + // In order to eliminate new/deletes, create storage that will be enough + // most of the time + uint16_t mStorage[2*MAX_STORAGE_COUNT]; +}; + +class FindBounder : public SkBounder { +public: + FindBounder() {} + ~FindBounder() {} +protected: + virtual bool onIRect(const SkIRect&) { return false; } +}; + +class FindCanvas : public SkCanvas { +public: + FindCanvas(int width, int height, const UChar* , const UChar*, + size_t byteLength); + + virtual ~FindCanvas(); + + virtual void drawText(const void* text, size_t byteLength, SkScalar x, + SkScalar y, const SkPaint& paint); + + /* FIXME: This path has not been tested. */ + virtual void drawPosText(const void* text, size_t byteLength, + const SkPoint pos[], const SkPaint& paint); + + /* Also untested */ + virtual void drawPosTextH(const void* text, size_t byteLength, + const SkScalar xpos[], SkScalar constY, + const SkPaint& paint); + + /* Not sure what to do here or for drawTextOnPathHV */ + virtual void drawTextOnPath(const void* text, size_t byteLength, + const SkPath& path, const SkMatrix* matrix, + const SkPaint& paint) { + } + + int found() const { return mNumFound; } + + // This method detaches our array of matches and passes ownership to + // the caller, who is then responsible for deleting them. + WTF::Vector<MatchInfo>* detachMatches() { + WTF::Vector<MatchInfo>* array = mMatches; + mMatches = NULL; + return array; + } + +private: + // These calls are made by findHelper to store information about each match + // that is found. They return a rectangle which is used to highlight the + // match. They also add to our SkPicture (which can be accessed with + // getDrawnMatches) a draw of each match. This way it can be drawn after + // the rectangle. The rect that is returned is in device coordinates. + SkRect addMatchNormal(int index, + const SkPaint& paint, int count, const uint16_t* glyphs, + const SkScalar pos[], SkScalar y); + + SkRect addMatchPos(int index, + const SkPaint& paint, int count, const uint16_t* glyphs, + const SkScalar xPos[], SkScalar /* y */); + + SkRect addMatchPosH(int index, + const SkPaint& paint, int count, const uint16_t* glyphs, + const SkScalar position[], SkScalar constY); + + // Helper for each of our draw calls + void findHelper(const void* text, size_t byteLength, const SkPaint& paint, + const SkScalar xPos[], SkScalar y, + SkRect (FindCanvas::*addMatch)(int index, + const SkPaint& paint, int count, const uint16_t* glyphs, + const SkScalar pos[], SkScalar y)); + + // If we already have a working canvas, grab it. Otherwise, create a new + // one. + SkCanvas* getWorkingCanvas(); + + // Return the set of glyphs and its count for the text being searched for + // and the parameter paint. If one has already been created and cached + // for this paint, use it. If not, create a new one and cache it. + GlyphSet* getGlyphs(const SkPaint& paint); + + // Store all the accumulated info about a match in our vector. + void insertMatchInfo(const SkRegion& region); + + // Throw away our cumulative information about our working SkCanvas. After + // this call, next call to getWorkingCanvas will create a new one. + void resetWorkingCanvas(); + + // Since we may transfer ownership of this array (see detachRects()), we + // hold a pointer to the array instead of just the array itself. + WTF::Vector<MatchInfo>* mMatches; + const UChar* mLowerText; + const UChar* mUpperText; + size_t mLength; + FindBounder mBounder; + int mNumFound; + SkScalar mOutset; + SkTDArray<GlyphSet> mGlyphSets; + + SkPicture* mWorkingPicture; + SkCanvas* mWorkingCanvas; + SkRegion mWorkingRegion; + int mWorkingIndex; +}; + +#endif // Find_Canvas_h + |