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

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, 5 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
« no previous file with comments | « chrome/browser/themes/browser_theme_pack.h ('k') | chrome/browser/themes/theme_service.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
Elliot Glaysher 2012/07/20 18:17:14 Do you need to rev this? You're adding members to
pkotwicz 2012/07/20 20:00:45 You're right I don't need to. Line 503 will force
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(char* input,
192 const std::vector<ui::ScaleFactor>& expected) {
193 float* scales = reinterpret_cast<float*>(input);
194 size_t index = 0;
195 for (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[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 return base::StringPiece(
214 reinterpret_cast<const char*>(&scales),
215 scales_size * sizeof(float));
180 } 216 }
181 217
182 struct StringToIntTable { 218 struct StringToIntTable {
183 const char* key; 219 const char* key;
184 int id; 220 int id;
185 }; 221 };
186 222
187 // Strings used by themes to identify tints in the JSON. 223 // Strings used by themes to identify tints in the JSON.
188 StringToIntTable kTintTable[] = { 224 StringToIntTable kTintTable[] = {
189 { "buttons", ThemeService::TINT_BUTTONS }, 225 { "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())); 337 char* data = reinterpret_cast<char*>(&(raw_data.front()));
302 if (file.ReadUntilComplete(data, size) == avail) 338 if (file.ReadUntilComplete(data, size) == avail)
303 return base::RefCountedBytes::TakeVector(&raw_data); 339 return base::RefCountedBytes::TakeVector(&raw_data);
304 } 340 }
305 } 341 }
306 } 342 }
307 343
308 return NULL; 344 return NULL;
309 } 345 }
310 346
311 // Shifts a bitmap's HSL values. The caller is responsible for deleting 347 // Shifts an image's HSL values. The caller is responsible for deleting
312 // the returned image. 348 // the returned image.
313 gfx::Image* CreateHSLShiftedImage(const gfx::Image& image, 349 gfx::Image* CreateHSLShiftedImage(const gfx::Image& image,
314 const color_utils::HSL& hsl_shift) { 350 const color_utils::HSL& hsl_shift) {
315 const gfx::ImageSkia* src_image = image.ToImageSkia(); 351 const gfx::ImageSkia* src_image = image.ToImageSkia();
316 std::vector<gfx::ImageSkiaRep> src_image_reps = src_image->image_reps(); 352 return new gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage(
317 gfx::ImageSkia dst_image; 353 *src_image, hsl_shift));
318 for (size_t i = 0; i < src_image_reps.size(); ++i) { 354 }
319 const gfx::ImageSkiaRep& image_rep = src_image_reps[i]; 355
320 SkBitmap dst_bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( 356 class TabBackgroundImageSource: public gfx::CanvasImageSource {
321 image_rep.sk_bitmap(), hsl_shift); 357 public:
322 dst_image.AddRepresentation(gfx::ImageSkiaRep(dst_bitmap, 358 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint,
323 image_rep.scale_factor())); 359 const gfx::ImageSkia& overlay,
360 const color_utils::HSL& hsl_shift,
361 int vertical_offset)
362 : gfx::CanvasImageSource(image_to_tint.size(), false),
363 image_to_tint_(image_to_tint),
364 overlay_(overlay),
365 hsl_shift_(hsl_shift),
366 vertical_offset_(vertical_offset) {
324 } 367 }
325 return new gfx::Image(dst_image); 368
326 } 369 ~TabBackgroundImageSource() {
370 }
371
372 // Overridden from CanvasImageSource:
373 virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
374 gfx::ImageSkia bg_tint =
375 gfx::ImageSkiaOperations::CreateHSLShiftedImage(image_to_tint_,
376 hsl_shift_);
377 canvas->TileImageInt(bg_tint, 0, vertical_offset_, 0, 0,
378 size().width(), size().height());
379
380 // If they've provided a custom image, overlay it.
381 if (!overlay_.isNull()) {
382 canvas->TileImageInt(overlay_, 0, 0, size().width(),
383 overlay_.height());
384 }
385 }
386
387 private:
388 const gfx::ImageSkia image_to_tint_;
389 const gfx::ImageSkia overlay_;
390 const color_utils::HSL hsl_shift_;
391 const int vertical_offset_;
392
393 DISALLOW_COPY_AND_ASSIGN(TabBackgroundImageSource);
394 };
327 395
328 } // namespace 396 } // namespace
329 397
330 BrowserThemePack::~BrowserThemePack() { 398 BrowserThemePack::~BrowserThemePack() {
331 if (!data_pack_.get()) { 399 if (!data_pack_.get()) {
332 delete header_; 400 delete header_;
333 delete [] tints_; 401 delete [] tints_;
334 delete [] colors_; 402 delete [] colors_;
335 delete [] display_properties_; 403 delete [] display_properties_;
336 delete [] source_images_; 404 delete [] source_images_;
337 } 405 }
338 406
339 STLDeleteValues(&prepared_images_); 407 STLDeleteValues(&images_on_ui_thread_);
340 STLDeleteValues(&loaded_images_); 408 STLDeleteValues(&images_on_file_thread_);
341 } 409 }
342 410
343 // static 411 // static
344 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension( 412 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension(
345 const Extension* extension) { 413 const Extension* extension) {
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
347 DCHECK(extension); 415 DCHECK(extension);
348 DCHECK(extension->is_theme()); 416 DCHECK(extension->is_theme());
349 417
350 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); 418 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
351 pack->BuildHeader(extension); 419 pack->BuildHeader(extension);
352 pack->BuildTintsFromJSON(extension->GetThemeTints()); 420 pack->BuildTintsFromJSON(extension->GetThemeTints());
353 pack->BuildColorsFromJSON(extension->GetThemeColors()); 421 pack->BuildColorsFromJSON(extension->GetThemeColors());
354 pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties()); 422 pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties());
355 423
356 // Builds the images. (Image building is dependent on tints). 424 // Builds the images. (Image building is dependent on tints).
357 FilePathMap file_paths; 425 FilePathMap file_paths;
358 pack->ParseImageNamesFromJSON(extension->GetThemeImages(), 426 pack->ParseImageNamesFromJSON(extension->GetThemeImages(),
359 extension->path(), 427 extension->path(),
360 &file_paths); 428 &file_paths);
361 pack->BuildSourceImagesArray(file_paths); 429 pack->BuildSourceImagesArray(file_paths);
362 430
363 if (!pack->LoadRawBitmapsTo(file_paths, &pack->prepared_images_)) 431 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_))
364 return NULL; 432 return NULL;
365 433
366 pack->GenerateFrameImages(&pack->prepared_images_); 434 pack->CopyImagesTo(pack->images_on_ui_thread_, &pack->images_on_file_thread_);
367 435
368 pack->GenerateTintedButtons( 436 pack->CreateImages(&pack->images_on_ui_thread_);
369 pack->GetTintInternal(ThemeService::TINT_BUTTONS), 437 pack->CreateImages(&pack->images_on_file_thread_);
370 &pack->prepared_images_);
371 438
372 pack->GenerateTabBackgroundImages(&pack->prepared_images_); 439 pack->GenerateImageReps(gfx::Screen::GetScaleFactorsInUse());
373 440
374 // The BrowserThemePack is now in a consistent state. 441 // The BrowserThemePack is now in a consistent state.
375 return pack; 442 return pack;
376 } 443 }
377 444
378 // static 445 // static
379 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack( 446 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack(
380 FilePath path, const std::string& expected_id) { 447 FilePath path, const std::string& expected_id) {
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 448 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
382 // Allow IO on UI thread due to deep-seated theme design issues. 449 // Allow IO on UI thread due to deep-seated theme design issues.
383 // (see http://crbug.com/80206) 450 // (see http://crbug.com/80206)
384 base::ThreadRestrictions::ScopedAllowIO allow_io; 451 base::ThreadRestrictions::ScopedAllowIO allow_io;
385 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); 452 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
453 // Scale factor parameter is moot as data pack has image resources for all
454 // supported scale factors.
386 pack->data_pack_.reset( 455 pack->data_pack_.reset(
387 new ui::DataPack(ui::SCALE_FACTOR_100P)); 456 new ui::DataPack(ui::SCALE_FACTOR_NONE));
388 457
389 if (!pack->data_pack_->LoadFromPath(path)) { 458 if (!pack->data_pack_->LoadFromPath(path)) {
390 LOG(ERROR) << "Failed to load theme data pack."; 459 LOG(ERROR) << "Failed to load theme data pack.";
391 return NULL; 460 return NULL;
392 } 461 }
393 462
394 base::StringPiece pointer; 463 base::StringPiece pointer;
395 if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer)) 464 if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer))
396 return NULL; 465 return NULL;
397 pack->header_ = reinterpret_cast<BrowserThemePackHeader*>(const_cast<char*>( 466 pack->header_ = reinterpret_cast<BrowserThemePackHeader*>(const_cast<char*>(
(...skipping 25 matching lines...) Expand all
423 if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer)) 492 if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer))
424 return NULL; 493 return NULL;
425 pack->display_properties_ = reinterpret_cast<DisplayPropertyPair*>( 494 pack->display_properties_ = reinterpret_cast<DisplayPropertyPair*>(
426 const_cast<char*>(pointer.data())); 495 const_cast<char*>(pointer.data()));
427 496
428 if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer)) 497 if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer))
429 return NULL; 498 return NULL;
430 pack->source_images_ = reinterpret_cast<int*>( 499 pack->source_images_ = reinterpret_cast<int*>(
431 const_cast<char*>(pointer.data())); 500 const_cast<char*>(pointer.data()));
432 501
502 if (!pack->data_pack_->GetStringPiece(kScaleFactorsID, &pointer))
503 return NULL;
504
505 if (!InputScalesValid(const_cast<char*>(pointer.data()),
506 pack->scale_factors_)) {
507 DLOG(ERROR) << "BuildFromDataPack failure! The pack scale factors differ "
508 << "from those supported by platform.";
509 }
510
433 return pack; 511 return pack;
434 } 512 }
435 513
436 bool BrowserThemePack::WriteToDisk(const FilePath& path) const { 514 bool BrowserThemePack::WriteToDisk(const FilePath& path) const {
437 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
438 // Add resources for each of the property arrays. 516 // Add resources for each of the property arrays.
439 RawDataForWriting resources; 517 RawDataForWriting resources;
440 resources[kHeaderID] = base::StringPiece( 518 resources[kHeaderID] = base::StringPiece(
441 reinterpret_cast<const char*>(header_), sizeof(BrowserThemePackHeader)); 519 reinterpret_cast<const char*>(header_), sizeof(BrowserThemePackHeader));
442 resources[kTintsID] = base::StringPiece( 520 resources[kTintsID] = base::StringPiece(
443 reinterpret_cast<const char*>(tints_), sizeof(TintEntry[kTintArraySize])); 521 reinterpret_cast<const char*>(tints_), sizeof(TintEntry[kTintArraySize]));
444 resources[kColorsID] = base::StringPiece( 522 resources[kColorsID] = base::StringPiece(
445 reinterpret_cast<const char*>(colors_), 523 reinterpret_cast<const char*>(colors_),
446 sizeof(ColorPair[kColorArraySize])); 524 sizeof(ColorPair[kColorArraySize]));
447 resources[kDisplayPropertiesID] = base::StringPiece( 525 resources[kDisplayPropertiesID] = base::StringPiece(
448 reinterpret_cast<const char*>(display_properties_), 526 reinterpret_cast<const char*>(display_properties_),
449 sizeof(DisplayPropertyPair[kDisplayPropertySize])); 527 sizeof(DisplayPropertyPair[kDisplayPropertySize]));
450 528
451 int source_count = 1; 529 int source_count = 1;
452 int* end = source_images_; 530 int* end = source_images_;
453 for (; *end != -1 ; end++) 531 for (; *end != -1 ; end++)
454 source_count++; 532 source_count++;
455 resources[kSourceImagesID] = base::StringPiece( 533 resources[kSourceImagesID] = base::StringPiece(
456 reinterpret_cast<const char*>(source_images_), 534 reinterpret_cast<const char*>(source_images_),
457 source_count * sizeof(*source_images_)); 535 source_count * sizeof(*source_images_));
458 536
537 resources[kScaleFactorsID] = GetScaleFactorsAsString(scale_factors_);
538
459 AddRawImagesTo(image_memory_, &resources); 539 AddRawImagesTo(image_memory_, &resources);
460 540
461 RawImages reencoded_images; 541 RawImages reencoded_images;
462 RepackImages(prepared_images_, &reencoded_images); 542 RepackImages(images_on_file_thread_, &reencoded_images);
463 AddRawImagesTo(reencoded_images, &resources); 543 AddRawImagesTo(reencoded_images, &resources);
464 544
465 return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY); 545 return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY);
466 } 546 }
467 547
468 bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const { 548 bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const {
469 if (tints_) { 549 if (tints_) {
470 for (int i = 0; i < kTintArraySize; ++i) { 550 for (int i = 0; i < kTintArraySize; ++i) {
471 if (tints_[i].id == id) { 551 if (tints_[i].id == id) {
472 hsl->h = tints_[i].h; 552 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 595 // to avoid changing the BrowserThemePack::GetBitmapNamed API. Once we
516 // switch to using gfx::Image everywhere this can be removed. 596 // switch to using gfx::Image everywhere this can be removed.
517 return const_cast<SkBitmap*>(image->ToSkBitmap()); 597 return const_cast<SkBitmap*>(image->ToSkBitmap());
518 } 598 }
519 599
520 const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const { 600 const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const {
521 int prs_id = GetPersistentIDByIDR(idr_id); 601 int prs_id = GetPersistentIDByIDR(idr_id);
522 if (prs_id == -1) 602 if (prs_id == -1)
523 return NULL; 603 return NULL;
524 604
525 // Check our cache of prepared images, first. 605 // Check if the image is cached.
526 ImageCache::const_iterator image_iter = prepared_images_.find(prs_id); 606 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id);
527 if (image_iter != prepared_images_.end()) 607 if (image_iter != images_on_ui_thread_.end())
528 return image_iter->second; 608 return image_iter->second;
529 609
530 // Check if we've already loaded this image. 610 // TODO(pkotwicz): Do something better than loading the bitmaps
531 image_iter = loaded_images_.find(prs_id); 611 // for all the scale factors associated with |idr_id|.
532 if (image_iter != loaded_images_.end()) 612 gfx::ImageSkia image_skia;
533 return image_iter->second; 613 for (size_t i = 0; i < scale_factors_.size(); ++i) {
614 scoped_refptr<base::RefCountedMemory> memory =
615 GetRawData(idr_id, scale_factors_[i]);
534 616
535 scoped_refptr<base::RefCountedMemory> memory; 617 if (memory.get()) {
536 if (data_pack_.get()) { 618 // Decode the PNG.
537 memory = data_pack_->GetStaticMemory(prs_id); 619 SkBitmap bitmap;
538 } else { 620 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(),
539 RawImages::const_iterator it = image_memory_.find(prs_id); 621 &bitmap)) {
540 if (it != image_memory_.end()) { 622 NOTREACHED() << "Unable to decode theme image resource " << idr_id
541 memory = it->second; 623 << " from saved DataPack.";
624 return NULL;
625 }
626 image_skia.AddRepresentation(
627 gfx::ImageSkiaRep(bitmap, scale_factors_[i]));
542 } 628 }
543 } 629 }
544 630
545 if (memory.get()) { 631 if (!image_skia.isNull()) {
546 // Decode the PNG. 632 gfx::Image* ret = new gfx::Image(image_skia);
547 SkBitmap bitmap; 633 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; 634 return ret;
559 } 635 }
560 636
561 return NULL; 637 return NULL;
562 } 638 }
563 639
564 base::RefCountedMemory* BrowserThemePack::GetRawData(int idr_id) const { 640 base::RefCountedMemory* BrowserThemePack::GetRawData(
641 int idr_id,
642 ui::ScaleFactor scale_factor) const {
565 base::RefCountedMemory* memory = NULL; 643 base::RefCountedMemory* memory = NULL;
566 int prs_id = GetPersistentIDByIDR(idr_id); 644 int prs_id = GetPersistentIDByIDR(idr_id);
645 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);
567 646
568 if (prs_id != -1) { 647 if (raw_id != -1) {
569 if (data_pack_.get()) { 648 if (data_pack_.get()) {
570 memory = data_pack_->GetStaticMemory(prs_id); 649 memory = data_pack_->GetStaticMemory(raw_id);
571 } else { 650 } else {
572 RawImages::const_iterator it = image_memory_.find(prs_id); 651 RawImages::const_iterator it = image_memory_.find(raw_id);
573 if (it != image_memory_.end()) { 652 if (it != image_memory_.end()) {
574 memory = it->second; 653 memory = it->second;
575 } 654 }
576 } 655 }
577 } 656 }
578 657
579 return memory; 658 return memory;
580 } 659 }
581 660
582 bool BrowserThemePack::HasCustomImage(int idr_id) const { 661 bool BrowserThemePack::HasCustomImage(int idr_id) const {
(...skipping 10 matching lines...) Expand all
593 return false; 672 return false;
594 } 673 }
595 674
596 // private: 675 // private:
597 676
598 BrowserThemePack::BrowserThemePack() 677 BrowserThemePack::BrowserThemePack()
599 : header_(NULL), 678 : header_(NULL),
600 tints_(NULL), 679 tints_(NULL),
601 colors_(NULL), 680 colors_(NULL),
602 display_properties_(NULL), 681 display_properties_(NULL),
603 source_images_(NULL) { 682 source_images_(NULL),
683 scale_factors_(ui::GetSupportedScaleFactors()) {
604 } 684 }
605 685
606 void BrowserThemePack::BuildHeader(const Extension* extension) { 686 void BrowserThemePack::BuildHeader(const Extension* extension) {
607 header_ = new BrowserThemePackHeader; 687 header_ = new BrowserThemePackHeader;
608 header_->version = kThemePackVersion; 688 header_->version = kThemePackVersion;
609 689
610 // TODO(erg): Need to make this endian safe on other computers. Prerequisite 690 // TODO(erg): Need to make this endian safe on other computers. Prerequisite
611 // is that ui::DataPack removes this same check. 691 // is that ui::DataPack removes this same check.
612 #if defined(__BYTE_ORDER) 692 #if defined(__BYTE_ORDER)
613 // Linux check 693 // Linux check
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 ids.push_back(it->first); 940 ids.push_back(it->first);
861 } 941 }
862 942
863 source_images_ = new int[ids.size() + 1]; 943 source_images_ = new int[ids.size() + 1];
864 std::copy(ids.begin(), ids.end(), source_images_); 944 std::copy(ids.begin(), ids.end(), source_images_);
865 source_images_[ids.size()] = -1; 945 source_images_[ids.size()] = -1;
866 } 946 }
867 947
868 bool BrowserThemePack::LoadRawBitmapsTo( 948 bool BrowserThemePack::LoadRawBitmapsTo(
869 const FilePathMap& file_paths, 949 const FilePathMap& file_paths,
870 ImageCache* raw_bitmaps) { 950 ImageCache* image_cache) {
871 // Themes should be loaded on the file thread, not the UI thread. 951 // Themes should be loaded on the file thread, not the UI thread.
872 // http://crbug.com/61838 952 // http://crbug.com/61838
873 base::ThreadRestrictions::ScopedAllowIO allow_io; 953 base::ThreadRestrictions::ScopedAllowIO allow_io;
874 954
875 for (FilePathMap::const_iterator it = file_paths.begin(); 955 for (FilePathMap::const_iterator it = file_paths.begin();
876 it != file_paths.end(); ++it) { 956 it != file_paths.end(); ++it) {
877 scoped_refptr<base::RefCountedMemory> raw_data(ReadFileData(it->second)); 957 scoped_refptr<base::RefCountedMemory> raw_data(ReadFileData(it->second));
878 if (!raw_data.get()) { 958 if (!raw_data.get()) {
879 LOG(ERROR) << "Could not load theme image"; 959 LOG(ERROR) << "Could not load theme image";
880 return false; 960 return false;
881 } 961 }
882 962
883 int id = it->first; 963 int prs_id = it->first;
884 964
885 // Some images need to go directly into |image_memory_|. No modification is 965 // Some images need to go directly into |image_memory_|. No modification is
886 // necessary or desirable. 966 // necessary or desirable.
887 bool is_copyable = false; 967 bool is_copyable = false;
888 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { 968 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) {
889 if (kPreloadIDs[i] == id) { 969 if (kPreloadIDs[i] == prs_id) {
890 is_copyable = true; 970 is_copyable = true;
891 break; 971 break;
892 } 972 }
893 } 973 }
894 974
895 if (is_copyable) { 975 if (is_copyable) {
896 image_memory_[id] = raw_data; 976 int raw_id = GetRawIDByPersistentID(prs_id, ui::SCALE_FACTOR_100P);
977 image_memory_[raw_id] = raw_data;
897 } else if (raw_data.get() && raw_data->size()) { 978 } else if (raw_data.get() && raw_data->size()) {
898 // Decode the PNG. 979 // Decode the PNG.
899 SkBitmap bitmap; 980 SkBitmap bitmap;
900 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), 981 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(),
901 &bitmap)) { 982 &bitmap)) {
902 (*raw_bitmaps)[it->first] = new gfx::Image(bitmap); 983 (*image_cache)[prs_id] = new gfx::Image(bitmap);
903 } else { 984 } else {
904 NOTREACHED() << "Unable to decode theme image resource " << it->first; 985 NOTREACHED() << "Unable to decode theme image resource " << it->first;
905 } 986 }
906 } 987 }
907 } 988 }
908 989
909 return true; 990 return true;
910 } 991 }
911 992
912 void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const { 993 void BrowserThemePack::CreateImages(ImageCache* images) const {
994 CreateFrameImages(images);
995 CreateTintedButtons(GetTintInternal(ThemeService::TINT_BUTTONS), images);
996 CreateTabBackgroundImages(images);
997 }
998
999 void BrowserThemePack::CreateFrameImages(ImageCache* images) const {
913 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1000 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
914 1001
915 // Create all the output bitmaps in a separate cache and move them back into 1002 // Create all the output images in a separate cache and move them back into
916 // the input bitmaps because there can be name collisions. 1003 // the input images because there can be name collisions.
917 ImageCache temp_output; 1004 ImageCache temp_output;
918 1005
919 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { 1006 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) {
920 int prs_id = kFrameTintMap[i].key; 1007 int prs_id = kFrameTintMap[i].key;
921 const gfx::Image* frame = NULL; 1008 const gfx::Image* frame = NULL;
922 // If there's no frame image provided for the specified id, then load 1009 // 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 1010 // the default provided frame. If that's not provided, skip this whole
924 // thing and just use the default images. 1011 // thing and just use the default images.
925 int prs_base_id; 1012 int prs_base_id;
926 1013
927 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { 1014 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) {
928 prs_base_id = bitmaps->count(PRS_THEME_FRAME_INCOGNITO) ? 1015 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ?
929 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; 1016 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME;
930 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { 1017 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) {
931 prs_base_id = PRS_THEME_FRAME_OVERLAY; 1018 prs_base_id = PRS_THEME_FRAME_OVERLAY;
932 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { 1019 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) {
933 prs_base_id = PRS_THEME_FRAME; 1020 prs_base_id = PRS_THEME_FRAME;
934 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && 1021 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO &&
935 !bitmaps->count(PRS_THEME_FRAME_INCOGNITO)) { 1022 !images->count(PRS_THEME_FRAME_INCOGNITO)) {
936 prs_base_id = PRS_THEME_FRAME; 1023 prs_base_id = PRS_THEME_FRAME;
937 } else { 1024 } else {
938 prs_base_id = prs_id; 1025 prs_base_id = prs_id;
939 } 1026 }
940 1027
941 if (bitmaps->count(prs_id)) { 1028 if (images->count(prs_id)) {
942 frame = (*bitmaps)[prs_id]; 1029 frame = (*images)[prs_id];
943 } else if (prs_base_id != prs_id && bitmaps->count(prs_base_id)) { 1030 } else if (prs_base_id != prs_id && images->count(prs_base_id)) {
944 frame = (*bitmaps)[prs_base_id]; 1031 frame = (*images)[prs_base_id];
945 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY && 1032 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY &&
946 bitmaps->count(PRS_THEME_FRAME)) { 1033 images->count(PRS_THEME_FRAME)) {
947 // If there is no theme overlay, don't tint the default frame, 1034 // 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 1035 // because it will overwrite the custom frame image when we cache and
949 // reload from disk. 1036 // reload from disk.
950 frame = NULL; 1037 frame = NULL;
951 } else { 1038 } else {
952 // If the theme doesn't specify an image, then apply the tint to 1039 // If the theme doesn't specify an image, then apply the tint to
953 // the default frame. 1040 // the default frame.
954 frame = &rb.GetImageNamed(IDR_THEME_FRAME); 1041 frame = &rb.GetImageNamed(IDR_THEME_FRAME);
955 } 1042 }
956 1043
957 if (frame) { 1044 if (frame) {
958 temp_output[prs_id] = CreateHSLShiftedImage( 1045 temp_output[prs_id] = CreateHSLShiftedImage(
959 *frame, GetTintInternal(kFrameTintMap[i].value)); 1046 *frame, GetTintInternal(kFrameTintMap[i].value));
960 } 1047 }
961 } 1048 }
962 1049 MergeImageCaches(temp_output, images);
963 MergeImageCaches(temp_output, bitmaps);
964 } 1050 }
965 1051
966 void BrowserThemePack::GenerateTintedButtons( 1052 void BrowserThemePack::CreateTintedButtons(
967 const color_utils::HSL& button_tint, 1053 const color_utils::HSL& button_tint,
968 ImageCache* processed_bitmaps) const { 1054 ImageCache* processed_images) const {
969 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { 1055 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) {
970 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1056 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
971 const std::set<int>& idr_ids = 1057 const std::set<int>& idr_ids =
972 ThemeService::GetTintableToolbarButtons(); 1058 ThemeService::GetTintableToolbarButtons();
973 for (std::set<int>::const_iterator it = idr_ids.begin(); 1059 for (std::set<int>::const_iterator it = idr_ids.begin();
974 it != idr_ids.end(); ++it) { 1060 it != idr_ids.end(); ++it) {
975 int prs_id = GetPersistentIDByIDR(*it); 1061 int prs_id = GetPersistentIDByIDR(*it);
976 DCHECK(prs_id > 0); 1062 DCHECK(prs_id > 0);
977 1063
978 // Fetch the image by IDR... 1064 // Fetch the image by IDR...
979 gfx::Image& button = rb.GetImageNamed(*it); 1065 gfx::Image& button = rb.GetImageNamed(*it);
980 1066
981 // but save a version with the persistent ID. 1067 // but save a version with the persistent ID.
982 (*processed_bitmaps)[prs_id] = 1068 (*processed_images)[prs_id] =
983 CreateHSLShiftedImage(button, button_tint); 1069 CreateHSLShiftedImage(button, button_tint);
984 } 1070 }
985 } 1071 }
986 } 1072 }
987 1073
988 void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const { 1074 void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const {
989 ImageCache temp_output; 1075 ImageCache temp_output;
990 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { 1076 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) {
991 int prs_id = kTabBackgroundMap[i].key; 1077 int prs_id = kTabBackgroundMap[i].key;
992 int prs_base_id = kTabBackgroundMap[i].value; 1078 int prs_base_id = kTabBackgroundMap[i].value;
993 1079
994 // We only need to generate the background tab images if we were provided 1080 // We only need to generate the background tab images if we were provided
995 // with a PRS_THEME_FRAME. 1081 // with a PRS_THEME_FRAME.
996 ImageCache::const_iterator it = bitmaps->find(prs_base_id); 1082 ImageCache::const_iterator it = images->find(prs_base_id);
997 if (it != bitmaps->end()) { 1083 if (it != images->end()) {
998 const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia(); 1084 const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia();
999 const std::vector<gfx::ImageSkiaRep> image_reps_to_tint = 1085 color_utils::HSL hsl_shift = GetTintInternal(
1000 image_to_tint->image_reps(); 1086 ThemeService::TINT_BACKGROUND_TAB);
1001 gfx::ImageSkia tinted_image; 1087 int vertical_offset = images->count(prs_id)
1002 for (size_t j = 0; j < image_reps_to_tint.size(); ++j) { 1088 ? 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 false);
1013 SkScalar image_rep_to_tint_scale =
1014 SkFloatToScalar(image_rep_to_tint.GetScale());
1015 canvas.sk_canvas()->scale(image_rep_to_tint_scale,
1016 image_rep_to_tint_scale);
1017 canvas.TileImageInt(bg_tint, 0, vertical_offset, 0, 0,
1018 bg_tint_dip_size.width(), bg_tint_dip_size.height());
1019 1089
1020 // If they've provided a custom image, overlay it. 1090 gfx::ImageSkia overlay;
1021 ImageCache::const_iterator overlay_it = bitmaps->find(prs_id); 1091 ImageCache::const_iterator overlay_it = images->find(prs_id);
1022 if (overlay_it != bitmaps->end()) { 1092 if (overlay_it != images->end())
1023 const gfx::ImageSkia* overlay = overlay_it->second->ToImageSkia(); 1093 overlay = *overlay_it->second->ToImageSkia();
1024 canvas.TileImageInt(*overlay, 0, 0, bg_tint_dip_size.width(),
1025 overlay->height());
1026 }
1027 SkBitmap bg_tab = canvas.ExtractBitmap();
1028 tinted_image.AddRepresentation(gfx::ImageSkiaRep(bg_tab,
1029 image_rep_to_tint.scale_factor()));
1030 }
1031 1094
1032 temp_output[prs_id] = new gfx::Image(tinted_image); 1095 gfx::ImageSkiaSource* source = new TabBackgroundImageSource(
1096 *image_to_tint, overlay, hsl_shift, vertical_offset);
1097 // ImageSkia takes ownership of |source|.
1098 temp_output[prs_id] = new gfx::Image(gfx::ImageSkia(source,
1099 image_to_tint->size()));
1033 } 1100 }
1034 } 1101 }
1035 1102 MergeImageCaches(temp_output, images);
1036 MergeImageCaches(temp_output, bitmaps);
1037 } 1103 }
1038 1104
1039 void BrowserThemePack::RepackImages(const ImageCache& images, 1105 void BrowserThemePack::RepackImages(const ImageCache& images,
1040 RawImages* reencoded_images) const { 1106 RawImages* reencoded_images) const {
1107
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1109
1110 typedef std::vector<ui::ScaleFactor> ScaleFactors;
1111 ScaleFactors scale_factors = ui::GetSupportedScaleFactors();
1112
1042 for (ImageCache::const_iterator it = images.begin(); 1113 for (ImageCache::const_iterator it = images.begin();
1043 it != images.end(); ++it) { 1114 it != images.end(); ++it) {
1044 std::vector<unsigned char> image_data; 1115 gfx::ImageSkia image_skia = *it->second->ToImageSkia();
1045 if (!gfx::PNGCodec::EncodeBGRASkBitmap(*it->second->ToSkBitmap(), false, 1116
1046 &image_data)) { 1117 // Attempt to generate image reps for all supported scale factors.
1118 for (ScaleFactors::iterator factor_it = scale_factors.begin();
1119 factor_it != scale_factors.end(); ++factor_it) {
1120 // Ask for representation to force the reprsentation to be generated
1121 // if it hasn't already.
1122 image_skia.GetRepresentation(*factor_it);
1123 }
1124
1125 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps;
1126 ImageSkiaReps image_reps = image_skia.image_reps();
1127 if (image_reps.empty()) {
1047 NOTREACHED() << "Image file for resource " << it->first 1128 NOTREACHED() << "Image file for resource " << it->first
1048 << " could not be encoded."; 1129 << " could not be encoded.";
1049 } else { 1130 }
1050 (*reencoded_images)[it->first] = 1131 for (ImageSkiaReps::iterator rep_it = image_reps.begin();
1132 rep_it != image_reps.end(); ++rep_it) {
1133 std::vector<unsigned char> image_data;
1134 CHECK(gfx::PNGCodec::EncodeBGRASkBitmap(rep_it->sk_bitmap(), false,
1135 &image_data));
1136 int raw_id = GetRawIDByPersistentID(it->first, rep_it->scale_factor());
1137 (*reencoded_images)[raw_id] =
1051 base::RefCountedBytes::TakeVector(&image_data); 1138 base::RefCountedBytes::TakeVector(&image_data);
1052 } 1139 }
1053 } 1140 }
1054 } 1141 }
1055 1142
1143 void BrowserThemePack::GenerateImageReps(
1144 const std::vector<ui::ScaleFactor>& scale_factors) {
Elliot Glaysher 2012/07/20 18:17:14 Could you add a thread dcheck here? I see you modi
pkotwicz 2012/07/20 20:00:45 Will do! It is supposed to run on the UI thread
1145 for (ImageCache::const_iterator it = images_on_ui_thread_.begin();
1146 it != images_on_ui_thread_.end();
1147 ++it) {
1148 const gfx::ImageSkia* image1 = it->second->ToImageSkia();
1149 const gfx::ImageSkia* image2 =
1150 images_on_file_thread_[it->first]->ToImageSkia();
1151
1152 // Ensure that image reps are generated and cached in |image1| by
1153 // calling GetRepresentation().
1154 for (size_t i = 0; i < scale_factors.size(); ++i)
1155 image1->GetRepresentation(scale_factors[i]);
1156
1157 // |image1| and |image2| have ImageSkiaSources which produce pixel
1158 // equivalent output. Instead of regenerating again, copy the image reps
1159 // which were generated for |image1| into |image2|.
1160 // Don't do a deep copy of the SkBitmaps as SkBitmap is thread safe.
1161 std::vector<gfx::ImageSkiaRep> image1_reps = image1->image_reps();
1162 for (size_t i = 0; i < image1_reps.size(); ++i) {
1163 gfx::ImageSkiaRep image1_rep = image1_reps[i];
1164 const_cast<gfx::ImageSkia*>(image2)->AddRepresentation(gfx::ImageSkiaRep(
1165 image1_rep.sk_bitmap(), image1_rep.scale_factor()));
1166 }
1167 }
1168 }
1169
1056 void BrowserThemePack::MergeImageCaches( 1170 void BrowserThemePack::MergeImageCaches(
1057 const ImageCache& source, ImageCache* destination) const { 1171 const ImageCache& source, ImageCache* destination) const {
1058 for (ImageCache::const_iterator it = source.begin(); it != source.end(); 1172 for (ImageCache::const_iterator it = source.begin(); it != source.end();
1059 ++it) { 1173 ++it) {
1060 ImageCache::const_iterator bitmap_it = destination->find(it->first); 1174 ImageCache::const_iterator image_it = destination->find(it->first);
1061 if (bitmap_it != destination->end()) 1175 if (image_it != destination->end())
1062 delete bitmap_it->second; 1176 delete image_it->second;
1063 1177
1064 (*destination)[it->first] = it->second; 1178 (*destination)[it->first] = it->second;
1065 } 1179 }
1066 } 1180 }
1067 1181
1182 void BrowserThemePack::CopyImagesTo(const ImageCache& source,
1183 ImageCache* destination) const {
1184 for (ImageCache::const_iterator it = source.begin(); it != source.end();
1185 ++it) {
1186 (*destination)[it->first] = new gfx::Image(*it->second);
1187 }
1188 }
1189
1068 void BrowserThemePack::AddRawImagesTo(const RawImages& images, 1190 void BrowserThemePack::AddRawImagesTo(const RawImages& images,
1069 RawDataForWriting* out) const { 1191 RawDataForWriting* out) const {
1070 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1071 for (RawImages::const_iterator it = images.begin(); it != images.end(); 1193 for (RawImages::const_iterator it = images.begin(); it != images.end();
1072 ++it) { 1194 ++it) {
1073 (*out)[it->first] = base::StringPiece( 1195 (*out)[it->first] = base::StringPiece(
1074 reinterpret_cast<const char*>(it->second->front()), it->second->size()); 1196 reinterpret_cast<const char*>(it->second->front()), it->second->size());
1075 } 1197 }
1076 } 1198 }
1077 1199
1078 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { 1200 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const {
1079 if (tints_) { 1201 if (tints_) {
1080 for (int i = 0; i < kTintArraySize; ++i) { 1202 for (int i = 0; i < kTintArraySize; ++i) {
1081 if (tints_[i].id == id) { 1203 if (tints_[i].id == id) {
1082 color_utils::HSL hsl; 1204 color_utils::HSL hsl;
1083 hsl.h = tints_[i].h; 1205 hsl.h = tints_[i].h;
1084 hsl.s = tints_[i].s; 1206 hsl.s = tints_[i].s;
1085 hsl.l = tints_[i].l; 1207 hsl.l = tints_[i].l;
1086 return hsl; 1208 return hsl;
1087 } 1209 }
1088 } 1210 }
1089 } 1211 }
1090 1212
1091 return ThemeService::GetDefaultTint(id); 1213 return ThemeService::GetDefaultTint(id);
1092 } 1214 }
1215
1216 int BrowserThemePack::GetRawIDByPersistentID(
1217 int prs_id,
1218 ui::ScaleFactor scale_factor) const {
1219 if (prs_id < 0)
1220 return -1;
1221
1222 for (size_t i = 0; i < scale_factors_.size(); ++i) {
1223 if (scale_factors_[i] == scale_factor)
1224 return static_cast<int>(kPersistingImagesLength * i) + prs_id;
1225 }
1226 return -1;
1227 }
OLDNEW
« no previous file with comments | « chrome/browser/themes/browser_theme_pack.h ('k') | chrome/browser/themes/theme_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698