1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
/*
* Copyright 2007, 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 CachedFrame_H
#define CachedFrame_H
#include "CachedNode.h"
#include "IntRect.h"
#include "SkFixed.h"
#include "wtf/Vector.h"
namespace WebCore {
class Frame;
class Node;
}
namespace android {
class CachedHistory;
class CachedRoot;
// first node referenced by cache is always document
class CachedFrame {
public:
enum Direction {
UNINITIALIZED = -1,
LEFT,
RIGHT,
UP,
DOWN,
DIRECTION_COUNT,
DIRECTION_MASK = DIRECTION_COUNT - 1,
UP_DOWN = UP & DOWN, // mask and result
RIGHT_DOWN = RIGHT & DOWN, // mask and result
};
enum Compare {
UNDECIDED = -1,
TEST_IS_BEST,
REJECT_TEST
};
CachedFrame() {}
void add(CachedNode& node) { mCachedNodes.append(node); }
void addFrame(CachedFrame& child) { mCachedFrames.append(child); }
bool checkVisited(const CachedNode* , CachedFrame::Direction ) const;
size_t childCount() { return mCachedFrames.size(); }
void clearFocus();
const CachedNode* currentFocus() const { return currentFocus(NULL); }
const CachedNode* currentFocus(const CachedFrame** ) const;
bool directionChange() const;
const CachedNode* document() const { return mCachedNodes.begin(); }
bool empty() const { return mCachedNodes.size() < 2; } // must have 1 past doc
const CachedNode* findBestAt(const WebCore::IntRect& , int* best, bool* inside,
const CachedNode** , const CachedFrame** , int* x, int* y) const;
const CachedFrame* findBestFrameAt(int x, int y) const;
const CachedNode* findBestHitAt(const WebCore::IntRect& ,
int* best, const CachedFrame** , int* x, int* y) const;
bool finishInit();
CachedFrame* firstChild() { return mCachedFrames.begin(); }
const CachedFrame* firstChild() const { return mCachedFrames.begin(); }
int focusIndex() const { return mFocus; }
void* framePointer() const { return mFrame; }
CachedNode* getIndex(int index) { return index >= 0 ?
&mCachedNodes[index] : NULL; }
const CachedFrame* hasFrame(const CachedNode* node) const;
int indexInParent() const { return mIndex; }
void init(const CachedRoot* root, int index, WebCore::Frame* frame);
const CachedFrame* lastChild() const { return &mCachedFrames.last(); }
CachedNode* lastNode() { return &mCachedNodes.last(); }
CachedFrame* lastChild() { return &mCachedFrames.last(); }
const CachedFrame* parent() const { return mParent; }
CachedFrame* parent() { return mParent; }
bool sameFrame(const CachedFrame* ) const;
void removeLast() { mCachedNodes.removeLast(); }
void resetClippedOut();
void setContentsSize(int width, int height) { mContents.setWidth(width);
mContents.setHeight(height); }
void setData();
bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y);
void setFocusIndex(int focusIndex) const { mFocus = focusIndex; }
void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; }
int size() { return mCachedNodes.size(); }
const CachedNode* validDocument() const;
protected:
struct BestData {
WebCore::IntRect mNodeBounds;
WebCore::IntRect mMouseBounds;
int mDistance;
int mSideDistance;
int mMajorDelta; // difference of center of object
// used only when leading and trailing edges contain another set of edges
int mMajorDelta2; // difference of leading edge (only used when center is same)
int mMajorButt; // checks for next cell butting up against or close to previous one
int mWorkingDelta;
int mWorkingDelta2;
int mNavDelta;
int mNavDelta2;
const CachedFrame* mFrame;
const CachedNode* mNode;
SkFixed mWorkingOverlap; // this and below are fuzzy answers instead of bools
SkFixed mNavOverlap;
SkFixed mPreferred;
bool mFocusChild;
bool mInNav;
bool mNavOutside;
bool mWorkingOutside;
int bottom() const { return bounds().bottom(); }
const WebCore::IntRect& bounds() const { return mNodeBounds; }
bool canBeReachedByAnotherDirection();
int height() const { return bounds().height(); }
bool inOrSubsumesNav() const { return (mNavDelta ^ mNavDelta2) >= 0; }
bool inOrSubsumesWorking() const { return (mWorkingDelta ^ mWorkingDelta2) >= 0; }
int isContainer(BestData* );
static SkFixed Overlap(int span, int left, int right);
void reset() { mNode = NULL; }
int right() const { return bounds().right(); }
void setDistances();
bool setDownDirection(const CachedHistory* );
bool setLeftDirection(const CachedHistory* );
bool setRightDirection(const CachedHistory* );
bool setUpDirection(const CachedHistory* );
void setNavInclusion(int left, int right);
void setNavOverlap(int span, int left, int right);
void setWorkingInclusion(int left, int right);
void setWorkingOverlap(int span, int left, int right);
int width() const { return bounds().width(); }
int x() const { return bounds().x(); }
int y() const { return bounds().y(); }
};
typedef const CachedNode* (CachedFrame::*MoveInDirection)(
const CachedNode* test, const CachedNode* limit, BestData* bestData,
const CachedNode* focus) const;
void adjustToTextColumn(int* delta) const;
static bool CheckBetween(Direction , const WebCore::IntRect& bestRect,
const WebCore::IntRect& prior, WebCore::IntRect* result);
bool checkBetween(BestData* , Direction );
int compare(BestData& testData, const BestData& bestData, const
CachedNode* focus) const;
void findClosest(BestData* , Direction original, Direction test,
WebCore::IntRect* clip) const;
int frameNodeCommon(BestData& testData, const CachedNode* test,
BestData* bestData, BestData* originalData,
const CachedNode* focus) const;
int framePartCommon(BestData& testData, const CachedNode* test,
BestData* bestData, const CachedNode* focus) const;
const CachedNode* frameDown(const CachedNode* test, const CachedNode* limit,
BestData* , const CachedNode* focus) const;
const CachedNode* frameLeft(const CachedNode* test, const CachedNode* limit,
BestData* , const CachedNode* focus) const;
const CachedNode* frameRight(const CachedNode* test, const CachedNode* limit,
BestData* , const CachedNode* focus) const;
const CachedNode* frameUp(const CachedNode* test, const CachedNode* limit,
BestData* , const CachedNode* focus) const;
int minWorkingHorizontal() const;
int minWorkingVertical() const;
int maxWorkingHorizontal() const;
int maxWorkingVertical() const;
bool moveInFrame(MoveInDirection , const CachedNode* test, BestData* best,
const CachedNode* focus) const;
const WebCore::IntRect& _navBounds() const;
WebCore::IntRect mContents;
WebCore::IntRect mLocalViewBounds;
WebCore::IntRect mViewBounds;
WTF::Vector<CachedNode> mCachedNodes;
WTF::Vector<CachedFrame> mCachedFrames;
void* mFrame; // WebCore::Frame*, used only to compare pointers
CachedFrame* mParent;
int mIndex; // index within parent's array of children, or -1 if root
const CachedRoot* mRoot;
mutable int mFocus;
private:
CachedHistory* history() const;
#ifdef BROWSER_DEBUG
public:
CachedNode* find(WebCore::Node* ); // !!! probably debugging only
int mDebugIndex;
int mDebugLoopbackOffset;
#endif
#if !defined NDEBUG || DUMP_NAV_CACHE
public:
class Debug {
public:
Debug() {
#if DUMP_NAV_CACHE
mFrameName[0] = '\0';
#endif
#if !defined NDEBUG
mInUse = true;
#endif
}
#if !defined NDEBUG
~Debug() { mInUse = false; }
bool mInUse;
#endif
#if DUMP_NAV_CACHE
CachedFrame* base() const;
void print() const;
bool validate(const CachedNode* ) const;
char mFrameName[256];
#endif
} mDebug;
#endif
};
}
#endif
|