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 "ui/base/resource/resource_bundle.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <limits> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/big_endian.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/file.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "grit/app_locale_settings.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/image_operations.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/data_pack.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_paths.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_switches.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/jpeg_codec.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_source.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/safe_integer_conversions.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size_conversions.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 390c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#if defined(OS_ANDROID) 400c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#include "ui/base/resource/resource_bundle_android.h" 410c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#endif 420c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_CHROMEOS) 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/platform_font_pango.h" 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN) 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/win/dpi_setup.h" 5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/win/dpi.h" 5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_MACOSX) && !defined(OS_IOS) 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/mac/mac_util.h" 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Font sizes relative to base font. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kSmallFontSizeDelta = -1; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMediumFontSizeDelta = 3; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLargeFontSizeDelta = 8; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PNG-related constants. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned char kPngMagic[8] = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 }; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kPngChunkMetadataSize = 12; // length, type, crc32 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned char kPngScaleChunkType[4] = { 'c', 's', 'C', 'l' }; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned char kPngDataChunkType[4] = { 'I', 'D', 'A', 'T' }; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 720c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#if !defined(OS_MACOSX) 730c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdochconst char kPakFileSuffix[] = ".pak"; 740c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#endif 750c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceBundle* g_shared_instance_ = NULL; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InitDefaultFontList() { 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_CHROMEOS) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string font_family = base::UTF16ToUTF8( 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rb.GetLocalizedString(IDS_UI_FONT_FAMILY_CROS)); 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::FontList::SetDefaultFontDescription(font_family); 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(yukishiino): Remove SetDefaultFontDescription() once the migration to 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the font list is done. We will no longer need SetDefaultFontDescription() 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // after every client gets started using a FontList instead of a Font. 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::PlatformFontPango::SetDefaultFontDescription(font_family); 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Use a single default font as the default font list. 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::FontList::SetDefaultFontDescription(std::string()); 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_ANDROID) 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Returns the scale factor closest to |scale| from the full list of factors. 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Note that it does NOT rely on the list of supported scale factors. 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Finding the closest match is inefficient and shouldn't be done frequently. 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ScaleFactor FindClosestScaleFactorUnsafe(float scale) { 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) float smallest_diff = std::numeric_limits<float>::max(); 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScaleFactor closest_match = SCALE_FACTOR_100P; 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (int i = SCALE_FACTOR_100P; i < NUM_SCALE_FACTORS; ++i) { 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ScaleFactor scale_factor = static_cast<ScaleFactor>(i); 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) float diff = std::abs(GetScaleForScaleFactor(scale_factor) - scale); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (diff < smallest_diff) { 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) closest_match = scale_factor; 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) smallest_diff = diff; 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return closest_match; 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif // OS_ANDROID 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An ImageSkiaSource that loads bitmaps for the requested scale factor from 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ResourceBundle on demand for a given |resource_id|. If the bitmap for the 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requested scale factor does not exist, it will return the 1x bitmap scaled 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by the scale factor. This may lead to broken UI if the correct size of the 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scaled image is not exactly |scale_factor| * the size of the 1x resource. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When --highlight-missing-scaled-resources flag is specified, scaled 1x images 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are higlighted by blending them with red. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResourceBundle::ResourceBundleImageSource : public gfx::ImageSkiaSource { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceBundleImageSource(ResourceBundle* rb, int resource_id) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : rb_(rb), resource_id_(resource_id) {} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ResourceBundleImageSource() {} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // gfx::ImageSkiaSource overrides: 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap image; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fell_back_to_1x = false; 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScaleFactor scale_factor = GetSupportedScaleFactor(scale); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool found = rb_->LoadBitmap(resource_id_, &scale_factor, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &image, &fell_back_to_1x); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::ImageSkiaRep(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If the resource is in the package with SCALE_FACTOR_NONE, it 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // can be used in any scale factor. The image is maked as "unscaled" 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // so that the ImageSkia do not automatically scale. 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (scale_factor == ui::SCALE_FACTOR_NONE) 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return gfx::ImageSkiaRep(image, 0.0f); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fell_back_to_1x) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GRIT fell back to the 100% image, so rescale it to the correct size. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image = skia::ImageOperations::Resize( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::ImageOperations::RESIZE_LANCZOS3, 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::ToCeiledInt(image.width() * scale), 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::ToCeiledInt(image.height() * scale)); 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scale = GetScaleForScaleFactor(scale_factor); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return gfx::ImageSkiaRep(image, scale); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceBundle* rb_; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int resource_id_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageSource); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ResourceBundle::InitSharedInstanceWithLocale( 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pref_locale, Delegate* delegate) { 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InitSharedInstance(delegate); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_shared_instance_->LoadCommonResources(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result = g_shared_instance_->LoadLocaleResources(pref_locale); 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitDefaultFontList(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ResourceBundle::InitSharedInstanceLocaleOnly( 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pref_locale, Delegate* delegate) { 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InitSharedInstance(delegate); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result = g_shared_instance_->LoadLocaleResources(pref_locale); 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitDefaultFontList(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1858d8c7bbf2600bb117d324f0708e6a6a9e0ec3ebaBen Murdochvoid ResourceBundle::InitSharedInstanceWithPakFileRegion( 1868d8c7bbf2600bb117d324f0708e6a6a9e0ec3ebaBen Murdoch base::File pak_file, 1878d8c7bbf2600bb117d324f0708e6a6a9e0ec3ebaBen Murdoch const base::MemoryMappedFile::Region& region, 1888d8c7bbf2600bb117d324f0708e6a6a9e0ec3ebaBen Murdoch bool should_load_common_resources) { 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InitSharedInstance(NULL); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_load_common_resources) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_shared_instance_->LoadCommonResources(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DataPack> data_pack( 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DataPack(SCALE_FACTOR_100P)); 1958d8c7bbf2600bb117d324f0708e6a6a9e0ec3ebaBen Murdoch if (!data_pack->LoadFromFileRegion(pak_file.Pass(), region)) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "failed to load pak file"; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_shared_instance_->locale_resources_data_.reset(data_pack.release()); 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitDefaultFontList(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceBundle::InitSharedInstanceWithPakPath(const base::FilePath& path) { 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InitSharedInstance(NULL); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_shared_instance_->LoadTestResources(path, path); 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitDefaultFontList(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceBundle::CleanupSharedInstance() { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_shared_instance_) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete g_shared_instance_; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_shared_instance_ = NULL; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ResourceBundle::HasSharedInstance() { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_shared_instance_ != NULL; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceBundle& ResourceBundle::GetSharedInstance() { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must call InitSharedInstance before this function. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(g_shared_instance_ != NULL); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *g_shared_instance_; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { 2320c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch bool locale_file_path_exists = !GetLocaleFilePath(locale, true).empty(); 2330c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#if defined(OS_ANDROID) 2340c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch // TODO(mkosiba,primiano): Chrome should mmap the .pak files too, in which 2350c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch // case we'd not need to check if locale_file_path_exists here. 2360c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch // http://crbug.com/394502. 2370c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch return locale_file_path_exists || 2380c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch AssetContainedInApk(locale + kPakFileSuffix); 2390c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#else 2400c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch return locale_file_path_exists; 2410c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch#endif 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceBundle::AddDataPackFromPath(const base::FilePath& path, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScaleFactor scale_factor) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddDataPackFromPathInternal(path, scale_factor, false); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceBundle::AddOptionalDataPackFromPath(const base::FilePath& path, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScaleFactor scale_factor) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddDataPackFromPathInternal(path, scale_factor, true); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceBundle::AddDataPackFromFile(base::File file, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScaleFactor scale_factor) { 256adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch AddDataPackFromFileRegion( 257adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch file.Pass(), base::MemoryMappedFile::Region::kWholeFile, scale_factor); 258adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch} 259adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch 260adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdochvoid ResourceBundle::AddDataPackFromFileRegion( 261adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch base::File file, 262adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch const base::MemoryMappedFile::Region& region, 263adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch ScaleFactor scale_factor) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DataPack> data_pack( 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DataPack(scale_factor)); 266adf47cdafabb7eed9d3d806ce331c2b810a7acd1Ben Murdoch if (data_pack->LoadFromFileRegion(file.Pass(), region)) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddDataPack(data_pack.release()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to load data pack from file." 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\nSome features may not be available."; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool test_file_exists) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_locale.empty()) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath locale_file_path; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(ui::DIR_LOCALES, &locale_file_path); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2840c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch if (!locale_file_path.empty()) { 2850c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch locale_file_path = 2860c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch locale_file_path.AppendASCII(app_locale + kPakFileSuffix); 2870c426db9e857768f27c4cb499a787b80ddc080f5Ben Murdoch } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) locale_file_path = 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->GetPathForLocalePack(locale_file_path, app_locale); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't try to load empty values or values that are not absolute paths. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (locale_file_path.empty() || !locale_file_path.IsAbsolute()) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (test_file_exists && !base::PathExists(locale_file_path)) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return locale_file_path; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ResourceBundle::LoadLocaleResources( 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pref_locale) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath locale_file_path = GetOverriddenPakPath(); 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (locale_file_path.empty()) 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) locale_file_path = GetLocaleFilePath(app_locale, true); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (locale_file_path.empty()) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that there is no locale.pak. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "locale_file_path.empty()"; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DataPack> data_pack( 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DataPack(SCALE_FACTOR_100P)); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data_pack->LoadFromPath(locale_file_path)) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError", 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::GetLastSystemErrorCode(), 16000); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "failed to load locale.pak"; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) locale_resources_data_.reset(data_pack.release()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_locale; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceBundle::LoadTestResources(const base::FilePath& path, 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& locale_path) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the given resource pak for both common and localized resources. 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P)); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!path.empty() && data_pack->LoadFromPath(path)) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddDataPack(data_pack.release()); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_pack.reset(new DataPack(ui::SCALE_FACTOR_NONE)); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!locale_path.empty() && data_pack->LoadFromPath(locale_path)) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) locale_resources_data_.reset(data_pack.release()); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) locale_resources_data_.reset(new DataPack(ui::SCALE_FACTOR_NONE)); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceBundle::UnloadLocaleResources() { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) locale_resources_data_.reset(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceBundle::OverrideLocalePakForTest(const base::FilePath& pak_path) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overridden_pak_path_ = pak_path; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath& ResourceBundle::GetOverriddenPakPath() { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overridden_pak_path_; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ResourceBundle::ReloadLocaleResources( 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pref_locale) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock_scope(*locale_resources_data_lock_); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnloadLocaleResources(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LoadLocaleResources(pref_locale); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia* ResourceBundle::GetImageSkiaNamed(int resource_id) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia* image = GetImageNamed(resource_id).ToImageSkia(); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<gfx::ImageSkia*>(image); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image& ResourceBundle::GetImageNamed(int resource_id) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to see if the image is already in the cache. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock_scope(*images_and_fonts_lock_); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (images_.count(resource_id)) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return images_[resource_id]; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image image; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image = delegate_->GetImageNamed(resource_id); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image.IsEmpty()) { 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!data_packs_.empty()) << 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing call to SetResourcesDataDLL?"; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS) || defined(OS_WIN) 389effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::ScaleFactor scale_factor_to_load = GetMaxScaleFactor(); 39068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else 391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::ScaleFactor scale_factor_to_load = ui::SCALE_FACTOR_100P; 39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(oshima): Consider reading the image size from png IHDR chunk and 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // skip decoding here and remove #ifdef below. 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ResourceBundle::GetSharedInstance() is destroyed after the 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BrowserMainLoop has finished running. |image_skia| is guaranteed to be 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroyed before the resource bundle is destroyed. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia image_skia(new ResourceBundleImageSource(this, resource_id), 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetScaleForScaleFactor(scale_factor_to_load)); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_skia.isNull()) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to load image with id " << resource_id; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); // Want to assert in debug mode. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The load failed to retrieve the image; show a debugging red square. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetEmptyImage(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_skia.SetReadOnly(); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image = gfx::Image(image_skia); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The load was successful, so cache the image. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock_scope(*images_and_fonts_lock_); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Another thread raced the load and has already cached the image. 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (images_.count(resource_id)) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return images_[resource_id]; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_[resource_id] = image; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return images_[resource_id]; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetNativeImageNamed(resource_id, RTL_DISABLED); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytes( 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_id) const { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LoadDataResourceBytesForScale(resource_id, ui::SCALE_FACTOR_NONE); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytesForScale( 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_id, 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScaleFactor scale_factor) const { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RefCountedStaticMemory* bytes = NULL; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes = delegate_->LoadDataResourceBytes(resource_id, scale_factor); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bytes) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece data = 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRawDataResourceForScale(resource_id, scale_factor); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data.empty()) { 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bytes = new base::RefCountedStaticMemory(data.data(), data.length()); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::StringPiece ResourceBundle::GetRawDataResource(int resource_id) const { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetRawDataResourceForScale(resource_id, ui::SCALE_FACTOR_NONE); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::StringPiece ResourceBundle::GetRawDataResourceForScale( 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_id, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScaleFactor scale_factor) const { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece data; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_ && 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->GetRawDataResource(resource_id, scale_factor, &data)) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scale_factor != ui::SCALE_FACTOR_100P) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < data_packs_.size(); i++) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_packs_[i]->GetScaleFactor() == scale_factor && 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_packs_[i]->GetStringPiece(resource_id, &data)) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < data_packs_.size(); i++) { 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_100P || 470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_200P || 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_NONE) && 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_packs_[i]->GetStringPiece(resource_id, &data)) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPiece(); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 ResourceBundle::GetLocalizedString(int message_id) { 480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 string; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_ && delegate_->GetLocalizedString(message_id, &string)) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that ReloadLocaleResources() doesn't drop the resources while 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we're using them. 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock_scope(*locale_resources_data_lock_); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If for some reason we were unable to load the resources , return an empty 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string (better than crashing). 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!locale_resources_data_.get()) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "locale resources are not loaded"; 492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::string16(); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPiece data; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!locale_resources_data_->GetStringPiece(message_id, &data)) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall back on the main data pack (shouldn't be any strings here except in 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unittests). 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = GetRawDataResource(message_id); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data.empty()) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "unable to find resource: " << message_id; 502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::string16(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings should not be loaded from a data pack that contains binary data. 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceHandle::TextEncodingType encoding = 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) locale_resources_data_->GetTextEncodingType(); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(encoding == ResourceHandle::UTF16 || encoding == ResourceHandle::UTF8) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "requested localized string from binary pack file"; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Data pack encodes strings as either UTF8 or UTF16. 513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 msg; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (encoding == ResourceHandle::UTF16) { 515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) msg = base::string16(reinterpret_cast<const base::char16*>(data.data()), 516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) data.length() / 2); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (encoding == ResourceHandle::UTF8) { 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) msg = base::UTF8ToUTF16(data); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return msg; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const gfx::FontList& ResourceBundle::GetFontList(FontStyle style) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock_scope(*images_and_fonts_lock_); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadFontsIfNecessary(); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (style) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BoldFont: 530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *bold_font_list_; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SmallFont: 532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *small_font_list_; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MediumFont: 534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *medium_font_list_; 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SmallBoldFont: 536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *small_bold_font_list_; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MediumBoldFont: 538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *medium_bold_font_list_; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LargeFont: 540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *large_font_list_; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LargeBoldFont: 542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *large_bold_font_list_; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return *base_font_list_; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 548a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const gfx::Font& ResourceBundle::GetFont(FontStyle style) { 549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return GetFontList(style).GetPrimaryFont(); 550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceBundle::ReloadFonts() { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock_scope(*images_and_fonts_lock_); 554a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base_font_list_.reset(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadFontsIfNecessary(); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ScaleFactor ResourceBundle::GetMaxScaleFactor() const { 559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS) || defined(OS_WIN) 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return max_scale_factor_; 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else 56268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetSupportedScaleFactors().back(); 56368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 56468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 56568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ResourceBundle::IsScaleFactorSupported(ScaleFactor scale_factor) { 567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<ScaleFactor>& supported_scale_factors = 568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::GetSupportedScaleFactors(); 569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return std::find(supported_scale_factors.begin(), 570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) supported_scale_factors.end(), 571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scale_factor) != supported_scale_factors.end(); 572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceBundle::ResourceBundle(Delegate* delegate) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(delegate), 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_and_fonts_lock_(new base::Lock), 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) locale_resources_data_lock_(new base::Lock), 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_scale_factor_(SCALE_FACTOR_100P) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceBundle::~ResourceBundle() { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreeImages(); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnloadLocaleResources(); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static 58768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ResourceBundle::InitSharedInstance(Delegate* delegate) { 58868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; 58968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) g_shared_instance_ = new ResourceBundle(delegate); 59068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) static std::vector<ScaleFactor> supported_scale_factors; 591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_IOS) && !defined(OS_WIN) 59268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // On platforms other than iOS, 100P is always a supported scale factor. 593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // For Windows we have a separate case in this function. 59468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_100P); 59568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 59668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID) 59768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::Display display = 59868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 59968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const float display_density = display.device_scale_factor(); 60068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScaleFactor closest = FindClosestScaleFactorUnsafe(display_density); 60168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (closest != SCALE_FACTOR_100P) 60268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_scale_factors.push_back(closest); 60368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#elif defined(OS_IOS) 60468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 60568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (display.device_scale_factor() > 1.0) { 60668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(2.0, display.device_scale_factor()); 60768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_200P); 60868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 60968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_100P); 61068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 61168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#elif defined(OS_MACOSX) 61268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (base::mac::IsOSLionOrLater()) 61368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_200P); 61468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#elif defined(OS_CHROMEOS) 61568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(oshima): Include 200P only if the device support 200P 61668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_200P); 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_LINUX) && defined(ENABLE_HIDPI) 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_200P); 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_WIN) 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool default_to_100P = true; 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (gfx::IsHighDPIEnabled()) { 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // On Windows if the dpi scale is greater than 1.25 on high dpi machines 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // downscaling from 200 percent looks better than scaling up from 100 624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // percent. 625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (gfx::GetDPIScale() > 1.25) { 626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_200P); 627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default_to_100P = false; 628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (default_to_100P) 631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) supported_scale_factors.push_back(SCALE_FACTOR_100P); 63268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::SetSupportedScaleFactors(supported_scale_factors); 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN) 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Must be called _after_ supported scale factors are set since it 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // uses them. 63746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Don't initialize the device scale factor if it has already been 63846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // initialized. 63946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!gfx::win::IsDeviceScaleFactorSet()) 64046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::win::InitDeviceScaleFactor(); 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 64268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 64368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceBundle::FreeImages() { 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_.clear(); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceBundle::AddDataPackFromPathInternal(const base::FilePath& path, 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScaleFactor scale_factor, 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool optional) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not pass an empty |path| value to this method. If the absolute path is 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unknown pass just the pack file name. 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!path.empty()); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath pack_path = path; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pack_path = delegate_->GetPathForResourcePack(pack_path, scale_factor); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't try to load empty values or values that are not absolute paths. 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pack_path.empty() || !pack_path.IsAbsolute()) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DataPack> data_pack( 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DataPack(scale_factor)); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_pack->LoadFromPath(pack_path)) { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddDataPack(data_pack.release()); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!optional) { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to load " << pack_path.value() 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\nSome features may not be available."; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceBundle::AddDataPack(DataPack* data_pack) { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_packs_.push_back(data_pack); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (GetScaleForScaleFactor(data_pack->GetScaleFactor()) > 6770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GetScaleForScaleFactor(max_scale_factor_)) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_scale_factor_ = data_pack->GetScaleFactor(); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceBundle::LoadFontsIfNecessary() { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) images_and_fonts_lock_->AssertAcquired(); 683a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!base_font_list_.get()) { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) { 685a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base_font_list_ = GetFontListFromDelegate(BaseFont); 686a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bold_font_list_ = GetFontListFromDelegate(BoldFont); 687a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) small_font_list_ = GetFontListFromDelegate(SmallFont); 688a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) small_bold_font_list_ = GetFontListFromDelegate(SmallBoldFont); 689a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) medium_font_list_ = GetFontListFromDelegate(MediumFont); 690a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) medium_bold_font_list_ = GetFontListFromDelegate(MediumBoldFont); 691a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) large_font_list_ = GetFontListFromDelegate(LargeFont); 692a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) large_bold_font_list_ = GetFontListFromDelegate(LargeBoldFont); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!base_font_list_.get()) 696a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base_font_list_.reset(new gfx::FontList()); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 698a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!bold_font_list_.get()) { 699a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bold_font_list_.reset(new gfx::FontList()); 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *bold_font_list_ = base_font_list_->DeriveWithStyle( 701a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base_font_list_->GetFontStyle() | gfx::Font::BOLD); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 704a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!small_font_list_.get()) { 705a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) small_font_list_.reset(new gfx::FontList()); 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *small_font_list_ = 7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base_font_list_->DeriveWithSizeDelta(kSmallFontSizeDelta); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 710a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!small_bold_font_list_.get()) { 711a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) small_bold_font_list_.reset(new gfx::FontList()); 7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *small_bold_font_list_ = small_font_list_->DeriveWithStyle( 713a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) small_font_list_->GetFontStyle() | gfx::Font::BOLD); 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!medium_font_list_.get()) { 717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) medium_font_list_.reset(new gfx::FontList()); 7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *medium_font_list_ = 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base_font_list_->DeriveWithSizeDelta(kMediumFontSizeDelta); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!medium_bold_font_list_.get()) { 723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) medium_bold_font_list_.reset(new gfx::FontList()); 7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *medium_bold_font_list_ = medium_font_list_->DeriveWithStyle( 725a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) medium_font_list_->GetFontStyle() | gfx::Font::BOLD); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 728a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!large_font_list_.get()) { 729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) large_font_list_.reset(new gfx::FontList()); 7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *large_font_list_ = 7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base_font_list_->DeriveWithSizeDelta(kLargeFontSizeDelta); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 734a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!large_bold_font_list_.get()) { 735a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) large_bold_font_list_.reset(new gfx::FontList()); 7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *large_bold_font_list_ = large_font_list_->DeriveWithStyle( 737a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) large_font_list_->GetFontStyle() | gfx::Font::BOLD); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<gfx::FontList> ResourceBundle::GetFontListFromDelegate( 743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FontStyle style) { 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(delegate_); 745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<gfx::Font> font = delegate_->GetFont(style); 746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (font.get()) 747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return scoped_ptr<gfx::FontList>(new gfx::FontList(*font)); 748a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return scoped_ptr<gfx::FontList>(); 749a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 750a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ResourceBundle::LoadBitmap(const ResourceHandle& data_handle, 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_id, 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap* bitmap, 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* fell_back_to_1x) const { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fell_back_to_1x); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedMemory> memory( 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_handle.GetStaticMemory(resource_id)); 758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!memory.get()) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DecodePNG(memory->front(), memory->size(), bitmap, fell_back_to_1x)) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // iOS does not compile or use the JPEG codec. On other platforms, 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 99% of our assets are PNGs, however fallback to JPEG. 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SkBitmap> jpeg_bitmap( 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::JPEGCodec::Decode(memory->front(), memory->size())); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (jpeg_bitmap.get()) { 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->swap(*jpeg_bitmap.get()); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fell_back_to_1x = false; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to decode theme image resource " << resource_id; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ResourceBundle::LoadBitmap(int resource_id, 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScaleFactor* scale_factor, 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap* bitmap, 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* fell_back_to_1x) const { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(fell_back_to_1x); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < data_packs_.size(); ++i) { 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_NONE && 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadBitmap(*data_packs_[i], resource_id, bitmap, fell_back_to_1x)) { 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!*fell_back_to_1x); 789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *scale_factor = ui::SCALE_FACTOR_NONE; 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data_packs_[i]->GetScaleFactor() == *scale_factor && 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadBitmap(*data_packs_[i], resource_id, bitmap, fell_back_to_1x)) { 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image& ResourceBundle::GetEmptyImage() { 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(*images_and_fonts_lock_); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (empty_image_.IsEmpty()) { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The placeholder bitmap is bright red so people notice the problem. 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.setConfig(SkBitmap::kARGB_8888_Config, 32, 32); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.allocPixels(); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.eraseARGB(255, 255, 0, 0); 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) empty_image_ = gfx::Image::CreateFrom1xBitmap(bitmap); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return empty_image_; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceBundle::PNGContainsFallbackMarker(const unsigned char* buf, 816a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t size) { 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size < arraysize(kPngMagic) || 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memcmp(buf, kPngMagic, arraysize(kPngMagic)) != 0) { 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Data invalid or a JPEG. 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t pos = arraysize(kPngMagic); 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Scan for custom chunks until we find one, find the IDAT chunk, or run out 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of chunks. 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (;;) { 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size - pos < kPngChunkMetadataSize) 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 length = 0; 830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ReadBigEndian(reinterpret_cast<const char*>(buf + pos), &length); 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size - pos - kPngChunkMetadataSize < length) 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (length == 0 && memcmp(buf + pos + sizeof(uint32), kPngScaleChunkType, 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arraysize(kPngScaleChunkType)) == 0) { 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (memcmp(buf + pos + sizeof(uint32), kPngDataChunkType, 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arraysize(kPngDataChunkType)) == 0) { 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop looking for custom chunks, any custom chunks should be before an 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // IDAT chunk. 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pos += length + kPngChunkMetadataSize; 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceBundle::DecodePNG(const unsigned char* buf, 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t size, 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkBitmap* bitmap, 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* fell_back_to_1x) { 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *fell_back_to_1x = PNGContainsFallbackMarker(buf, size); 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::PNGCodec::Decode(buf, size, bitmap); 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 858