// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/gfx/ipc/gfx_param_traits.h" #include #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/range/range.h" namespace { struct SkBitmap_Data { // The color type for the bitmap (bits per pixel, etc). SkColorType fColorType; // The alpha type for the bitmap (opaque, premul, unpremul). SkAlphaType fAlphaType; // The width of the bitmap in pixels. uint32 fWidth; // The height of the bitmap in pixels. uint32 fHeight; void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) { const SkImageInfo& info = bitmap.info(); fColorType = info.fColorType; fAlphaType = info.fAlphaType; fWidth = info.fWidth; fHeight = info.fHeight; } // Returns whether |bitmap| successfully initialized. bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels, size_t pixels_size) const { if (!bitmap->tryAllocPixels( SkImageInfo::Make(fWidth, fHeight, fColorType, fAlphaType))) return false; if (pixels_size != bitmap->getSize()) return false; memcpy(bitmap->getPixels(), pixels, pixels_size); return true; } }; } // namespace namespace IPC { void ParamTraits::Write(Message* m, const gfx::Point& p) { m->WriteInt(p.x()); m->WriteInt(p.y()); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::Point* r) { int x, y; if (!iter->ReadInt(&x) || !iter->ReadInt(&y)) return false; r->set_x(x); r->set_y(y); return true; } void ParamTraits::Log(const gfx::Point& p, std::string* l) { l->append(base::StringPrintf("(%d, %d)", p.x(), p.y())); } void ParamTraits::Write(Message* m, const gfx::PointF& v) { ParamTraits::Write(m, v.x()); ParamTraits::Write(m, v.y()); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::PointF* r) { float x, y; if (!ParamTraits::Read(m, iter, &x) || !ParamTraits::Read(m, iter, &y)) return false; r->set_x(x); r->set_y(y); return true; } void ParamTraits::Log(const gfx::PointF& v, std::string* l) { l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); } void ParamTraits::Write(Message* m, const gfx::Size& p) { DCHECK_GE(p.width(), 0); DCHECK_GE(p.height(), 0); int values[2] = { p.width(), p.height() }; m->WriteBytes(&values, sizeof(int) * 2); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::Size* r) { const char* char_values; if (!iter->ReadBytes(&char_values, sizeof(int) * 2)) return false; const int* values = reinterpret_cast(char_values); if (values[0] < 0 || values[1] < 0) return false; r->set_width(values[0]); r->set_height(values[1]); return true; } void ParamTraits::Log(const gfx::Size& p, std::string* l) { l->append(base::StringPrintf("(%d, %d)", p.width(), p.height())); } void ParamTraits::Write(Message* m, const gfx::SizeF& p) { float values[2] = { p.width(), p.height() }; m->WriteBytes(&values, sizeof(float) * 2); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::SizeF* r) { const char* char_values; if (!iter->ReadBytes(&char_values, sizeof(float) * 2)) return false; const float* values = reinterpret_cast(char_values); r->set_width(values[0]); r->set_height(values[1]); return true; } void ParamTraits::Log(const gfx::SizeF& p, std::string* l) { l->append(base::StringPrintf("(%f, %f)", p.width(), p.height())); } void ParamTraits::Write(Message* m, const gfx::Vector2d& p) { int values[2] = { p.x(), p.y() }; m->WriteBytes(&values, sizeof(int) * 2); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::Vector2d* r) { const char* char_values; if (!iter->ReadBytes(&char_values, sizeof(int) * 2)) return false; const int* values = reinterpret_cast(char_values); r->set_x(values[0]); r->set_y(values[1]); return true; } void ParamTraits::Log(const gfx::Vector2d& v, std::string* l) { l->append(base::StringPrintf("(%d, %d)", v.x(), v.y())); } void ParamTraits::Write(Message* m, const gfx::Vector2dF& p) { float values[2] = { p.x(), p.y() }; m->WriteBytes(&values, sizeof(float) * 2); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::Vector2dF* r) { const char* char_values; if (!iter->ReadBytes(&char_values, sizeof(float) * 2)) return false; const float* values = reinterpret_cast(char_values); r->set_x(values[0]); r->set_y(values[1]); return true; } void ParamTraits::Log(const gfx::Vector2dF& v, std::string* l) { l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); } void ParamTraits::Write(Message* m, const gfx::Rect& p) { int values[4] = { p.x(), p.y(), p.width(), p.height() }; m->WriteBytes(&values, sizeof(int) * 4); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::Rect* r) { const char* char_values; if (!iter->ReadBytes(&char_values, sizeof(int) * 4)) return false; const int* values = reinterpret_cast(char_values); if (values[2] < 0 || values[3] < 0) return false; r->SetRect(values[0], values[1], values[2], values[3]); return true; } void ParamTraits::Log(const gfx::Rect& p, std::string* l) { l->append(base::StringPrintf("(%d, %d, %d, %d)", p.x(), p.y(), p.width(), p.height())); } void ParamTraits::Write(Message* m, const gfx::RectF& p) { float values[4] = { p.x(), p.y(), p.width(), p.height() }; m->WriteBytes(&values, sizeof(float) * 4); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::RectF* r) { const char* char_values; if (!iter->ReadBytes(&char_values, sizeof(float) * 4)) return false; const float* values = reinterpret_cast(char_values); r->SetRect(values[0], values[1], values[2], values[3]); return true; } void ParamTraits::Log(const gfx::RectF& p, std::string* l) { l->append(base::StringPrintf("(%f, %f, %f, %f)", p.x(), p.y(), p.width(), p.height())); } void ParamTraits::Write(Message* m, const SkBitmap& p) { size_t fixed_size = sizeof(SkBitmap_Data); SkBitmap_Data bmp_data; bmp_data.InitSkBitmapDataForTransfer(p); m->WriteData(reinterpret_cast(&bmp_data), static_cast(fixed_size)); size_t pixel_size = p.getSize(); SkAutoLockPixels p_lock(p); m->WriteData(reinterpret_cast(p.getPixels()), static_cast(pixel_size)); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, SkBitmap* r) { const char* fixed_data; int fixed_data_size = 0; if (!iter->ReadData(&fixed_data, &fixed_data_size) || (fixed_data_size <= 0)) { NOTREACHED(); return false; } if (fixed_data_size != sizeof(SkBitmap_Data)) return false; // Message is malformed. const char* variable_data; int variable_data_size = 0; if (!iter->ReadData(&variable_data, &variable_data_size) || (variable_data_size < 0)) { NOTREACHED(); return false; } const SkBitmap_Data* bmp_data = reinterpret_cast(fixed_data); return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size); } void ParamTraits::Log(const SkBitmap& p, std::string* l) { l->append(""); } void ParamTraits::Write(Message* m, const gfx::Range& r) { m->WriteSizeT(r.start()); m->WriteSizeT(r.end()); } bool ParamTraits::Read(const Message* m, PickleIterator* iter, gfx::Range* r) { size_t start, end; if (!iter->ReadSizeT(&start) || !iter->ReadSizeT(&end)) return false; r->set_start(start); r->set_end(end); return true; } void ParamTraits::Log(const gfx::Range& r, std::string* l) { l->append(base::StringPrintf("(%" PRIuS ", %" PRIuS ")", r.start(), r.end())); } } // namespace IPC