OSDN Git Service

Add UI considerations to layers
[android-x86/external-webkit.git] / WebKit / android / nav / FindCanvas.h
1 /*
2  * Copyright 2008, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef Find_Canvas_h
27 #define Find_Canvas_h
28
29 #include "IntRect.h"
30 #include "SkBounder.h"
31 #include "SkCanvas.h"
32 #include "SkPicture.h"
33 #include "SkRegion.h"
34 #include "SkTDArray.h"
35 #include "icu/unicode/umachine.h"
36 #include "wtf/Vector.h"
37
38 // class SkIRect;
39 // class SkRect;
40 // class SkTypeface;
41
42 namespace WebCore {
43     class LayerAndroid;
44 }
45
46 // Stores both region information and an SkPicture of the match, so that the
47 // region can be drawn, followed by drawing the matching text on top of it.
48 // This class owns its SkPicture
49 class MatchInfo {
50 public:
51     MatchInfo();
52     ~MatchInfo();
53     MatchInfo(const MatchInfo& src);
54     const SkRegion& getLocation() const { return m_location; }
55     // Return a pointer to our picture, representing the matching text.  Does
56     // not transfer ownership of the picture.
57     SkPicture* getPicture() const { return m_picture; }
58     // This will make a copy of the region, and increase the ref count on the
59     // SkPicture.  If this MatchInfo already had one, unref it.
60     bool isInLayer() const { return m_layerId >= 0; }
61     int layerId() const { return m_layerId; }
62     void set(const SkRegion& region, SkPicture* pic, int layerId);
63 private:
64     MatchInfo& operator=(MatchInfo& src);
65     SkRegion    m_location;
66     SkPicture*  m_picture;
67     int         m_layerId;
68 };
69
70 // A class containing a typeface for reference, the length in glyphs, and
71 // the upper and lower case representations of the search string.
72 class GlyphSet {
73 public:
74     GlyphSet(const SkPaint& paint, const UChar* lower, const UChar* upper,
75             size_t byteLength);
76     ~GlyphSet();
77     GlyphSet& operator=(GlyphSet& src);
78
79     // Return true iff c matches one of our glyph arrays at index
80     bool characterMatches(uint16_t c, int index);
81     
82     int getCount() const { return mCount; }
83
84     const SkTypeface* getTypeface() const { return mTypeface; }
85
86 private:
87     // Disallow copy constructor
88     GlyphSet(GlyphSet& src) { }
89
90     // mTypeface is used for comparison only
91     const SkTypeface* mTypeface;
92     // mLowerGlyphs points to all of our storage space: the lower set followed
93     // by the upper set.  mUpperGlyphs is purely a convenience pointer to the
94     // start of the upper case glyphs.
95     uint16_t*   mLowerGlyphs;
96     uint16_t*   mUpperGlyphs;
97     // mCount is the number of glyphs of the search string.  Must be the same
98     // for both the lower case set and the upper case set.
99     int         mCount;
100
101     // Arbitrarily chose the maximum storage to use in the GlyphSet.  This is
102     // based on the length of the word being searched.  If users are always
103     // searching for 3 letter words (for example), an ideal number would be 3.
104     // Each time the user searches for a word longer than (in this case, 3) that
105     // will result in calling new/delete.
106     enum Storage {
107         MAX_STORAGE_COUNT = 16
108     };
109     // In order to eliminate new/deletes, create storage that will be enough
110     // most of the time
111     uint16_t    mStorage[2*MAX_STORAGE_COUNT];
112 };
113
114 class FindBounder : public SkBounder {
115 public:
116     FindBounder() {}
117     ~FindBounder() {}
118 protected:
119     virtual bool onIRect(const SkIRect&) { return false; }
120 };
121
122 class FindCanvas : public SkCanvas {
123 public:
124     FindCanvas(int width, int height, const UChar* , const UChar*,
125             size_t byteLength);
126
127     virtual ~FindCanvas();
128
129     virtual void drawText(const void* text, size_t byteLength, SkScalar x,
130                           SkScalar y, const SkPaint& paint);
131
132     /* FIXME: This path has not been tested. */
133     virtual void drawPosText(const void* text, size_t byteLength,
134                              const SkPoint pos[], const SkPaint& paint);
135
136     /* Also untested */
137     virtual void drawPosTextH(const void* text, size_t byteLength,
138                               const SkScalar xpos[], SkScalar constY,
139                               const SkPaint& paint);
140
141     /* Not sure what to do here or for drawTextOnPathHV */
142     virtual void drawTextOnPath(const void* text, size_t byteLength,
143                                 const SkPath& path, const SkMatrix* matrix,
144                                 const SkPaint& paint) {
145     }
146
147     void drawLayers(WebCore::LayerAndroid* );
148     int found() const { return mNumFound; }
149     void setLayerId(int layerId) { mLayerId = layerId; }
150
151     // This method detaches our array of matches and passes ownership to
152     // the caller, who is then responsible for deleting them.
153     WTF::Vector<MatchInfo>* detachMatches() {
154         WTF::Vector<MatchInfo>* array = mMatches;
155         mMatches = NULL;
156         return array;
157     }
158
159 private:
160     // These calls are made by findHelper to store information about each match
161     // that is found.  They return a rectangle which is used to highlight the
162     // match.  They also add to our SkPicture (which can be accessed with
163     // getDrawnMatches) a draw of each match.  This way it can be drawn after
164     // the rectangle.  The rect that is returned is in device coordinates.
165     SkRect addMatchNormal(int index,
166         const SkPaint& paint, int count, const uint16_t* glyphs,
167         const SkScalar pos[], SkScalar y);
168
169     SkRect addMatchPos(int index,
170         const SkPaint& paint, int count, const uint16_t* glyphs,
171         const SkScalar xPos[], SkScalar /* y */);
172
173     SkRect addMatchPosH(int index,
174         const SkPaint& paint, int count, const uint16_t* glyphs,
175         const SkScalar position[], SkScalar constY);
176
177     // Helper for each of our draw calls
178     void findHelper(const void* text, size_t byteLength, const SkPaint& paint,
179                     const SkScalar xPos[], SkScalar y,
180                     SkRect (FindCanvas::*addMatch)(int index,
181                     const SkPaint& paint, int count, const uint16_t* glyphs,
182                     const SkScalar pos[], SkScalar y));
183
184     // If we already have a working canvas, grab it.  Otherwise, create a new
185     // one.
186     SkCanvas* getWorkingCanvas();
187
188     // Return the set of glyphs and its count for the text being searched for
189     // and the parameter paint.  If one has already been created and cached
190     // for this paint, use it.  If not, create a new one and cache it.
191     GlyphSet* getGlyphs(const SkPaint& paint);
192
193     // Store all the accumulated info about a match in our vector.
194     void insertMatchInfo(const SkRegion& region);
195
196     // Throw away our cumulative information about our working SkCanvas.  After
197     // this call, next call to getWorkingCanvas will create a new one.
198     void resetWorkingCanvas();
199
200     // Since we may transfer ownership of this array (see detachRects()), we
201     // hold a pointer to the array instead of just the array itself.
202     WTF::Vector<MatchInfo>* mMatches;
203     const UChar*            mLowerText;
204     const UChar*            mUpperText;
205     size_t                  mLength;
206     FindBounder             mBounder;
207     int                     mNumFound;
208     SkScalar                mOutset;
209     SkTDArray<GlyphSet>     mGlyphSets;
210
211     SkPicture*              mWorkingPicture;
212     SkCanvas*               mWorkingCanvas;
213     SkRegion                mWorkingRegion;
214     int                     mWorkingIndex;
215     int                     mLayerId;
216 };
217
218 class FindOnPage {
219 public:
220     FindOnPage() {
221         m_matches = 0;
222         m_hasCurrentLocation = false;
223         m_isFindPaintSetUp = false;
224     }
225     ~FindOnPage() { delete m_matches; }
226     void clearCurrentLocation() { m_hasCurrentLocation = false; }
227     WebCore::IntRect currentMatchBounds() const;
228     void drawLayer(SkCanvas* canvas, const WebCore::IntRect* vis, int layerId);
229     void findNext(bool forward);
230     void setMatches(WTF::Vector<MatchInfo>* matches);
231 private:
232     void drawMatch(const SkRegion& region, SkCanvas* canvas, bool focused);
233     void setUpFindPaint();
234     void storeCurrentMatchLocation();
235     WTF::Vector<MatchInfo>* m_matches;
236     // Stores the location of the current match.
237     SkIPoint m_currentMatchLocation;
238     // Tells whether the value in m_currentMatchLocation is valid.
239     bool m_hasCurrentLocation;
240     // Tells whether we have done the setup to draw the Find matches.
241     bool m_isFindPaintSetUp;
242     // Paint used to draw our Find matches.
243     SkPaint m_findPaint;
244     // Paint used for the background of our Find matches.
245     SkPaint m_findBlurPaint;
246     unsigned m_findIndex;
247 };
248
249 #endif  // Find_Canvas_h