changed canvas to be able to copy any rectangular region from inputs to canvas
Stefan Schuermans

Stefan Schuermans commited on 2011-11-19 14:28:08
Showing 4 changed files, with 70 additions and 115 deletions.

... ...
@@ -27,17 +27,18 @@ namespace Blinker {
27 27
 Canvas::Input::Input(Canvas &canvas, const Directory &dirBase):
28 28
   m_canvas(canvas),
29 29
   m_fileInStream(dirBase.getFile("instream")),
30
-  m_filePosition(dirBase.getFile("position")),
30
+  m_fileSrcPos(dirBase.getFile("srcpos")),
31 31
   m_fileSize(dirBase.getFile("size")),
32
-  m_havePosition(false),
33
-  m_haveSize(false),
32
+  m_fileDestPos(dirBase.getFile("destpos")),
34 33
   m_pInStream(NULL),
35
-  m_ownFrame(false),
36
-  m_pFrame(NULL)
34
+  m_haveSrcPos(false),
35
+  m_haveSize(false),
36
+  m_haveDestPos(false)
37 37
 {
38 38
   // get setting and attach to input stream
39
-  getPosition();
39
+  getSrcPos();
40 40
   getSize();
41
+  getDestPos();
41 42
   getInStream();
42 43
 }
43 44
 
... ...
@@ -57,15 +58,13 @@ void Canvas::Input::updateConfig()
57 58
     getInStream();
58 59
   }
59 60
 
60
-  // position file was modified -> re-get position
61
-  if (m_filePosition.checkModified()) {
62
-    getPosition();
63
-  }
64
-
65
-  // size file was modified -> re-get size
66
-  if (m_fileSize.checkModified()) {
61
+  // position/size files were modified -> re-get position/size
62
+  if (m_fileSrcPos.checkModified())
63
+    getSrcPos();
64
+  if (m_fileSize.checkModified())
67 65
     getSize();
68
-  }
66
+  if (m_fileDestPos.checkModified())
67
+    getDestPos();
69 68
 }
70 69
 
71 70
 /**
... ...
@@ -75,12 +74,10 @@ void Canvas::Input::updateConfig()
75 74
  */
76 75
 void Canvas::Input::setFrame(const std::string &stream, stBlinkenFrame *pFrame)
77 76
 {
78
-  // prepare frame
79
-  prepareFrame(pFrame);
80
-
81 77
   // notify canvas to redraw
82 78
   m_canvas.redraw();
83 79
 
80
+  (void)pFrame; // unused (frame fetched from stream when requested to draw)
84 81
   (void)stream; // unused
85 82
 }
86 83
 
... ...
@@ -90,9 +87,6 @@ void Canvas::Input::setFrame(const std::string &stream, stBlinkenFrame *pFrame)
90 87
  */
91 88
 void Canvas::Input::setNoFrame(const std::string &stream)
