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