Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright 2010, 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 #define LOG_TAG "WebCore"
     27 
     28 #include "config.h"
     29 #include "CString.h"
     30 #include "android_graphics.h"
     31 #include "Document.h"
     32 #include "IntRect.h"
     33 #include "Node.h"
     34 #include "RenderSkinMediaButton.h"
     35 #include "SkCanvas.h"
     36 #include "SkNinePatch.h"
     37 #include "SkRect.h"
     38 #include <utils/Debug.h>
     39 #include <utils/Log.h>
     40 
     41 struct PatchData {
     42     const char* name;
     43     int8_t outset, margin;
     44 };
     45 
     46 static const PatchData gFiles[] =
     47     {
     48         { "btn_media_player.9.png", 0, 0 }, // DEFAULT BGD BUTTON
     49         { "ic_media_pause.png", 0, 0}, // PAUSE
     50         { "ic_media_play.png", 0, 0 }, // PLAY
     51         { "ic_media_pause.png", 0, 0 }, // MUTE
     52         { "ic_media_rew.png", 0, 0 }, // REWIND
     53         { "ic_media_ff.png", 0, 0 }, // FORWARD
     54         { "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER
     55         { "btn_media_player_pressed.9.png", 0, 0 },  // SLIDER_TRACK
     56         { "btn_media_player.9.png", 0, 0 }           // SLIDER_THUMB
     57     };
     58 
     59 static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])];
     60 static bool gDecoded;
     61 static bool gHighRes;
     62 
     63 namespace WebCore {
     64 
     65 void RenderSkinMediaButton::Init(android::AssetManager* am, String drawableDirectory)
     66 {
     67     static bool gInited;
     68     if (gInited)
     69         return;
     70 
     71     gInited = true;
     72     gDecoded = true;
     73     gHighRes = drawableDirectory[drawableDirectory.length() - 5] == 'h';
     74     for (size_t i = 0; i < sizeof(gFiles)/sizeof(gFiles[0]); i++) {
     75         String path = drawableDirectory + gFiles[i].name;
     76         if (!RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &gButton[i])) {
     77             gDecoded = false;
     78             LOGD("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw");
     79             break;
     80         }
     81     }
     82 }
     83 
     84 void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonType)
     85 {
     86     // If we failed to decode, do nothing.  This way the browser still works,
     87     // and webkit will still draw the label and layout space for us.
     88     if (!gDecoded) {
     89         return;
     90     }
     91 
     92     bool drawsNinePatch = true;
     93     bool drawsImage = true;
     94     bool drawsBackgroundColor = false;
     95 
     96     int ninePatchIndex = 0;
     97     int imageIndex = 0;
     98 
     99     SkRect bounds(r);
    100     SkScalar imageMargin = 8;
    101     SkPaint paint;
    102     SkColor backgroundColor = SkColorSetARGB(255, 200, 200, 200);
    103     SkColor trackBackgroundColor = SkColorSetARGB(255, 100, 100, 100);
    104 
    105     switch (buttonType) {
    106     case PAUSE:
    107     case PLAY:
    108     case MUTE:
    109     case REWIND:
    110     case FORWARD:
    111     {
    112          imageIndex = buttonType + 1;
    113          drawsBackgroundColor = true;
    114          paint.setColor(backgroundColor);
    115          break;
    116     }
    117     case BACKGROUND_SLIDER:
    118     {
    119          drawsImage = false;
    120          drawsNinePatch = false;
    121          drawsBackgroundColor = true;
    122          paint.setColor(backgroundColor);
    123          break;
    124     }
    125     case SLIDER_TRACK:
    126     {
    127          drawsImage = false;
    128          drawsNinePatch = false;
    129          drawsBackgroundColor = true;
    130          paint.setColor(trackBackgroundColor);
    131          bounds.fTop += 8;
    132          bounds.fBottom -= 8;
    133          break;
    134     }
    135     case SLIDER_THUMB:
    136     {
    137          drawsImage = false;
    138          ninePatchIndex = buttonType + 1;
    139          break;
    140     }
    141     default:
    142          drawsImage = false;
    143          drawsNinePatch = false;
    144     }
    145 
    146     if (drawsBackgroundColor) {
    147         canvas->drawRect(r, paint);
    148     }
    149 
    150     if (drawsNinePatch) {
    151         const PatchData& pd = gFiles[ninePatchIndex];
    152         int marginValue = pd.margin + pd.outset;
    153 
    154         SkIRect margin;
    155         margin.set(marginValue, marginValue, marginValue, marginValue);
    156         SkNinePatch::DrawNine(canvas, bounds, gButton[0], margin);
    157     }
    158 
    159     if (drawsImage) {
    160         SkScalar SIZE = gButton[imageIndex].width();
    161         SkScalar width = r.width();
    162         SkScalar scale = SkScalarDiv(width - 2*imageMargin, SIZE);
    163         int saveScaleCount = canvas->save();
    164         canvas->translate(bounds.fLeft + imageMargin, bounds.fTop + imageMargin);
    165         canvas->scale(scale, scale);
    166         canvas->drawBitmap(gButton[imageIndex], 0, 0, &paint);
    167         canvas->restoreToCount(saveScaleCount);
    168     }
    169 }
    170 
    171 } //WebCore
    172