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(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(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 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
);
162 bool has_shadow
= false;
163 if (!it
->ReadBool(&has_shadow
))
164 return scoped_ptr
<AppListItem
>();
166 if (!UnpickleImage(it
, &icon
))
167 return scoped_ptr
<AppListItem
>();
168 result
->SetIcon(icon
, has_shadow
);
169 return result
.Pass();
172 bool FastShowPickler::PickleAppListItem(Pickle
* pickle
, AppListItem
* item
) {
173 if (!pickle
->WriteString(item
->id()))
175 if (!pickle
->WriteString(item
->name()))
177 if (!pickle
->WriteString(item
->short_name()))
179 if (!pickle
->WriteBool(item
->has_shadow()))
181 if (!PickleImage(pickle
, item
->icon()))
186 void FastShowPickler::CopyOverItem(AppListItem
* src_item
,
187 AppListItem
* dest_item
) {
188 dest_item
->SetNameAndShortName(src_item
->name(), src_item
->short_name());
189 dest_item
->SetIcon(src_item
->icon(), src_item
->has_shadow());
190 // Do not set folder_id, pass that to AppListModel::AddItemToFolder() instead.
193 // The version of the pickle format defined here. This needs to be incremented
194 // whenever this format is changed so new clients can invalidate old versions.
195 const int FastShowPickler::kVersion
= 3;
197 scoped_ptr
<Pickle
> FastShowPickler::PickleAppListModelForFastShow(
198 AppListModel
* model
) {
199 scoped_ptr
<Pickle
> result(new Pickle
);
200 if (!result
->WriteInt(kVersion
))
201 return scoped_ptr
<Pickle
>();
202 if (!result
->WriteInt((int)model
->top_level_item_list()->item_count()))
203 return scoped_ptr
<Pickle
>();
204 for (size_t i
= 0; i
< model
->top_level_item_list()->item_count(); ++i
) {
205 if (!PickleAppListItem(result
.get(),
206 model
->top_level_item_list()->item_at(i
))) {
207 return scoped_ptr
<Pickle
>();
210 return result
.Pass();
213 void FastShowPickler::CopyOver(AppListModel
* src
, AppListModel
* dest
) {
214 DCHECK_EQ(0u, dest
->top_level_item_list()->item_count());
215 for (size_t i
= 0; i
< src
->top_level_item_list()->item_count(); i
++) {
216 AppListItem
* src_item
= src
->top_level_item_list()->item_at(i
);
217 scoped_ptr
<AppListItem
> dest_item(new AppListItem(src_item
->id()));
218 CopyOverItem(src_item
, dest_item
.get());
219 dest
->AddItemToFolder(dest_item
.Pass(), src_item
->folder_id());
223 scoped_ptr
<AppListModel
>
224 FastShowPickler::UnpickleAppListModelForFastShow(Pickle
* pickle
) {
225 PickleIterator
it(*pickle
);
226 int read_version
= 0;
227 if (!it
.ReadInt(&read_version
))
228 return scoped_ptr
<AppListModel
>();
229 if (read_version
!= kVersion
)
230 return scoped_ptr
<AppListModel
>();
232 if (!it
.ReadInt(&app_count
))
233 return scoped_ptr
<AppListModel
>();
235 scoped_ptr
<AppListModel
> model(new AppListModel
);
236 for (int i
= 0; i
< app_count
; ++i
) {
237 scoped_ptr
<AppListItem
> item(UnpickleAppListItem(&it
).Pass());
239 return scoped_ptr
<AppListModel
>();
240 std::string folder_id
= item
->folder_id();
241 model
->AddItemToFolder(item
.Pass(), folder_id
);