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 }; 75 CachedFrame() {} 76 void add(CachedColor& color) { mCachedColors.append(color); } 77 void add(CachedInput& input) { mCachedTextInputs.append(input); } 78 #if USE(ACCELERATED_COMPOSITING) 79 void add(CachedLayer& layer) { mCachedLayers.append(layer); } 80 #endif 81 void add(CachedNode& node) { mCachedNodes.append(node); } 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; 88 size_t childCount() { return mCachedFrames.size(); } 89 void clearCursor(); 90 const CachedColor& color(const CachedNode* node) const { 91 return mCachedColors[node->colorIndex()]; 92 } 93 const CachedNode* currentCursor() const { return currentCursor(NULL); } 94 const CachedNode* currentCursor(const CachedFrame** ) const; 95 const CachedNode* currentFocus() const { return currentFocus(NULL); } 96 const CachedNode* currentFocus(const CachedFrame** ) const; 97 bool directionChange() const; 98 const CachedNode* document() const { return mCachedNodes.begin(); } 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(); 108 CachedFrame* firstChild() { return mCachedFrames.begin(); } 109 const CachedFrame* firstChild() const { return mCachedFrames.begin(); } 110 void* framePointer() const { return mFrame; } 111 CachedNode* getIndex(int index) { return index >= 0 ? 112 &mCachedNodes[index] : NULL; } 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(); 118 int indexInParent() const { return mIndexInParent; } 119 void init(const CachedRoot* root, int index, WebCore::Frame* frame); 120 const CachedFrame* lastChild() const { return &mCachedFrames.last(); } 121 #if USE(ACCELERATED_COMPOSITING) 122 const CachedLayer* lastLayer() const { return &mCachedLayers.last(); } 123 #endif 124 CachedNode* lastNode() { return &mCachedNodes.last(); } 125 CachedFrame* lastChild() { return &mCachedFrames.last(); } 126 #if USE(ACCELERATED_COMPOSITING) 127 const CachedLayer* layer(const CachedNode* ) const; 128 size_t layerCount() const { return mCachedLayers.size(); } 129 #endif 130 WebCore::IntRect localBounds(const CachedNode* , 131 const WebCore::IntRect& ) const; 132 const CachedFrame* parent() const { return mParent; } 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; 138 void removeLast() { mCachedNodes.removeLast(); } 139 void resetClippedOut(); 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); 143 void setCursorIndex(int index) { mCursorIndex = index; } 144 void setData(); 145 bool setFocus(WebCore::Frame* , WebCore::Node* , int x, int y); 146 void setFocusIndex(int index) { mFocusIndex = index; } 147 void setIndexInParent(int index) { mIndexInParent = index; } 148 void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; } 149 int size() { return mCachedNodes.size(); } 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; 178 int bottom() const { return bounds().maxY(); } 179 const WebCore::IntRect& bounds() const { return mNodeBounds; } 180 bool canBeReachedByAnotherDirection(); 181 int height() const { return bounds().height(); } 182 bool inOrSubsumesNav() const { return (mNavDelta ^ mNavDelta2) >= 0; } 183 bool inOrSubsumesWorking() const { return (mWorkingDelta ^ mWorkingDelta2) >= 0; } 184 int isContainer(BestData* ); 185 const WebCore::IntRect& mouseBounds() const { return mMouseBounds; } 186 static SkFixed Overlap(int span, int left, int right); 187 void reset() { mNode = NULL; } 188 int right() const { return bounds().maxX(); } 189 void setMouseBounds(const WebCore::IntRect& b) { mMouseBounds = b; } 190 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); 200 int width() const { return bounds().width(); } 201 int x() const { return bounds().x(); } 202 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: 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 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