Home | History | Annotate | Download | only in nav
      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