summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/android/nav/CachedFrame.h
blob: c7b1327fee5f6a5903dc9c8bdd895067d580617a (plain)
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
/* 
** Copyright 2007, 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 CachedFrame_H
#define CachedFrame_H

#include "CachedNode.h"
#include "IntRect.h"
#include "SkFixed.h"
#include "wtf/Vector.h"

namespace WebCore {
    class Frame;
    class FrameAndroid;
    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();
    bool containsFrame(const CachedFrame* ) const;
    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,
        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::FrameAndroid* 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; }
    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