transformer.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
  2. // Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
  3. // Copyright (C) 2015 Christoph Friedrich <christoph.friedrich@vonaffenfels.de>
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation version 2.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://gnu.org/licenses/gpl-2.0.txt>
  16. /*
  17. * NOTE:
  18. *
  19. * Transformers are deprecated. For the kind of mappings they were be
  20. * used by they turned out to be too complicated.
  21. *
  22. * They have been superseeded by the simpler PixelMapper, see pixel-mapper.h
  23. */
  24. #ifndef REMOVE_DEPRECATED_TRANSFORMERS
  25. #include <assert.h>
  26. #include <stdio.h>
  27. #include "transformer.h"
  28. namespace rgb_matrix {
  29. /*****************************/
  30. /* Rotate Transformer Canvas */
  31. /*****************************/
  32. class RotateTransformer::TransformCanvas : public Canvas {
  33. public:
  34. TransformCanvas(int angle);
  35. void SetDelegatee(Canvas* delegatee);
  36. void SetAngle(int angle);
  37. virtual int width() const;
  38. virtual int height() const;
  39. virtual void SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue);
  40. virtual void Clear();
  41. virtual void Fill(uint8_t red, uint8_t green, uint8_t blue);
  42. private:
  43. Canvas *delegatee_;
  44. int angle_;
  45. };
  46. RotateTransformer::TransformCanvas::TransformCanvas(int angle)
  47. : delegatee_(NULL) {
  48. SetAngle(angle);
  49. }
  50. void RotateTransformer::TransformCanvas::SetDelegatee(Canvas* delegatee) {
  51. delegatee_ = delegatee;
  52. }
  53. void RotateTransformer::TransformCanvas::SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
  54. switch (angle_) {
  55. case 0:
  56. delegatee_->SetPixel(x, y, red, green, blue);
  57. break;
  58. case 90:
  59. delegatee_->SetPixel(delegatee_->width() - y - 1, x,
  60. red, green, blue);
  61. break;
  62. case 180:
  63. delegatee_->SetPixel(delegatee_->width() - x - 1,
  64. delegatee_->height() - y - 1,
  65. red, green, blue);
  66. break;
  67. case 270:
  68. delegatee_->SetPixel(y, delegatee_->height() - x - 1, red, green, blue);
  69. break;
  70. }
  71. }
  72. int RotateTransformer::TransformCanvas::width() const {
  73. return (angle_ % 180 == 0) ? delegatee_->width() : delegatee_->height();
  74. }
  75. int RotateTransformer::TransformCanvas::height() const {
  76. return (angle_ % 180 == 0) ? delegatee_->height() : delegatee_->width();
  77. }
  78. void RotateTransformer::TransformCanvas::Clear() {
  79. delegatee_->Clear();
  80. }
  81. void RotateTransformer::TransformCanvas::Fill(uint8_t red, uint8_t green, uint8_t blue) {
  82. delegatee_->Fill(red, green, blue);
  83. }
  84. void RotateTransformer::TransformCanvas::SetAngle(int angle) {
  85. assert(angle % 90 == 0); // We currenlty enforce that for more pretty output
  86. angle_ = (angle + 360) % 360;
  87. }
  88. /**********************/
  89. /* Rotate Transformer */
  90. /**********************/
  91. RotateTransformer::RotateTransformer(int angle)
  92. : angle_(angle), canvas_(new TransformCanvas(angle)) {
  93. }
  94. RotateTransformer::~RotateTransformer() {
  95. delete canvas_;
  96. }
  97. Canvas *RotateTransformer::Transform(Canvas *output) {
  98. assert(output != NULL);
  99. canvas_->SetDelegatee(output);
  100. return canvas_;
  101. }
  102. void RotateTransformer::SetAngle(int angle) {
  103. canvas_->SetAngle(angle);
  104. angle_ = angle;
  105. }
  106. /**********************/
  107. /* Linked Transformer */
  108. /**********************/
  109. void LinkedTransformer::AddTransformer(CanvasTransformer *transformer) {
  110. list_.push_back(transformer);
  111. }
  112. void LinkedTransformer::AddTransformer(List transformer_list) {
  113. list_.insert(list_.end(), transformer_list.begin(), transformer_list.end());
  114. }
  115. void LinkedTransformer::SetTransformer(List transformer_list) {
  116. list_ = transformer_list;
  117. }
  118. Canvas *LinkedTransformer::Transform(Canvas *output) {
  119. for (size_t i = 0; i < list_.size(); ++i) {
  120. output = list_[i]->Transform(output);
  121. }
  122. return output;
  123. }
  124. void LinkedTransformer::DeleteTransformers() {
  125. for (size_t i = 0; i < list_.size(); ++i) {
  126. delete list_[i];
  127. }
  128. list_.clear();
  129. }
  130. // U-Arrangement Transformer.
  131. class UArrangementTransformer::TransformCanvas : public Canvas {
  132. public:
  133. TransformCanvas(int parallel) : parallel_(parallel), delegatee_(NULL) {}
  134. void SetDelegatee(Canvas* delegatee);
  135. virtual void Clear();
  136. virtual void Fill(uint8_t red, uint8_t green, uint8_t blue);
  137. virtual int width() const { return width_; }
  138. virtual int height() const { return height_; }
  139. virtual void SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue);
  140. private:
  141. const int parallel_;
  142. int width_;
  143. int height_;
  144. int panel_height_;
  145. Canvas *delegatee_;
  146. };
  147. void UArrangementTransformer::TransformCanvas::SetDelegatee(Canvas* delegatee) {
  148. delegatee_ = delegatee;
  149. width_ = (delegatee->width() / 64) * 32; // Div in middle at 32px boundary
  150. height_ = 2 * delegatee->height();
  151. if (delegatee->width() % 64 != 0) {
  152. fprintf(stderr, "An U-arrangement would need an even number of panels "
  153. "unless you can fold one in the middle...\n");
  154. }
  155. if (delegatee->height() % parallel_ != 0) {
  156. fprintf(stderr, "For parallel=%d we would expect the height=%d to be "
  157. "divisible by %d ??\n", parallel_, delegatee->height(), parallel_);
  158. assert(false);
  159. }
  160. panel_height_ = delegatee->height() / parallel_;
  161. }
  162. void UArrangementTransformer::TransformCanvas::Clear() {
  163. delegatee_->Clear();
  164. }
  165. void UArrangementTransformer::TransformCanvas::Fill(
  166. uint8_t red, uint8_t green, uint8_t blue) {
  167. delegatee_->Fill(red, green, blue);
  168. }
  169. void UArrangementTransformer::TransformCanvas::SetPixel(
  170. int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
  171. if (x < 0 || x >= width_ || y < 0 || y >= height_) return;
  172. const int slab_height = 2*panel_height_; // one folded u-shape
  173. const int base_y = (y / slab_height) * panel_height_;
  174. y %= slab_height;
  175. if (y < panel_height_) {
  176. x += delegatee_->width() / 2;
  177. } else {
  178. x = width_ - x - 1;
  179. y = slab_height - y - 1;
  180. }
  181. delegatee_->SetPixel(x, base_y + y, red, green, blue);
  182. }
  183. UArrangementTransformer::UArrangementTransformer(int parallel)
  184. : canvas_(new TransformCanvas(parallel)) {
  185. assert(parallel > 0);
  186. }
  187. UArrangementTransformer::~UArrangementTransformer() {
  188. delete canvas_;
  189. }
  190. Canvas *UArrangementTransformer::Transform(Canvas *output) {
  191. assert(output != NULL);
  192. canvas_->SetDelegatee(output);
  193. return canvas_;
  194. }
  195. // Legacly LargeSquare64x64Transformer: uses the UArrangementTransformer, but
  196. // does things so that it looks the same as before.
  197. LargeSquare64x64Transformer::LargeSquare64x64Transformer()
  198. : arrange_(1), rotated_(180) { }
  199. Canvas *LargeSquare64x64Transformer::Transform(Canvas *output) {
  200. return rotated_.Transform(arrange_.Transform(output));
  201. }
  202. } // namespace rgb_matrix
  203. #endif // REMOVE_DEPRECATED_TRANSFORMERS