logo.cc
Go to the documentation of this file.
1 /*
2  * Roboception GmbH
3  * Munich, Germany
4  * www.roboception.com
5  *
6  * Copyright (c) 2024 Roboception GmbH
7  * All rights reserved
8  *
9  * Author: Heiko Hirschmueller
10  */
11 
12 #include "logo.h"
13 
14 #include "resources/logo_128.xpm"
15 
16 #include <FL/Fl_Pixmap.H>
17 #include <FL/Fl_RGB_Image.H>
18 #include <FL/fl_draw.H>
19 
20 #include <algorithm>
21 #include <cmath>
22 
23 namespace
24 {
25 
26 void timerCb(void *user_data)
27 {
28  Logo *logo=reinterpret_cast<Logo *>(user_data);
29  logo->nextRotation();
30 
31  Fl::repeat_timeout(0.1, timerCb, user_data);
32 }
33 
34 }
35 
36 Logo::Logo(int x, int y, int w, int h) : Fl_Box(x, y, w, h, 0)
37 {
38  Fl_Pixmap icon_xpm(logo_128_xpm);
39 
40  image_orig=new Fl_RGB_Image(&icon_xpm, FL_GRAY);
42 
43  spinning=false;
44  rotation=0;
45 }
46 
48 {
49  Fl::remove_timeout(timerCb, this);
50 
51  delete image_orig;
52  delete image;
53 }
54 
56 {
57  // start spinning if not done already
58 
59  if (!spinning)
60  {
61  spinning=true;
62  Fl::add_timeout(0.1, timerCb, this);
63  }
64 }
65 
67 {
68  if (spinning)
69  {
70  Fl::remove_timeout(timerCb, this);
71  spinning=false;
72 
73  rotation=0;
74  delete image;
76 
77  redraw();
78  }
79 }
80 
82 {
83  rotation+=0.157;
84 
85  delete image;
87 
88  redraw();
89 }
90 
91 void Logo::draw()
92 {
93  fl_rectf(x(), y(), w(), h(), color());
94 
95  if (image)
96  {
97  // draw image in the middle
98 
99  int xx=x()+(w()-image->w())/2;
100  int yy=y()+(h()-image->h())/2;
101 
102  image->draw(xx, yy);
103  }
104 }
105 
106 namespace
107 {
108 
109 inline void addPixel(double tp[4], const uchar *pixel, int i, int k, int depth, int ld, double scale)
110 {
111  const uchar *p=pixel+(k*ld+i*depth);
112 
113  for (int d=0; d<depth; d++)
114  {
115  tp[d]+=p[d] * scale;
116  }
117 }
118 
119 }
120 
121 Fl_RGB_Image *Logo::copyScaledRotated(const Fl_RGB_Image *image, int width, int height, double a)
122 {
123  // create target pixel array
124 
125  int depth=image->d();
126  int line=std::max(image->ld(), image->w()*image->d());
127  uchar *pixel=new uchar [width*height*depth];
128 
129  // scale factors
130 
131  double sx=static_cast<double>(image->w())/width;
132  double sy=static_cast<double>(image->h())/height;
133 
134  double xc=image->w()/2.0;
135  double yc=image->h()/2.0;
136 
137  double ca=std::cos(a);
138  double sa=std::sin(a);
139 
140  // get background color for filling out of bound pixel
141 
142  uchar bg[]={0, 0, 0, 0};
143 
144  {
145  unsigned background=Fl::get_color(FL_BACKGROUND_COLOR);
146 
147  bg[0]=static_cast<uchar>(background>>24);
148  bg[1]=static_cast<uchar>(background>>16);
149  bg[2]=static_cast<uchar>(background>>8);
150  bg[3]=static_cast<uchar>(background);
151  }
152 
153  // go through target pixels
154 
155  uchar *tp=pixel;
156  for (int k=0; k<height; k++)
157  {
158  for (int i=0; i<width; i++)
159  {
160  // scale target pixel position to source
161 
162  double x=sx*(i+0.5);
163  double y=sy*(k+0.5);
164 
165  // rotate position around image center
166 
167  if (a != 0)
168  {
169  x-=xc;
170  y-=yc;
171 
172  double tx = x*ca + y*sa;
173  double ty = -x*sa + y*ca;
174 
175  x=tx+xc;
176  y=ty+yc;
177  }
178 
179  // get source pixel value bilinearly interpolated and store as target pixel
180 
181  if (x >= 0 && y >= 0 && x+1 < image->w() && y+1 < image->h())
182  {
183  x-=0.5;
184  y-=0.5;
185 
186  x=std::max(0.0, std::min(x, image->w()-1.001));
187  y=std::max(0.0, std::min(y, image->h()-1.001));
188 
189  int si=static_cast<int>(x);
190  int sk=static_cast<int>(y);
191 
192  x=4*(x-si);
193  y=4*(y-sk);
194 
195  double p[4]={0, 0, 0, 0};
196 
197  addPixel(p, image->array, si, sk, depth, line, (4-x)*(4-y));
198  addPixel(p, image->array, si+1, sk, depth, line, x*(4-y));
199  addPixel(p, image->array, si, sk+1, depth, line, (4-x)*y);
200  addPixel(p, image->array, si+1, sk+1, depth, line, x*y);
201 
202  for (int d=0; d<depth; d++)
203  {
204  tp[d]=static_cast<uchar>(0.0625*p[d]);
205  }
206  }
207  else
208  {
209  for (int d=0; d<depth; d++)
210  {
211  tp[d]=bg[d];
212  }
213  }
214 
215  tp+=depth;
216  }
217  }
218 
219  // create and return target image
220 
221  Fl_RGB_Image *ret=new Fl_RGB_Image(pixel, width, height, depth, width*depth);
222  ret->alloc_array=1; // p is deleted by the newly created image
223 
224  return ret;
225 }
Logo::rotation
double rotation
Definition: logo.h:40
Logo
Definition: logo.h:19
Logo::copyScaledRotated
Fl_RGB_Image * copyScaledRotated(const Fl_RGB_Image *image, int width, int height, double a)
Definition: logo.cc:121
Logo::draw
void draw()
Definition: logo.cc:91
Logo::image
Fl_RGB_Image * image
Definition: logo.h:37
Logo::nextRotation
void nextRotation()
Definition: logo.cc:81
Logo::image_orig
Fl_RGB_Image * image_orig
Definition: logo.h:36
Logo::startSpinning
void startSpinning()
Definition: logo.cc:55
Logo::Logo
Logo(int x, int y, int w, int h)
Definition: logo.cc:36
Logo::stopSpinning
void stopSpinning()
Definition: logo.cc:66
logo.h
Logo::~Logo
~Logo()
Definition: logo.cc:47
Logo::spinning
bool spinning
Definition: logo.h:39


rcdiscover
Author(s): Heiko Hirschmueller , Raphael Schaller
autogenerated on Thu Aug 1 2024 02:55:56