Home | History | Annotate | Download | only in efl
      1 /*
      2  * Copyright (C) 2007 Apple Inc.
      3  * Copyright (C) 2007 Alp Toker <alp (at) atoker.com>
      4  * Copyright (C) 2008 Collabora Ltd.
      5  * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
      6  * Copyright (C) 2009-2010 ProFUSION embedded systems
      7  * Copyright (C) 2009-2011 Samsung Electronics
      8  *
      9  * This library is free software; you can redistribute it and/or
     10  * modify it under the terms of the GNU Library General Public
     11  * License as published by the Free Software Foundation; either
     12  * version 2 of the License, or (at your option) any later version.
     13  *
     14  * This library is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17  * Library General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU Library General Public License
     20  * along with this library; see the file COPYING.LIB.  If not, write to
     21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     22  * Boston, MA 02110-1301, USA.
     23  *
     24  */
     25 
     26 #include "config.h"
     27 #include "RenderThemeEfl.h"
     28 
     29 #include "CSSValueKeywords.h"
     30 #include "FileSystem.h"
     31 #include "Frame.h"
     32 #include "FrameView.h"
     33 #include "GraphicsContext.h"
     34 #include "NotImplemented.h"
     35 #include "PaintInfo.h"
     36 #include "Page.h"
     37 #include "PlatformContextCairo.h"
     38 #include "RenderBox.h"
     39 #include "RenderObject.h"
     40 #include "RenderProgress.h"
     41 #include "RenderSlider.h"
     42 #include "UserAgentStyleSheets.h"
     43 #include <wtf/text/CString.h>
     44 
     45 #include <Ecore_Evas.h>
     46 #include <Edje.h>
     47 
     48 #if ENABLE(VIDEO)
     49 #include "HTMLMediaElement.h"
     50 #include "HTMLNames.h"
     51 #endif
     52 
     53 namespace WebCore {
     54 #if ENABLE(VIDEO)
     55 using namespace HTMLNames;
     56 #endif
     57 
     58 // TODO: change from object count to ecore_evas size (bytes)
     59 // TODO: as objects are webpage/user defined and they can be very large.
     60 #define RENDER_THEME_EFL_PART_CACHE_MAX 32
     61 
     62 void RenderThemeEfl::adjustSizeConstraints(RenderStyle* style, FormType type) const
     63 {
     64     const struct ThemePartDesc* desc = m_partDescs + (size_t)type;
     65 
     66     if (style->minWidth().isIntrinsicOrAuto())
     67         style->setMinWidth(desc->min.width());
     68     if (style->minHeight().isIntrinsicOrAuto())
     69         style->setMinHeight(desc->min.height());
     70 
     71     if (desc->max.width().value() > 0 && style->maxWidth().isIntrinsicOrAuto())
     72         style->setMaxWidth(desc->max.width());
     73     if (desc->max.height().value() > 0 && style->maxHeight().isIntrinsicOrAuto())
     74         style->setMaxHeight(desc->max.height());
     75 
     76     style->setPaddingTop(desc->padding.top());
     77     style->setPaddingBottom(desc->padding.bottom());
     78     style->setPaddingLeft(desc->padding.left());
     79     style->setPaddingRight(desc->padding.right());
     80 }
     81 
     82 bool RenderThemeEfl::themePartCacheEntryReset(struct ThemePartCacheEntry* entry, FormType type)
     83 {
     84     const char *file, *group;
     85 
     86     ASSERT(entry);
     87 
     88     edje_object_file_get(m_edje, &file, 0);
     89     group = edjeGroupFromFormType(type);
     90     ASSERT(file);
     91     ASSERT(group);
     92 
     93     if (!edje_object_file_set(entry->o, file, group)) {
     94         Edje_Load_Error err = edje_object_load_error_get(entry->o);
     95         const char *errmsg = edje_load_error_str(err);
     96         EINA_LOG_ERR("Could not load '%s' from theme %s: %s",
     97                      group, file, errmsg);
     98         return false;
     99     }
    100     return true;
    101 }
    102 
    103 bool RenderThemeEfl::themePartCacheEntrySurfaceCreate(struct ThemePartCacheEntry* entry)
    104 {
    105     int w, h;
    106     cairo_status_t status;
    107 
    108     ASSERT(entry);
    109     ASSERT(entry->ee);
    110 
    111     ecore_evas_geometry_get(entry->ee, 0, 0, &w, &h);
    112     ASSERT(w > 0);
    113     ASSERT(h > 0);
    114 
    115     entry->surface = cairo_image_surface_create_for_data((unsigned char *)ecore_evas_buffer_pixels_get(entry->ee),
    116                                                       CAIRO_FORMAT_ARGB32, w, h, w * 4);
    117     status = cairo_surface_status(entry->surface);
    118     if (status != CAIRO_STATUS_SUCCESS) {
    119         EINA_LOG_ERR("Could not create cairo surface: %s",
    120                      cairo_status_to_string(status));
    121         return false;
    122     }
    123 
    124     return true;
    125 }
    126 
    127 // allocate a new entry and fill it with edje group
    128 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartNew(FormType type, const IntSize& size)
    129 {
    130     struct ThemePartCacheEntry *entry = new struct ThemePartCacheEntry;
    131 
    132     if (!entry) {
    133         EINA_LOG_ERR("could not allocate ThemePartCacheEntry.");
    134         return 0;
    135     }
    136 
    137     entry->ee = ecore_evas_buffer_new(size.width(), size.height());
    138     if (!entry->ee) {
    139         EINA_LOG_ERR("ecore_evas_buffer_new(%d, %d) failed.",
    140                      size.width(), size.height());
    141         delete entry;
    142         return 0;
    143     }
    144 
    145     entry->o = edje_object_add(ecore_evas_get(entry->ee));
    146     ASSERT(entry->o);
    147     if (!themePartCacheEntryReset(entry, type)) {
    148         evas_object_del(entry->o);
    149         ecore_evas_free(entry->ee);
    150         delete entry;
    151         return 0;
    152     }
    153 
    154     if (!themePartCacheEntrySurfaceCreate(entry)) {
    155         evas_object_del(entry->o);
    156         ecore_evas_free(entry->ee);
    157         delete entry;
    158         return 0;
    159     }
    160 
    161     evas_object_resize(entry->o, size.width(), size.height());
    162     evas_object_show(entry->o);
    163 
    164     entry->type = type;
    165     entry->size = size;
    166 
    167     m_partCache.prepend(entry);
    168     return entry;
    169 }
    170 
    171 // just change the edje group and return the same entry
    172 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartReset(FormType type, struct RenderThemeEfl::ThemePartCacheEntry* entry)
    173 {
    174     if (!themePartCacheEntryReset(entry, type)) {
    175         entry->type = FormTypeLast; // invalidate
    176         m_partCache.append(entry);
    177         return 0;
    178     }
    179     entry->type = type;
    180     m_partCache.prepend(entry);
    181     return entry;
    182 }
    183 
    184 // resize entry and reset it
    185 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartResizeAndReset(FormType type, const IntSize& size, struct RenderThemeEfl::ThemePartCacheEntry* entry)
    186 {
    187     cairo_surface_finish(entry->surface);
    188     ecore_evas_resize(entry->ee, size.width(), size.height());
    189     evas_object_resize(entry->o, size.width(), size.height());
    190 
    191     if (!themePartCacheEntrySurfaceCreate(entry)) {
    192         evas_object_del(entry->o);
    193         ecore_evas_free(entry->ee);
    194         delete entry;
    195         return 0;
    196     }
    197 
    198     return cacheThemePartReset(type, entry);
    199 }
    200 
    201 // general purpose get (will create, reuse and all)
    202 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartGet(FormType type, const IntSize& size)
    203 {
    204     Vector<struct ThemePartCacheEntry *>::iterator itr, end;
    205     struct ThemePartCacheEntry *ce_last_size = 0;
    206     int i, idxLastSize = -1;
    207 
    208     itr = m_partCache.begin();
    209     end = m_partCache.end();
    210     for (i = 0; itr != end; i++, itr++) {
    211         struct ThemePartCacheEntry *entry = *itr;
    212         if (entry->size == size) {
    213             if (entry->type == type)
    214                 return entry;
    215             ce_last_size = entry;
    216             idxLastSize = i;
    217         }
    218     }
    219 
    220     if (m_partCache.size() < RENDER_THEME_EFL_PART_CACHE_MAX)
    221         return cacheThemePartNew(type, size);
    222 
    223     if (ce_last_size && ce_last_size != m_partCache.first()) {
    224         m_partCache.remove(idxLastSize);
    225         return cacheThemePartReset(type, ce_last_size);
    226     }
    227 
    228     ThemePartCacheEntry* entry = m_partCache.last();
    229     m_partCache.removeLast();
    230     return cacheThemePartResizeAndReset(type, size, entry);
    231 }
    232 
    233 void RenderThemeEfl::cacheThemePartFlush()
    234 {
    235     Vector<struct ThemePartCacheEntry *>::iterator itr, end;
    236 
    237     itr = m_partCache.begin();
    238     end = m_partCache.end();
    239     for (; itr != end; itr++) {
    240         struct ThemePartCacheEntry *entry = *itr;
    241         cairo_surface_finish(entry->surface);
    242         evas_object_del(entry->o);
    243         ecore_evas_free(entry->ee);
    244         delete entry;
    245     }
    246     m_partCache.clear();
    247 }
    248 
    249 void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* object, ControlStates states)
    250 {
    251     const char *signals[] = { // keep in sync with WebCore/platform/ThemeTypes.h
    252         "hovered",
    253         "pressed",
    254         "focused",
    255         "enabled",
    256         "checked",
    257         "read-only",
    258         "default",
    259         "window-inactive",
    260         "indeterminate"
    261     };
    262 
    263     edje_object_signal_emit(object, "reset", "");
    264 
    265     for (size_t i = 0; i < WTF_ARRAY_LENGTH(signals); ++i) {
    266         if (states & (1 << i))
    267             edje_object_signal_emit(object, signals[i], "");
    268     }
    269 }
    270 
    271 bool RenderThemeEfl::paintThemePart(RenderObject* object, FormType type, const PaintInfo& info, const IntRect& rect)
    272 {
    273     ThemePartCacheEntry* entry;
    274     Eina_List* updates;
    275     cairo_t* cairo;
    276 
    277     ASSERT(m_canvas);
    278     ASSERT(m_edje);
    279 
    280     entry = cacheThemePartGet(type, rect.size());
    281     ASSERT(entry);
    282     if (!entry)
    283         return false;
    284 
    285     applyEdjeStateFromForm(entry->o, controlStatesForRenderer(object));
    286 
    287     cairo = info.context->platformContext()->cr();
    288     ASSERT(cairo);
    289 
    290     // Currently, only sliders needs this message; if other widget ever needs special
    291     // treatment, move them to special functions.
    292     if (type == SliderVertical || type == SliderHorizontal) {
    293         RenderSlider* renderSlider = toRenderSlider(object);
    294         Edje_Message_Float_Set* msg;
    295         int max, value;
    296 
    297         if (type == SliderVertical) {
    298             max = rect.height() - renderSlider->thumbRect().height();
    299             value = renderSlider->thumbRect().y();
    300         } else {
    301             max = rect.width() - renderSlider->thumbRect().width();
    302             value = renderSlider->thumbRect().x();
    303         }
    304 
    305         msg = static_cast<Edje_Message_Float_Set*>(alloca(sizeof(Edje_Message_Float_Set) + sizeof(float)));
    306 
    307         msg->count = 2;
    308         msg->val[0] = static_cast<float>(value) / static_cast<float>(max);
    309         msg->val[1] = 0.1;
    310         edje_object_message_send(entry->o, EDJE_MESSAGE_FLOAT_SET, 0, msg);
    311 #if ENABLE(PROGRESS_TAG)
    312     } else if (type == ProgressBar) {
    313         RenderProgress* renderProgress = toRenderProgress(object);
    314         Edje_Message_Float_Set* msg;
    315         int max;
    316         double value;
    317 
    318         msg = static_cast<Edje_Message_Float_Set*>(alloca(sizeof(Edje_Message_Float_Set) + sizeof(float)));
    319         max = rect.width();
    320         value = renderProgress->position();
    321 
    322         msg->count = 2;
    323         if (object->style()->direction() == RTL)
    324             msg->val[0] = (1.0 - value) * max;
    325         else
    326             msg->val[0] = 0;
    327         msg->val[1] = value;
    328         edje_object_message_send(entry->o, EDJE_MESSAGE_FLOAT_SET, 0, msg);
    329 #endif
    330     }
    331 
    332     edje_object_calc_force(entry->o);
    333     edje_object_message_signal_process(entry->o);
    334     updates = evas_render_updates(ecore_evas_get(entry->ee));
    335     evas_render_updates_free(updates);
    336 
    337     cairo_save(cairo);
    338     cairo_set_source_surface(cairo, entry->surface, rect.x(), rect.y());
    339     cairo_paint_with_alpha(cairo, 1.0);
    340     cairo_restore(cairo);
    341 
    342     return false;
    343 }
    344 
    345 PassRefPtr<RenderTheme> RenderThemeEfl::create(Page* page)
    346 {
    347     return adoptRef(new RenderThemeEfl(page));
    348 }
    349 
    350 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
    351 {
    352     if (page)
    353         return RenderThemeEfl::create(page);
    354 
    355     static RenderTheme* fallback = RenderThemeEfl::create(0).releaseRef();
    356     return fallback;
    357 }
    358 
    359 static void renderThemeEflColorClassSelectionActive(void* data, Evas_Object* object, const char* signal, const char* source)
    360 {
    361     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    362     int fr, fg, fb, fa, br, bg, bb, ba;
    363 
    364     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    365         return;
    366 
    367     that->setActiveSelectionColor(fr, fg, fb, fa, br, bg, bb, ba);
    368 }
    369 
    370 static void renderThemeEflColorClassSelectionInactive(void* data, Evas_Object* object, const char* signal, const char* source)
    371 {
    372     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    373     int fr, fg, fb, fa, br, bg, bb, ba;
    374 
    375     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    376         return;
    377 
    378     that->setInactiveSelectionColor(fr, fg, fb, fa, br, bg, bb, ba);
    379 }
    380 
    381 static void renderThemeEflColorClassFocusRing(void* data, Evas_Object* object, const char* signal, const char* source)
    382 {
    383     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    384     int fr, fg, fb, fa;
    385 
    386     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, 0, 0, 0, 0, 0, 0, 0, 0))
    387         return;
    388 
    389     that->setFocusRingColor(fr, fg, fb, fa);
    390 }
    391 
    392 static void renderThemeEflColorClassButtonText(void* data, Evas_Object* object, const char* signal, const char* source)
    393 {
    394     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    395     int fr, fg, fb, fa, br, bg, bb, ba;
    396 
    397     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    398         return;
    399 
    400     that->setButtonTextColor(fr, fg, fb, fa, br, bg, bb, ba);
    401 }
    402 
    403 static void renderThemeEflColorClassComboText(void* data, Evas_Object* object, const char* signal, const char* source)
    404 {
    405     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    406     int fr, fg, fb, fa, br, bg, bb, ba;
    407 
    408     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    409         return;
    410 
    411     that->setComboTextColor(fr, fg, fb, fa, br, bg, bb, ba);
    412 }
    413 
    414 static void renderThemeEflColorClassEntryText(void* data, Evas_Object* object, const char* signal, const char* source)
    415 {
    416     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    417     int fr, fg, fb, fa, br, bg, bb, ba;
    418 
    419     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    420         return;
    421 
    422     that->setEntryTextColor(fr, fg, fb, fa, br, bg, bb, ba);
    423 }
    424 
    425 static void renderThemeEflColorClassSearchText(void* data, Evas_Object* object, const char* signal, const char* source)
    426 {
    427     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    428     int fr, fg, fb, fa, br, bg, bb, ba;
    429     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    430         return;
    431 
    432     that->setSearchTextColor(fr, fg, fb, fa, br, bg, bb, ba);
    433 }
    434 
    435 void RenderThemeEfl::createCanvas()
    436 {
    437     ASSERT(!m_canvas);
    438     m_canvas = ecore_evas_buffer_new(1, 1);
    439     ASSERT(m_canvas);
    440 }
    441 
    442 void RenderThemeEfl::createEdje()
    443 {
    444     ASSERT(!m_edje);
    445     Frame* frame = m_page ? m_page->mainFrame() : 0;
    446     FrameView* view = frame ? frame->view() : 0;
    447     String theme = view ? view->edjeThemeRecursive() : "";
    448     if (theme.isEmpty())
    449         EINA_LOG_ERR("No theme defined, unable to set RenderThemeEfl.");
    450     else {
    451         m_edje = edje_object_add(ecore_evas_get(m_canvas));
    452         if (!m_edje)
    453             EINA_LOG_ERR("Could not create base edje object.");
    454         else if (!edje_object_file_set(m_edje, theme.utf8().data(), "webkit/base")) {
    455             Edje_Load_Error err = edje_object_load_error_get(m_edje);
    456             const char* errmsg = edje_load_error_str(err);
    457             EINA_LOG_ERR("Could not load 'webkit/base' from theme %s: %s",
    458                          theme.utf8().data(), errmsg);
    459             evas_object_del(m_edje);
    460             m_edje = 0;
    461         } else {
    462 #define CONNECT(cc, func)                                               \
    463             edje_object_signal_callback_add(m_edje, "color_class,set",  \
    464                                             "webkit/"cc, func, this)
    465 
    466             CONNECT("selection/active",
    467                     renderThemeEflColorClassSelectionActive);
    468             CONNECT("selection/inactive",
    469                     renderThemeEflColorClassSelectionInactive);
    470             CONNECT("focus_ring", renderThemeEflColorClassFocusRing);
    471             CONNECT("button/text", renderThemeEflColorClassButtonText);
    472             CONNECT("combo/text", renderThemeEflColorClassComboText);
    473             CONNECT("entry/text", renderThemeEflColorClassEntryText);
    474             CONNECT("search/text", renderThemeEflColorClassSearchText);
    475 #undef CONNECT
    476         }
    477     }
    478     ASSERT(m_edje);
    479 }
    480 
    481 void RenderThemeEfl::applyEdjeColors()
    482 {
    483     int fr, fg, fb, fa, br, bg, bb, ba;
    484     ASSERT(m_edje);
    485 #define COLOR_GET(cls)                                                  \
    486     edje_object_color_class_get(m_edje, "webkit/"cls,                   \
    487                                 &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, \
    488                                 0, 0, 0, 0)
    489 
    490     if (COLOR_GET("selection/active")) {
    491         m_activeSelectionForegroundColor = Color(fr, fg, fb, fa);
    492         m_activeSelectionBackgroundColor = Color(br, bg, bb, ba);
    493     }
    494     if (COLOR_GET("selection/inactive")) {
    495         m_inactiveSelectionForegroundColor = Color(fr, fg, fb, fa);
    496         m_inactiveSelectionBackgroundColor = Color(br, bg, bb, ba);
    497     }
    498     if (COLOR_GET("focus_ring")) {
    499         m_focusRingColor = Color(fr, fg, fb, fa);
    500         // webkit just use platformFocusRingColor() for default theme (without page)
    501         // this is ugly, but no other way to do it unless we change
    502         // it to use page themes as much as possible.
    503         RenderTheme::setCustomFocusRingColor(m_focusRingColor);
    504     }
    505     if (COLOR_GET("button/text")) {
    506         m_buttonTextForegroundColor = Color(fr, fg, fb, fa);
    507         m_buttonTextBackgroundColor = Color(br, bg, bb, ba);
    508     }
    509     if (COLOR_GET("combo/text")) {
    510         m_comboTextForegroundColor = Color(fr, fg, fb, fa);
    511         m_comboTextBackgroundColor = Color(br, bg, bb, ba);
    512     }
    513     if (COLOR_GET("entry/text")) {
    514         m_entryTextForegroundColor = Color(fr, fg, fb, fa);
    515         m_entryTextBackgroundColor = Color(br, bg, bb, ba);
    516     }
    517     if (COLOR_GET("search/text")) {
    518         m_searchTextForegroundColor = Color(fr, fg, fb, fa);
    519         m_searchTextBackgroundColor = Color(br, bg, bb, ba);
    520     }
    521 #undef COLOR_GET
    522     platformColorsDidChange();
    523 }
    524 
    525 void RenderThemeEfl::applyPartDescriptionFallback(struct ThemePartDesc* desc)
    526 {
    527     desc->min.setWidth(Length(0, Fixed));
    528     desc->min.setHeight(Length(0, Fixed));
    529 
    530     desc->max.setWidth(Length(0, Fixed));
    531     desc->max.setHeight(Length(0, Fixed));
    532 
    533     desc->padding = LengthBox(0, 0, 0, 0);
    534 }
    535 
    536 void RenderThemeEfl::applyPartDescription(Evas_Object* object, struct ThemePartDesc* desc)
    537 {
    538     Evas_Coord minw, minh, maxw, maxh;
    539 
    540     edje_object_size_min_get(object, &minw, &minh);
    541     if (!minw && !minh)
    542         edje_object_size_min_calc(object, &minw, &minh);
    543 
    544     desc->min.setWidth(Length(minw, Fixed));
    545     desc->min.setHeight(Length(minh, Fixed));
    546 
    547     edje_object_size_max_get(object, &maxw, &maxh);
    548     desc->max.setWidth(Length(maxw, Fixed));
    549     desc->max.setHeight(Length(maxh, Fixed));
    550 
    551     if (!edje_object_part_exists(object, "text_confinement"))
    552         desc->padding = LengthBox(0, 0, 0, 0);
    553     else {
    554         Evas_Coord px, py, pw, ph;
    555         Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
    556         int t, r, b, l;
    557 
    558         if (minw > 0)
    559             ow = minw;
    560         else
    561             ow = 100;
    562         if (minh > 0)
    563             oh = minh;
    564         else
    565             oh = 100;
    566         if (maxw > 0 && ow > maxw)
    567             ow = maxw;
    568         if (maxh > 0 && oh > maxh)
    569             oh = maxh;
    570 
    571         evas_object_move(object, ox, oy);
    572         evas_object_resize(object, ow, oh);
    573         edje_object_calc_force(object);
    574         edje_object_message_signal_process(object);
    575         edje_object_part_geometry_get(object, "text_confinement", &px, &py, &pw, &ph);
    576 
    577         t = py - oy;
    578         b = (oh + oy) - (ph + py);
    579 
    580         l = px - ox;
    581         r = (ow + ox) - (pw + px);
    582 
    583         desc->padding = LengthBox(t, r, b, l);
    584     }
    585 }
    586 
    587 const char* RenderThemeEfl::edjeGroupFromFormType(FormType type) const
    588 {
    589     static const char* groups[] = {
    590 #define W(n) "webkit/widget/"n
    591         W("button"),
    592         W("radio"),
    593         W("entry"),
    594         W("checkbox"),
    595         W("combo"),
    596 #if ENABLE(PROGRESS_TAG)
    597         W("progressbar"),
    598 #endif
    599         W("search/field"),
    600         W("search/decoration"),
    601         W("search/results_button"),
    602         W("search/results_decoration"),
    603         W("search/cancel_button"),
    604         W("slider/vertical"),
    605         W("slider/horizontal"),
    606 #if ENABLE(VIDEO)
    607         W("mediacontrol/playpause_button"),
    608         W("mediacontrol/mute_button"),
    609         W("mediacontrol/seekforward_button"),
    610         W("mediacontrol/seekbackward_button"),
    611 #endif
    612 #undef W
    613         0
    614     };
    615     ASSERT(type >= 0);
    616     ASSERT((size_t)type < sizeof(groups) / sizeof(groups[0])); // out of sync?
    617     return groups[type];
    618 }
    619 
    620 void RenderThemeEfl::applyPartDescriptions()
    621 {
    622     Evas_Object* object;
    623     unsigned int i;
    624     const char* file;
    625 
    626     ASSERT(m_canvas);
    627     ASSERT(m_edje);
    628 
    629     edje_object_file_get(m_edje, &file, 0);
    630     ASSERT(file);
    631 
    632     object = edje_object_add(ecore_evas_get(m_canvas));
    633     if (!object) {
    634         EINA_LOG_ERR("Could not create Edje object.");
    635         return;
    636     }
    637 
    638     for (i = 0; i < FormTypeLast; i++) {
    639         FormType type = static_cast<FormType>(i);
    640         const char* group = edjeGroupFromFormType(type);
    641         m_partDescs[i].type = type;
    642         if (!edje_object_file_set(object, file, group)) {
    643             Edje_Load_Error err = edje_object_load_error_get(object);
    644             const char* errmsg = edje_load_error_str(err);
    645             EINA_LOG_ERR("Could not set theme group '%s' of file '%s': %s",
    646                          group, file, errmsg);
    647 
    648             applyPartDescriptionFallback(m_partDescs + i);
    649         } else
    650             applyPartDescription(object, m_partDescs + i);
    651     }
    652     evas_object_del(object);
    653 }
    654 
    655 void RenderThemeEfl::themeChanged()
    656 {
    657     cacheThemePartFlush();
    658 
    659     if (!m_canvas) {
    660         createCanvas();
    661         if (!m_canvas)
    662             return;
    663     }
    664 
    665     if (!m_edje) {
    666         createEdje();
    667         if (!m_edje)
    668             return;
    669     }
    670 
    671     applyEdjeColors();
    672     applyPartDescriptions();
    673 }
    674 
    675 float RenderThemeEfl::defaultFontSize = 16.0f;
    676 
    677 RenderThemeEfl::RenderThemeEfl(Page* page)
    678     : RenderTheme()
    679     , m_page(page)
    680     , m_activeSelectionBackgroundColor(0, 0, 255)
    681     , m_activeSelectionForegroundColor(255, 255, 255)
    682     , m_inactiveSelectionBackgroundColor(0, 0, 128)
    683     , m_inactiveSelectionForegroundColor(200, 200, 200)
    684     , m_focusRingColor(32, 32, 224, 224)
    685     , m_buttonTextBackgroundColor(0, 0, 0, 0)
    686     , m_buttonTextForegroundColor(0, 0, 0)
    687     , m_comboTextBackgroundColor(0, 0, 0, 0)
    688     , m_comboTextForegroundColor(0, 0, 0)
    689     , m_entryTextBackgroundColor(0, 0, 0, 0)
    690     , m_entryTextForegroundColor(0, 0, 0)
    691     , m_searchTextBackgroundColor(0, 0, 0, 0)
    692     , m_searchTextForegroundColor(0, 0, 0)
    693     , m_canvas(0)
    694     , m_edje(0)
    695 {
    696     if (page && page->mainFrame() && page->mainFrame()->view())
    697         themeChanged();
    698 }
    699 
    700 RenderThemeEfl::~RenderThemeEfl()
    701 {
    702     cacheThemePartFlush();
    703 
    704     if (m_canvas) {
    705         if (m_edje)
    706             evas_object_del(m_edje);
    707         ecore_evas_free(m_canvas);
    708     }
    709 }
    710 
    711 void RenderThemeEfl::setActiveSelectionColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    712 {
    713     m_activeSelectionForegroundColor = Color(foreR, foreG, foreB, foreA);
    714     m_activeSelectionBackgroundColor = Color(backR, backG, backB, backA);
    715     platformColorsDidChange();
    716 }
    717 
    718 void RenderThemeEfl::setInactiveSelectionColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    719 {
    720     m_inactiveSelectionForegroundColor = Color(foreR, foreG, foreB, foreA);
    721     m_inactiveSelectionBackgroundColor = Color(backR, backG, backB, backA);
    722     platformColorsDidChange();
    723 }
    724 
    725 void RenderThemeEfl::setFocusRingColor(int r, int g, int b, int a)
    726 {
    727     m_focusRingColor = Color(r, g, b, a);
    728     // webkit just use platformFocusRingColor() for default theme (without page)
    729     // this is ugly, but no other way to do it unless we change
    730     // it to use page themes as much as possible.
    731     RenderTheme::setCustomFocusRingColor(m_focusRingColor);
    732     platformColorsDidChange();
    733 }
    734 
    735 void RenderThemeEfl::setButtonTextColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    736 {
    737     m_buttonTextForegroundColor = Color(foreR, foreG, foreB, foreA);
    738     m_buttonTextBackgroundColor = Color(backR, backG, backB, backA);
    739     platformColorsDidChange();
    740 }
    741 
    742 void RenderThemeEfl::setComboTextColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    743 {
    744     m_comboTextForegroundColor = Color(foreR, foreG, foreB, foreA);
    745     m_comboTextBackgroundColor = Color(backR, backG, backB, backA);
    746     platformColorsDidChange();
    747 }
    748 
    749 void RenderThemeEfl::setEntryTextColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    750 {
    751     m_entryTextForegroundColor = Color(foreR, foreG, foreB, foreA);
    752     m_entryTextBackgroundColor = Color(backR, backG, backB, backA);
    753     platformColorsDidChange();
    754 }
    755 
    756 void RenderThemeEfl::setSearchTextColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    757 {
    758     m_searchTextForegroundColor = Color(foreR, foreG, foreB, foreA);
    759     m_searchTextBackgroundColor = Color(backR, backG, backB, backA);
    760     platformColorsDidChange();
    761 }
    762 
    763 static bool supportsFocus(ControlPart appearance)
    764 {
    765     switch (appearance) {
    766     case PushButtonPart:
    767     case ButtonPart:
    768     case TextFieldPart:
    769     case TextAreaPart:
    770     case SearchFieldPart:
    771     case MenulistPart:
    772     case RadioPart:
    773     case CheckboxPart:
    774     case SliderVerticalPart:
    775     case SliderHorizontalPart:
    776         return true;
    777     default:
    778         return false;
    779     }
    780 }
    781 
    782 bool RenderThemeEfl::supportsFocusRing(const RenderStyle* style) const
    783 {
    784     return supportsFocus(style->appearance());
    785 }
    786 
    787 bool RenderThemeEfl::controlSupportsTints(const RenderObject* object) const
    788 {
    789     return isEnabled(object);
    790 }
    791 
    792 int RenderThemeEfl::baselinePosition(const RenderObject* object) const
    793 {
    794     if (!object->isBox())
    795         return 0;
    796 
    797     if (object->style()->appearance() == CheckboxPart
    798     ||  object->style()->appearance() == RadioPart)
    799         return toRenderBox(object)->marginTop() + toRenderBox(object)->height() - 3;
    800 
    801     return RenderTheme::baselinePosition(object);
    802 }
    803 
    804 bool RenderThemeEfl::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    805 {
    806     if (object->style()->appearance() == SliderHorizontalPart)
    807         return paintThemePart(object, SliderHorizontal, info, rect);
    808     return paintThemePart(object, SliderVertical, info, rect);
    809 }
    810 
    811 void RenderThemeEfl::adjustSliderTrackStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    812 {
    813     if (!m_page && element && element->document()->page()) {
    814         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSliderTrackStyle(selector, style, element);
    815         return;
    816     }
    817 
    818     adjustSizeConstraints(style, SliderHorizontal);
    819     style->resetBorder();
    820 
    821     const struct ThemePartDesc *desc = m_partDescs + (size_t)SliderHorizontal;
    822     if (style->width().value() < desc->min.width().value())
    823         style->setWidth(desc->min.width());
    824     if (style->height().value() < desc->min.height().value())
    825         style->setHeight(desc->min.height());
    826 }
    827 
    828 void RenderThemeEfl::adjustSliderThumbStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    829 {
    830     adjustSliderTrackStyle(selector, style, element);
    831 }
    832 
    833 bool RenderThemeEfl::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    834 {
    835     return paintSliderTrack(object, info, rect);
    836 }
    837 
    838 void RenderThemeEfl::adjustCheckboxStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    839 {
    840     if (!m_page && element && element->document()->page()) {
    841         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustCheckboxStyle(selector, style, element);
    842         return;
    843     }
    844     adjustSizeConstraints(style, CheckBox);
    845     style->resetBorder();
    846 
    847     const struct ThemePartDesc *desc = m_partDescs + (size_t)CheckBox;
    848     if (style->width().value() < desc->min.width().value())
    849         style->setWidth(desc->min.width());
    850     if (style->height().value() < desc->min.height().value())
    851         style->setHeight(desc->min.height());
    852 }
    853 
    854 bool RenderThemeEfl::paintCheckbox(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    855 {
    856     return paintThemePart(object, CheckBox, info, rect);
    857 }
    858 
    859 void RenderThemeEfl::adjustRadioStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    860 {
    861     if (!m_page && element && element->document()->page()) {
    862         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustRadioStyle(selector, style, element);
    863         return;
    864     }
    865     adjustSizeConstraints(style, RadioButton);
    866     style->resetBorder();
    867 
    868     const struct ThemePartDesc *desc = m_partDescs + (size_t)RadioButton;
    869     if (style->width().value() < desc->min.width().value())
    870         style->setWidth(desc->min.width());
    871     if (style->height().value() < desc->min.height().value())
    872         style->setHeight(desc->min.height());
    873 }
    874 
    875 bool RenderThemeEfl::paintRadio(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    876 {
    877     return paintThemePart(object, RadioButton, info, rect);
    878 }
    879 
    880 void RenderThemeEfl::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    881 {
    882     if (!m_page && element && element->document()->page()) {
    883         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustButtonStyle(selector, style, element);
    884         return;
    885     }
    886 
    887     adjustSizeConstraints(style, Button);
    888 
    889     if (style->appearance() == PushButtonPart) {
    890         style->resetBorder();
    891         style->setWhiteSpace(PRE);
    892         style->setHeight(Length(Auto));
    893         style->setColor(m_buttonTextForegroundColor);
    894         style->setBackgroundColor(m_buttonTextBackgroundColor);
    895     }
    896 }
    897 
    898 bool RenderThemeEfl::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    899 {
    900     return paintThemePart(object, Button, info, rect);
    901 }
    902 
    903 void RenderThemeEfl::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    904 {
    905     if (!m_page && element && element->document()->page()) {
    906         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustMenuListStyle(selector, style, element);
    907         return;
    908     }
    909     adjustSizeConstraints(style, ComboBox);
    910     style->resetBorder();
    911     style->setWhiteSpace(PRE);
    912     style->setColor(m_comboTextForegroundColor);
    913     style->setBackgroundColor(m_comboTextBackgroundColor);
    914 }
    915 
    916 bool RenderThemeEfl::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    917 {
    918     return paintThemePart(object, ComboBox, info, rect);
    919 }
    920 
    921 void RenderThemeEfl::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    922 {
    923     if (!m_page && element && element->document()->page()) {
    924         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustTextFieldStyle(selector, style, element);
    925         return;
    926     }
    927     adjustSizeConstraints(style, TextField);
    928     style->resetBorder();
    929     style->setWhiteSpace(PRE);
    930     style->setColor(m_entryTextForegroundColor);
    931     style->setBackgroundColor(m_entryTextBackgroundColor);
    932 }
    933 
    934 bool RenderThemeEfl::paintTextField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    935 {
    936     return paintThemePart(object, TextField, info, rect);
    937 }
    938 
    939 void RenderThemeEfl::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    940 {
    941     adjustTextFieldStyle(selector, style, element);
    942 }
    943 
    944 bool RenderThemeEfl::paintTextArea(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    945 {
    946     return paintTextField(object, info, rect);
    947 }
    948 
    949 void RenderThemeEfl::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    950 {
    951     if (!m_page && element && element->document()->page()) {
    952         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldDecorationStyle(selector, style, element);
    953         return;
    954     }
    955     adjustSizeConstraints(style, SearchFieldDecoration);
    956     style->resetBorder();
    957     style->setWhiteSpace(PRE);
    958 }
    959 
    960 bool RenderThemeEfl::paintSearchFieldDecoration(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    961 {
    962     return paintThemePart(object, SearchFieldDecoration, info, rect);
    963 }
    964 
    965 void RenderThemeEfl::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    966 {
    967     if (!m_page && element && element->document()->page()) {
    968         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldResultsButtonStyle(selector, style, element);
    969         return;
    970     }
    971     adjustSizeConstraints(style, SearchFieldResultsButton);
    972     style->resetBorder();
    973     style->setWhiteSpace(PRE);
    974 }
    975 
    976 bool RenderThemeEfl::paintSearchFieldResultsButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    977 {
    978     return paintThemePart(object, SearchFieldResultsButton, info, rect);
    979 }
    980 
    981 void RenderThemeEfl::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    982 {
    983     if (!m_page && element && element->document()->page()) {
    984         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldResultsDecorationStyle(selector, style, element);
    985         return;
    986     }
    987     adjustSizeConstraints(style, SearchFieldResultsDecoration);
    988     style->resetBorder();
    989     style->setWhiteSpace(PRE);
    990 }
    991 
    992 bool RenderThemeEfl::paintSearchFieldResultsDecoration(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    993 {
    994     return paintThemePart(object, SearchFieldResultsDecoration, info, rect);
    995 }
    996 
    997 void RenderThemeEfl::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
    998 {
    999     if (!m_page && element && element->document()->page()) {
   1000         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldCancelButtonStyle(selector, style, element);
   1001         return;
   1002     }
   1003     adjustSizeConstraints(style, SearchFieldCancelButton);
   1004     style->resetBorder();
   1005     style->setWhiteSpace(PRE);
   1006 }
   1007 
   1008 bool RenderThemeEfl::paintSearchFieldCancelButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1009 {
   1010     return paintThemePart(object, SearchFieldCancelButton, info, rect);
   1011 }
   1012 
   1013 void RenderThemeEfl::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
   1014 {
   1015     if (!m_page && element && element->document()->page()) {
   1016         static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldStyle(selector, style, element);
   1017         return;
   1018     }
   1019     adjustSizeConstraints(style, SearchField);
   1020     style->resetBorder();
   1021     style->setWhiteSpace(PRE);
   1022     style->setColor(m_searchTextForegroundColor);
   1023     style->setBackgroundColor(m_searchTextBackgroundColor);
   1024 }
   1025 
   1026 bool RenderThemeEfl::paintSearchField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1027 {
   1028     return paintThemePart(object, SearchField, info, rect);
   1029 }
   1030 
   1031 void RenderThemeEfl::setDefaultFontSize(int size)
   1032 {
   1033     defaultFontSize = size;
   1034 }
   1035 
   1036 void RenderThemeEfl::systemFont(int propId, FontDescription& fontDescription) const
   1037 {
   1038     // It was called by RenderEmbeddedObject::paintReplaced to render alternative string.
   1039     // To avoid cairo_error while rendering, fontDescription should be passed.
   1040     DEFINE_STATIC_LOCAL(String, fontFace, ("Sans"));
   1041     float fontSize = defaultFontSize;
   1042 
   1043     fontDescription.firstFamily().setFamily(fontFace);
   1044     fontDescription.setSpecifiedSize(fontSize);
   1045     fontDescription.setIsAbsoluteSize(true);
   1046     fontDescription.setGenericFamily(FontDescription::NoFamily);
   1047     fontDescription.setWeight(FontWeightNormal);
   1048     fontDescription.setItalic(false);
   1049 }
   1050 
   1051 #if ENABLE(PROGRESS_TAG)
   1052 void RenderThemeEfl::adjustProgressBarStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const
   1053 {
   1054     style->setBoxShadow(0);
   1055 }
   1056 
   1057 bool RenderThemeEfl::paintProgressBar(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1058 {
   1059     return paintThemePart(object, ProgressBar, info, rect);
   1060 }
   1061 #endif
   1062 
   1063 #if ENABLE(VIDEO)
   1064 bool RenderThemeEfl::emitMediaButtonSignal(FormType formType, MediaControlElementType mediaElementType, const IntRect& rect)
   1065 {
   1066     ThemePartCacheEntry* entry;
   1067 
   1068     entry = cacheThemePartGet(formType, rect.size());
   1069     ASSERT(entry);
   1070     if (!entry)
   1071         return false;
   1072 
   1073     if (mediaElementType == MediaPlayButton)
   1074         edje_object_signal_emit(entry->o, "play", "");
   1075     else if (mediaElementType == MediaPauseButton)
   1076         edje_object_signal_emit(entry->o, "pause", "");
   1077     else if (mediaElementType == MediaMuteButton)
   1078         edje_object_signal_emit(entry->o, "mute", "");
   1079     else if (mediaElementType == MediaUnMuteButton)
   1080         edje_object_signal_emit(entry->o, "sound", "");
   1081     else if (mediaElementType == MediaSeekForwardButton)
   1082         edje_object_signal_emit(entry->o, "seekforward", "");
   1083     else if (mediaElementType == MediaSeekBackButton)
   1084         edje_object_signal_emit(entry->o, "seekbackward", "");
   1085     else
   1086         return false;
   1087 
   1088     return true;
   1089 }
   1090 
   1091 String RenderThemeEfl::extraMediaControlsStyleSheet()
   1092 {
   1093     return String(mediaControlsEflUserAgentStyleSheet, sizeof(mediaControlsEflUserAgentStyleSheet));
   1094 }
   1095 
   1096 String RenderThemeEfl::formatMediaControlsCurrentTime(float currentTime, float duration) const
   1097 {
   1098     notImplemented();
   1099     return String();
   1100 }
   1101 
   1102 bool RenderThemeEfl::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1103 {
   1104     notImplemented();
   1105     return false;
   1106 }
   1107 
   1108 bool RenderThemeEfl::paintMediaMuteButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1109 {
   1110     Node* mediaNode = object->node() ? object->node()->shadowAncestorNode() : 0;
   1111     if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
   1112         return false;
   1113 
   1114     HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode);
   1115 
   1116     if (!emitMediaButtonSignal(MuteUnMuteButton, mediaElement->muted() ? MediaMuteButton : MediaUnMuteButton, rect))
   1117         return false;
   1118 
   1119     return paintThemePart(object, MuteUnMuteButton, info, rect);
   1120 }
   1121 
   1122 bool RenderThemeEfl::paintMediaPlayButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1123 {
   1124     Node* node = object->node();
   1125     if (!node || !node->isMediaControlElement())
   1126         return false;
   1127 
   1128     MediaControlPlayButtonElement* button = static_cast<MediaControlPlayButtonElement*>(node);
   1129     if (!emitMediaButtonSignal(PlayPauseButton, button->displayType(), rect))
   1130         return false;
   1131 
   1132     return paintThemePart(object, PlayPauseButton, info, rect);
   1133 }
   1134 
   1135 bool RenderThemeEfl::paintMediaSeekBackButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1136 {
   1137     Node* node = object->node();
   1138     if (!node || !node->isMediaControlElement())
   1139         return 0;
   1140 
   1141     MediaControlSeekButtonElement* button = static_cast<MediaControlSeekButtonElement*>(node);
   1142     if (!emitMediaButtonSignal(SeekBackwardButton, button->displayType(), rect))
   1143         return false;
   1144 
   1145     return paintThemePart(object, SeekBackwardButton, info, rect);
   1146 }
   1147 
   1148 bool RenderThemeEfl::paintMediaSeekForwardButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1149 {
   1150     Node* node = object->node();
   1151     if (!node || !node->isMediaControlElement())
   1152         return 0;
   1153 
   1154     MediaControlSeekButtonElement* button = static_cast<MediaControlSeekButtonElement*>(node);
   1155     if (!emitMediaButtonSignal(SeekForwardButton, button->displayType(), rect))
   1156         return false;
   1157 
   1158     return paintThemePart(object, SeekForwardButton, info, rect);
   1159 }
   1160 
   1161 bool RenderThemeEfl::paintMediaSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1162 {
   1163     notImplemented();
   1164     return false;
   1165 }
   1166 
   1167 bool RenderThemeEfl::paintMediaSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1168 {
   1169     notImplemented();
   1170     return false;
   1171 }
   1172 
   1173 bool RenderThemeEfl::paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo& info, const IntRect& rect)
   1174 {
   1175     notImplemented();
   1176     return false;
   1177 }
   1178 
   1179 bool RenderThemeEfl::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1180 {
   1181     notImplemented();
   1182     return false;
   1183 }
   1184 
   1185 bool RenderThemeEfl::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1186 {
   1187     notImplemented();
   1188     return false;
   1189 }
   1190 
   1191 bool RenderThemeEfl::paintMediaCurrentTime(RenderObject* object, const PaintInfo& info, const IntRect& rect)
   1192 {
   1193     notImplemented();
   1194     return false;
   1195 }
   1196 #endif
   1197 }
   1198