]> git.vomp.tv Git - vompclient.git/blob - boxx.cc
Optimizations in OMX handling towards accelerated image decoding, not working, but...
[vompclient.git] / boxx.cc
1 /*
2     Copyright 2007 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include <stdlib.h>
22
23 #include "defines.h"
24 #include "bitmap.h"
25 #include "log.h"
26 #include "osd.h"
27
28 #include "boxx.h"
29 #include "surfacevector.h"
30 char Boxx::numBoxxes = 0;
31
32 Boxx::Boxx()
33 {
34   // I want a parent box or a surface.
35   parent = NULL;
36   surface = NULL;
37
38   area.x = 0;
39   area.y = 0;
40   area.w = 0;
41   area.h = 0;
42
43   paraVSpace = 6; // default gap for drawPara
44
45   backgroundColourSet = false;
46   visible = true;
47
48   numBoxxes++;
49   Log::getInstance()->log("Boxx", Log::DEBUG, "Construct, now %u", numBoxxes);
50 }
51
52 Boxx::~Boxx()
53 {
54   if (surface) delete surface;
55   numBoxxes--;
56   Log::getInstance()->log("Boxx", Log::DEBUG, "Destruct, now %u", numBoxxes);
57 }
58
59 void Boxx::draw()
60 {
61   //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p", this, surface);
62   if (backgroundColourSet) fillColour(backgroundColour);
63
64   Boxx* currentBoxx;
65   vector<Boxx*>::iterator j;
66   //int count=0;
67   for (j = children.begin(); j != children.end(); j++)
68   {
69     currentBoxx = *j;
70    // Log::getInstance()->log("Boxx", Log::DEBUG, "Draw child %d %d", count,currentBoxx);
71     if (currentBoxx->getVisible()) currentBoxx->draw();
72    // count++;
73   }  
74  // Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p End", this, surface);
75 }
76
77 void Boxx::setSize(UINT w, UINT h)
78 {
79   area.w = w;
80   area.h = h;
81 }
82
83 void Boxx::setPosition(UINT x, UINT y)
84 {
85   area.x = x;
86   area.y = y;
87 }
88
89 void Boxx::createBuffer()
90 {
91   surface = Osd::getInstance()->createNewSurface();
92   surface->create(area.w, area.h);
93 }
94
95 void Boxx::add(Boxx* newChild)
96 {
97   newChild->setParent(this);
98   children.push_back(newChild);
99 }
100
101 void Boxx::remove(Boxx* oldChild)
102 {
103   for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
104   {
105     if (*i == oldChild)
106     {
107       children.erase(i);
108       return;
109     }
110   }
111   Log::getInstance()->log("Boxx", Log::ERR, "Remove child box called, child %p not found", oldChild);
112 }
113
114 void Boxx::setParent(Boxx* newParent)
115 {
116   parent = newParent;
117 }
118
119 void Boxx::setBackgroundColour(const DrawStyle& Tcolour)
120 {
121   backgroundColour = Tcolour;
122   backgroundColourSet = true;
123 }
124
125 void Boxx::setVisible(bool isVisible)
126 {
127   visible = isVisible;
128 }
129
130 bool Boxx::getVisible()
131 {
132   return visible;
133 }
134
135 void Boxx::setGap(UINT gap)
136 {
137   paraVSpace = gap;
138 }
139
140 void Boxx::blt(Region& r)
141 {
142   /* surface update to screen needs:
143   source x distance into this surface
144   source y distance into this surface
145   width of update
146   height of update
147   destination x on screen
148   destination y on screen
149   */
150
151   if (parent) abort(); // if (parent) then this is a child boxx. It can not blt.
152
153   // this shouldn't be here
154   r.x -= area.x;
155   r.y -= area.y;
156
157   surface->updateToScreen(r.x, r.y, r.w, r.h, area.x + r.x, area.y + r.y);
158
159 }
160
161 int Boxx::getScreenX()
162 {
163   if (parent) return area.x + parent->getScreenX();
164   return area.x;
165 }
166
167 int Boxx::getScreenY()
168 {
169   if (parent) return area.y + parent->getScreenY();
170   return area.y;
171 }
172
173 int Boxx::getRootBoxOffsetX() // convert this to be getX and silently do the parent/not thing? same for Y below?
174 {
175   if (parent) return area.x + parent->getRootBoxOffsetX();
176   return 0;
177 }
178
179 int Boxx::getRootBoxOffsetY()
180 {
181   if (parent) return area.y + parent->getRootBoxOffsetY();
182   return 0;
183 }
184
185 int Boxx::getX()
186 {
187   return area.x;
188 }
189
190 int Boxx::getY()
191 {
192   return area.y;
193 }
194
195 int Boxx::getX2()
196 {
197   return area.x + area.w;
198 }
199
200 int Boxx::getY2()
201 {
202   return area.y + area.h;
203 }
204
205 UINT Boxx::getWidth()
206 {
207   return area.w;
208 }
209
210 UINT Boxx::getHeight()
211 {
212   return area.h;
213 }
214
215 // FIXME Clean up the code to use just one of the following
216
217 Region* Boxx::getRegion()
218 {
219   return &area;
220 }
221
222 Region Boxx::getRegionR()
223 {
224   return area;
225 }
226
227 void Boxx::getRootBoxRegion(Region* r)
228 {
229   // Returns a region that describes the position of this box on the box with the surface
230   // To be used for boxstack->update calls
231
232   r->x = getRootBoxOffsetX();
233   r->y = getRootBoxOffsetY();
234   r->w = area.w;
235   r->h = area.h;  
236 }
237
238 // Level 1 drawing functions
239
240 void Boxx::fillColour(const DrawStyle& colour)
241 {
242   rectangle(0, 0, area.w, area.h, colour);
243 }
244
245 int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsigned int skiplines)
246 {
247   char line[256];
248   int lineHeight = getFontHeight() + paraVSpace;
249
250   float lineWidth;
251   float thisCharWidth;
252   int textPos;
253   int linePos;
254   int ypos;
255   int printLine;
256   int leftlines=0;
257
258   int drawLinePos=-skiplines;
259
260   textPos = 0;
261   ypos = y;
262
263   while(1)
264   {
265     linePos = 0;
266     lineWidth = 0;
267     while(1)
268     {
269       printLine = 0;
270       UINT cur_length = 1;
271       wchar_t cur_char = getWChar(text + textPos, &cur_length);
272
273       if (cur_char == '\0') break;
274
275       if (cur_char == '\n')
276       {
277         textPos += cur_length; // ignore the \n
278         printLine = 1;
279         break;
280       }
281       thisCharWidth = charWidth(cur_char);
282       if ((lineWidth + thisCharWidth) > (int)(area.w - (2 * paraMargin)))
283       {
284         // this character would break the right margin
285         if (cur_char == ' ')
286         {
287           // this char is a space, ignore and break
288           textPos += cur_length;
289           break;
290         }
291         else
292         {
293           // Need to go back to the last space in the line
294           while ((cur_char != ' ') && (linePos >= 0))
295           {
296             textPos -= cur_length;
297             cur_char = getWChar(text + textPos, &cur_length);
298             linePos--;
299           }
300           // Now take the space we just found
301           textPos += cur_length;
302           break;
303         }
304       }
305       for (UINT n = 0; n < cur_length; n++) line[linePos++] = text[textPos + n];
306       lineWidth += thisCharWidth;
307       textPos += cur_length;
308     }
309
310 //    line[linePos++] = '\0';
311     if (linePos >= 0) line[linePos++] = '\0'; //Here is the change
312
313     if (printLine || (linePos > 1)) // if some text was put in line
314     {
315         if (ypos <= (int)(area.h - lineHeight + paraVSpace)) {
316                 if (drawLinePos >= 0) {
317                         drawText(line, x, ypos, colour);
318                         ypos += lineHeight;
319                 }
320         } else {
321                 leftlines++;
322         }
323       drawLinePos++;
324     }
325     else
326     {
327       break;
328     }
329   }
330   return leftlines;
331 }
332
333 void Boxx::rectangle(Region& region, const DrawStyle& colour)
334 {
335   rectangle(region.x, region.y, region.w, region.h, colour);
336 }
337
338 // Level 0 drawing functions
339
340 void Boxx::rectangle(UINT x, UINT y, UINT w, UINT h, const DrawStyle& colour)
341 {
342   if (parent) parent->rectangle(area.x + x, area.y + y, w, h, colour);
343   else surface->fillblt(x, y, w, h, colour);
344 }
345
346 void Boxx::drawText(const char* text, int x, int y, const DrawStyle& colour)
347 {
348   if (parent) parent->drawText(text, area.x + x, area.y + y, colour);
349   else surface->drawText(text, x, y, colour);
350 }
351
352 void Boxx::drawText(const char* text, int x, int y, int width, const DrawStyle& colour)
353 {
354   if (parent) parent->drawText(text, area.x + x, area.y + y, width, colour);
355   else surface->drawText(text, x, y, width, colour);
356 }
357
358 void Boxx::drawTextRJ(const char* text, int x, int y, const DrawStyle& colour)
359 {
360   if (parent) parent->drawTextRJ(text, area.x + x, area.y + y, colour);
361   else surface->drawTextRJ(text, x, y, colour);
362 }
363
364 void Boxx::drawTextCentre(const char* text, int x, int y, const DrawStyle& colour)
365 {
366   if (parent) parent->drawTextCentre(text, area.x + x, area.y + y, colour);
367   else  surface->drawTextCentre(text, x, y, colour);
368 }
369 // Now deprecated
370 /*
371 void Boxx::drawPixelAlpha(UINT x, UINT y, const Colour& colour,bool fastdraw)
372 {
373   if (parent) parent->drawPixelAlpha(area.x + x, area.y + y, colour,fastdraw);
374   else
375   {
376     int c = (  (colour.alpha << 24 )
377              | (colour.red    << 16)
378              | (colour.green  <<  8)
379              | (colour.blue        ) );
380
381     surface->drawPixel(x, y, c,fastdraw);
382   }
383 }
384
385 void Boxx::drawPixel(UINT x, UINT y, const Colour& colour, bool fastdraw)
386 {
387   if (parent) parent->drawPixel(area.x + x, area.y + y, colour,fastdraw);
388   else
389   {
390     int c = (  (0xFF000000         )
391              | (colour.red    << 16)
392              | (colour.green  <<  8)
393              | (colour.blue        ) );
394
395     surface->drawPixel(x, y, c,fastdraw);
396   }
397 }
398 */
399
400 void Boxx::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
401 {
402         if (parent) parent->drawTTChar(area.x + ox, area.y + oy, x,y,c);
403         else  if (surface) surface->drawTTChar(ox, oy,x,y,c);
404
405 }
406
407 void Boxx::drawBitmap(UINT x, UINT y, const Bitmap& bm, const DisplayRegion & region)
408 {
409   if (parent) parent->drawBitmap(area.x + x, area.y + y, bm, region);
410   else  if (surface) surface->drawBitmap(x, y, bm, region);
411 }
412
413 void Boxx::drawJpeg(const char *fileName, int x, int y, int *width, int *height)
414 {
415   if (parent) parent->drawJpeg(fileName, area.x + x, area.y + y, width, height);
416   else if (surface) surface->drawJpeg(fileName, x, y, width, height);
417 }
418
419 void Boxx::drawMonoBitmap(UCHAR*base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
420 {
421   if (parent) parent->drawMonoBitmap(base, area.x +dx, area.y + dy, height, width, nextColour);
422   else if (surface) surface->drawMonoBitmap(base, dx,dy, height, width, nextColour);
423 }
424
425 void Boxx::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float  width, float height, Corner corner)
426 {
427         if (parent) parent->drawTVMedia(tvmedia,area.x + x,area.y + y,width, height, corner);
428         else if (surface) {
429                 SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
430                 if (surfacevector) surfacevector->drawTVMedia(tvmedia,x, y,width, height, corner);
431                 else surface->fillblt(x, y, width, height, DrawStyle::RED); // Signal that something went wrong
432         }
433
434 }
435
436 void Boxx::drawClippingRectangle(float x, float y, float w, float h)
437 {
438         if (parent) parent->drawClippingRectangle(area.x + x, area.y + y, w, h);
439         else if (surface) {
440                 SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
441                 if (surfacevector) surfacevector->drawClippingRectangle(x, y, w, h);
442
443         }
444 }
445
446 int Boxx::getFontHeight()
447 {
448   if (parent) return parent->getFontHeight();
449   else if (surface) return surface->getFontHeight();
450   else return 18;
451 }
452
453 void Boxx::startFastDraw()
454 {
455   if (parent)
456   {
457     parent->startFastDraw();
458   }
459   else
460   {
461     if (surface) surface->startFastDraw();
462   }
463 }
464
465 void Boxx::endFastDraw()
466 {
467   if (parent)
468   {
469     parent->endFastDraw();
470   }
471   else
472   {
473     if (surface) surface->endFastDraw();
474   }
475 }
476
477 float Boxx::charWidth(wchar_t c)
478 {
479   if (parent) return parent->charWidth(c);
480   else if (surface) return surface->getCharWidth(c);
481   else return 16.; //?
482 }
483
484 wchar_t Boxx::getWChar(const char* str, UINT *length)
485 {
486   if (parent) return parent->getWChar(str, length);
487   else  if (surface) return surface->getWChar(str, length);
488   else return '?'; //?
489 }
490
491 Surface* Boxx::getSurface()
492 {
493   if (parent) return parent->getSurface();
494   return surface;
495 }