2 Copyright 2007 Chris Tallon
4 This file is part of VOMP.
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.
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.
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.
29 #include "surfacevector.h"
30 char Boxx::numBoxxes = 0;
34 // I want a parent box or a surface.
45 paraVSpace = 6; // default gap for drawPara
47 backgroundColourSet = false;
51 Log::getInstance()->log("Boxx", Log::DEBUG, "Construct, now %u", numBoxxes);
56 if (surface) delete surface;
58 Log::getInstance()->log("Boxx", Log::DEBUG, "Destruct, now %u", numBoxxes);
63 //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p", this, surface);
64 if (backgroundColourSet) fillColour(backgroundColour);
67 vector<Boxx*>::iterator j;
69 for (j = children.begin(); j != children.end(); j++)
72 //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw child %d %d %s", count,currentBoxx,typeid(*currentBoxx).name());
73 if (currentBoxx->getVisible()) currentBoxx->draw();
74 //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw child %d %d end", count,currentBoxx);
77 // Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p End", this, surface);
80 void Boxx::setSize(UINT w, UINT h)
86 void Boxx::setPosition(UINT x, UINT y)
92 void Boxx::createBuffer()
94 surface = Osd::getInstance()->createNewSurface();
95 surface->create(area.w, area.h);
98 void Boxx::add(Boxx* newChild)
100 newChild->setParent(this);
101 children.push_back(newChild);
104 void Boxx::remove(Boxx* oldChild)
106 for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
114 Log::getInstance()->log("Boxx", Log::ERR, "Remove child box called, child %p not found", oldChild);
117 void Boxx::removeVisibleChilds(Region & r)
119 for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
121 if ((*i)->getVisible())
123 Region temp=(*i)->getRegionR();
124 if (r.intersects(temp)) {
131 void Boxx::setParent(Boxx* newParent)
136 void Boxx::setBackgroundColour(const DrawStyle& Tcolour)
138 backgroundColour = Tcolour;
139 backgroundColourSet = true;
142 void Boxx::setVideoBackground()
144 vdisplay.mode=Window;
145 vdisplay.fallbackMode=Fullscreen;
146 vdisplay.x=getScreenX();
147 vdisplay.y=getScreenY();
148 vdisplay.width=getWidth();
149 vdisplay.height=getHeight();
152 void Boxx::setVisible(bool isVisible)
157 bool Boxx::getVisible()
162 void Boxx::setGap(UINT gap)
167 void Boxx::blt(Region& r)
169 /* surface update to screen needs:
170 source x distance into this surface
171 source y distance into this surface
174 destination x on screen
175 destination y on screen
178 if (parent) abort(); // if (parent) then this is a child boxx. It can not blt.
180 // this shouldn't be here
184 surface->updateToScreen(r.x, r.y, r.w, r.h, area.x + r.x, area.y + r.y);
188 int Boxx::getScreenX()
190 if (parent) return area.x + parent->getScreenX();
194 int Boxx::getScreenY()
196 if (parent) return area.y + parent->getScreenY();
200 int Boxx::getRootBoxOffsetX() // convert this to be getX and silently do the parent/not thing? same for Y below?
202 if (parent) return area.x + parent->getRootBoxOffsetX();
206 int Boxx::getRootBoxOffsetY()
208 if (parent) return area.y + parent->getRootBoxOffsetY();
224 return area.x + area.w;
229 return area.y + area.h;
232 UINT Boxx::getWidth()
237 UINT Boxx::getHeight()
242 // FIXME Clean up the code to use just one of the following
244 Region* Boxx::getRegion()
249 Region Boxx::getRegionR()
254 void Boxx::getRootBoxRegion(Region* r)
256 // Returns a region that describes the position of this box on the box with the surface
257 // To be used for boxstack->update calls
259 r->x = getRootBoxOffsetX();
260 r->y = getRootBoxOffsetY();
265 bool Boxx::getVideoDisplay(VideoDisplay &vd)
267 for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
269 if ((*i)->getVideoDisplay(vd)) return true;
272 if (vdisplay.mode==None) return false;
277 // Level 1 drawing functions
279 void Boxx::fillColour(const DrawStyle& colour)
281 rectangle(0, 0, area.w, area.h, colour);
284 int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsigned int skiplines)
287 int lineHeight = getFontHeight() + paraVSpace;
297 int drawLinePos=-skiplines;
300 textLength = strlen(text);
305 bool haschildren = true;
306 if ( children.size() == 0) haschildren = false;
308 Osd *osd=Osd::getInstance();
309 if (osd->charSet()!=1) mchar=true;
310 OsdVector *osdv=dynamic_cast<OsdVector*>(osd);
311 float *charwidtharray=NULL;
312 if (osdv) charwidtharray=osdv->getCharWidthArray();
315 memset((void*)&state,0,sizeof(state));
322 tester.h = lineHeight;
325 tester.w = area.w - (2 * paraMargin);
327 if (haschildren) removeVisibleChilds(tester);
334 if (*(text + textPos) == '\0') break;
336 cur_length = mbrtowc(&cur_char, text + textPos, textLength-textPos, &state);
337 if (cur_length <= 0){
341 } else cur_char= *(text + textPos);
344 if (cur_char == '\0') break;
346 if (cur_char == '\n')
348 textPos += cur_length; // ignore the \n
352 if (charwidtharray) {
353 thisCharWidth=charwidtharray[cur_char & 0xFF];
354 if (cur_char && 0xFFFFFF00) thisCharWidth=osdv->getCharWidth(cur_char);
355 } else thisCharWidth = charWidth(cur_char);
361 if ((lineWidth + thisCharWidth + x) > tester.w)
363 // this character would break the right margin
366 // this char is a space, ignore and break
367 textPos += cur_length;
372 // Need to go back to the last space in the line
373 while ((cur_char != ' ') && (linePos >= 0))
375 textPos -= cur_length;
377 cur_length = mbrtowc(&cur_char, text + textPos, textLength-textPos, &state);
378 if (cur_length <= 0){
382 } else cur_char= *(text + textPos);
385 // Now take the space we just found
386 textPos += cur_length;
390 for (int n = 0; n < cur_length; n++) line[linePos++] = text[textPos + n];
391 lineWidth += thisCharWidth;
392 textPos += cur_length;
395 // line[linePos++] = '\0';
396 if (linePos >= 0) line[linePos++] = '\0'; //Here is the change
398 if (printLine || (linePos > 1)) // if some text was put in line
400 if (ypos <= (int)(area.h - lineHeight + paraVSpace)) {
401 if (drawLinePos >= 0) {
402 drawText(line, x, ypos, colour);
418 void Boxx::rectangle(Region& region, const DrawStyle& colour)
420 rectangle(region.x, region.y, region.w, region.h, colour);
423 // Level 0 drawing functions
425 void Boxx::rectangle(UINT x, UINT y, UINT w, UINT h, const DrawStyle& colour)
427 if (parent) parent->rectangle(area.x + x, area.y + y, w, h, colour);
428 else surface->fillblt(x, y, w, h, colour);
431 void Boxx::drawText(const char* text, int x, int y, const DrawStyle& colour)
433 if (parent) parent->drawText(text, area.x + x, area.y + y, colour);
434 else surface->drawText(text, x, y, colour);
437 void Boxx::drawText(const char* text, int x, int y, int width, const DrawStyle& colour)
439 if (parent) parent->drawText(text, area.x + x, area.y + y, width, colour);
440 else surface->drawText(text, x, y, width, colour);
443 void Boxx::drawTextRJ(const char* text, int x, int y, const DrawStyle& colour)
445 if (parent) parent->drawTextRJ(text, area.x + x, area.y + y, colour);
446 else surface->drawTextRJ(text, x, y, colour);
449 void Boxx::drawTextCentre(const char* text, int x, int y, const DrawStyle& colour)
451 if (parent) parent->drawTextCentre(text, area.x + x, area.y + y, colour);
452 else surface->drawTextCentre(text, x, y, colour);
456 void Boxx::drawPixelAlpha(UINT x, UINT y, const Colour& colour,bool fastdraw)
458 if (parent) parent->drawPixelAlpha(area.x + x, area.y + y, colour,fastdraw);
461 int c = ( (colour.alpha << 24 )
463 | (colour.green << 8)
466 surface->drawPixel(x, y, c,fastdraw);
470 void Boxx::drawPixel(UINT x, UINT y, const Colour& colour, bool fastdraw)
472 if (parent) parent->drawPixel(area.x + x, area.y + y, colour,fastdraw);
475 int c = ( (0xFF000000 )
477 | (colour.green << 8)
480 surface->drawPixel(x, y, c,fastdraw);
485 void Boxx::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
487 if (parent) parent->drawTTChar(area.x + ox, area.y + oy, x,y,c);
488 else if (surface) surface->drawTTChar(ox, oy,x,y,c);
492 void Boxx::drawBitmap(UINT x, UINT y, const Bitmap& bm, const DisplayRegion & region)
494 if (parent) parent->drawBitmap(area.x + x, area.y + y, bm, region);
495 else if (surface) surface->drawBitmap(x, y, bm, region);
498 void Boxx::drawJpeg(const char *fileName, int x, int y, int *width, int *height)
500 if (parent) parent->drawJpeg(fileName, area.x + x, area.y + y, width, height);
501 else if (surface) surface->drawJpeg(fileName, x, y, width, height);
504 void Boxx::drawMonoBitmap(UCHAR*base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
506 if (parent) parent->drawMonoBitmap(base, area.x +dx, area.y + dy, height, width, nextColour);
507 else if (surface) surface->drawMonoBitmap(base, dx,dy, height, width, nextColour);
510 void Boxx::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner)
512 if (parent) parent->drawTVMedia(tvmedia,area.x + x,area.y + y,width, height, corner);
514 SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
515 if (surfacevector) surfacevector->drawTVMedia(tvmedia,x, y,width, height, corner);
516 else surface->fillblt((int)x, (int)y, (int)width, (int)height, DrawStyle::RED); // Signal that something went wrong
521 void Boxx::drawClippingRectangle(float x, float y, float w, float h)
523 if (parent) parent->drawClippingRectangle(area.x + x, area.y + y, w, h);
525 SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
526 if (surfacevector) surfacevector->drawClippingRectangle(x, y, w, h);
531 int Boxx::getFontHeight()
533 if (parent) return parent->getFontHeight();
534 else if (surface) return surface->getFontHeight();
538 void Boxx::startFastDraw()
542 parent->startFastDraw();
546 if (surface) surface->startFastDraw();
550 void Boxx::endFastDraw()
554 parent->endFastDraw();
558 if (surface) surface->endFastDraw();
562 float Boxx::charWidth(wchar_t c)
564 if (parent) return parent->charWidth(c);
565 else if (surface) return surface->getCharWidth(c);
570 Surface* Boxx::getSurface()
572 if (parent) return parent->getSurface();
576 bool Boxx::mouseMove(int x, int y)
578 if ((x >= (int)area.x) && (x<(int)area.x2())
579 && (y >= (int)area.y) && (y < (int)area.y2()))
589 bool Boxx::mouseLBDOWN(int x, int y)
591 if ((x >= (int)area.x) && (x<(int)area.x2())
592 && (y >= (int)area.y) && (y < (int)area.y2()))