1 // Copyright 2012 The ChromiumOS Authors
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 "include/box_filter_interpreter.h"
6
7 #include "include/macros.h"
8 #include "include/tracer.h"
9 #include "include/util.h"
10
11 namespace gestures {
12
BoxFilterInterpreter(PropRegistry * prop_reg,Interpreter * next,Tracer * tracer)13 BoxFilterInterpreter::BoxFilterInterpreter(PropRegistry* prop_reg,
14 Interpreter* next,
15 Tracer* tracer)
16 : FilterInterpreter(NULL, next, tracer, false),
17 box_width_(prop_reg, "Box Width", 0.0),
18 box_height_(prop_reg, "Box Height", 0.0) {
19 InitName();
20 }
21
SyncInterpretImpl(HardwareState * hwstate,stime_t * timeout)22 void BoxFilterInterpreter::SyncInterpretImpl(HardwareState* hwstate,
23 stime_t* timeout) {
24 if (box_width_.val_ == 0.0 && box_height_.val_ == 0.0) {
25 next_->SyncInterpret(hwstate, timeout);
26 return;
27 }
28 RemoveMissingIdsFromMap(&previous_output_, *hwstate);
29
30 const float kHalfWidth = box_width_.val_ * 0.5;
31 const float kHalfHeight = box_height_.val_ * 0.5;
32
33 for (size_t i = 0; i < hwstate->finger_cnt; i++) {
34 FingerState& fs = hwstate->fingers[i];
35 // If it's new, pass it through
36 if (!MapContainsKey(previous_output_, fs.tracking_id))
37 continue;
38 const FingerState& prev_out = previous_output_[fs.tracking_id];
39 float FingerState::*fields[] = { &FingerState::position_x,
40 &FingerState::position_y };
41 const float kBounds[] = { kHalfWidth, kHalfHeight };
42 unsigned warp[] = { GESTURES_FINGER_WARP_X_MOVE,
43 GESTURES_FINGER_WARP_Y_MOVE };
44 for (size_t f_idx = 0; f_idx < arraysize(fields); f_idx++) {
45 if (fs.flags & warp[f_idx]) // If warping, just move to the new point
46 continue;
47 float FingerState::*field = fields[f_idx];
48 float prev_out_val = prev_out.*field;
49 float val = fs.*field;
50 float bound = kBounds[f_idx];
51
52 if (prev_out_val - bound < val && val < prev_out_val + bound) {
53 // keep box in place
54 fs.*field = prev_out_val;
55 } else if (val > prev_out_val) {
56 fs.*field -= bound;
57 } else {
58 fs.*field += bound;
59 }
60 }
61 }
62
63 for (size_t i = 0; i < hwstate->finger_cnt; i++)
64 previous_output_[hwstate->fingers[i].tracking_id] = hwstate->fingers[i];
65
66 next_->SyncInterpret(hwstate, timeout);
67 }
68
69 } // namespace gestures
70