diff options
Diffstat (limited to 'displaybase.h')
-rw-r--r-- | displaybase.h | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/displaybase.h b/displaybase.h new file mode 100644 index 0000000..708689f --- /dev/null +++ b/displaybase.h @@ -0,0 +1,287 @@ +/*************************************************************************** + * * + * displaybase.h - Base class for rendering a teletext cRenderPage to * + * an actual VDR OSD. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * Changelog: * + * 2005-03 initial version (c) Udo Richter * + * * + ***************************************************************************/ + +#ifndef OSDTELETEXT_DISPLAYBASE_H_ +#define OSDTELETEXT_DISPLAYBASE_H_ + +#include "txtrender.h" +#include <vdr/osd.h> + +//#define timingdebug +// Enables some time measure debugging code + +#ifdef timingdebug + #include <sys/timeb.h> + + class cTime { + // Debugging: Simple class to measure time + timeb start; + public: + void Start() { + ftime(&start); + } + void Stop(char *txt) { + timeb t; + ftime(&t); + int s=t.time-start.time; + int ms=t.millitm-start.millitm; + if (ms<0) { + s--; + ms+=1000; + } + printf("%s: %i.%03i\n",txt,s,ms); + } + }; +#endif + + +class cDisplay : public cRenderPage { + // Class that extends the virtual cRenderPage with the capability + // to render its contents to an OSD of variable size. + // Renders incrementally - just changes + // plus adds some more display features like message display. + +public: + enum enumZoom { + // Zoom up upper/lower half of page + Zoom_Off, + Zoom_Upper, + Zoom_Lower + } Zoom; + +protected: + bool Concealed; + // Hidden text internal state + + bool Blinked; + // Blinking text internal state + + int FlushLock; + // Lock counter for bundeling OSD flushes + + bool Boxed; + // Page is 'boxed mode' transparent + + int Width; + int Height; + // OSD pixel dimension + + tColor Background; + // Color to be used for black background + // - allow transparency + + cOsd *osd; + // The osd object. If creation fails, may be NULL + + int ScaleX,ScaleY; + int OffsetX,OffsetY; + // Virtual coordinate system, see InitScaler + + const cFont *MessageFont; + int MessageX,MessageY,MessageW,MessageH; + // Message overlay window, position and font + + class cBox { + // helper class. Represents a character's box in virtual coordinates + public: + int XMin,YMin,XMax,YMax; + inline void SetToCharacter(int x, int y); + }; + friend class cBox; + + class cVirtualCoordinate { + // helper class. Represents a coordinate in virtual display space + // and in OSD pixel coordinates. + public: + int OsdX,OsdY; + int VirtX,VirtY; + inline void VirtualToPixel(cDisplay *Display, int x, int y); + inline void IncPixelX(cDisplay *Display); + inline void IncPixelY(cDisplay *Display); + }; + friend class cVirtualCoordinate; + +public: + cDisplay(int width, int height); + virtual ~cDisplay(); + bool Valid() { return (osd!=NULL); } + // After creation, check for Valid(). Destroy, if not valid. + +protected: + void InitScaler(); + // Initialize transformation for OSD->Virtual coordinates + // Some words about scaling: + + // OSD display is variable width x height, with 3 pixels border + // on all sides. There is a virtual coordinate system projected + // on this, with (3,3) mapped to (0,0) and (width-3,height-3) + // mapped to (480<<16,250<<16). + // The idea is, that each font pixel uses a virtual rectangle + // of (1<<16,1<<16) size. + + // ScaleX,ScaleY represent the (virtual) width and height of a + // physical OSD pixel. + // OffsetX,OffsetY default to 3,3 to represent the border offset, + // but may be used differently. + +public: + bool GetBlink() { return Blinked; } + bool SetBlink(bool blink); + // Switch blink frequently to get blinking chars + // Returns true if there are blinking characters. + + bool GetConceal() { return Concealed; } + bool SetConceal(bool conceal); + // Hidden text. Set to true to see hidden text. + // Returns true if there are concealed characters. + + enumZoom GetZoom() { return Zoom; } + void SetZoom(enumZoom zoom); + // Zoom to upper/lower half of page + + void SetBackgroundColor(tColor c); + tColor GetBackgroundColor() { return Background; } + // Set the background color for black. Allows transparent black. + + // Color mapping interface. + virtual tColor GetColorRGB(enumTeletextColor ttc, int Area); + // Map a teletext color to an OSD color in #Area. + + virtual tColor GetColorRGBAlternate(enumTeletextColor ttc, int Area); + // For color collision: + // Map this teletext color to an OSD color in #Area, but dont + // return same as GetColorRGB(). Used to solve conflicts if + // foreground and background are mapped to same color. + // Defaults to 1:1 identity. Not needed if all colors actually + // supported by OSD. + + int GetColorIndex(enumTeletextColor ttc, int Area) { + // Map this teletext color to an OSD color index in #Area. + if (!osd) return 0; + cBitmap *bm=osd->GetBitmap(Area); + if (!bm) return 0; + return bm->Index(GetColorRGB(ttc,Area)); + } + + int GetColorIndexAlternate(enumTeletextColor ttc, int Area) { + // Map this teletext color to an OSD color index in #Area. + if (!osd) return 0; + cBitmap *bm=osd->GetBitmap(Area); + if (!bm) return 0; + return bm->Index(GetColorRGBAlternate(ttc,Area)); + } + + + +protected: + void InitPalette(); + // Initialize palette(s) for OSD + + void DrawDisplay(); + // Draw all dirty characters from cRenderPage buffer to OSD + + void CleanDisplay(); + // Clean OSD completely + + virtual void DrawChar(int x, int y, cTeletextChar c); + // Draw a single character to OSD + + +public: + void HoldFlush() { FlushLock++; } + // Hold all OSD flush updates to bundle operations. + + void ReleaseFlush() { FlushLock--; Flush(); } + // Release hold of flush updates. After last release, + // the flush will be done + +protected: + void Flush() { + // Commit all changes from OSD internal bitmaps to device + // All draw operations inside cDisplay should call it, + // no one outside should need to call it. + + if (FlushLock>0) return; + if (!osd) return; + if (IsDirty()) DrawDisplay(); + + #ifdef timingdebug + cTime t; + t.Start(); + #endif + + osd->Flush(); + + #ifdef timingdebug + t.Stop("osd Flush"); + #endif + } + +public: + void RenderTeletextCode(unsigned char *PageCode); + // Interprete teletext code referenced by PageCode + // and draw the whole page content into OSD. + // PageCode must be a 40*24+12 bytes buffer + + void DrawText(int x, int y, const char *text, int len); + // Draw some characters in teletext page. + // Max len chars, fill up with spaces + + void DrawClock(); + // Draw current time to OSD + + void DrawPageId(const char *text) + { DrawText(0,0,text,8); } + // Draw Page ID string to OSD + + void DrawMessage(const char *txt); + // Draw a framed, centered message box to OSD + + void ClearMessage(); + // Remove message box and redraw hidden content +}; + + + +inline void cDisplay::cBox::SetToCharacter(int x, int y) { + // Virtual box area of a character + XMin=(x*12)<<16; + YMin=(y*10)<<16; + XMax=XMin+(12<<16)-1; + YMax=YMin+(10<<16)-1; +} + +inline void cDisplay::cVirtualCoordinate::VirtualToPixel(cDisplay *Display, int x, int y) { + // Map virtual coordinate to OSD pixel + OsdX=x/Display->ScaleX+Display->OffsetX; + OsdY=y/Display->ScaleY+Display->OffsetY; + + // map OSD pixel back to virtual coordinate, use center of pixel + VirtX=(OsdX-Display->OffsetX)*Display->ScaleX+Display->ScaleX/2; + VirtY=(OsdY-Display->OffsetY)*Display->ScaleY+Display->ScaleY/2; +} + +inline void cDisplay::cVirtualCoordinate::IncPixelX(cDisplay *Display) { + // Move one OSD pixel + OsdX++; + VirtX+=Display->ScaleX; +} +inline void cDisplay::cVirtualCoordinate::IncPixelY(cDisplay *Display) { + // Move one OSD pixel + OsdY++; + VirtY+=Display->ScaleY; +} + +#endif |