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