• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2007, 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 CachedFrame_H
27 #define CachedFrame_H
28 
29 #include "CachedInput.h"
30 #include "CachedLayer.h"
31 #include "CachedNode.h"
32 #include "IntRect.h"
33 #include "SkFixed.h"
34 #include "wtf/Vector.h"
35 
36 class SkPicture;
37 
38 namespace WebCore {
39     class Frame;
40     class Node;
41 }
42 
43 namespace android {
44 
45 class CachedHistory;
46 class CachedRoot;
47 
48     // first node referenced by cache is always document
49 class CachedFrame {
50 public:
51     enum Direction {
52         UNINITIALIZED = -1,
53         LEFT,
54         RIGHT,
55         UP,
56         DOWN,
57         DIRECTION_COUNT,
58         DIRECTION_MASK = DIRECTION_COUNT - 1,
59         UP_DOWN = UP & DOWN,  // mask and result
60         RIGHT_DOWN = RIGHT & DOWN, // mask and result
61     };
62     enum Compare {
63         UNDECIDED = -1,
64         TEST_IS_BEST,
65         REJECT_TEST
66     };
67     enum CursorInit {
68         CURSOR_UNINITIALIZED = -2,
69         CURSOR_CLEARED = -1,
70         CURSOR_SET = 0
71     };
CachedFrame()72     CachedFrame() {}
add(CachedInput & input)73     void add(CachedInput& input) { mCachedTextInputs.append(input); }
74 #if USE(ACCELERATED_COMPOSITING)
add(CachedLayer & layer)75     void add(CachedLayer& layer) { mCachedLayers.append(layer); }
76 #endif
add(CachedNode & node)77     void add(CachedNode& node) { mCachedNodes.append(node); }
addFrame(CachedFrame & child)78     void addFrame(CachedFrame& child) { mCachedFrames.append(child); }
79     WebCore::IntRect adjustBounds(const CachedNode* ,
80         const WebCore::IntRect& ) const;
81     bool checkRings(const CachedNode* node,
82         const WTF::Vector<WebCore::IntRect>& rings,
83         const WebCore::IntRect& bounds) const;
84     bool checkVisited(const CachedNode* , CachedFrame::Direction ) const;
childCount()85     size_t childCount() { return mCachedFrames.size(); }
86     void clearCursor();
currentCursor()87     const CachedNode* currentCursor() const { return currentCursor(NULL); }
88     const CachedNode* currentCursor(const CachedFrame** ) const;
currentFocus()89     const CachedNode* currentFocus() const { return currentFocus(NULL); }
90     const CachedNode* currentFocus(const CachedFrame** ) const;
91     bool directionChange() const;
document()92     const CachedNode* document() const { return mCachedNodes.begin(); }
empty()93     bool empty() const { return mCachedNodes.size() < 2; } // must have 1 past doc
94     const CachedNode* findBestAt(const WebCore::IntRect& , int* best,
95         bool* inside, const CachedNode** , const CachedFrame** directFrame,
96         const CachedFrame** resultFrame, int* x,
97         int* y, bool checkForHidden) const;
98     const CachedFrame* findBestFrameAt(int x, int y) const;
99     const CachedNode* findBestHitAt(const WebCore::IntRect& ,
100         const CachedFrame** , int* x, int* y) const;
101     void finishInit();
firstChild()102     CachedFrame* firstChild() { return mCachedFrames.begin(); }
firstChild()103     const CachedFrame* firstChild() const { return mCachedFrames.begin(); }
framePointer()104     void* framePointer() const { return mFrame; }
getIndex(int index)105     CachedNode* getIndex(int index) { return index >= 0 ?
106         &mCachedNodes[index] : NULL; }
107     const CachedFrame* hasFrame(const CachedNode* node) const;
108     void hideCursor();
indexInParent()109     int indexInParent() const { return mIndexInParent; }
110     void init(const CachedRoot* root, int index, WebCore::Frame* frame);
lastChild()111     const CachedFrame* lastChild() const { return &mCachedFrames.last(); }
112 #if USE(ACCELERATED_COMPOSITING)
lastLayer()113     const CachedLayer* lastLayer() const { return &mCachedLayers.last(); }
114 #endif
lastNode()115     CachedNode* lastNode() { return &mCachedNodes.last(); }
lastChild()116     CachedFrame* lastChild() { return &mCachedFrames.last(); }
117 #if USE(ACCELERATED_COMPOSITING)
118     const CachedLayer* layer(const CachedNode* ) const;
layerCount()119     size_t layerCount() const { return mCachedLayers.size(); }
120 #endif
121     WebCore::IntRect localBounds(const CachedNode* ,
122         const WebCore::IntRect& ) const;
parent()123     const CachedFrame* parent() const { return mParent; }
parent()124     CachedFrame* parent() { return mParent; }
125     SkPicture* picture(const CachedNode* ) const;
126     void resetLayers();
127     bool sameFrame(const CachedFrame* ) const;
removeLast()128     void removeLast() { mCachedNodes.removeLast(); }
129     void resetClippedOut();
setContentsSize(int width,int height)130     void setContentsSize(int width, int height) { mContents.setWidth(width);
131         mContents.setHeight(height); }
132     bool setCursor(WebCore::Frame* , WebCore::Node* , int x, int y);
setCursorIndex(int index)133     void setCursorIndex(int index) { mCursorIndex = index; }
134     void setData();
135     bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y);
setFocusIndex(int index)136     void setFocusIndex(int index) { mFocusIndex = index; }
setLocalViewBounds(const WebCore::IntRect & bounds)137     void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; }
size()138     int size() { return mCachedNodes.size(); }
textInput(const CachedNode * node)139     const CachedInput* textInput(const CachedNode* node) const {
140         return node->isTextInput() ? &mCachedTextInputs[node->textInputIndex()]
141             : 0;
142     }
143     const CachedNode* validDocument() const;
144 protected:
145     const CachedNode* nextTextField(const CachedNode* start,
146         const CachedFrame** framePtr, bool* found) const;
147     struct BestData {
148         int mDistance;
149         int mSideDistance;
150         int mMajorDelta; // difference of center of object
151             // used only when leading and trailing edges contain another set of edges
152         int mMajorDelta2; // difference of leading edge (only used when center is same)
153         int mMajorButt; // checks for next cell butting up against or close to previous one
154         int mWorkingDelta;
155         int mWorkingDelta2;
156         int mNavDelta;
157         int mNavDelta2;
158         const CachedFrame* mFrame;
159         const CachedNode* mNode;
160         SkFixed mWorkingOverlap;   // this and below are fuzzy answers instead of bools
161         SkFixed mNavOverlap;
162         SkFixed mPreferred;
163         bool mCursorChild;
164         bool mInNav;
165         bool mNavOutside;
166         bool mWorkingOutside;
bottomBestData167         int bottom() const { return bounds().bottom(); }
boundsBestData168         const WebCore::IntRect& bounds() const { return mNodeBounds; }
169         bool canBeReachedByAnotherDirection();
heightBestData170         int height() const { return bounds().height(); }
inOrSubsumesNavBestData171         bool inOrSubsumesNav() const { return (mNavDelta ^ mNavDelta2) >= 0; }
inOrSubsumesWorkingBestData172         bool inOrSubsumesWorking() const { return (mWorkingDelta ^ mWorkingDelta2) >= 0; }
173         int isContainer(BestData* );
mouseBoundsBestData174         const WebCore::IntRect& mouseBounds() const { return mMouseBounds; }
175         static SkFixed Overlap(int span, int left, int right);
resetBestData176         void reset() { mNode = NULL; }
rightBestData177         int right() const { return bounds().right(); }
setMouseBoundsBestData178         void setMouseBounds(const WebCore::IntRect& b) { mMouseBounds = b; }
setNodeBoundsBestData179         void setNodeBounds(const WebCore::IntRect& b) { mNodeBounds = b; }
180         void setDistances();
181         bool setDownDirection(const CachedHistory* );
182         bool setLeftDirection(const CachedHistory* );
183         bool setRightDirection(const CachedHistory* );
184         bool setUpDirection(const CachedHistory* );
185         void setNavInclusion(int left, int right);
186         void setNavOverlap(int span, int left, int right);
187         void setWorkingInclusion(int left, int right);
188         void setWorkingOverlap(int span, int left, int right);
widthBestData189         int width() const { return bounds().width(); }
xBestData190         int x() const { return bounds().x(); }
yBestData191         int y() const { return bounds().y(); }
192 private: // since computing these is complicated, protect them so that the
193          // are only written by appropriate helpers
194         WebCore::IntRect mMouseBounds;
195         WebCore::IntRect mNodeBounds;
196     };
197     typedef const CachedNode* (CachedFrame::*MoveInDirection)(
198         const CachedNode* test, const CachedNode* limit, BestData* ) const;
199     void adjustToTextColumn(int* delta) const;
200     static bool CheckBetween(Direction , const WebCore::IntRect& bestRect,
201         const WebCore::IntRect& prior, WebCore::IntRect* result);
202     bool checkBetween(BestData* , Direction );
203     int compare(BestData& testData, const BestData& bestData) const;
204     void findClosest(BestData* , Direction original, Direction test,
205         WebCore::IntRect* clip) const;
206     int frameNodeCommon(BestData& testData, const CachedNode* test,
207         BestData* bestData, BestData* originalData) const;
208     int framePartCommon(BestData& testData, const CachedNode* test,
209         BestData* ) const;
210     const CachedNode* frameDown(const CachedNode* test, const CachedNode* limit,
211         BestData* ) const;
212     const CachedNode* frameLeft(const CachedNode* test, const CachedNode* limit,
213         BestData* ) const;
214     const CachedNode* frameRight(const CachedNode* test, const CachedNode* limit,
215         BestData* ) const;
216     const CachedNode* frameUp(const CachedNode* test, const CachedNode* limit,
217         BestData* ) const;
218     int minWorkingHorizontal() const;
219     int minWorkingVertical() const;
220     int maxWorkingHorizontal() const;
221     int maxWorkingVertical() const;
222     bool moveInFrame(MoveInDirection , const CachedNode* test, BestData* ) const;
223     const WebCore::IntRect& _navBounds() const;
224     WebCore::IntRect mContents;
225     WebCore::IntRect mLocalViewBounds;
226     WebCore::IntRect mViewBounds;
227     WTF::Vector<CachedNode> mCachedNodes;
228     WTF::Vector<CachedFrame> mCachedFrames;
229     WTF::Vector<CachedInput> mCachedTextInputs;
230 #if USE(ACCELERATED_COMPOSITING)
231     WTF::Vector<CachedLayer> mCachedLayers;
232 #endif
233     void* mFrame; // WebCore::Frame*, used only to compare pointers
234     CachedFrame* mParent;
235     int mCursorIndex;
236     int mFocusIndex;
237     int mIndexInParent; // index within parent's array of children, or -1 if root
238     const CachedRoot* mRoot;
239 private:
240     CachedHistory* history() const;
241 #ifdef BROWSER_DEBUG
242 public:
243         CachedNode* find(WebCore::Node* ); // !!! probably debugging only
244         int mDebugIndex;
245         int mDebugLoopbackOffset;
246 #endif
247 #if !defined NDEBUG || DUMP_NAV_CACHE
248 public:
249     class Debug {
250 public:
Debug()251         Debug() {
252 #if DUMP_NAV_CACHE
253             mFrameName[0] = '\0';
254 #endif
255 #if !defined NDEBUG
256             mInUse = true;
257 #endif
258         }
259 #if !defined NDEBUG
~Debug()260         ~Debug() { mInUse = false; }
261         bool mInUse;
262 #endif
263 #if DUMP_NAV_CACHE
264         CachedFrame* base() const;
265         void print() const;
266         bool validate(const CachedNode* ) const;
267         char mFrameName[256];
268 #endif
269     } mDebug;
270 #endif
271 };
272 
273 }
274 
275 #endif
276