1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/app_list/fast_show_pickler.h"
7 #include "third_party/skia/include/core/SkBitmap.h"
8 #include "ui/app_list/app_list_item.h"
9 #include "ui/gfx/image/image_skia_rep.h"
13 using app_list::AppListItem
;
14 using app_list::AppListModel
;
16 // These have the same meaning as SkBitmap::Config. Reproduced here to insure
17 // against their value changing in Skia. If the order of these changes kVersion
18 // should be incremented.
28 bool FormatToColorType(ImageFormat format
, SkColorType
* out
) {
31 *out
= kUnknown_SkColorType
;
34 *out
= kAlpha_8_SkColorType
;
37 *out
= kIndex_8_SkColorType
;
40 *out
= kRGB_565_SkColorType
;
43 *out
= kARGB_4444_SkColorType
;
46 *out
= kN32_SkColorType
;
48 default: return false;
53 bool ColorTypeToFormat(SkColorType colorType
, ImageFormat
* out
) {
55 case kUnknown_SkColorType
:
58 case kAlpha_8_SkColorType
:
61 case kIndex_8_SkColorType
:
64 case kRGB_565_SkColorType
:
67 case kARGB_4444_SkColorType
:
70 case kN32_SkColorType
:
73 default: return false;
78 bool PickleImage(base::Pickle
* pickle
, const gfx::ImageSkia
& image
) {
79 std::vector
<gfx::ImageSkiaRep
> reps(image
.image_reps());
80 pickle
->WriteInt(static_cast<int>(reps
.size()));
81 for (std::vector
<gfx::ImageSkiaRep
>::const_iterator it
= reps
.begin();
82 it
!= reps
.end(); ++it
) {
83 pickle
->WriteFloat(it
->scale());
84 pickle
->WriteInt(it
->pixel_width());
85 pickle
->WriteInt(it
->pixel_height());
86 ImageFormat format
= NONE
;
87 if (!ColorTypeToFormat(it
->sk_bitmap().colorType(), &format
))
89 pickle
->WriteInt(static_cast<int>(format
));
90 int size
= static_cast<int>(it
->sk_bitmap().getSafeSize());
91 pickle
->WriteInt(size
);
92 SkBitmap bitmap
= it
->sk_bitmap();
93 SkAutoLockPixels
lock(bitmap
);
94 pickle
->WriteBytes(bitmap
.getPixels(), size
);
99 bool UnpickleImage(base::PickleIterator
* it
, gfx::ImageSkia
* out
) {
101 if (!it
->ReadInt(&rep_count
))
104 gfx::ImageSkia result
;
105 for (int i
= 0; i
< rep_count
; ++i
) {
107 if (!it
->ReadFloat(&scale
))
111 if (!it
->ReadInt(&width
))
115 if (!it
->ReadInt(&height
))
119 if (!it
->ReadInt(&format_int
))
121 ImageFormat format
= static_cast<ImageFormat
>(format_int
);
122 SkColorType color_type
= kUnknown_SkColorType
;
123 if (!FormatToColorType(format
, &color_type
))
127 if (!it
->ReadInt(&size
))
130 const char* pixels
= NULL
;
131 if (!it
->ReadBytes(&pixels
, size
))
135 if (!bitmap
.tryAllocPixels(SkImageInfo::Make(
136 width
, height
, color_type
, kPremul_SkAlphaType
)))
139 memcpy(bitmap
.getPixels(), pixels
, bitmap
.getSize());
140 result
.AddRepresentation(gfx::ImageSkiaRep(bitmap
, scale
));
149 scoped_ptr
<AppListItem
> FastShowPickler::UnpickleAppListItem(
150 base::PickleIterator
* it
) {
152 if (!it
->ReadString(&id
))
153 return scoped_ptr
<AppListItem
>();
154 scoped_ptr
<AppListItem
> result(new AppListItem(id
));
156 if (!it
->ReadString(&name
))
157 return scoped_ptr
<AppListItem
>();
158 std::string short_name
;
159 if (!it
->ReadString(&short_name
))
160 return scoped_ptr
<AppListItem
>();
161 result
->SetNameAndShortName(name
, short_name
);
163 if (!UnpickleImage(it
, &icon
))
164 return scoped_ptr
<AppListItem
>();
165 result
->SetIcon(icon
);
166 return result
.Pass();
169 bool FastShowPickler::PickleAppListItem(base::Pickle
* pickle
,
171 if (!pickle
->WriteString(item
->id()))
173 if (!pickle
->WriteString(item
->name()))
175 if (!pickle
->WriteString(item
->short_name()))
177 if (!PickleImage(pickle
, item
->icon()))
182 void FastShowPickler::CopyOverItem(AppListItem
* src_item
,
183 AppListItem
* dest_item
) {
184 dest_item
->SetNameAndShortName(src_item
->name(), src_item
->short_name());
185 dest_item
->SetIcon(src_item
->icon());
186 // Do not set folder_id, pass that to AppListModel::AddItemToFolder() instead.
189 // The version of the pickle format defined here. This needs to be incremented
190 // whenever this format is changed so new clients can invalidate old versions.
191 const int FastShowPickler::kVersion
= 4;
193 scoped_ptr
<base::Pickle
> FastShowPickler::PickleAppListModelForFastShow(
194 AppListModel
* model
) {
195 scoped_ptr
<base::Pickle
> result(new base::Pickle
);
196 if (!result
->WriteInt(kVersion
))
197 return scoped_ptr
<base::Pickle
>();
198 if (!result
->WriteInt((int)model
->top_level_item_list()->item_count()))
199 return scoped_ptr
<base::Pickle
>();
200 for (size_t i
= 0; i
< model
->top_level_item_list()->item_count(); ++i
) {
201 if (!PickleAppListItem(result
.get(),
202 model
->top_level_item_list()->item_at(i
))) {
203 return scoped_ptr
<base::Pickle
>();
206 return result
.Pass();
209 void FastShowPickler::CopyOver(AppListModel
* src
, AppListModel
* dest
) {
210 DCHECK_EQ(0u, dest
->top_level_item_list()->item_count());
211 for (size_t i
= 0; i
< src
->top_level_item_list()->item_count(); i
++) {
212 AppListItem
* src_item
= src
->top_level_item_list()->item_at(i
);
213 scoped_ptr
<AppListItem
> dest_item(new AppListItem(src_item
->id()));
214 CopyOverItem(src_item
, dest_item
.get());
215 dest
->AddItemToFolder(dest_item
.Pass(), src_item
->folder_id());
219 scoped_ptr
<AppListModel
> FastShowPickler::UnpickleAppListModelForFastShow(
220 base::Pickle
* pickle
) {
221 base::PickleIterator
it(*pickle
);
222 int read_version
= 0;
223 if (!it
.ReadInt(&read_version
))
224 return scoped_ptr
<AppListModel
>();
225 if (read_version
!= kVersion
)
226 return scoped_ptr
<AppListModel
>();
228 if (!it
.ReadInt(&app_count
))
229 return scoped_ptr
<AppListModel
>();
231 scoped_ptr
<AppListModel
> model(new AppListModel
);
232 for (int i
= 0; i
< app_count
; ++i
) {
233 scoped_ptr
<AppListItem
> item(UnpickleAppListItem(&it
).Pass());
235 return scoped_ptr
<AppListModel
>();
236 std::string folder_id
= item
->folder_id();
237 model
->AddItemToFolder(item
.Pass(), folder_id
);