1 // Copyright 2014 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. 4 5 #include "ui/gfx/ipc/gfx_param_traits.h" 6 7 #include <string> 8 9 #include "third_party/skia/include/core/SkBitmap.h" 10 #include "ui/gfx/rect.h" 11 #include "ui/gfx/rect_f.h" 12 13 namespace { 14 15 struct SkBitmap_Data { 16 // The color type for the bitmap (bits per pixel, etc). 17 SkColorType fColorType; 18 19 // The alpha type for the bitmap (opaque, premul, unpremul). 20 SkAlphaType fAlphaType; 21 22 // The width of the bitmap in pixels. 23 uint32 fWidth; 24 25 // The height of the bitmap in pixels. 26 uint32 fHeight; 27 28 void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) { 29 const SkImageInfo& info = bitmap.info(); 30 fColorType = info.fColorType; 31 fAlphaType = info.fAlphaType; 32 fWidth = info.fWidth; 33 fHeight = info.fHeight; 34 } 35 36 // Returns whether |bitmap| successfully initialized. 37 bool InitSkBitmapFromData(SkBitmap* bitmap, 38 const char* pixels, 39 size_t pixels_size) const { 40 if (!bitmap->tryAllocPixels( 41 SkImageInfo::Make(fWidth, fHeight, fColorType, fAlphaType))) 42 return false; 43 if (pixels_size != bitmap->getSize()) 44 return false; 45 memcpy(bitmap->getPixels(), pixels, pixels_size); 46 return true; 47 } 48 }; 49 50 } // namespace 51 52 namespace IPC { 53 54 void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) { 55 m->WriteInt(p.x()); 56 m->WriteInt(p.y()); 57 } 58 59 bool ParamTraits<gfx::Point>::Read(const Message* m, PickleIterator* iter, 60 gfx::Point* r) { 61 int x, y; 62 if (!m->ReadInt(iter, &x) || 63 !m->ReadInt(iter, &y)) 64 return false; 65 r->set_x(x); 66 r->set_y(y); 67 return true; 68 } 69 70 void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::string* l) { 71 l->append(base::StringPrintf("(%d, %d)", p.x(), p.y())); 72 } 73 74 void ParamTraits<gfx::PointF>::Write(Message* m, const gfx::PointF& v) { 75 ParamTraits<float>::Write(m, v.x()); 76 ParamTraits<float>::Write(m, v.y()); 77 } 78 79 bool ParamTraits<gfx::PointF>::Read(const Message* m, 80 PickleIterator* iter, 81 gfx::PointF* r) { 82 float x, y; 83 if (!ParamTraits<float>::Read(m, iter, &x) || 84 !ParamTraits<float>::Read(m, iter, &y)) 85 return false; 86 r->set_x(x); 87 r->set_y(y); 88 return true; 89 } 90 91 void ParamTraits<gfx::PointF>::Log(const gfx::PointF& v, std::string* l) { 92 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); 93 } 94 95 void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) { 96 DCHECK_GE(p.width(), 0); 97 DCHECK_GE(p.height(), 0); 98 int values[2] = { p.width(), p.height() }; 99 m->WriteBytes(&values, sizeof(int) * 2); 100 } 101 102 bool ParamTraits<gfx::Size>::Read(const Message* m, 103 PickleIterator* iter, 104 gfx::Size* r) { 105 const char* char_values; 106 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2)) 107 return false; 108 const int* values = reinterpret_cast<const int*>(char_values); 109 if (values[0] < 0 || values[1] < 0) 110 return false; 111 r->set_width(values[0]); 112 r->set_height(values[1]); 113 return true; 114 } 115 116 void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::string* l) { 117 l->append(base::StringPrintf("(%d, %d)", p.width(), p.height())); 118 } 119 120 void ParamTraits<gfx::SizeF>::Write(Message* m, const gfx::SizeF& p) { 121 float values[2] = { p.width(), p.height() }; 122 m->WriteBytes(&values, sizeof(float) * 2); 123 } 124 125 bool ParamTraits<gfx::SizeF>::Read(const Message* m, 126 PickleIterator* iter, 127 gfx::SizeF* r) { 128 const char* char_values; 129 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2)) 130 return false; 131 const float* values = reinterpret_cast<const float*>(char_values); 132 r->set_width(values[0]); 133 r->set_height(values[1]); 134 return true; 135 } 136 137 void ParamTraits<gfx::SizeF>::Log(const gfx::SizeF& p, std::string* l) { 138 l->append(base::StringPrintf("(%f, %f)", p.width(), p.height())); 139 } 140 141 void ParamTraits<gfx::Vector2d>::Write(Message* m, const gfx::Vector2d& p) { 142 int values[2] = { p.x(), p.y() }; 143 m->WriteBytes(&values, sizeof(int) * 2); 144 } 145 146 bool ParamTraits<gfx::Vector2d>::Read(const Message* m, 147 PickleIterator* iter, 148 gfx::Vector2d* r) { 149 const char* char_values; 150 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2)) 151 return false; 152 const int* values = reinterpret_cast<const int*>(char_values); 153 r->set_x(values[0]); 154 r->set_y(values[1]); 155 return true; 156 } 157 158 void ParamTraits<gfx::Vector2d>::Log(const gfx::Vector2d& v, std::string* l) { 159 l->append(base::StringPrintf("(%d, %d)", v.x(), v.y())); 160 } 161 162 void ParamTraits<gfx::Vector2dF>::Write(Message* m, const gfx::Vector2dF& p) { 163 float values[2] = { p.x(), p.y() }; 164 m->WriteBytes(&values, sizeof(float) * 2); 165 } 166 167 bool ParamTraits<gfx::Vector2dF>::Read(const Message* m, 168 PickleIterator* iter, 169 gfx::Vector2dF* r) { 170 const char* char_values; 171 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2)) 172 return false; 173 const float* values = reinterpret_cast<const float*>(char_values); 174 r->set_x(values[0]); 175 r->set_y(values[1]); 176 return true; 177 } 178 179 void ParamTraits<gfx::Vector2dF>::Log(const gfx::Vector2dF& v, std::string* l) { 180 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); 181 } 182 183 void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) { 184 int values[4] = { p.x(), p.y(), p.width(), p.height() }; 185 m->WriteBytes(&values, sizeof(int) * 4); 186 } 187 188 bool ParamTraits<gfx::Rect>::Read(const Message* m, 189 PickleIterator* iter, 190 gfx::Rect* r) { 191 const char* char_values; 192 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 4)) 193 return false; 194 const int* values = reinterpret_cast<const int*>(char_values); 195 if (values[2] < 0 || values[3] < 0) 196 return false; 197 r->SetRect(values[0], values[1], values[2], values[3]); 198 return true; 199 } 200 201 void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::string* l) { 202 l->append(base::StringPrintf("(%d, %d, %d, %d)", p.x(), p.y(), 203 p.width(), p.height())); 204 } 205 206 void ParamTraits<gfx::RectF>::Write(Message* m, const gfx::RectF& p) { 207 float values[4] = { p.x(), p.y(), p.width(), p.height() }; 208 m->WriteBytes(&values, sizeof(float) * 4); 209 } 210 211 bool ParamTraits<gfx::RectF>::Read(const Message* m, 212 PickleIterator* iter, 213 gfx::RectF* r) { 214 const char* char_values; 215 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 4)) 216 return false; 217 const float* values = reinterpret_cast<const float*>(char_values); 218 r->SetRect(values[0], values[1], values[2], values[3]); 219 return true; 220 } 221 222 void ParamTraits<gfx::RectF>::Log(const gfx::RectF& p, std::string* l) { 223 l->append(base::StringPrintf("(%f, %f, %f, %f)", p.x(), p.y(), 224 p.width(), p.height())); 225 } 226 227 void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) { 228 size_t fixed_size = sizeof(SkBitmap_Data); 229 SkBitmap_Data bmp_data; 230 bmp_data.InitSkBitmapDataForTransfer(p); 231 m->WriteData(reinterpret_cast<const char*>(&bmp_data), 232 static_cast<int>(fixed_size)); 233 size_t pixel_size = p.getSize(); 234 SkAutoLockPixels p_lock(p); 235 m->WriteData(reinterpret_cast<const char*>(p.getPixels()), 236 static_cast<int>(pixel_size)); 237 } 238 239 bool ParamTraits<SkBitmap>::Read(const Message* m, 240 PickleIterator* iter, 241 SkBitmap* r) { 242 const char* fixed_data; 243 int fixed_data_size = 0; 244 if (!m->ReadData(iter, &fixed_data, &fixed_data_size) || 245 (fixed_data_size <= 0)) { 246 NOTREACHED(); 247 return false; 248 } 249 if (fixed_data_size != sizeof(SkBitmap_Data)) 250 return false; // Message is malformed. 251 252 const char* variable_data; 253 int variable_data_size = 0; 254 if (!m->ReadData(iter, &variable_data, &variable_data_size) || 255 (variable_data_size < 0)) { 256 NOTREACHED(); 257 return false; 258 } 259 const SkBitmap_Data* bmp_data = 260 reinterpret_cast<const SkBitmap_Data*>(fixed_data); 261 return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size); 262 } 263 264 void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) { 265 l->append("<SkBitmap>"); 266 } 267 268 } // namespace IPC 269