92 89
 {
93
-  // throw away prepared frame
94
-  unprepareFrame();
95
-
96 90
   // notify canvas to redraw
97 91
   m_canvas.redraw();
98 92
 
... ...
@@ -105,15 +99,33 @@ void Canvas::Input::setNoFrame(const std::string &stream)
105 99
  */
106 100
 bool Canvas::Input::draw()
107 101
 {
108
-  // no position, no frame or no canvas -> leave
109
-  if (!m_havePosition || !m_pFrame || !m_canvas.m_pCanvas)
102
+  stBlinkenFrame *pFrame;
103
+
104
+  // no destination position or no canvas -> leave
105
+  if (!m_haveDestPos || !m_canvas.m_pCanvas)
110 106
     return false;
111 107
 
112
-  // draw frame to canvas
113
-  BlinkenFrameCopyRect(m_canvas.m_pCanvas, m_position.m_y, m_position.m_x,
114
-                       m_pFrame, 0, 0,
115
-                       BlinkenFrameGetHeight(m_pFrame),
116
-                       BlinkenFrameGetWidth(m_pFrame));
108
+  // get current frame from stream (levae if no stream or no frame)
109
+  if (!m_pInStream || !m_pInStream->getCurFrame(pFrame))
110
+    return false;
111
+
112
+  // no source position -> use top left
113
+  if (!m_haveSrcPos) {
114
+    m_srcPos.m_x = 0;
115
+    m_srcPos.m_y = 0;
116
+  }
117
+
118
+  // no size -> use entire source frame
119
+  //            (BlinkenLib will clip this if too large)
120
+  if (!m_haveSize) {
121
+    m_size.m_width = BlinkenFrameGetWidth(pFrame);
122
+    m_size.m_height = BlinkenFrameGetHeight(pFrame);
123
+  }
124
+
125
+  // draw rectangular area to canvas
126
+  BlinkenFrameCopyRect(m_canvas.m_pCanvas, m_destPos.m_y, m_destPos.m_x,
127
+                       pFrame, m_srcPos.m_y, m_srcPos.m_x,
128
+                       m_size.m_height, m_size.m_width);
117 129
 
118 130
   return true;
119 131
 }
... ...
@@ -135,9 +147,6 @@ void Canvas::Input::getInStream()
135 147
 /// detach from input stream and release it
136 148
 void Canvas::Input::releaseInStream()
137 149
 {
138
-  // get rid of prepared frame
139
-  unprepareFrame();
140
-
141 150
   // detach from input stream
142 151
   if (m_pInStream)
143 152
     m_pInStream->detach(this);
... ...
@@ -150,86 +159,40 @@ void Canvas::Input::releaseInStream()
150 159
   m_canvas.redraw();
151 160
 }
152 161
 
153
-/// (re-)get position of stream on canvas
154
-void Canvas::Input::getPosition()
162
+/// (re-)get position of area to copy from stream
163
+void Canvas::Input::getSrcPos()
155 164
 {
156 165
   std::string strPos;
157 166
 
158
-  // read position from position file
159
-  m_havePosition = m_filePosition.getStr(strPos) && m_position.fromStr(strPos);
167
+  // read source position from file and parse it
168
+  m_haveSrcPos = m_fileSrcPos.getStr(strPos) && m_srcPos.fromStr(strPos);
160 169
 
161 170
   // notify canvas to redraw
162 171
   m_canvas.redraw();
163 172
 }
164 173
 
165
-/// (re-)get size of stream on canvas
174
+/// (re-)get size of area to copy from stream
166 175
 void Canvas::Input::getSize()
167 176
 {
168 177
   std::string strSize;
169 178
 
170
-  // read size from size file
179
+  // read size from file and parse it
171 180
   m_haveSize = m_fileSize.getStr(strSize) && m_size.fromStr(strSize);
172 181
 
173
-  // update prepared frame
174
-  updateFrame();
175
-
176 182
   // notify canvas to redraw
177 183
   m_canvas.redraw();
178 184
 }
179 185
 
180
-/// (un-)prepare frame based on current frame of stream
181
-void Canvas::Input::updateFrame()
186
+/// (re-)get destination position on canvas
187
+void Canvas::Input::getDestPos()
182 188
 {
183
-  stBlinkenFrame *pFrame;
184
-
185
-  // get current frame from stream
186
-  if (m_pInStream && m_pInStream->getCurFrame(pFrame)) {
187
-    // got a frame -> prepare it
188
-    prepareFrame(pFrame);
189
-  } else {
190
-    // no frame -> throw away prepared frame
191
-    unprepareFrame();
192
-  }
193
-}
194
-
195
-/**
196
- * @brief prepare frame (scale it if needed)
197
- * @param[in] pFrame frame to prepare
198
- */
199
-void Canvas::Input::prepareFrame(stBlinkenFrame *pFrame)
200
-{
201
-  // throw away old frame
202
-  unprepareFrame();
203
-
204
-  // no scaling needed
205
-  if (!m_haveSize ||
206
-      ((unsigned int)BlinkenFrameGetWidth(pFrame) == m_size.m_width &&
207
-       (unsigned int)BlinkenFrameGetHeight(pFrame) == m_size.m_height)) {
208
-    // just remember pointer
209
-    m_pFrame = pFrame;
210
-  }
211
-  // scaling needed
212
-  else {
213
-    // clone frame and scale it
214
-    m_pFrame = BlinkenFrameClone(pFrame);
215
-    if (m_pFrame) {
216
-      BlinkenFrameScale(m_pFrame, m_size.m_height, m_size.m_width);
217
-      m_ownFrame = true; // frame allocated ourself -> free it later
218
-    }
219
-  }
220
-}
189
+  std::string strPos;
221 190
 
222
-/// throw away prepared frame
223
-void Canvas::Input::unprepareFrame()
224
-{
225
-  // free frame if it was allocated ourself
226
-  if (m_ownFrame) {
227
-    BlinkenFrameFree(m_pFrame);
228
-    m_ownFrame = false;
229
-  }
191
+  // read destination position from file and parse it
192
+  m_haveDestPos = m_fileDestPos.getStr(strPos) && m_destPos.fromStr(strPos);
230 193
 
231
-  // no frame any more
232
-  m_pFrame = NULL;
194
+  // notify canvas to redraw
195
+  m_canvas.redraw();
233 196
 }
234 197
 
235 198
 } // namespace Blinker
