Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Side by Side Diff: chrome/browser/themes/browser_theme_pack.cc

Issue 10783015: Add ability to store hidpi theme images in data pack (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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> 7 #include <limits>
8 8
9 #include "base/memory/ref_counted_memory.h" 9 #include "base/memory/ref_counted_memory.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/threading/thread_restrictions.h" 13 #include "base/threading/thread_restrictions.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "chrome/browser/themes/theme_service.h" 16 #include "chrome/browser/themes/theme_service.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "grit/theme_resources.h" 18 #include "grit/theme_resources.h"
19 #include "grit/ui_resources.h" 19 #include "grit/ui_resources.h"
20 #include "net/base/file_stream.h" 20 #include "net/base/file_stream.h"
21 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
22 #include "third_party/skia/include/core/SkCanvas.h" 22 #include "third_party/skia/include/core/SkCanvas.h"
23 #include "ui/base/resource/data_pack.h" 23 #include "ui/base/resource/data_pack.h"
24 #include "ui/base/resource/resource_bundle.h" 24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/gfx/canvas.h" 25 #include "ui/gfx/canvas.h"
26 #include "ui/gfx/codec/png_codec.h" 26 #include "ui/gfx/codec/png_codec.h"
27 #include "ui/gfx/image/canvas_image_source.h"
27 #include "ui/gfx/image/image.h" 28 #include "ui/gfx/image/image.h"
28 #include "ui/gfx/image/image_skia.h" 29 #include "ui/gfx/image/image_skia.h"
29 #include "ui/gfx/skbitmap_operations.h" 30 #include "ui/gfx/image/image_skia_operations.h"
31 #include "ui/gfx/screen.h"
30 32
31 using content::BrowserThread; 33 using content::BrowserThread;
32 using extensions::Extension; 34 using extensions::Extension;
33 35
34 namespace { 36 namespace {
35 37
36 // Version number of the current theme pack. We just throw out and rebuild 38 // Version number of the current theme pack. We just throw out and rebuild
37 // theme packs that aren't int-equal to this. Increment this number if you 39 // theme packs that aren't int-equal to this. Increment this number if you
38 // change default theme assets. 40 // change default theme assets.
39 const int kThemePackVersion = 24; 41 const int kThemePackVersion = 24;
40 42
41 // IDs that are in the DataPack won't clash with the positive integer 43 // IDs that are in the DataPack won't clash with the positive integer
42 // uint16. kHeaderID should always have the maximum value because we want the 44 // uint16. kHeaderID should always have the maximum value because we want the
43 // "header" to be written last. That way we can detect whether the pack was 45 // "header" to be written last. That way we can detect whether the pack was
44 // successfully written and ignore and regenerate if it was only partially 46 // successfully written and ignore and regenerate if it was only partially
45 // written (i.e. chrome crashed on a different thread while writing the pack). 47 // written (i.e. chrome crashed on a different thread while writing the pack).
46 const int kMaxID = 0x0000FFFF; // Max unsigned 16-bit int. 48 const int kMaxID = 0x0000FFFF; // Max unsigned 16-bit int.
47 const int kHeaderID = kMaxID - 1; 49 const int kHeaderID = kMaxID - 1;
48 const int kTintsID = kMaxID - 2; 50 const int kTintsID = kMaxID - 2;
49 const int kColorsID = kMaxID - 3; 51 const int kColorsID = kMaxID - 3;
50 const int kDisplayPropertiesID = kMaxID - 4; 52 const int kDisplayPropertiesID = kMaxID - 4;
51 const int kSourceImagesID = kMaxID - 5; 53 const int kSourceImagesID = kMaxID - 5;
54 const int kScaleFactorsID = kMaxID - 6;
52 55
53 // Static size of the tint/color/display property arrays that are mmapped. 56 // Static size of the tint/color/display property arrays that are mmapped.
54 const int kTintArraySize = 6; 57 const int kTintArraySize = 6;
55 const int kColorArraySize = 19; 58 const int kColorArraySize = 19;
56 const int kDisplayPropertySize = 3; 59 const int kDisplayPropertySize = 3;
57 60
58 // The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from 61 // The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from
59 // OpaqueBrowserFrameView. 62 // OpaqueBrowserFrameView.
60 const int kRestoredTabVerticalOffset = 15; 63 const int kRestoredTabVerticalOffset = 15;
61 64
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 { 37, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL }, 153 { 37, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL },
151 { 38, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL }, 154 { 38, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL },
152 { 39, IDR_TOOLS, NULL }, 155 { 39, IDR_TOOLS, NULL },
153 { 40, IDR_TOOLS_H, NULL }, 156 { 40, IDR_TOOLS_H, NULL },
154 { 41, IDR_TOOLS_P, NULL }, 157 { 41, IDR_TOOLS_P, NULL },
155 { 42, IDR_MENU_DROPARROW, NULL }, 158 { 42, IDR_MENU_DROPARROW, NULL },
156 { 43, IDR_THROBBER, NULL }, 159 { 43, IDR_THROBBER, NULL },
157 { 44, IDR_THROBBER_WAITING, NULL }, 160 { 44, IDR_THROBBER_WAITING, NULL },
158 { 45, IDR_THROBBER_LIGHT, NULL }, 161 { 45, IDR_THROBBER_LIGHT, NULL },
159 }; 162 };
163 size_t kPersistingImagesLength = arraysize(kPersistingImages);
160 164
161 int GetPersistentIDByName(const std::string& key) { 165 int GetPersistentIDByName(const std::string& key) {
162 for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { 166 for (size_t i = 0; i < kPersistingImagesLength; ++i) {
163 if (kPersistingImages[i].key != NULL && 167 if (kPersistingImages[i].key != NULL &&
164 base::strcasecmp(key.c_str(), kPersistingImages[i].key) == 0) { 168 base::strcasecmp(key.c_str(), kPersistingImages[i].key) == 0) {
165 return kPersistingImages[i].persistent_id; 169 return kPersistingImages[i].persistent_id;
166 } 170 }
167 } 171 }
168 172
169 return -1; 173 return -1;
170 } 174 }
171 175
172 int GetPersistentIDByIDR(int idr) { 176 int GetPersistentIDByIDR(int idr) {
173 for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { 177 static std::map<int,int>* lookup_table = new std::map<int,int>();
174 if (kPersistingImages[i].idr_id == idr) { 178 if (lookup_table->empty()) {
175 return kPersistingImages[i].persistent_id; 179 for (size_t i = 0; i < kPersistingImagesLength; ++i) {
180 int idr = kPersistingImages[i].idr_id;
181 int prs_id = kPersistingImages[i].persistent_id;
182 (*lookup_table)[idr] = prs_id;
176 } 183 }
177 } 184 }
185 std::map<int,int>::iterator it = lookup_table->find(idr);
186 return (it == lookup_table->end()) ? -1 : it->second;
187 }
178 188
179 return -1; 189 // Returns true if the scales in |input| match those in |expected|.
190 // The order must match as the index is used in determining the raw id.
191 bool InputScalesValid(const char* input,
192 const std::vector<ui::ScaleFactor>& expected) {
193 const float* scales = reinterpret_cast<const float*>(input);
194 size_t index = 0;
195 for (const float* end = scales; *end != -1.0f; ++end) {
196 if (index >= expected.size())
197 return false;
198 if (*end != ui::GetScaleFactorScale(expected[index]))
199 return false;
200 index++;
201 }
202 return (index == expected.size());
203 }
204
205 // Returns |scale_factors| as a string to be written to disk.
206 base::StringPiece GetScaleFactorsAsString(
207 const std::vector<ui::ScaleFactor>& scale_factors) {
208 size_t scales_size = scale_factors.size() + 1;
209 float* scales = new float[scales_size];
210 for (size_t i = 0; i < scale_factors.size(); ++i)
211 scales[i] = ui::GetScaleFactorScale(scale_factors[i]);
212 scales[scales_size - 1] = -1.0f;
213 base::StringPiece out_string = base::StringPiece(
214 reinterpret_cast<const char*>(&scales),
215 scales_size * sizeof(float));
216 delete[] scales;
217 return out_string;
180 } 218 }
181 219
182 struct StringToIntTable { 220 struct StringToIntTable {
183 const char* key; 221 const char* key;
184 int id; 222 int id;
185 }; 223 };
186 224
187 // Strings used by themes to identify tints in the JSON. 225 // Strings used by themes to identify tints in the JSON.
188 StringToIntTable kTintTable[] = { 226 StringToIntTable kTintTable[] = {
189 { "buttons", ThemeService::TINT_BUTTONS }, 227 { "buttons", ThemeService::TINT_BUTTONS },
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 char* data = reinterpret_cast<char*>(&(raw_data.front())); 339 char* data = reinterpret_cast<char*>(&(raw_data.front()));
302 if (file.ReadUntilComplete(data, size) == avail) 340 if (file.ReadUntilComplete(data, size) == avail)
303 return base::RefCountedBytes::TakeVector(&raw_data); 341 return base::RefCountedBytes::TakeVector(&raw_data);
304 } 342 }
305 } 343 }
306 } 344 }
307 345
308 return NULL; 346 return NULL;
309 } 347 }
310 348
311 // Shifts a bitmap's HSL values. The caller is responsible for deleting 349 // Shifts an image's HSL values. The caller is responsible for deleting
312 // the returned image. 350 // the returned image.
313 gfx::Image* CreateHSLShiftedImage(const gfx::Image& image, 351 gfx::Image* CreateHSLShiftedImage(const gfx::Image& image,
314 const color_utils::HSL& hsl_shift) { 352 const color_utils::HSL& hsl_shift) {
315 const gfx::ImageSkia* src_image = image.ToImageSkia(); 353 const gfx::ImageSkia* src_image = image.ToImageSkia();
316 std::vector<gfx::ImageSkiaRep> src_image_reps = src_image->image_reps(); 354 return new gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage(
317 gfx::ImageSkia dst_image; 355 *src_image, hsl_shift));
318 for (size_t i = 0; i < src_image_reps.size(); ++i) { 356 }
319 const gfx::ImageSkiaRep& image_rep = src_image_reps[i]; 357
320 SkBitmap dst_bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( 358 class TabBackgroundImageSource: public gfx::CanvasImageSource {
321 image_rep.sk_bitmap(), hsl_shift); 359 public:
322 dst_image.AddRepresentation(gfx::ImageSkiaRep(dst_bitmap, 360 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint,
323 image_rep.scale_factor())); 361 const gfx::ImageSkia& overlay,
362 const color_utils::HSL& hsl_shift,
363 int vertical_offset)
364 : gfx::CanvasImageSource(image_to_tint.size(), false),
365 image_to_tint_(image_to_tint),
366 overlay_(overlay),
367 hsl_shift_(hsl_shift),
368 vertical_offset_(vertical_offset) {
324 } 369 }
325 return new gfx::Image(dst_image); 370
326 } 371 virtual ~TabBackgroundImageSource() {
372 }
373
374 // Overridden from CanvasImageSource:
375 virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
376 gfx::ImageSkia bg_tint =
377 gfx::ImageSkiaOperations::CreateHSLShiftedImage(image_to_tint_,
378 hsl_shift_);
379 canvas->TileImageInt(bg_tint, 0, vertical_offset_, 0, 0,
380 size().width(), size().height());
381
382 // If they've provided a custom image, overlay it.
383 if (!overlay_.isNull()) {
384 canvas->TileImageInt(overlay_, 0, 0, size().width(),
385 overlay_.height());
386 }
387 }
388
389 private:
390 const gfx::ImageSkia image_to_tint_;
391 const gfx::ImageSkia overlay_;
392 const color_utils::HSL hsl_shift_;
393 const int vertical_offset_;
394
395 DISALLOW_COPY_AND_ASSIGN(TabBackgroundImageSource);
396 };
327 397
328 } // namespace 398 } // namespace
329 399
330 BrowserThemePack::~BrowserThemePack() { 400 BrowserThemePack::~BrowserThemePack() {
331 if (!data_pack_.get()) { 401 if (!data_pack_.get()) {
332 delete header_; 402 delete header_;
333 delete [] tints_; 403 delete [] tints_;
334 delete [] colors_; 404 delete [] colors_;
335 delete [] display_properties_; 405 delete [] display_properties_;
336 delete [] source_images_; 406 delete [] source_images_;
337 } 407 }
338 408
339 STLDeleteValues(&prepared_images_); 409 STLDeleteValues(&images_on_ui_thread_);
340 STLDeleteValues(&loaded_images_); 410 STLDeleteValues(&images_on_file_thread_);
341 } 411 }
342 412
343 // static 413 // static
344 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension( 414 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension(
345 const Extension* extension) { 415 const Extension* extension) {
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
347 DCHECK(extension); 417 DCHECK(extension);
348 DCHECK(extension->is_theme()); 418 DCHECK(extension->is_theme());
349 419
350 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); 420 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
351 pack->BuildHeader(extension); 421 pack->BuildHeader(extension);
352 pack->BuildTintsFromJSON(extension->GetThemeTints()); 422 pack->BuildTintsFromJSON(extension->GetThemeTints());
353 pack->BuildColorsFromJSON(extension->GetThemeColors()); 423 pack->BuildColorsFromJSON(extension->GetThemeColors());
354 pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties()); 424 pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties());
355 425
356 // Builds the images. (Image building is dependent on tints). 426 // Builds the images. (Image building is dependent on tints).
357 FilePathMap file_paths; 427 FilePathMap file_paths;
358 pack->ParseImageNamesFromJSON(extension->GetThemeImages(), 428 pack->ParseImageNamesFromJSON(extension->GetThemeImages(),
359 extension->path(), 429 extension->path(),
360 &file_paths); 430 &file_paths);
361 pack->BuildSourceImagesArray(file_paths); 431 pack->BuildSourceImagesArray(file_paths);
362 432
363 if (!pack->LoadRawBitmapsTo(file_paths, &pack->prepared_images_)) 433 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_))
364 return NULL; 434 return NULL;
365 435
366 pack->GenerateFrameImages(&pack->prepared_images_); 436 pack->CopyImagesTo(pack->images_on_ui_thread_, &pack->images_on_file_thread_);
367 437
368 pack->GenerateTintedButtons( 438 pack->CreateImages(&pack->images_on_ui_thread_);
369 pack->GetTintInternal(ThemeService::TINT_BUTTONS), 439 pack->CreateImages(&pack->images_on_file_thread_);
370 &pack->prepared_images_);
371 440
372 pack->GenerateTabBackgroundImages(&pack->prepared_images_); 441 // For M22, as it is not possible to easily determine which scale factors are
442 // in use, assume that the 1x scale factor is in use.
443 std::vector<ui::ScaleFactor> scale_factors_in_use;
444 scale_factors_in_use.push_back(ui::SCALE_FACTOR_100P);
445 pack->GenerateImageReps(scale_factors_in_use);
373 446
374 // The BrowserThemePack is now in a consistent state. 447 // The BrowserThemePack is now in a consistent state.
375 return pack; 448 return pack;
376 } 449 }
377 450
378 // static 451 // static
379 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack( 452 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack(
380 const FilePath& path, const std::string& expected_id) { 453 const FilePath& path, const std::string& expected_id) {
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 454 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
382 // Allow IO on UI thread due to deep-seated theme design issues. 455 // Allow IO on UI thread due to deep-seated theme design issues.
383 // (see http://crbug.com/80206) 456 // (see http://crbug.com/80206)
384 base::ThreadRestrictions::ScopedAllowIO allow_io; 457 base::ThreadRestrictions::ScopedAllowIO allow_io;
385 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); 458 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
459 // Scale factor parameter is moot as data pack has image resources for all
460 // supported scale factors.
386 pack->data_pack_.reset( 461 pack->data_pack_.reset(
387 new ui::DataPack(ui::SCALE_FACTOR_100P)); 462 new ui::DataPack(ui::SCALE_FACTOR_NONE));
388 463
389 if (!pack->data_pack_->LoadFromPath(path)) { 464 if (!pack->data_pack_->LoadFromPath(path)) {
390 LOG(ERROR) << "Failed to load theme data pack."; 465 LOG(ERROR) << "Failed to load theme data pack.";
391 return NULL; 466 return NULL;
392 } 467 }
393 468
394 base::StringPiece pointer; 469 base::StringPiece pointer;
395 if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer)) 470 if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer))
396 return NULL; 471 return NULL;
397 pack->header_ = reinterpret_cast<BrowserThemePackHeader*>(const_cast<char*>( 472 pack->header_ = reinterpret_cast<BrowserThemePackHeader*>(const_cast<char*>(
(...skipping 25 matching lines...) Expand all
423 if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer)) 498 if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer))
424 return NULL; 499 return NULL;
425 pack->display_properties_ = reinterpret_cast<DisplayPropertyPair*>( 500 pack->display_properties_ = reinterpret_cast<DisplayPropertyPair*>(
426 const_cast<char*>(pointer.data())); 501 const_cast<char*>(pointer.data()));
427 502
428 if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer)) 503 if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer))
429 return NULL; 504 return NULL;
430 pack->source_images_ = reinterpret_cast<int*>( 505 pack->source_images_ = reinterpret_cast<int*>(
431 const_cast<char*>(pointer.data())); 506 const_cast<char*>(pointer.data()));
432 507
508 if (!pack->data_pack_->GetStringPiece(kScaleFactorsID, &pointer))
509 return NULL;
510
511 if (!InputScalesValid(const_cast<char*>(pointer.data()),
512 pack->scale_factors_)) {
513 DLOG(ERROR) << "BuildFromDataPack failure! The pack scale factors differ "
514 << "from those supported by platform.";
515 }
516
433 return pack; 517 return pack;
434 } 518 }
435 519
436 bool BrowserThemePack::WriteToDisk(const FilePath& path) const { 520 bool BrowserThemePack::WriteToDisk(const FilePath& path) const {
437 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 521 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
438 // Add resources for each of the property arrays. 522 // Add resources for each of the property arrays.
439 RawDataForWriting resources; 523 RawDataForWriting resources;
440 resources[kHeaderID] = base::StringPiece( 524 resources[kHeaderID] = base::StringPiece(
441 reinterpret_cast<const char*>(header_), sizeof(BrowserThemePackHeader)); 525 reinterpret_cast<const char*>(header_), sizeof(BrowserThemePackHeader));
442 resources[kTintsID] = base::StringPiece( 526 resources[kTintsID] = base::StringPiece(
443 reinterpret_cast<const char*>(tints_), sizeof(TintEntry[kTintArraySize])); 527 reinterpret_cast<const char*>(tints_), sizeof(TintEntry[kTintArraySize]));
444 resources[kColorsID] = base::StringPiece( 528 resources[kColorsID] = base::StringPiece(
445 reinterpret_cast<const char*>(colors_), 529 reinterpret_cast<const char*>(colors_),
446 sizeof(ColorPair[kColorArraySize])); 530 sizeof(ColorPair[kColorArraySize]));
447 resources[kDisplayPropertiesID] = base::StringPiece( 531 resources[kDisplayPropertiesID] = base::StringPiece(
448 reinterpret_cast<const char*>(display_properties_), 532 reinterpret_cast<const char*>(display_properties_),
449 sizeof(DisplayPropertyPair[kDisplayPropertySize])); 533 sizeof(DisplayPropertyPair[kDisplayPropertySize]));
450 534
451 int source_count = 1; 535 int source_count = 1;
452 int* end = source_images_; 536 int* end = source_images_;
453 for (; *end != -1 ; end++) 537 for (; *end != -1 ; end++)
454 source_count++; 538 source_count++;
455 resources[kSourceImagesID] = base::StringPiece( 539 resources[kSourceImagesID] = base::StringPiece(
456 reinterpret_cast<const char*>(source_images_), 540 reinterpret_cast<const char*>(source_images_),
457 source_count * sizeof(*source_images_)); 541 source_count * sizeof(*source_images_));
458 542
543 resources[kScaleFactorsID] = GetScaleFactorsAsString(scale_factors_);
544
459 AddRawImagesTo(image_memory_, &resources); 545 AddRawImagesTo(image_memory_, &resources);
460 546
461 RawImages reencoded_images; 547 RawImages reencoded_images;
462 RepackImages(prepared_images_, &reencoded_images); 548 RepackImages(images_on_file_thread_, &reencoded_images);
463 AddRawImagesTo(reencoded_images, &resources); 549 AddRawImagesTo(reencoded_images, &resources);
464 550
465 return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY); 551 return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY);
466 } 552 }
467 553
468 bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const { 554 bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const {
469 if (tints_) { 555 if (tints_) {
470 for (int i = 0; i < kTintArraySize; ++i) { 556 for (int i = 0; i < kTintArraySize; ++i) {
471 if (tints_[i].id == id) { 557 if (tints_[i].id == id) {
472 hsl->h = tints_[i].h; 558 hsl->h = tints_[i].h;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 // to avoid changing the BrowserThemePack::GetBitmapNamed API. Once we 601 // to avoid changing the BrowserThemePack::GetBitmapNamed API. Once we
516 // switch to using gfx::Image everywhere this can be removed. 602 // switch to using gfx::Image everywhere this can be removed.
517 return const_cast<SkBitmap*>(image->ToSkBitmap()); 603 return const_cast<SkBitmap*>(image->ToSkBitmap());
518 } 604 }
519 605
520 const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const { 606 const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const {
521 int prs_id = GetPersistentIDByIDR(idr_id); 607 int prs_id = GetPersistentIDByIDR(idr_id);
522 if (prs_id == -1) 608 if (prs_id == -1)
523 return NULL; 609 return NULL;
524 610
525 // Check our cache of prepared images, first. 611 // Check if the image is cached.
526 ImageCache::const_iterator image_iter = prepared_images_.find(prs_id); 612 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id);
527 if (image_iter != prepared_images_.end()) 613 if (image_iter != images_on_ui_thread_.end())
528 return image_iter->second; 614 return image_iter->second;
529 615
530 // Check if we've already loaded this image. 616 // TODO(pkotwicz): Do something better than loading the bitmaps
531 image_iter = loaded_images_.find(prs_id); 617 // for all the scale factors associated with |idr_id|.
532 if (image_iter != loaded_images_.end()) 618 gfx::ImageSkia image_skia;
533 return image_iter->second; 619 for (size_t i = 0; i < scale_factors_.size(); ++i) {
620 scoped_refptr<base::RefCountedMemory> memory =
621 GetRawData(idr_id, scale_factors_[i]);
534 622
535 scoped_refptr<base::RefCountedMemory> memory; 623 if (memory.get()) {
536 if (data_pack_.get()) { 624 // Decode the PNG.
537 memory = data_pack_->GetStaticMemory(prs_id); 625 SkBitmap bitmap;
538 } else { 626 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(),
539 RawImages::const_iterator it = image_memory_.find(prs_id); 627 &bitmap)) {
540 if (it != image_memory_.end()) { 628 NOTREACHED() << "Unable to decode theme image resource " << idr_id
541 memory = it->second; 629 << " from saved DataPack.";
630 return NULL;
631 }
632 image_skia.AddRepresentation(
633 gfx::ImageSkiaRep(bitmap, scale_factors_[i]));
542 } 634 }
543 } 635 }
544 636
545 if (memory.get()) { 637 if (!image_skia.isNull()) {
546 // Decode the PNG. 638 gfx::Image* ret = new gfx::Image(image_skia);
547 SkBitmap bitmap; 639 images_on_ui_thread_[prs_id] = ret;
548 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(),
549 &bitmap)) {
550 NOTREACHED() << "Unable to decode theme image resource " << idr_id
551 << " from saved DataPack.";
552 return NULL;
553 }
554
555 gfx::Image* ret = new gfx::Image(bitmap);
556 loaded_images_[prs_id] = ret;
557
558 return ret; 640 return ret;
559 } 641 }
560 642
561 return NULL; 643 return NULL;
562 } 644 }
563 645
564 base::RefCountedMemory* BrowserThemePack::GetRawData(int idr_id) const { 646 base::RefCountedMemory* BrowserThemePack::GetRawData(
647 int idr_id,
648 ui::ScaleFactor scale_factor) const {
565 base::RefCountedMemory* memory = NULL; 649 base::RefCountedMemory* memory = NULL;
566 int prs_id = GetPersistentIDByIDR(idr_id); 650 int prs_id = GetPersistentIDByIDR(idr_id);
651 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);
567 652
568 if (prs_id != -1) { 653 if (raw_id != -1) {
569 if (data_pack_.get()) { 654 if (data_pack_.get()) {
570 memory = data_pack_->GetStaticMemory(prs_id); 655 memory = data_pack_->GetStaticMemory(raw_id);
571 } else { 656 } else {
572 RawImages::const_iterator it = image_memory_.find(prs_id); 657 RawImages::const_iterator it = image_memory_.find(raw_id);
573 if (it != image_memory_.end()) { 658 if (it != image_memory_.end()) {
574 memory = it->second; 659 memory = it->second;
575 } 660 }
576 } 661 }
577 } 662 }
578 663
579 return memory; 664 return memory;
580 } 665 }
581 666
582 bool BrowserThemePack::HasCustomImage(int idr_id) const { 667 bool BrowserThemePack::HasCustomImage(int idr_id) const {
(...skipping 11 matching lines...) Expand all
594 } 679 }
595 680
596 // private: 681 // private:
597 682
598 BrowserThemePack::BrowserThemePack() 683 BrowserThemePack::BrowserThemePack()
599 : header_(NULL), 684 : header_(NULL),
600 tints_(NULL), 685 tints_(NULL),
601 colors_(NULL), 686 colors_(NULL),
602 display_properties_(NULL), 687 display_properties_(NULL),
603 source_images_(NULL) { 688 source_images_(NULL) {
689 #if defined(OS_MACOSX)
690 scale_factors_ = ui::GetSupportedScaleFactors();
691 #else
692 scale_factors_.push_back(ui::SCALE_FACTOR_100P);
693 #endif
604 } 694 }
605 695
606 void BrowserThemePack::BuildHeader(const Extension* extension) { 696 void BrowserThemePack::BuildHeader(const Extension* extension) {
607 header_ = new BrowserThemePackHeader; 697 header_ = new BrowserThemePackHeader;
608 header_->version = kThemePackVersion; 698 header_->version = kThemePackVersion;
609 699
610 // TODO(erg): Need to make this endian safe on other computers. Prerequisite 700 // TODO(erg): Need to make this endian safe on other computers. Prerequisite
611 // is that ui::DataPack removes this same check. 701 // is that ui::DataPack removes this same check.
612 #if defined(__BYTE_ORDER) 702 #if defined(__BYTE_ORDER)
613 // Linux check 703 // Linux check
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 ids.push_back(it->first); 950 ids.push_back(it->first);
861 } 951 }
862 952
863 source_images_ = new int[ids.size() + 1]; 953 source_images_ = new int[ids.size() + 1];
864 std::copy(ids.begin(), ids.end(), source_images_); 954 std::copy(ids.begin(), ids.end(), source_images_);
865 source_images_[ids.size()] = -1; 955 source_images_[ids.size()] = -1;
866 } 956 }
867 957
868 bool BrowserThemePack::LoadRawBitmapsTo( 958 bool BrowserThemePack::LoadRawBitmapsTo(
869 const FilePathMap& file_paths, 959 const FilePathMap& file_paths,
870 ImageCache* raw_bitmaps) { 960 ImageCache* image_cache) {
871 // Themes should be loaded on the file thread, not the UI thread. 961 // Themes should be loaded on the file thread, not the UI thread.
872 // http://crbug.com/61838 962 // http://crbug.com/61838
873 base::ThreadRestrictions::ScopedAllowIO allow_io; 963 base::ThreadRestrictions::ScopedAllowIO allow_io;
874 964
875 for (FilePathMap::const_iterator it = file_paths.begin(); 965 for (FilePathMap::const_iterator it = file_paths.begin();
876 it != file_paths.end(); ++it) { 966 it != file_paths.end(); ++it) {
877 scoped_refptr<base::RefCountedMemory> raw_data(ReadFileData(it->second)); 967 scoped_refptr<base::RefCountedMemory> raw_data(ReadFileData(it->second));
878 if (!raw_data.get()) { 968 if (!raw_data.get()) {
879 LOG(ERROR) << "Could not load theme image"; 969 LOG(ERROR) << "Could not load theme image";
880 return false; 970 return false;
881 } 971 }
882 972
883 int id = it->first; 973 int prs_id = it->first;
884 974
885 // Some images need to go directly into |image_memory_|. No modification is 975 // Some images need to go directly into |image_memory_|. No modification is
886 // necessary or desirable. 976 // necessary or desirable.
887 bool is_copyable = false; 977 bool is_copyable = false;
888 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { 978 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) {
889 if (kPreloadIDs[i] == id) { 979 if (kPreloadIDs[i] == prs_id) {
890 is_copyable = true; 980 is_copyable = true;
891 break; 981 break;
892 } 982 }
893 } 983 }
894 984
895 if (is_copyable) { 985 if (is_copyable) {
896 image_memory_[id] = raw_data; 986 int raw_id = GetRawIDByPersistentID(prs_id, ui::SCALE_FACTOR_100P);
987 image_memory_[raw_id] = raw_data;
897 } else if (raw_data.get() && raw_data->size()) { 988 } else if (raw_data.get() && raw_data->size()) {
898 // Decode the PNG. 989 // Decode the PNG.
899 SkBitmap bitmap; 990 SkBitmap bitmap;
900 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), 991 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(),
901 &bitmap)) { 992 &bitmap)) {
902 (*raw_bitmaps)[it->first] = new gfx::Image(bitmap); 993 (*image_cache)[prs_id] = new gfx::Image(bitmap);
903 } else { 994 } else {
904 NOTREACHED() << "Unable to decode theme image resource " << it->first; 995 NOTREACHED() << "Unable to decode theme image resource " << it->first;
905 } 996 }
906 } 997 }
907 } 998 }
908 999
909 return true; 1000 return true;
910 } 1001 }
911 1002
912 void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const { 1003 void BrowserThemePack::CreateImages(ImageCache* images) const {
1004 CreateFrameImages(images);
1005 CreateTintedButtons(GetTintInternal(ThemeService::TINT_BUTTONS), images);
1006 CreateTabBackgroundImages(images);
1007 }
1008
1009 void BrowserThemePack::CreateFrameImages(ImageCache* images) const {
913 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1010 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
914 1011
915 // Create all the output bitmaps in a separate cache and move them back into 1012 // Create all the output images in a separate cache and move them back into
916 // the input bitmaps because there can be name collisions. 1013 // the input images because there can be name collisions.
917 ImageCache temp_output; 1014 ImageCache temp_output;
918 1015
919 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { 1016 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) {
920 int prs_id = kFrameTintMap[i].key; 1017 int prs_id = kFrameTintMap[i].key;
921 const gfx::Image* frame = NULL; 1018 const gfx::Image* frame = NULL;
922 // If there's no frame image provided for the specified id, then load 1019 // If there's no frame image provided for the specified id, then load
923 // the default provided frame. If that's not provided, skip this whole 1020 // the default provided frame. If that's not provided, skip this whole
924 // thing and just use the default images. 1021 // thing and just use the default images.
925 int prs_base_id; 1022 int prs_base_id;
926 1023
927 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { 1024 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) {
928 prs_base_id = bitmaps->count(PRS_THEME_FRAME_INCOGNITO) ? 1025 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ?
929 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; 1026 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME;
930 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { 1027 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) {
931 prs_base_id = PRS_THEME_FRAME_OVERLAY; 1028 prs_base_id = PRS_THEME_FRAME_OVERLAY;
932 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { 1029 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) {
933 prs_base_id = PRS_THEME_FRAME; 1030 prs_base_id = PRS_THEME_FRAME;
934 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && 1031 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO &&
935 !bitmaps->count(PRS_THEME_FRAME_INCOGNITO)) { 1032 !images->count(PRS_THEME_FRAME_INCOGNITO)) {
936 prs_base_id = PRS_THEME_FRAME; 1033 prs_base_id = PRS_THEME_FRAME;
937 } else { 1034 } else {
938 prs_base_id = prs_id; 1035 prs_base_id = prs_id;
939 } 1036 }
940 1037
941 if (bitmaps->count(prs_id)) { 1038 if (images->count(prs_id)) {
942 frame = (*bitmaps)[prs_id]; 1039 frame = (*images)[prs_id];
943 } else if (prs_base_id != prs_id && bitmaps->count(prs_base_id)) { 1040 } else if (prs_base_id != prs_id && images->count(prs_base_id)) {
944 frame = (*bitmaps)[prs_base_id]; 1041 frame = (*images)[prs_base_id];
945 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY && 1042 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY &&
946 bitmaps->count(PRS_THEME_FRAME)) { 1043 images->count(PRS_THEME_FRAME)) {
947 // If there is no theme overlay, don't tint the default frame, 1044 // If there is no theme overlay, don't tint the default frame,
948 // because it will overwrite the custom frame image when we cache and 1045 // because it will overwrite the custom frame image when we cache and
949 // reload from disk. 1046 // reload from disk.
950 frame = NULL; 1047 frame = NULL;
951 } else { 1048 } else {
952 // If the theme doesn't specify an image, then apply the tint to 1049 // If the theme doesn't specify an image, then apply the tint to
953 // the default frame. 1050 // the default frame.
954 frame = &rb.GetImageNamed(IDR_THEME_FRAME); 1051 frame = &rb.GetImageNamed(IDR_THEME_FRAME);
955 } 1052 }
956 1053
957 if (frame) { 1054 if (frame) {
958 temp_output[prs_id] = CreateHSLShiftedImage( 1055 temp_output[prs_id] = CreateHSLShiftedImage(
959 *frame, GetTintInternal(kFrameTintMap[i].value)); 1056 *frame, GetTintInternal(kFrameTintMap[i].value));
960 } 1057 }
961 } 1058 }
962 1059 MergeImageCaches(temp_output, images);
963 MergeImageCaches(temp_output, bitmaps);
964 } 1060 }
965 1061
966 void BrowserThemePack::GenerateTintedButtons( 1062 void BrowserThemePack::CreateTintedButtons(
967 const color_utils::HSL& button_tint, 1063 const color_utils::HSL& button_tint,
968 ImageCache* processed_bitmaps) const { 1064 ImageCache* processed_images) const {
969 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { 1065 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) {
970 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1066 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
971 const std::set<int>& idr_ids = 1067 const std::set<int>& idr_ids =
972 ThemeService::GetTintableToolbarButtons(); 1068 ThemeService::GetTintableToolbarButtons();
973 for (std::set<int>::const_iterator it = idr_ids.begin(); 1069 for (std::set<int>::const_iterator it = idr_ids.begin();
974 it != idr_ids.end(); ++it) { 1070 it != idr_ids.end(); ++it) {
975 int prs_id = GetPersistentIDByIDR(*it); 1071 int prs_id = GetPersistentIDByIDR(*it);
976 DCHECK(prs_id > 0); 1072 DCHECK(prs_id > 0);
977 1073
978 // Fetch the image by IDR... 1074 // Fetch the image by IDR...
979 gfx::Image& button = rb.GetImageNamed(*it); 1075 gfx::Image& button = rb.GetImageNamed(*it);
980 1076
981 // but save a version with the persistent ID. 1077 // but save a version with the persistent ID.
982 (*processed_bitmaps)[prs_id] = 1078 (*processed_images)[prs_id] =
983 CreateHSLShiftedImage(button, button_tint); 1079 CreateHSLShiftedImage(button, button_tint);
984 } 1080 }
985 } 1081 }
986 } 1082 }
987 1083
988 void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const { 1084 void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const {
989 ImageCache temp_output; 1085 ImageCache temp_output;
990 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { 1086 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) {
991 int prs_id = kTabBackgroundMap[i].key; 1087 int prs_id = kTabBackgroundMap[i].key;
992 int prs_base_id = kTabBackgroundMap[i].value; 1088 int prs_base_id = kTabBackgroundMap[i].value;
993 1089
994 // We only need to generate the background tab images if we were provided 1090 // We only need to generate the background tab images if we were provided
995 // with a PRS_THEME_FRAME. 1091 // with a PRS_THEME_FRAME.
996 ImageCache::const_iterator it = bitmaps->find(prs_base_id); 1092 ImageCache::const_iterator it = images->find(prs_base_id);
997 if (it != bitmaps->end()) { 1093 if (it != images->end()) {
998 const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia(); 1094 const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia();
999 const std::vector<gfx::ImageSkiaRep> image_reps_to_tint = 1095 color_utils::HSL hsl_shift = GetTintInternal(
1000 image_to_tint->image_reps(); 1096 ThemeService::TINT_BACKGROUND_TAB);
1001 gfx::ImageSkia tinted_image; 1097 int vertical_offset = images->count(prs_id)
1002 for (size_t j = 0; j < image_reps_to_tint.size(); ++j) { 1098 ? kRestoredTabVerticalOffset : 0;
1003 gfx::ImageSkiaRep image_rep_to_tint = image_reps_to_tint[j];
1004 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap(
1005 image_rep_to_tint.sk_bitmap(), GetTintInternal(
1006 ThemeService::TINT_BACKGROUND_TAB));
1007 gfx::Size bg_tint_dip_size(image_rep_to_tint.GetWidth(),
1008 image_rep_to_tint.GetHeight());
1009 int vertical_offset = bitmaps->count(prs_id)
1010 ? kRestoredTabVerticalOffset : 0;
1011 gfx::Canvas canvas(gfx::Size(bg_tint.width(), bg_tint.height()),
1012 image_rep_to_tint.scale_factor(),
1013 false);
1014 canvas.TileImageInt(bg_tint, 0, vertical_offset, 0, 0,
1015 bg_tint_dip_size.width(), bg_tint_dip_size.height());
1016 1099
1017 // If they've provided a custom image, overlay it. 1100 gfx::ImageSkia overlay;
1018 ImageCache::const_iterator overlay_it = bitmaps->find(prs_id); 1101 ImageCache::const_iterator overlay_it = images->find(prs_id);
1019 if (overlay_it != bitmaps->end()) { 1102 if (overlay_it != images->end())
1020 const gfx::ImageSkia* overlay = overlay_it->second->ToImageSkia(); 1103 overlay = *overlay_it->second->ToImageSkia();
1021 canvas.TileImageInt(*overlay, 0, 0, bg_tint_dip_size.width(),
1022 overlay->height());
1023 }
1024 tinted_image.AddRepresentation(canvas.ExtractImageRep());
1025 }
1026 1104
1027 temp_output[prs_id] = new gfx::Image(tinted_image); 1105 gfx::ImageSkiaSource* source = new TabBackgroundImageSource(
1106 *image_to_tint, overlay, hsl_shift, vertical_offset);
1107 // ImageSkia takes ownership of |source|.
1108 temp_output[prs_id] = new gfx::Image(gfx::ImageSkia(source,
1109 image_to_tint->size()));
1028 } 1110 }
1029 } 1111 }
1030 1112 MergeImageCaches(temp_output, images);
1031 MergeImageCaches(temp_output, bitmaps);
1032 } 1113 }
1033 1114
1034 void BrowserThemePack::RepackImages(const ImageCache& images, 1115 void BrowserThemePack::RepackImages(const ImageCache& images,
1035 RawImages* reencoded_images) const { 1116 RawImages* reencoded_images) const {
1117
1036 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1119
1120 typedef std::vector<ui::ScaleFactor> ScaleFactors;
1037 for (ImageCache::const_iterator it = images.begin(); 1121 for (ImageCache::const_iterator it = images.begin();
1038 it != images.end(); ++it) { 1122 it != images.end(); ++it) {
1039 std::vector<unsigned char> image_data; 1123 gfx::ImageSkia image_skia = *it->second->ToImageSkia();
1040 if (!gfx::PNGCodec::EncodeBGRASkBitmap(*it->second->ToSkBitmap(), false, 1124
1041 &image_data)) { 1125 // Attempt to generate image reps for all supported scale factors.
1042 NOTREACHED() << "Image file for resource " << it->first 1126 for (ScaleFactors::const_iterator factor_it = scale_factors_.begin();
1043 << " could not be encoded."; 1127 factor_it != scale_factors_.end(); ++factor_it) {
1044 } else { 1128 // Ask for representation to force the representation to be generated
1045 (*reencoded_images)[it->first] = 1129 // if it wasn't already.
1046 base::RefCountedBytes::TakeVector(&image_data); 1130 image_skia.GetRepresentation(*factor_it);
1131 }
1132
1133 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps;
1134 ImageSkiaReps image_reps = image_skia.image_reps();
1135 if (image_reps.empty()) {
1136 NOTREACHED() << "No image reps for resource " << it->first << ".";
1137 }
1138 for (ImageSkiaReps::iterator rep_it = image_reps.begin();
1139 rep_it != image_reps.end(); ++rep_it) {
1140 std::vector<unsigned char> bitmap_data;
1141 if (!gfx::PNGCodec::EncodeBGRASkBitmap(rep_it->sk_bitmap(), false,
1142 &bitmap_data)) {
1143 NOTREACHED() << "Image file for resource " << it->first
1144 << " could not be encoded.";
1145 }
1146 int raw_id = GetRawIDByPersistentID(it->first, rep_it->scale_factor());
1147 (*reencoded_images)[raw_id] =
1148 base::RefCountedBytes::TakeVector(&bitmap_data);
1047 } 1149 }
1048 } 1150 }
1049 } 1151 }
1152
1153 void BrowserThemePack::GenerateImageReps(
1154 const std::vector<ui::ScaleFactor>& scale_factors) {
1155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1156 for (ImageCache::const_iterator it = images_on_ui_thread_.begin();
1157 it != images_on_ui_thread_.end();
1158 ++it) {
1159 const gfx::ImageSkia* image1 = it->second->ToImageSkia();
1160 const gfx::ImageSkia* image2 =
1161 images_on_file_thread_[it->first]->ToImageSkia();
1162
1163 // Ensure that image reps are generated and cached in |image1| by
1164 // calling GetRepresentation().
1165 for (size_t i = 0; i < scale_factors.size(); ++i)
1166 image1->GetRepresentation(scale_factors[i]);
1167
1168 // |image1| and |image2| have ImageSkiaSources which produce pixel
1169 // equivalent output. Instead of regenerating again, copy the image reps
1170 // which were generated for |image1| into |image2|.
1171 // Don't do a deep copy of the SkBitmaps as SkBitmap is thread safe.
1172 std::vector<gfx::ImageSkiaRep> image1_reps = image1->image_reps();
1173 for (size_t i = 0; i < image1_reps.size(); ++i) {
1174 gfx::ImageSkiaRep image1_rep = image1_reps[i];
1175 const_cast<gfx::ImageSkia*>(image2)->AddRepresentation(gfx::ImageSkiaRep(
1176 image1_rep.sk_bitmap(), image1_rep.scale_factor()));
1177 }
1178 }
1179 }
1050 1180
1051 void BrowserThemePack::MergeImageCaches( 1181 void BrowserThemePack::MergeImageCaches(
1052 const ImageCache& source, ImageCache* destination) const { 1182 const ImageCache& source, ImageCache* destination) const {
1053 for (ImageCache::const_iterator it = source.begin(); it != source.end(); 1183 for (ImageCache::const_iterator it = source.begin(); it != source.end();
1054 ++it) { 1184 ++it) {
1055 ImageCache::const_iterator bitmap_it = destination->find(it->first); 1185 ImageCache::const_iterator image_it = destination->find(it->first);
1056 if (bitmap_it != destination->end()) 1186 if (image_it != destination->end())
1057 delete bitmap_it->second; 1187 delete image_it->second;
1058 1188
1059 (*destination)[it->first] = it->second; 1189 (*destination)[it->first] = it->second;
1060 } 1190 }
1061 } 1191 }
1062 1192
1193 void BrowserThemePack::CopyImagesTo(const ImageCache& source,
1194 ImageCache* destination) const {
1195 for (ImageCache::const_iterator it = source.begin(); it != source.end();
1196 ++it) {
1197 (*destination)[it->first] = new gfx::Image(*it->second);
1198 }
1199 }
1200
1063 void BrowserThemePack::AddRawImagesTo(const RawImages& images, 1201 void BrowserThemePack::AddRawImagesTo(const RawImages& images,
1064 RawDataForWriting* out) const { 1202 RawDataForWriting* out) const {
1065 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1066 for (RawImages::const_iterator it = images.begin(); it != images.end(); 1204 for (RawImages::const_iterator it = images.begin(); it != images.end();
1067 ++it) { 1205 ++it) {
1068 (*out)[it->first] = base::StringPiece( 1206 (*out)[it->first] = base::StringPiece(
1069 reinterpret_cast<const char*>(it->second->front()), it->second->size()); 1207 reinterpret_cast<const char*>(it->second->front()), it->second->size());
1070 } 1208 }
1071 } 1209 }
1072 1210
1073 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { 1211 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const {
1074 if (tints_) { 1212 if (tints_) {
1075 for (int i = 0; i < kTintArraySize; ++i) { 1213 for (int i = 0; i < kTintArraySize; ++i) {
1076 if (tints_[i].id == id) { 1214 if (tints_[i].id == id) {
1077 color_utils::HSL hsl; 1215 color_utils::HSL hsl;
1078 hsl.h = tints_[i].h; 1216 hsl.h = tints_[i].h;
1079 hsl.s = tints_[i].s; 1217 hsl.s = tints_[i].s;
1080 hsl.l = tints_[i].l; 1218 hsl.l = tints_[i].l;
1081 return hsl; 1219 return hsl;
1082 } 1220 }
1083 } 1221 }
1084 } 1222 }
1085 1223
1086 return ThemeService::GetDefaultTint(id); 1224 return ThemeService::GetDefaultTint(id);
1087 } 1225 }
1226
1227 int BrowserThemePack::GetRawIDByPersistentID(
1228 int prs_id,
1229 ui::ScaleFactor scale_factor) const {
1230 if (prs_id < 0)
1231 return -1;
1232
1233 for (size_t i = 0; i < scale_factors_.size(); ++i) {
1234 if (scale_factors_[i] == scale_factor)
1235 return static_cast<int>(kPersistingImagesLength * i) + prs_id;
1236 }
1237 return -1;
1238 }
OLDNEW
« no previous file with comments | « chrome/browser/themes/browser_theme_pack.h ('k') | chrome/browser/themes/browser_theme_pack_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698