Chromium Code Reviews| Index: remoting/client/plugin/touch_input_scaler.cc |
| diff --git a/remoting/client/plugin/touch_input_scaler.cc b/remoting/client/plugin/touch_input_scaler.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6397e10e5dd77315b81da95a34b0804d2d9c410f |
| --- /dev/null |
| +++ b/remoting/client/plugin/touch_input_scaler.cc |
| @@ -0,0 +1,77 @@ |
| +// Copyright 2015 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 "remoting/client/plugin/touch_input_scaler.h" |
| + |
| +#include "base/logging.h" |
| +#include "remoting/proto/event.pb.h" |
| + |
| +namespace remoting { |
| + |
| +using protocol::TouchEvent; |
| +using protocol::TouchEventPoint; |
| + |
| +namespace { |
| + |
| +// |value| is the number to be scaled. |output_max| is the output desktop's max |
| +// height or width. |input_max| is the input desktop's max height or width. |
| +float Scale(float value, int output_max, int input_max) { |
| + DCHECK_GT(output_max, 0); |
| + DCHECK_GT(input_max, 0); |
| + value *= output_max; |
| + value /= input_max; |
| + return value; |
| +} |
| + |
| +// Same as Scale() but |value| will be scaled and clamped using |output_max| and |
| +// |input_max|. |
| +float ScaleAndClamp(float value, int output_max, int input_max) { |
| + value = Scale(value, output_max, input_max); |
| + return std::max(0.0f, std::min(static_cast<float>(output_max), value)); |
| +} |
| + |
| +} // namespace |
| + |
| +TouchInputScaler::TouchInputScaler(InputStub* input_stub) |
| + : InputFilter(input_stub) {} |
| + |
| +TouchInputScaler::~TouchInputScaler() {} |
| + |
| +void TouchInputScaler::InjectTouchEvent(const TouchEvent& event) { |
| + if (input_size_.is_empty() || output_size_.is_empty()) |
| + return; |
| + |
| + // We scale based on the maximum input & output coordinates, rather than the |
| + // input and output sizes, so that it's possible to reach the edge of the |
| + // output when up-scaling. We also take care to round up or down correctly, |
| + // which is important when down-scaling. |
| + TouchEvent out_event(event); |
| + for (int i = 0; i < out_event.touch_points().size(); ++i) { |
| + TouchEventPoint* point = out_event.mutable_touch_points(i); |
| + if (point->has_x() || point->has_y()) { |
| + DCHECK(point->has_x() && point->has_y()); |
| + point->set_x( |
| + ScaleAndClamp(point->x(), output_size_.width(), input_size_.width())); |
| + point->set_y(ScaleAndClamp(point->y(), output_size_.height(), |
| + input_size_.height())); |
| + } |
| + |
| + // Also scale the touch size. When the output desktop and the input desktop |
| + // sizes do not match, the touch size should be scaled for more predicatable |
|
Wez
2015/02/23 23:24:07
typo: predictable.
It's not clear what it means f
Rintaro Kuroiwa
2015/02/24 23:43:10
Changed description and an example where scaling i
|
| + // hit testing. |
| + // TODO(rkuroiwa): Also clamp. Note that point->angle() affects the maximum |
| + // size. |
| + if (point->has_radius_x() || point->has_radius_y()) { |
| + DCHECK(point->has_radius_x() && point->has_radius_y()); |
| + point->set_radius_x( |
| + Scale(point->radius_x(), output_size_.width(), input_size_.width())); |
| + point->set_radius_y(Scale(point->radius_y(), output_size_.height(), |
| + input_size_.height())); |
| + } |
| + } |
| + |
| + InputFilter::InjectTouchEvent(out_event); |
| +} |
| + |
| +} // namespace remoting |