... ...
@@ -72,37 +72,29 @@ protected:
72 72
   /// detach from input stream and release it
73 73
   void releaseInStream();
74 74
 
75
-  /// (re-)get position of stream on canvas
76
-  void getPosition();
75
+  /// (re-)get position of area to copy from stream
76
+  void getSrcPos();
77 77
 
78
-  /// (re-)get size of stream on canvas
78
+  /// (re-)get size of area to copy from stream
79 79
   void getSize();
80 80
 
81
-  /// (un-)prepare frame based on current frame of stream
82
-  void updateFrame();
83
-
84
-  /**
85
-   * @brief prepare frame (scale it if needed)
86
-   * @param[in] pFrame frame to prepare
87
-   */
88
-  void prepareFrame(stBlinkenFrame *pFrame);
89
-
90
-  /// throw away prepared frame
91
-  void unprepareFrame();
81
+  /// (re-)get destination position on canvas
82
+  void getDestPos();
92 83
 
93 84
 protected:
94 85
   Canvas         &m_canvas;      ///< owning canvas
95 86
   SettingFile    m_fileInStream; ///< input stream name file
96
-  SettingFile    m_filePosition; ///< position file
87
+  SettingFile    m_fileSrcPos;   ///< source position file
97 88
   SettingFile    m_fileSize;     ///< size file
89
+  SettingFile    m_fileDestPos;  ///< destination position file
98 90
   std::string    m_nameInStream; ///< name of input stream
99
-  bool           m_havePosition; ///< if position of stream on canvas is defined
100
-  Position       m_position;     ///< position of stream on canvas
101
-  bool           m_haveSize;     ///< if size of stream on canvas is defined
102
-  Size           m_size;         ///< size of stream on canvas
103 91
   Stream         *m_pInStream;   ///< input stream
104
-  bool           m_ownFrame;     ///< if the frame was allocated ourself
105
-  stBlinkenFrame *m_pFrame;      ///< frame to draw (already scaled to size)
92
+  bool           m_haveSrcPos;   ///< if copy-area src position is defined
93
+  Position       m_srcPos;       ///< copy-area position in source
94
+  bool           m_haveSize;     ///< if copy-area size is defined
95
+  Size           m_size;         ///< copy-area size
96
+  bool           m_haveDestPos;  ///< if copy-area dest position is defined
97
+  Position       m_destPos;      ///< copy-area position on canvas (i.e. dest)
106 98
 }; // class Canvas::Input
107 99
 
108 100
 } // namespace Blinker
... ...
@@ -26,11 +26,11 @@ Position::Position():
26 26
 bool Position::fromStr(const std::string &str)
27 27
 {
28 28
   StringParser parser(str);
29
-  int x, y;
29
+  unsigned int x, y;
30 30
 
31
-  if (!parser.sintNo(x) ||
31
+  if (!parser.uintNo(x) ||
32 32
       !parser.fixChr(',') ||
33
-      !parser.sintNo(y))
33
+      !parser.uintNo(y))
34 34
     return false;
35 35
   m_x = x;
36 36
   m_y = y;
... ...
@@ -32,8 +32,8 @@ public:
32 32
   std::string toStr() const;
33 33
 
34 34
 public:
35
-  int m_x; ///< X coordinate within a frame (in pixels)
36
-  int m_y; ///< Y ccordinate within a frame (in pixels)
35
+  unsigned int m_x; ///< X coordinate within a frame (in pixels)
36
+  unsigned int m_y; ///< Y ccordinate within a frame (in pixels)
37 37
 }; // class Position
38 38
 
39 39
 } // namespace Blinker
40 40