• 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 APPLE COMPUTER, INC. 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 class WebCore::Node;
38 
39 class Container {
40 public:
Container(WebCore::Node * node,const WebCore::IntRect & r)41     Container(WebCore::Node* node, const WebCore::IntRect& r)
42         : m_node(node), m_rect(r), m_state(WebCore::RenderSkinAndroid::kDisabled)
43     {
44         m_picture = new SkPicture;
45     }
46 
~Container()47     ~Container()
48     {
49         m_picture->unref();
50     }
51 
52     Container& operator=(const Container& src)
53     {
54         if (this != &src) {
55             m_node = src.m_node;
56             if (m_picture)
57                 m_picture->unref();
58             m_picture = src.m_picture;
59             m_picture->ref();
60             m_rect = src.m_rect;
61             m_state = WebCore::RenderSkinAndroid::kDisabled;
62         }
63         return *this;
64     }
65 
Container(const Container & src)66     Container(const Container& src)
67     {
68         m_node = src.m_node;
69         m_picture = src.m_picture;
70         m_picture->ref();
71         m_rect = src.m_rect;
72         m_state = WebCore::RenderSkinAndroid::kDisabled;
73     }
74 
75     // m_picture has a ref count of 1 to begin with.  It will increase each time
76     // m_picture is referenced by another picture.  When the other pictures are
77     // deleted, the ref count gets decremented.  If the ref count is one, then
78     // no other pictures reference this one, so the button is no longer being
79     // used, and therefore can be removed.
canBeRemoved()80     bool canBeRemoved()
81     {
82         return m_picture->getRefCnt() == 1;
83     }
84 
matches(const WebCore::Node * match)85     bool matches(const WebCore::Node* match) { return m_node == match; }
86 
node()87     const WebCore::Node* node() const { return m_node; }
88 
89     // Provide a pointer to our SkPicture.
picture()90     SkPicture* picture() { return m_picture; }
91 
rect()92     WebCore::IntRect rect() { return m_rect; }
93 
94     // Update the rectangle with a new rectangle, as the positioning of this
95     // button may have changed due to a new layout.  If it is a new rectangle,
96     // set its state to disabled, so that it will be redrawn when we cycle
97     // through the list of buttons.
setRect(WebCore::IntRect r)98     void setRect(WebCore::IntRect r)
99     {
100         if (m_rect != r) {
101             m_rect = r;
102             m_state = WebCore::RenderSkinAndroid::kDisabled;
103         }
104     }
105 
106     // Update the focus state of this button, depending on whether it
107     // corresponds to the focused node passed in.  If its state has changed,
108     // re-record to the subpicture, so the master picture will reflect the
109     // change.
updateFocusState(WebCore::RenderSkinAndroid::State state)110     void updateFocusState(WebCore::RenderSkinAndroid::State state)
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.width(), m_rect.height());
122         WebCore::RenderSkinButton::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     void setupFillPaint(GraphicsContext*, SkPaint*);
153     void setupStrokePaint(GraphicsContext*, SkPaint*);
154 
155     SkCanvas*                   mCanvas;
156 
deleteUs()157     bool deleteUs() const { return m_deleteCanvas; }
158     // If our graphicscontext has a button list, add a new container for the
159     // nod/rect, and record a new subpicture for this node/button in the current
160     // mCanvas
161     void storeButtonInfo(Node* node, const IntRect& r);
162 private:
163     bool                     m_deleteCanvas;
164     WTF::Vector<Container>*    m_buttons;
165 };
166 
167 }
168 #endif
169 
170