• 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,WebCore::RenderSkinButton * buttonSkin)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 
deleteUs()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