Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright 2006, 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 #ifndef platform_graphics_context_h
     27 #define platform_graphics_context_h
     28 
     29 #include "IntRect.h"
     30 #include "RenderSkinAndroid.h"
     31 #include "RenderSkinButton.h"
     32 #include "SkCanvas.h"
     33 #include "SkPicture.h"
     34 #include "SkTDArray.h"
     35 
     36 class SkCanvas;
     37 
     38 class Container {
     39 public:
     40     Container(WebCore::Node* node, const WebCore::IntRect& r)
     41         : m_node(node), m_rect(r), m_state(WebCore::RenderSkinAndroid::kDisabled)
     42     {
     43         m_picture = new SkPicture;
     44     }
     45 
     46     ~Container()
     47     {
     48         m_picture->unref();
     49     }
     50 
     51     Container& operator=(const Container& src)
     52     {
     53         if (this != &src) {
     54             m_node = src.m_node;
     55             if (m_picture)
     56                 m_picture->unref();
     57             m_picture = src.m_picture;
     58             m_picture->ref();
     59             m_rect = src.m_rect;
     60             m_state = WebCore::RenderSkinAndroid::kDisabled;
     61         }
     62         return *this;
     63     }
     64 
     65     Container(const Container& src)
     66     {
     67         m_node = src.m_node;
     68         m_picture = src.m_picture;
     69         m_picture->ref();
     70         m_rect = src.m_rect;
     71         m_state = WebCore::RenderSkinAndroid::kDisabled;
     72     }
     73 
     74     // m_picture has a ref count of 1 to begin with.  It will increase each time
     75     // m_picture is referenced by another picture.  When the other pictures are
     76     // deleted, the ref count gets decremented.  If the ref count is one, then
     77     // no other pictures reference this one, so the button is no longer being
     78     // used, and therefore can be removed.
     79     bool canBeRemoved()
     80     {
     81         return m_picture->getRefCnt() == 1;
     82     }
     83 
     84     bool matches(const WebCore::Node* match) { return m_node == match; }
     85 
     86     const WebCore::Node* node() const { return m_node; }
     87 
     88     // Provide a pointer to our SkPicture.
     89     SkPicture* picture() { return m_picture; }
     90 
     91     WebCore::IntRect rect() { return m_rect; }
     92 
     93     // Update the rectangle with a new rectangle, as the positioning of this
     94     // button may have changed due to a new layout.  If it is a new rectangle,
     95     // set its state to disabled, so that it will be redrawn when we cycle
     96     // through the list of buttons.
     97     void setRect(WebCore::IntRect r)
     98     {
     99         if (m_rect != r) {
    100             m_rect = r;
    101             m_state = WebCore::RenderSkinAndroid::kDisabled;
    102         }
    103     }
    104 
    105     // Update the focus state of this button, depending on whether it
    106     // corresponds to the focused node passed in.  If its state has changed,
    107     // re-record to the subpicture, so the master picture will reflect the
    108     // change.
    109     void updateFocusState(WebCore::RenderSkinAndroid::State state,
    110                           WebCore::RenderSkinButton* buttonSkin)
    111     {
    112         if (state == m_state)
    113             return;
    114         // If this button is being told to draw focused, but it is already in a
    115         // pressed state, leave it in the pressed state, to show that it is
    116         // being followed.
    117         if (m_state == WebCore::RenderSkinAndroid::kPressed &&
    118                 state == WebCore::RenderSkinAndroid::kFocused)
    119             return;
    120         m_state = state;
    121         SkCanvas* canvas = m_picture->beginRecording(m_rect.maxX(), m_rect.maxY());
    122         buttonSkin->draw(canvas, m_rect, state);
    123         m_picture->endRecording();
    124     }
    125 private:
    126     // Only used for comparison, since after it is stored it will be transferred
    127     // to the UI thread.
    128     WebCore::Node*                      m_node;
    129     // The rectangle representing the bounds of the button.
    130     WebCore::IntRect                    m_rect;
    131     // An SkPicture that, thanks to storeButtonInfo, is pointed to by the master
    132     // picture, so that we can rerecord this button without rerecording the
    133     // world.
    134     SkPicture*                          m_picture;
    135     // The state of the button - Currently kFocused or kNormal (and kDisabled
    136     // as an initial value), but could be expanded to include other states.
    137     WebCore::RenderSkinAndroid::State   m_state;
    138 };
    139 
    140 namespace WebCore {
    141 
    142     class GraphicsContext;
    143 
    144 class PlatformGraphicsContext {
    145 public:
    146     PlatformGraphicsContext();
    147     // Pass in a recording canvas, and an array of button information to be
    148     // updated.
    149     PlatformGraphicsContext(SkCanvas* canvas, WTF::Vector<Container>* buttons);
    150     ~PlatformGraphicsContext();
    151 
    152     SkCanvas*                   mCanvas;
    153 
    154     bool deleteUs() const { return m_deleteCanvas; }
    155     // If our graphicscontext has a button list, add a new container for the
    156     // nod/rect, and record a new subpicture for this node/button in the current
    157     // mCanvas
    158     void storeButtonInfo(Node* node, const IntRect& r);
    159 private:
    160     bool                     m_deleteCanvas;
    161     WTF::Vector<Container>*    m_buttons;
    162 };
    163 
    164 }
    165 #endif
    166