1/* 2 Copyright (C) 2009-2012 Samsung Electronics 3 Copyright (C) 2009-2010 ProFUSION embedded systems 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public License 16 along with this library; see the file COPYING.LIB. If not, write to 17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19*/ 20 21#include "config.h" 22 23#include "TiledBackingStore.h" 24#include "ewk_paint_context_private.h" 25#include "ewk_private.h" 26 27#if ENABLE(INSPECTOR) 28#include "InspectorController.h" 29#include "Page.h" 30#endif 31 32Ewk_Paint_Context* ewk_paint_context_new(cairo_t* cairo) 33{ 34 EINA_SAFETY_ON_NULL_RETURN_VAL(cairo, 0); 35 36 Ewk_Paint_Context* context = new Ewk_Paint_Context; 37 context->graphicContext = adoptPtr(new WebCore::GraphicsContext(cairo)); 38 context->cairo = adoptRef(cairo_reference(cairo)); 39 context->image = 0; 40 context->pixels = 0; 41 42 return context; 43} 44 45Ewk_Paint_Context* ewk_paint_context_from_image_new(Evas_Object* image) 46{ 47 EINA_SAFETY_ON_NULL_RETURN_VAL(image, 0); 48 49 Evas_Coord width, height; 50 uint8_t* pixels = static_cast<uint8_t*>(evas_object_image_data_get(image, true)); 51 evas_object_image_size_get(image, &width, &height); 52 53 Ewk_Paint_Context* context = ewk_paint_context_from_image_data_new(pixels, width, height, EVAS_COLORSPACE_ARGB8888); 54 if (context) { 55 context->pixels = pixels; 56 context->image = image; 57 } 58 59 return context; 60} 61 62Ewk_Paint_Context* ewk_paint_context_from_image_data_new(uint8_t* pixels, int width, int height, int colorSpace) 63{ 64 EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, 0); 65 66 OwnPtr<Ewk_Paint_Context> context = adoptPtr(new Ewk_Paint_Context); 67 context->pixels = pixels; 68 context->image = 0; 69 70 cairo_format_t format; 71 int stride; 72 switch (colorSpace) { 73 case EVAS_COLORSPACE_ARGB8888: 74 stride = width * 4; 75 format = CAIRO_FORMAT_ARGB32; 76 break; 77 case EVAS_COLORSPACE_RGB565_A5P: 78 stride = width * 2; 79 format = CAIRO_FORMAT_RGB16_565; 80 break; 81 default: 82 ERR("unknown color space: %d", colorSpace); 83 return 0; 84 } 85 86 context->surface = adoptRef(cairo_image_surface_create_for_data(pixels, format, width, height, stride)); 87 cairo_status_t status = cairo_surface_status(context->surface.get()); 88 if (status != CAIRO_STATUS_SUCCESS) { 89 ERR("could not create surface from data %dx%d: %s", width, height, cairo_status_to_string(status)); 90 return 0; 91 } 92 93 context->cairo = adoptRef(cairo_create(context->surface.get())); 94 status = cairo_status(context->cairo.get()); 95 if (status != CAIRO_STATUS_SUCCESS) { 96 ERR("could not create cairo from surface %dx%d: %s", width, height, cairo_status_to_string(status)); 97 return 0; 98 } 99 100 context->graphicContext = adoptPtr(new WebCore::GraphicsContext(context->cairo.get())); 101 102 return context.release().leakPtr(); 103} 104 105void ewk_paint_context_free(Ewk_Paint_Context* context) 106{ 107 EINA_SAFETY_ON_NULL_RETURN(context); 108 109 if (context->image && context->pixels) { 110 // Decrease refcount inside image object. 111 evas_object_image_data_set(context->image, context->pixels); 112 } 113 delete context; 114} 115 116void ewk_paint_context_save(Ewk_Paint_Context* context) 117{ 118 EINA_SAFETY_ON_NULL_RETURN(context); 119 120 cairo_save(context->cairo.get()); 121 context->graphicContext->save(); 122} 123 124void ewk_paint_context_restore(Ewk_Paint_Context* context) 125{ 126 EINA_SAFETY_ON_NULL_RETURN(context); 127 128 context->graphicContext->restore(); 129 cairo_restore(context->cairo.get()); 130} 131 132void ewk_paint_context_clip(Ewk_Paint_Context* context, const Eina_Rectangle* area) 133{ 134 EINA_SAFETY_ON_NULL_RETURN(context); 135 EINA_SAFETY_ON_NULL_RETURN(area); 136 137 context->graphicContext->clip(WebCore::IntRect(*area)); 138} 139 140void ewk_paint_context_scale(Ewk_Paint_Context* context, float scaleX, float scaleY) 141{ 142 EINA_SAFETY_ON_NULL_RETURN(context); 143 144 context->graphicContext->scale(WebCore::FloatSize(scaleX, scaleY)); 145} 146 147void ewk_paint_context_translate(Ewk_Paint_Context* context, float x, float y) 148{ 149 EINA_SAFETY_ON_NULL_RETURN(context); 150 151 context->graphicContext->translate(x, y); 152} 153 154void ewk_paint_context_paint(Ewk_Paint_Context* context, WebCore::FrameView* view, const Eina_Rectangle* area) 155{ 156 EINA_SAFETY_ON_NULL_RETURN(context); 157 EINA_SAFETY_ON_NULL_RETURN(view); 158 EINA_SAFETY_ON_NULL_RETURN(area); 159 160 WebCore::IntRect paintArea(*area); 161 162#if USE(TILED_BACKING_STORE) 163 if (view->frame()->tiledBackingStore()) { 164 int scrollX = view->scrollX(); 165 int scrollY = view->scrollY(); 166 167 context->graphicContext->translate(-scrollX, -scrollY); 168 169 paintArea.move(scrollX, scrollY); 170 171 view->frame()->tiledBackingStore()->paint(context->graphicContext.get(), paintArea); 172 return; 173 } 174#endif 175 176 if (view->isTransparent()) 177 context->graphicContext->clearRect(paintArea); 178 view->paint(context->graphicContext.get(), paintArea); 179} 180 181void ewk_paint_context_paint_contents(Ewk_Paint_Context* context, WebCore::FrameView* view, const Eina_Rectangle* area) 182{ 183 EINA_SAFETY_ON_NULL_RETURN(context); 184 EINA_SAFETY_ON_NULL_RETURN(view); 185 EINA_SAFETY_ON_NULL_RETURN(area); 186 187 WebCore::IntRect paintArea(*area); 188 189 if (view->isTransparent()) 190 context->graphicContext->clearRect(paintArea); 191 view->paintContents(context->graphicContext.get(), paintArea); 192 193#if ENABLE(INSPECTOR) 194 WebCore::Page* page = view->frame()->page(); 195 if (page) { 196 WebCore::InspectorController* controller = page->inspectorController(); 197 if (controller->highlightedNode()) 198 controller->drawHighlight(*context->graphicContext); 199 } 200#endif 201} 202