| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/themes/browser_theme_pack.h" | 5 #include "chrome/browser/themes/browser_theme_pack.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <utility> |
| 12 | 13 |
| 13 #include "base/files/file.h" | 14 #include "base/files/file.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 15 #include "base/memory/ref_counted_memory.h" | 16 #include "base/memory/ref_counted_memory.h" |
| 16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/threading/sequenced_worker_pool.h" | 21 #include "base/threading/sequenced_worker_pool.h" |
| 21 #include "base/threading/thread_restrictions.h" | 22 #include "base/threading/thread_restrictions.h" |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 extensions::ThemeInfo::GetDisplayProperties(extension)); | 614 extensions::ThemeInfo::GetDisplayProperties(extension)); |
| 614 | 615 |
| 615 // Builds the images. (Image building is dependent on tints). | 616 // Builds the images. (Image building is dependent on tints). |
| 616 FilePathMap file_paths; | 617 FilePathMap file_paths; |
| 617 pack->ParseImageNamesFromJSON( | 618 pack->ParseImageNamesFromJSON( |
| 618 extensions::ThemeInfo::GetImages(extension), | 619 extensions::ThemeInfo::GetImages(extension), |
| 619 extension->path(), | 620 extension->path(), |
| 620 &file_paths); | 621 &file_paths); |
| 621 pack->BuildSourceImagesArray(file_paths); | 622 pack->BuildSourceImagesArray(file_paths); |
| 622 | 623 |
| 623 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_)) | 624 // Create images for use on the FILE thread (which is where these Image |
| 625 // objects will live). |
| 626 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_file_thread_)) |
| 624 return NULL; | 627 return NULL; |
| 625 | 628 |
| 626 pack->CreateImages(&pack->images_on_ui_thread_); | 629 pack->CreateImages(&pack->images_on_file_thread_); |
| 627 | 630 |
| 628 // Make sure the |images_on_file_thread_| has bitmaps for supported | 631 // Make sure the |images_on_file_thread_| has bitmaps for supported |
| 629 // scale factors before passing to FILE thread. | 632 // scale factors before passing to FILE thread. |
| 630 pack->images_on_file_thread_ = pack->images_on_ui_thread_; | 633 for (auto& item : pack->images_on_file_thread_) { |
| 631 for (ImageCache::iterator it = pack->images_on_file_thread_.begin(); | |
| 632 it != pack->images_on_file_thread_.end(); ++it) { | |
| 633 gfx::ImageSkia* image_skia = | 634 gfx::ImageSkia* image_skia = |
| 634 const_cast<gfx::ImageSkia*>(it->second.ToImageSkia()); | 635 const_cast<gfx::ImageSkia*>(item.second.ToImageSkia()); |
| 635 image_skia->MakeThreadSafe(); | 636 image_skia->MakeThreadSafe(); |
| 636 } | 637 } |
| 637 | 638 |
| 639 // Copy the images over for use on the UI thread. To avoid sharing |
| 640 // thread-unsafe Image objects across threads, new Image objects are created. |
| 641 // |
| 638 // Set ThemeImageSource on |images_on_ui_thread_| to resample the source | 642 // Set ThemeImageSource on |images_on_ui_thread_| to resample the source |
| 639 // image if a caller of BrowserThemePack::GetImageNamed() requests an | 643 // image if a caller of BrowserThemePack::GetImageNamed() requests an |
| 640 // ImageSkiaRep for a scale factor not specified by the theme author. | 644 // ImageSkiaRep for a scale factor not specified by the theme author. |
| 641 // Callers of BrowserThemePack::GetImageNamed() to be able to retrieve | 645 // Callers of BrowserThemePack::GetImageNamed() to be able to retrieve |
| 642 // ImageSkiaReps for all supported scale factors. | 646 // ImageSkiaReps for all supported scale factors. |
| 643 for (ImageCache::iterator it = pack->images_on_ui_thread_.begin(); | 647 for (auto& item : pack->images_on_file_thread_) { |
| 644 it != pack->images_on_ui_thread_.end(); ++it) { | 648 const gfx::ImageSkia source_image_skia = item.second.AsImageSkia(); |
| 645 const gfx::ImageSkia source_image_skia = it->second.AsImageSkia(); | |
| 646 ThemeImageSource* source = new ThemeImageSource(source_image_skia); | 649 ThemeImageSource* source = new ThemeImageSource(source_image_skia); |
| 647 // image_skia takes ownership of source. | 650 // image_skia takes ownership of source. |
| 648 gfx::ImageSkia image_skia(source, source_image_skia.size()); | 651 gfx::ImageSkia image_skia(source, source_image_skia.size()); |
| 649 it->second = gfx::Image(image_skia); | 652 pack->images_on_ui_thread_.insert( |
| 653 std::make_pair(item.first, gfx::Image(image_skia))); |
| 650 } | 654 } |
| 651 | 655 |
| 652 // Generate raw images (for new-tab-page attribution and background) for | 656 // Generate raw images (for new-tab-page attribution and background) for |
| 653 // any missing scale from an available scale image. | 657 // any missing scale from an available scale image. |
| 654 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { | 658 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { |
| 655 pack->GenerateRawImageForAllSupportedScales(kPreloadIDs[i]); | 659 pack->GenerateRawImageForAllSupportedScales(kPreloadIDs[i]); |
| 656 } | 660 } |
| 657 | 661 |
| 658 // The BrowserThemePack is now in a consistent state. | 662 // The BrowserThemePack is now in a consistent state. |
| 659 return pack; | 663 return pack; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 if (display_properties_[i].id == id) { | 811 if (display_properties_[i].id == id) { |
| 808 *result = display_properties_[i].property; | 812 *result = display_properties_[i].property; |
| 809 return true; | 813 return true; |
| 810 } | 814 } |
| 811 } | 815 } |
| 812 } | 816 } |
| 813 | 817 |
| 814 return false; | 818 return false; |
| 815 } | 819 } |
| 816 | 820 |
| 817 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { | 821 const gfx::Image& BrowserThemePack::GetImageNamed(int idr_id) { |
| 818 int prs_id = GetPersistentIDByIDR(idr_id); | 822 int prs_id = GetPersistentIDByIDR(idr_id); |
| 819 if (prs_id == -1) | 823 if (prs_id == -1) |
| 820 return gfx::Image(); | 824 return empty_image(); |
| 821 | 825 |
| 822 // Check if the image is cached. | 826 // Check if the image is cached. |
| 823 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); | 827 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); |
| 824 if (image_iter != images_on_ui_thread_.end()) | 828 if (image_iter != images_on_ui_thread_.end()) |
| 825 return image_iter->second; | 829 return image_iter->second; |
| 826 | 830 |
| 827 ThemeImagePngSource::PngMap png_map; | 831 ThemeImagePngSource::PngMap png_map; |
| 828 for (size_t i = 0; i < scale_factors_.size(); ++i) { | 832 for (size_t i = 0; i < scale_factors_.size(); ++i) { |
| 829 scoped_refptr<base::RefCountedMemory> memory = | 833 scoped_refptr<base::RefCountedMemory> memory = |
| 830 GetRawData(idr_id, scale_factors_[i]); | 834 GetRawData(idr_id, scale_factors_[i]); |
| 831 if (memory.get()) | 835 if (memory.get()) |
| 832 png_map[scale_factors_[i]] = memory; | 836 png_map[scale_factors_[i]] = memory; |
| 833 } | 837 } |
| 834 if (!png_map.empty()) { | 838 if (!png_map.empty()) { |
| 835 gfx::ImageSkia image_skia(new ThemeImagePngSource(png_map), 1.0f); | 839 gfx::ImageSkia image_skia(new ThemeImagePngSource(png_map), 1.0f); |
| 836 // |image_skia| takes ownership of ThemeImagePngSource. | 840 // |image_skia| takes ownership of ThemeImagePngSource. |
| 837 gfx::Image ret = gfx::Image(image_skia); | 841 auto result = images_on_ui_thread_.insert( |
| 838 images_on_ui_thread_[prs_id] = ret; | 842 std::make_pair(prs_id, gfx::Image(image_skia))); |
| 839 return ret; | 843 return result.first->second; |
| 840 } | 844 } |
| 841 | 845 |
| 842 return gfx::Image(); | 846 return empty_image(); |
| 843 } | 847 } |
| 844 | 848 |
| 845 base::RefCountedMemory* BrowserThemePack::GetRawData( | 849 base::RefCountedMemory* BrowserThemePack::GetRawData( |
| 846 int idr_id, | 850 int idr_id, |
| 847 ui::ScaleFactor scale_factor) const { | 851 ui::ScaleFactor scale_factor) const { |
| 848 base::RefCountedMemory* memory = NULL; | 852 base::RefCountedMemory* memory = NULL; |
| 849 int prs_id = GetPersistentIDByIDR(idr_id); | 853 int prs_id = GetPersistentIDByIDR(idr_id); |
| 850 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); | 854 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); |
| 851 | 855 |
| 852 if (raw_id != -1) { | 856 if (raw_id != -1) { |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 | 1286 |
| 1283 void BrowserThemePack::CreateFrameImages(ImageCache* images) const { | 1287 void BrowserThemePack::CreateFrameImages(ImageCache* images) const { |
| 1284 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1288 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1285 | 1289 |
| 1286 // Create all the output images in a separate cache and move them back into | 1290 // Create all the output images in a separate cache and move them back into |
| 1287 // the input images because there can be name collisions. | 1291 // the input images because there can be name collisions. |
| 1288 ImageCache temp_output; | 1292 ImageCache temp_output; |
| 1289 | 1293 |
| 1290 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { | 1294 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { |
| 1291 int prs_id = kFrameTintMap[i].key; | 1295 int prs_id = kFrameTintMap[i].key; |
| 1292 gfx::Image frame; | 1296 const gfx::Image* frame = &empty_image(); |
| 1293 // If there's no frame image provided for the specified id, then load | 1297 // If there's no frame image provided for the specified id, then load |
| 1294 // the default provided frame. If that's not provided, skip this whole | 1298 // the default provided frame. If that's not provided, skip this whole |
| 1295 // thing and just use the default images. | 1299 // thing and just use the default images. |
| 1296 int prs_base_id = 0; | 1300 int prs_base_id = 0; |
| 1297 | 1301 |
| 1298 if (!prs_base_id) { | 1302 if (!prs_base_id) { |
| 1299 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { | 1303 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { |
| 1300 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ? | 1304 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ? |
| 1301 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; | 1305 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; |
| 1302 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { | 1306 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { |
| 1303 prs_base_id = PRS_THEME_FRAME_OVERLAY; | 1307 prs_base_id = PRS_THEME_FRAME_OVERLAY; |
| 1304 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { | 1308 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { |
| 1305 prs_base_id = PRS_THEME_FRAME; | 1309 prs_base_id = PRS_THEME_FRAME; |
| 1306 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && | 1310 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && |
| 1307 !images->count(PRS_THEME_FRAME_INCOGNITO)) { | 1311 !images->count(PRS_THEME_FRAME_INCOGNITO)) { |
| 1308 prs_base_id = PRS_THEME_FRAME; | 1312 prs_base_id = PRS_THEME_FRAME; |
| 1309 } else { | 1313 } else { |
| 1310 prs_base_id = prs_id; | 1314 prs_base_id = prs_id; |
| 1311 } | 1315 } |
| 1312 } | 1316 } |
| 1313 if (images->count(prs_id)) { | 1317 if (images->count(prs_id)) { |
| 1314 frame = (*images)[prs_id]; | 1318 frame = &(*images)[prs_id]; |
| 1315 } else if (prs_base_id != prs_id && images->count(prs_base_id)) { | 1319 } else if (prs_base_id != prs_id && images->count(prs_base_id)) { |
| 1316 frame = (*images)[prs_base_id]; | 1320 frame = &(*images)[prs_base_id]; |
| 1317 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY) { | 1321 } else if (prs_base_id != PRS_THEME_FRAME_OVERLAY) { |
| 1318 if (images->count(PRS_THEME_FRAME)) { | 1322 // If there is no theme overlay, don't tint the default frame, |
| 1319 // If there is no theme overlay, don't tint the default frame, | 1323 // because it will overwrite the custom frame image when we cache and |
| 1320 // because it will overwrite the custom frame image when we cache and | 1324 // reload from disk. If the theme doesn't specify an image, then apply the |
| 1321 // reload from disk. | 1325 // tint to the default frame. |
| 1322 frame = gfx::Image(); | 1326 frame = &rb.GetImageNamed(IDR_THEME_FRAME); |
| 1323 } | |
| 1324 } else { | |
| 1325 // If the theme doesn't specify an image, then apply the tint to | |
| 1326 // the default frame. | |
| 1327 frame = rb.GetImageNamed(IDR_THEME_FRAME); | |
| 1328 } | 1327 } |
| 1329 if (!frame.IsEmpty()) { | 1328 if (!frame->IsEmpty()) { |
| 1330 temp_output[prs_id] = CreateHSLShiftedImage( | 1329 temp_output[prs_id] = CreateHSLShiftedImage( |
| 1331 frame, GetTintInternal(kFrameTintMap[i].value)); | 1330 *frame, GetTintInternal(kFrameTintMap[i].value)); |
| 1332 } | 1331 } |
| 1333 } | 1332 } |
| 1334 MergeImageCaches(temp_output, images); | 1333 MergeImageCaches(std::move(temp_output), images); |
| 1335 } | 1334 } |
| 1336 | 1335 |
| 1337 void BrowserThemePack::CreateTintedButtons( | 1336 void BrowserThemePack::CreateTintedButtons( |
| 1338 const color_utils::HSL& button_tint, | 1337 const color_utils::HSL& button_tint, |
| 1339 ImageCache* processed_images) const { | 1338 ImageCache* processed_images) const { |
| 1340 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { | 1339 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { |
| 1341 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1340 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1342 const std::set<int>& idr_ids = | 1341 const std::set<int>& idr_ids = |
| 1343 ThemeProperties::GetTintableToolbarButtons(); | 1342 ThemeProperties::GetTintableToolbarButtons(); |
| 1344 for (std::set<int>::const_iterator it = idr_ids.begin(); | 1343 for (std::set<int>::const_iterator it = idr_ids.begin(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 if (overlay_it != images->end()) | 1376 if (overlay_it != images->end()) |
| 1378 overlay = overlay_it->second.AsImageSkia(); | 1377 overlay = overlay_it->second.AsImageSkia(); |
| 1379 | 1378 |
| 1380 gfx::ImageSkiaSource* source = new TabBackgroundImageSource( | 1379 gfx::ImageSkiaSource* source = new TabBackgroundImageSource( |
| 1381 image_to_tint, overlay, hsl_shift, vertical_offset); | 1380 image_to_tint, overlay, hsl_shift, vertical_offset); |
| 1382 // ImageSkia takes ownership of |source|. | 1381 // ImageSkia takes ownership of |source|. |
| 1383 temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source, | 1382 temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source, |
| 1384 image_to_tint.size())); | 1383 image_to_tint.size())); |
| 1385 } | 1384 } |
| 1386 } | 1385 } |
| 1387 MergeImageCaches(temp_output, images); | 1386 MergeImageCaches(std::move(temp_output), images); |
| 1388 } | 1387 } |
| 1389 | 1388 |
| 1390 void BrowserThemePack::RepackImages(const ImageCache& images, | 1389 void BrowserThemePack::RepackImages(const ImageCache& images, |
| 1391 RawImages* reencoded_images) const { | 1390 RawImages* reencoded_images) const { |
| 1392 for (ImageCache::const_iterator it = images.begin(); | 1391 for (ImageCache::const_iterator it = images.begin(); |
| 1393 it != images.end(); ++it) { | 1392 it != images.end(); ++it) { |
| 1394 gfx::ImageSkia image_skia = *it->second.ToImageSkia(); | 1393 gfx::ImageSkia image_skia = *it->second.ToImageSkia(); |
| 1395 | 1394 |
| 1396 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps; | 1395 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps; |
| 1397 ImageSkiaReps image_reps = image_skia.image_reps(); | 1396 ImageSkiaReps image_reps = image_skia.image_reps(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1408 } | 1407 } |
| 1409 int raw_id = GetRawIDByPersistentID( | 1408 int raw_id = GetRawIDByPersistentID( |
| 1410 it->first, | 1409 it->first, |
| 1411 ui::GetSupportedScaleFactor(rep_it->scale())); | 1410 ui::GetSupportedScaleFactor(rep_it->scale())); |
| 1412 (*reencoded_images)[raw_id] = | 1411 (*reencoded_images)[raw_id] = |
| 1413 base::RefCountedBytes::TakeVector(&bitmap_data); | 1412 base::RefCountedBytes::TakeVector(&bitmap_data); |
| 1414 } | 1413 } |
| 1415 } | 1414 } |
| 1416 } | 1415 } |
| 1417 | 1416 |
| 1418 void BrowserThemePack::MergeImageCaches( | 1417 void BrowserThemePack::MergeImageCaches(ImageCache source, |
| 1419 const ImageCache& source, ImageCache* destination) const { | 1418 ImageCache* destination) const { |
| 1420 for (ImageCache::const_iterator it = source.begin(); it != source.end(); | 1419 for (auto& item : source) |
| 1421 ++it) { | 1420 (*destination)[item.first] = std::move(item.second); |
| 1422 (*destination)[it->first] = it->second; | |
| 1423 } | |
| 1424 } | 1421 } |
| 1425 | 1422 |
| 1426 void BrowserThemePack::AddRawImagesTo(const RawImages& images, | 1423 void BrowserThemePack::AddRawImagesTo(const RawImages& images, |
| 1427 RawDataForWriting* out) const { | 1424 RawDataForWriting* out) const { |
| 1428 for (RawImages::const_iterator it = images.begin(); it != images.end(); | 1425 for (RawImages::const_iterator it = images.begin(); it != images.end(); |
| 1429 ++it) { | 1426 ++it) { |
| 1430 (*out)[it->first] = base::StringPiece( | 1427 (*out)[it->first] = base::StringPiece( |
| 1431 it->second->front_as<char>(), it->second->size()); | 1428 it->second->front_as<char>(), it->second->size()); |
| 1432 } | 1429 } |
| 1433 } | 1430 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1540 false, | 1537 false, |
| 1541 &bitmap_data)) { | 1538 &bitmap_data)) { |
| 1542 NOTREACHED() << "Unable to encode theme image for prs_id=" | 1539 NOTREACHED() << "Unable to encode theme image for prs_id=" |
| 1543 << prs_id << " for scale_factor=" << scale_factors_[i]; | 1540 << prs_id << " for scale_factor=" << scale_factors_[i]; |
| 1544 break; | 1541 break; |
| 1545 } | 1542 } |
| 1546 image_memory_[scaled_raw_id] = | 1543 image_memory_[scaled_raw_id] = |
| 1547 base::RefCountedBytes::TakeVector(&bitmap_data); | 1544 base::RefCountedBytes::TakeVector(&bitmap_data); |
| 1548 } | 1545 } |
| 1549 } | 1546 } |
| OLD | NEW |