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.
43 paraVSpace = 6; // default gap for drawPara
45 backgroundColourSet = false;
49 Log::getInstance()->log("Boxx", Log::DEBUG, "Construct, now %u", numBoxxes);
54 if (surface) delete surface;
56 Log::getInstance()->log("Boxx", Log::DEBUG, "Destruct, now %u", numBoxxes);
61 //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p", this, surface);
62 if (backgroundColourSet) fillColour(backgroundColour);
65 vector<Boxx*>::iterator j;
67 for (j = children.begin(); j != children.end(); j++)
70 // Log::getInstance()->log("Boxx", Log::DEBUG, "Draw child %d %d", count,currentBoxx);
71 if (currentBoxx->getVisible()) currentBoxx->draw();
74 // Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p End", this, surface);
77 void Boxx::setSize(UINT w, UINT h)
83 void Boxx::setPosition(UINT x, UINT y)
89 void Boxx::createBuffer()
91 surface = Osd::getInstance()->createNewSurface();
92 surface->create(area.w, area.h);
95 void Boxx::add(Boxx* newChild)
97 newChild->setParent(this);
98 children.push_back(newChild);
101 void Boxx::remove(Boxx* oldChild)
103 for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
111 Log::getInstance()->log("Boxx", Log::ERR, "Remove child box called, child %p not found", oldChild);
114 bool Boxx::overlapsVisibleChilds(Region & r)
116 for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
118 if ((*i)->getVisible() && r.intersects((*i)->getRegionR()))
126 void Boxx::setParent(Boxx* newParent)
131 void Boxx::setBackgroundColour(const DrawStyle& Tcolour)
133 backgroundColour = Tcolour;
134 backgroundColourSet = true;
137 void Boxx::setVisible(bool isVisible)
142 bool Boxx::getVisible()
147 void Boxx::setGap(UINT gap)
152 void Boxx::blt(Region& r)
154 /* surface update to screen needs:
155 source x distance into this surface
156 source y distance into this surface
159 destination x on screen
160 destination y on screen
163 if (parent) abort(); // if (parent) then this is a child boxx. It can not blt.
165 // this shouldn't be here
169 surface->updateToScreen(r.x, r.y, r.w, r.h, area.x + r.x, area.y + r.y);
173 int Boxx::getScreenX()
175 if (parent) return area.x + parent->getScreenX();
179 int Boxx::getScreenY()
181 if (parent) return area.y + parent->getScreenY();
185 int Boxx::getRootBoxOffsetX() // convert this to be getX and silently do the parent/not thing? same for Y below?
187 if (parent) return area.x + parent->getRootBoxOffsetX();
191 int Boxx::getRootBoxOffsetY()
193 if (parent) return area.y + parent->getRootBoxOffsetY();
209 return area.x + area.w;
214 return area.y + area.h;
217 UINT Boxx::getWidth()
222 UINT Boxx::getHeight()
227 // FIXME Clean up the code to use just one of the following
229 Region* Boxx::getRegion()
234 Region Boxx::getRegionR()
239 void Boxx::getRootBoxRegion(Region* r)
241 // Returns a region that describes the position of this box on the box with the surface
242 // To be used for boxstack->update calls
244 r->x = getRootBoxOffsetX();
245 r->y = getRootBoxOffsetY();
250 // Level 1 drawing functions
252 void Boxx::fillColour(const DrawStyle& colour)
254 rectangle(0, 0, area.w, area.h, colour);
257 int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsigned int skiplines)
260 int lineHeight = getFontHeight() + paraVSpace;
270 int drawLinePos=-skiplines;
275 tester.h = lineHeight;
277 bool haschildren = true;
278 if ( children.size() == 0) haschildren = false;
289 wchar_t cur_char = getWChar(text + textPos, &cur_length);
291 if (cur_char == '\0') break;
293 if (cur_char == '\n')
295 textPos += cur_length; // ignore the \n
299 thisCharWidth = charWidth(cur_char);
300 tester.x = lineWidth;
301 tester.w = thisCharWidth + 10;
303 if ((lineWidth + thisCharWidth) > (int)(area.w - (2 * paraMargin))
304 || (haschildren && overlapsVisibleChilds(tester)))
306 // this character would break the right margin
309 // this char is a space, ignore and break
310 textPos += cur_length;
315 // Need to go back to the last space in the line
316 while ((cur_char != ' ') && (linePos >= 0))
318 textPos -= cur_length;
319 cur_char = getWChar(text + textPos, &cur_length);
322 // Now take the space we just found
323 textPos += cur_length;
327 for (UINT n = 0; n < cur_length; n++) line[linePos++] = text[textPos + n];
328 lineWidth += thisCharWidth;
329 textPos += cur_length;
332 // line[linePos++] = '\0';
333 if (linePos >= 0) line[linePos++] = '\0'; //Here is the change
335 if (printLine || (linePos > 1)) // if some text was put in line
337 if (ypos <= (int)(area.h - lineHeight + paraVSpace)) {
338 if (drawLinePos >= 0) {
339 drawText(line, x, ypos, colour);
355 void Boxx::rectangle(Region& region, const DrawStyle& colour)
357 rectangle(region.x, region.y, region.w, region.h, colour);
360 // Level 0 drawing functions
362 void Boxx::rectangle(UINT x, UINT y, UINT w, UINT h, const DrawStyle& colour)
364 if (parent) parent->rectangle(area.x + x, area.y + y, w, h, colour);
365 else surface->fillblt(x, y, w, h, colour);
368 void Boxx::drawText(const char* text, int x, int y, const DrawStyle& colour)
370 if (parent) parent->drawText(text, area.x + x, area.y + y, colour);
371 else surface->drawText(text, x, y, colour);
374 void Boxx::drawText(const char* text, int x, int y, int width, const DrawStyle& colour)
376 if (parent) parent->drawText(text, area.x + x, area.y + y, width, colour);
377 else surface->drawText(text, x, y, width, colour);
380 void Boxx::drawTextRJ(const char* text, int x, int y, const DrawStyle& colour)
382 if (parent) parent->drawTextRJ(text, area.x + x, area.y + y, colour);
383 else surface->drawTextRJ(text, x, y, colour);
386 void Boxx::drawTextCentre(const char* text, int x, int y, const DrawStyle& colour)
388 if (parent) parent->drawTextCentre(text, area.x + x, area.y + y, colour);
389 else surface->drawTextCentre(text, x, y, colour);
393 void Boxx::drawPixelAlpha(UINT x, UINT y, const Colour& colour,bool fastdraw)
395 if (parent) parent->drawPixelAlpha(area.x + x, area.y + y, colour,fastdraw);
398 int c = ( (colour.alpha << 24 )
400 | (colour.green << 8)
403 surface->drawPixel(x, y, c,fastdraw);
407 void Boxx::drawPixel(UINT x, UINT y, const Colour& colour, bool fastdraw)
409 if (parent) parent->drawPixel(area.x + x, area.y + y, colour,fastdraw);
412 int c = ( (0xFF000000 )
414 | (colour.green << 8)
417 surface->drawPixel(x, y, c,fastdraw);
422 void Boxx::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
424 if (parent) parent->drawTTChar(area.x + ox, area.y + oy, x,y,c);
425 else if (surface) surface->drawTTChar(ox, oy,x,y,c);
429 void Boxx::drawBitmap(UINT x, UINT y, const Bitmap& bm, const DisplayRegion & region)
431 if (parent) parent->drawBitmap(area.x + x, area.y + y, bm, region);
432 else if (surface) surface->drawBitmap(x, y, bm, region);
435 void Boxx::drawJpeg(const char *fileName, int x, int y, int *width, int *height)
437 if (parent) parent->drawJpeg(fileName, area.x + x, area.y + y, width, height);
438 else if (surface) surface->drawJpeg(fileName, x, y, width, height);
441 void Boxx::drawMonoBitmap(UCHAR*base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
443 if (parent) parent->drawMonoBitmap(base, area.x +dx, area.y + dy, height, width, nextColour);
444 else if (surface) surface->drawMonoBitmap(base, dx,dy, height, width, nextColour);
447 void Boxx::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner)
449 if (parent) parent->drawTVMedia(tvmedia,area.x + x,area.y + y,width, height, corner);
451 SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
452 if (surfacevector) surfacevector->drawTVMedia(tvmedia,x, y,width, height, corner);
453 else surface->fillblt(x, y, width, height, DrawStyle::RED); // Signal that something went wrong
458 void Boxx::drawClippingRectangle(float x, float y, float w, float h)
460 if (parent) parent->drawClippingRectangle(area.x + x, area.y + y, w, h);
462 SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
463 if (surfacevector) surfacevector->drawClippingRectangle(x, y, w, h);
468 int Boxx::getFontHeight()
470 if (parent) return parent->getFontHeight();
471 else if (surface) return surface->getFontHeight();
475 void Boxx::startFastDraw()
479 parent->startFastDraw();
483 if (surface) surface->startFastDraw();
487 void Boxx::endFastDraw()
491 parent->endFastDraw();
495 if (surface) surface->endFastDraw();
499 float Boxx::charWidth(wchar_t c)
501 if (parent) return parent->charWidth(c);
502 else if (surface) return surface->getCharWidth(c);
506 wchar_t Boxx::getWChar(const char* str, UINT *length)
508 if (parent) return parent->getWChar(str, length);
509 else if (surface) return surface->getWChar(str, length);
513 Surface* Boxx::getSurface()
515 if (parent) return parent->getSurface();