Home | History | Annotate | Download | only in ipc
      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