• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
Container(WebCore::Node * node,const WebCore::IntRect & r)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 
~Container()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 
Container(const Container & src)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.
canBeRemoved()79     bool canBeRemoved()
80     {
81         return m_picture->getRefCnt() == 1;
82     }
83 
matches(const WebCore::Node * match)84     bool matches(const WebCore::Node* match) { return m_node == match; }
85 
node()86     const WebCore::Node* node() const { return m_node; }
87 
88     // Provide a pointer to our SkPicture.
picture()89     SkPicture* picture() { return m_picture; }
90 
rect()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.
setRect(WebCore::IntRect r)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.
updateFocusState(WebCore::RenderSkinAndroid::State state)109     void updateFocusState(WebCore::RenderSkinAndroid::State state)
110     {
111         if (state == m_state)
112             return;
113         // If this button is being told to draw focused, but it is already in a
114         // pressed state, leave it in the pressed state, to show that it is
115         // being followed.
116         if (m_state == WebCore::RenderSkinAndroid::kPressed &&
117                 state == WebCore::RenderSkinAndroid::kFocused)
118             return;
119         m_state = state;
120         SkCanvas* canvas = m_picture->beginRecording(m_rect.width(), m_rect.height());
121         WebCore::RenderSkinButton::Draw(canvas, m_rect, state);
122         m_picture->endRecording();
123     }
124 private:
125     // Only used for comparison, since after it is stored it will be transferred
126     // to the UI thread.
127     WebCore::Node*                      m_node;
128     // The rectangle representing the bounds of the button.
129     WebCore::IntRect                    m_rect;
130     // An SkPicture that, thanks to storeButtonInfo, is pointed to by the master
131     // picture, so that we can rerecord this button without rerecording the
132     // world.
133     SkPicture*                          m_picture;
134     // The state of the button - Currently kFocused or kNormal (and kDisabled
135     // as an initial value), but could be expanded to include other states.
136     WebCore::RenderSkinAndroid::State   m_state;
137 };
138 
139 namespace WebCore {
140 
141     class GraphicsContext;
142 
143 class PlatformGraphicsContext {
144 public:
145     PlatformGraphicsContext();
146     // Pass in a recording canvas, and an array of button information to be
147     // updated.
148     PlatformGraphicsContext(SkCanvas* canvas, WTF::Vector<Container>* buttons);
149     ~PlatformGraphicsContext();
150 
151     SkCanvas*                   mCanvas;
152 
deleteUs()153     bool deleteUs() const { return m_deleteCanvas; }
154     // If our graphicscontext has a button list, add a new container for the
155     // nod/rect, and record a new subpicture for this node/button in the current
156     // mCanvas
157     void storeButtonInfo(Node* node, const IntRect& r);
158 private:
159     bool                     m_deleteCanvas;
160     WTF::Vector<Container>*    m_buttons;
161 };
162 
163 }
164 #endif
165