15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk-pixbuf/gdk-pixbuf.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkPixbuf* ThemeService::GetRTLEnabledPixbufNamed(int id) const {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetPixbufImpl(id, true);
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkPixbuf* ThemeService::GetPixbufImpl(int id, bool rtl_enabled) const {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the negative |resource_id| for the key for BIDI-aware images.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int key = rtl_enabled ? -id : id;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see if we already have the pixbuf in the cache.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkPixbufMap::const_iterator pixbufs_iter = gdk_pixbufs_.find(key);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pixbufs_iter != gdk_pixbufs_.end())
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pixbufs_iter->second;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap = GetImageNamed(id).AsBitmap();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(bitmap);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We loaded successfully.  Cache the pixbuf.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pixbuf) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::i18n::IsRTL() && rtl_enabled) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GdkPixbuf* original_pixbuf = pixbuf;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pixbuf = gdk_pixbuf_flip(pixbuf, TRUE);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_object_unref(original_pixbuf);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gdk_pixbufs_[key] = pixbuf;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pixbuf;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We failed to retrieve the bitmap, show a debugging red square.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(WARNING) << "Unable to load GdkPixbuf with id " << id;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();  // Want to assert in debug mode.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GdkPixbuf* empty_bitmap = NULL;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!empty_bitmap) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The placeholder bitmap is bright red so people notice the problem.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkBitmap skia_bitmap;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia_bitmap.allocPixels();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia_bitmap.eraseARGB(255, 255, 0, 0);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    empty_bitmap = gfx::GdkPixbufFromSkBitmap(skia_bitmap);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return empty_bitmap;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::FreePlatformCaches() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Free GdkPixbufs.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != gdk_pixbufs_.end(); i++) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_object_unref(i->second);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_pixbufs_.clear();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71