summaryrefslogtreecommitdiff
path: root/PLUGINS/src/dvbhddevice/hdffosd.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2011-04-17 16:50:00 +0200
committerKlaus Schmidinger <Klaus (dot) Schmidinger (at) tvdr (dot) de>2011-04-17 17:09:00 +0200
commit8b9350c091bc5ae8c9bb30b83a1fb567c3a7cb7f (patch)
tree51880b55c64c719561524fa4721d933b9205656e /PLUGINS/src/dvbhddevice/hdffosd.c
parent5619c0602bc623adeddf3385ada8c742aaea9762 (diff)
downloadvdr-patches-8b9350c091bc5ae8c9bb30b83a1fb567c3a7cb7f.tar.gz
vdr-patches-8b9350c091bc5ae8c9bb30b83a1fb567c3a7cb7f.tar.bz2
Version 1.7.18
- Changed -O2 to -O3 in Make.config.template (reported by Matti Lehtimäki). - Added a missing 'default' case in cPixmapMemory::DrawEllipse(). - Fixed some direct comparisons of double values. - Fixed detecting frames on channels that broadcast with separate "fields" instead of complete frames. - Made updating the editing marks during replay react faster in case the marks file has just been written (with a patch from Udo Richter). - Fixed horizontal scaling of subtitles (reported by Reinhard Nissl). - Stripped the note "The data returned by this function is only used for informational purposes (if any)" from the description of cDevice::GetVideoSize(). The VideoAspect is now used to properly scale subtitles. - Fixed cUnbufferedFile::Seek() in case it is compiled without USE_FADVISE (thanks to Juergen Lock). - Fixed the Language header of the Serbian translation file (thanks to Ville Skyttä). - Added anti-aliasing when upscaling bitmaps, which improves the display of SD subtitles when replayed on an HD OSD (thanks to Reinhard Nissl for his help in debugging). - Renamed cBitmap::Scale() to Scaled(), because it doesn't modify the bitmap itself, but rather returns a scaled copy. - Fixed the description of cReceiver in PLUGINS.html, regarding detaching a receiver from its device before deleting it (reported by Winfried Köhler). This change in behavior was introduced in version 1.5.7. - Fixed scaling subtitles in case the OSD size is exactly the same as the display size of the subtitles. - Added a missing initialization to sDvbSpuRect (reported by Sergiu Dotenco). - Replaced "%lld" and "%llX" print format specifiers with "PRId64" and "PRIX64" to avoid compiler warnings with gcc 4.5.2 (thanks to Sergiu Dotenco). On a personal note: I find it a step in the totally wrong direction that there have been macros introduced to work around this problem in the first place. There should have been "real" format specifiers defined that address this. These macros are nothing but an ugly workaround. - Added Cancel(3) to ~cTrueColorDemo() in the "osddemo" plugin (thanks to Reinhard Nissl). - Added a missing font deletion in cTrueColorDemo::Action() in the "osddemo" plugin (thanks to Reinhard Nissl). - Fixed a buffer overflow in cFont::Bidi() (thanks to Reinhard Nissl). - Added HD stream content identifiers to vdr.5 (thanks to Christoph Haubrich). - Made cRecordingInfo::Read(FILE *f) private to avoid calls to it from outside cRecordingInfo or cRecording (reported by Mika Laitio). - The dvbhddevice plugin is now part of the VDR distribution archive (thanks to Andreas Regel). - Removed an obsolete local variable in dvbsdffosd.c (thanks to Paul Menzel). - Fixed a possible NULL pointer dereference in osddemo.c (reported by Paul Menzel). - Now using pkg-config to get fribidi, freetype and fontconfig cflags and libs (thanks to Ville Skyttä). - The Makefile now also installs the include files (thanks to Ville Skyttä). - Added handling of "ANSI/SCTE 57" descriptors (thanks too Rolf Ahrenberg). - Avoiding an unecessary call to Recordings.ResetResume() (thanks to Reinhard Nissl).
Diffstat (limited to 'PLUGINS/src/dvbhddevice/hdffosd.c')
-rw-r--r--PLUGINS/src/dvbhddevice/hdffosd.c755
1 files changed, 755 insertions, 0 deletions
diff --git a/PLUGINS/src/dvbhddevice/hdffosd.c b/PLUGINS/src/dvbhddevice/hdffosd.c
new file mode 100644
index 0000000..254f2af
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/hdffosd.c
@@ -0,0 +1,755 @@
+/*
+ * hdffosd.c: Implementation of the DVB HD Full Featured On Screen Display
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: hdffosd.c 1.9 2011/04/17 11:20:22 kls Exp $
+ */
+
+#include "hdffosd.h"
+#include <linux/dvb/osd.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include "hdffcmd.h"
+#include "setup.h"
+
+#define MAX_NUM_FONTFACES 8
+#define MAX_NUM_FONTS 8
+#define MAX_BITMAP_SIZE (1024*1024)
+
+typedef struct _tFontFace
+{
+ cString Name;
+ uint32_t Handle;
+} tFontFace;
+
+typedef struct _tFont
+{
+ uint32_t hFontFace;
+ int Size;
+ uint32_t Handle;
+} tFont;
+
+class cHdffOsd : public cOsd
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+ int mLeft;
+ int mTop;
+ int mDispWidth;
+ int mDispHeight;
+ bool shown;
+ bool mChanged;
+ bool mBitmapModified;
+ uint32_t mDisplay;
+ tFontFace mFontFaces[MAX_NUM_FONTFACES];
+ tFont mFonts[MAX_NUM_FONTS];
+ uint32_t mBitmapPalette;
+ uint32_t mBitmapColors[256];
+ uint32_t mBitmapNumColors;
+
+protected:
+ virtual void SetActive(bool On);
+public:
+ cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level);
+ virtual ~cHdffOsd();
+ cBitmap *GetBitmap(int Area);
+ virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
+ virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
+ virtual void SaveRegion(int x1, int y1, int x2, int y2);
+ virtual void RestoreRegion(void);
+ virtual void DrawPixel(int x, int y, tColor Color);
+ virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool ReplacePalette = false, bool Overlay = false);
+ virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
+ virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
+ virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0);
+ virtual void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type);
+ virtual void Flush(void);
+};
+
+cHdffOsd::cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level)
+: cOsd(Left, Top, Level)
+{
+ double pixelAspect;
+ HDFF::tOsdConfig config;
+
+ //printf("cHdffOsd %d, %d, %d\n", Left, Top, Level);
+ mHdffCmdIf = pHdffCmdIf;
+ mLeft = Left;
+ mTop = Top;
+ shown = false;
+ mChanged = false;
+ mBitmapModified = false;
+ mBitmapPalette = InvalidHandle;
+ config.FontKerning = false;
+ config.FontAntialiasing = Setup.AntiAlias ? true : false;
+ mHdffCmdIf->CmdOsdConfigure(&config);
+
+ gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect);
+ mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF::colorTypeARGB8888);
+ mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, SizeFullScreen, SizeFullScreen);
+ for (int i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ mFontFaces[i].Name = "";
+ mFontFaces[i].Handle = InvalidHandle;
+ }
+ for (int i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ mFonts[i].hFontFace = InvalidHandle;
+ mFonts[i].Size = 0;
+ mFonts[i].Handle = InvalidHandle;
+ }
+}
+
+cHdffOsd::~cHdffOsd()
+{
+ //printf("~cHdffOsd %d %d\n", mLeft, mTop);
+ SetActive(false);
+
+ for (int i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ if (mFonts[i].Handle == InvalidHandle)
+ break;
+ mHdffCmdIf->CmdOsdDeleteFont(mFonts[i].Handle);
+ }
+ for (int i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ if (mFontFaces[i].Handle == InvalidHandle)
+ break;
+ mHdffCmdIf->CmdOsdDeleteFontFace(mFontFaces[i].Handle);
+ }
+
+ if (mBitmapPalette != InvalidHandle)
+ mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette);
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay);
+}
+
+cBitmap * cHdffOsd::GetBitmap(int Area)
+{
+ //printf("GetBitmap %d\n", Area);
+ mChanged = true;
+ mBitmapModified = true;
+ return cOsd::GetBitmap(Area);
+}
+
+eOsdError cHdffOsd::CanHandleAreas(const tArea *Areas, int NumAreas)
+{
+ eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
+ if (Result == oeOk)
+ {
+ for (int i = 0; i < NumAreas; i++)
+ {
+ if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8)
+ return oeBppNotSupported;
+ }
+ }
+ return Result;
+}
+
+eOsdError cHdffOsd::SetAreas(const tArea *Areas, int NumAreas)
+{
+ for (int i = 0; i < NumAreas; i++)
+ {
+ //printf("SetAreas %d: %d %d %d %d %d\n", i, Areas[i].x1, Areas[i].y1, Areas[i].x2, Areas[i].y2, Areas[i].bpp);
+ }
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ return cOsd::SetAreas(Areas, NumAreas);
+}
+
+void cHdffOsd::SetActive(bool On)
+{
+ if (On != Active())
+ {
+ cOsd::SetActive(On);
+ if (On)
+ {
+ }
+ else if (shown)
+ {
+ shown = false;
+ }
+ }
+}
+
+void cHdffOsd::SaveRegion(int x1, int y1, int x2, int y2)
+{
+ mHdffCmdIf->CmdOsdSaveRegion(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1);
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::RestoreRegion(void)
+{
+ mHdffCmdIf->CmdOsdRestoreRegion(mDisplay);
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawPixel(int x, int y, tColor Color)
+{
+ //printf("DrawPixel\n");
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay)
+{
+ //printf("DrawBitmap %d %d %d\n", x, y, Overlay);
+ int i;
+ int numColors;
+ const tColor * colors = Bitmap.Colors(numColors);
+
+ for (i = 0; i < numColors; i++)
+ {
+ mBitmapColors[i] = colors[i];
+ if (ColorFg || ColorBg)
+ {
+ if (i == 0)
+ mBitmapColors[i] = ColorBg;
+ else if (i == 1)
+ mBitmapColors[i] = ColorFg;
+ }
+ }
+ if (mBitmapPalette == InvalidHandle)
+ {
+ mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF::colorTypeClut8,
+ HDFF::colorFormatARGB, numColors, mBitmapColors);
+ }
+ else
+ {
+ mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette,
+ HDFF::colorFormatARGB, 0, numColors, mBitmapColors);
+ }
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y,
+ (uint8_t *) Bitmap.Data(0, 0), Bitmap.Width(), Bitmap.Height(),
+ Bitmap.Width() * Bitmap.Height(), HDFF::colorTypeClut8, mBitmapPalette);
+#if 0
+ uint32_t * tmpBitmap = new uint32_t[Bitmap.Width() * Bitmap.Height()];
+ for (int ix = 0; ix < Bitmap.Width(); ix++)
+ {
+ for (int iy = 0; iy < Bitmap.Height(); iy++)
+ {
+ const tIndex * pixel = Bitmap.Data(ix, iy);
+ tColor color = Bitmap.Color(*pixel);
+ if (!Overlay || *pixel != 0)
+ {
+ if (ColorFg || ColorBg)
+ {
+ if (*pixel == 0)
+ color = ColorBg;
+ else if (*pixel == 1)
+ color = ColorFg;
+ }
+ tmpBitmap[Bitmap.Width() * iy + ix] = color;
+ }
+ }
+ }
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y,
+ (uint8_t *) tmpBitmap, Bitmap.Width(), Bitmap.Height(),
+ Bitmap.Width() * Bitmap.Height() * 4, HDFF::colorTypeARGB8888, InvalidHandle);
+ delete[] tmpBitmap;
+#endif
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment)
+{
+ int w = Font->Width(s);
+ int h = Font->Height();
+ int limit = 0;
+ int cw = Width ? Width : w;
+ int ch = Height ? Height : h;
+ int i;
+ int size = Font->Size();
+ tFontFace * pFontFace;
+ tFont * pFont;
+
+ if (ColorBg != clrTransparent)
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, mLeft + x, mTop + y, cw, ch, ColorBg);
+
+ if (s == NULL)
+ return;
+
+ pFontFace = NULL;
+ for (i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ if (mFontFaces[i].Handle == InvalidHandle)
+ break;
+
+ if (strcmp(mFontFaces[i].Name, Font->FontName()) == 0)
+ {
+ pFontFace = &mFontFaces[i];
+ break;
+ }
+ }
+ if (pFontFace == NULL)
+ {
+ if (i < MAX_NUM_FONTFACES)
+ {
+ cString fontFileName = Font->FontName();
+ FILE * fp = fopen(fontFileName, "rb");
+ if (fp)
+ {
+ fseek(fp, 0, SEEK_END);
+ long fileSize = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ if (fileSize > 0)
+ {
+ uint8_t * buffer = new uint8_t[fileSize];
+ if (buffer)
+ {
+ if (fread(buffer, fileSize, 1, fp) == 1)
+ {
+ mFontFaces[i].Handle = mHdffCmdIf->CmdOsdCreateFontFace(buffer, fileSize);
+ if (mFontFaces[i].Handle != InvalidHandle)
+ {
+ mFontFaces[i].Name = Font->FontName();
+ pFontFace = &mFontFaces[i];
+ }
+ }
+ delete[] buffer;
+ }
+ }
+ fclose(fp);
+ }
+ }
+ }
+ if (pFontFace == NULL)
+ return;
+
+ pFont = NULL;
+ for (i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ if (mFonts[i].Handle == InvalidHandle)
+ break;
+
+ if (mFonts[i].hFontFace == pFontFace->Handle
+ && mFonts[i].Size == size)
+ {
+ pFont = &mFonts[i];
+ break;
+ }
+ }
+ if (pFont == NULL)
+ {
+ if (i < MAX_NUM_FONTS)
+ {
+ mFonts[i].Handle = mHdffCmdIf->CmdOsdCreateFont(pFontFace->Handle, size);
+ if (mFonts[i].Handle != InvalidHandle)
+ {
+ mFonts[i].hFontFace = pFontFace->Handle;
+ mFonts[i].Size = size;
+ pFont = &mFonts[i];
+ }
+ }
+ }
+ if (pFont == NULL)
+ return;
+
+ mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, true, mLeft + x, mTop + y, cw, ch);
+
+ if (Width || Height)
+ {
+ limit = x + cw;// - mLeft;
+ if (Width)
+ {
+ if ((Alignment & taLeft) != 0)
+ ;
+ else if ((Alignment & taRight) != 0)
+ {
+ if (w < Width)
+ x += Width - w;
+ }
+ else
+ { // taCentered
+ if (w < Width)
+ x += (Width - w) / 2;
+ }
+ }
+ if (Height)
+ {
+ if ((Alignment & taTop) != 0)
+ ;
+ else if ((Alignment & taBottom) != 0)
+ {
+ if (h < Height)
+ y += Height - h;
+ }
+ else
+ { // taCentered
+ if (h < Height)
+ y += (Height - h) / 2;
+ }
+ }
+ }
+ //x -= mLeft;
+ //y -= mTop;
+ {
+ uint16_t tmp[1000];
+ uint16_t len = 0;
+ while (*s && (len < (sizeof(tmp) - 1)))
+ {
+ int sl = Utf8CharLen(s);
+ uint sym = Utf8CharGet(s, sl);
+ s += sl;
+ tmp[len] = sym;
+ len++;
+ }
+ tmp[len] = 0;
+ mHdffCmdIf->CmdOsdDrawTextW(mDisplay, pFont->Handle, x + mLeft, y + mTop + h, tmp, ColorFg);
+ }
+ //mHdffCmdIf->CmdOsdDrawText(mDisplay, pFont->Handle, x + mLeft, y + mTop + h - 7, s, ColorFg);
+ mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, false, 0, 0, 0, 0);
+ //Font->DrawText(this, x, y, s, ColorFg, ColorBg, limit);
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
+{
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1, Color);
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants)
+{
+ uint32_t flags;
+ int cx;
+ int cy;
+ int rx;
+ int ry;
+
+ switch (abs(Quadrants))
+ {
+ case 1:
+ if (Quadrants > 0)
+ flags = HDFF::drawQuarterTopRight;
+ else
+ flags = HDFF::drawQuarterTopRightInverted;
+ cx = x1;
+ cy = y2;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 2:
+ if (Quadrants > 0)
+ flags = HDFF::drawQuarterTopLeft;
+ else
+ flags = HDFF::drawQuarterTopLeftInverted;
+ cx = x2;
+ cy = y2;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 3:
+ if (Quadrants > 0)
+ flags = HDFF::drawQuarterBottomLeft;
+ else
+ flags = HDFF::drawQuarterBottomLeftInverted;
+ cx = x2;
+ cy = y1;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 4:
+ if (Quadrants > 0)
+ flags = HDFF::drawQuarterBottomRight;
+ else
+ flags = HDFF::drawQuarterBottomRightInverted;
+ cx = x1;
+ cy = y1;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 5:
+ flags = HDFF::drawHalfRight;
+ cx = x1;
+ cy = (y1 + y2) / 2;
+ rx = x2 - x1;
+ ry = (y2 - y1) / 2;
+ break;
+ case 6:
+ flags = HDFF::drawHalfTop;
+ cx = (x1 + x2) / 2;
+ cy = y2;
+ rx = (x2 - x1) / 2;
+ ry = y2 - y1;
+ break;
+ case 7:
+ flags = HDFF::drawHalfLeft;
+ cx = x2;
+ cy = (y1 + y2) / 2;
+ rx = x2 - x1;
+ ry = (y2 - y1) / 2;
+ break;
+ case 8:
+ flags = HDFF::drawHalfBottom;
+ cx = (x1 + x2) / 2;
+ cy = y1;
+ rx = (x2 - x1) / 2;
+ ry = y2 - y1;
+ break;
+ default:
+ flags = HDFF::drawFull;
+ cx = (x1 + x2) / 2;
+ cy = (y1 + y2) / 2;
+ rx = (x2 - x1) / 2;
+ ry = (y2 - y1) / 2;
+ break;
+ }
+ mHdffCmdIf->CmdOsdDrawEllipse(mDisplay, mLeft + cx, mTop + cy, rx, ry, Color, flags);
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type)
+{
+ //printf("DrawSlope\n");
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::Flush(void)
+{
+ if (!Active())
+ return;
+
+ if (!mChanged)
+ return;
+
+ //printf("Flush\n");
+ if (mBitmapModified)
+ {
+ cBitmap *Bitmap;
+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++)
+ {
+ DrawBitmap(0, 0, *Bitmap);
+ }
+ }
+
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+
+ mChanged = false;
+ mBitmapModified = false;
+}
+
+
+class cHdffOsdRaw : public cOsd
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+ int mDispWidth;
+ int mDispHeight;
+ bool shown;
+ uint32_t mDisplay;
+ uint32_t mBitmapPalette;
+ uint32_t mBitmapColors[256];
+ uint32_t mBitmapNumColors;
+
+protected:
+ virtual void SetActive(bool On);
+public:
+ cHdffOsdRaw(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level);
+ virtual ~cHdffOsdRaw();
+ virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
+ virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
+ virtual void Flush(void);
+};
+
+cHdffOsdRaw::cHdffOsdRaw(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level)
+: cOsd(Left, Top, Level)
+{
+ double pixelAspect;
+
+ //printf("cHdffOsdRaw %d, %d, %d\n", Left, Top, Level);
+ mHdffCmdIf = pHdffCmdIf;
+ shown = false;
+ mBitmapPalette = InvalidHandle;
+
+ gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect);
+ mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF::colorTypeARGB8888);
+ mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, SizeFullScreen, SizeFullScreen);
+}
+
+cHdffOsdRaw::~cHdffOsdRaw()
+{
+ //printf("~cHdffOsdRaw %d %d\n", Left(), Top());
+ SetActive(false);
+
+ if (mBitmapPalette != InvalidHandle)
+ mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette);
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay);
+}
+
+void cHdffOsdRaw::SetActive(bool On)
+{
+ if (On != Active())
+ {
+ cOsd::SetActive(On);
+ if (On)
+ {
+ }
+ else if (shown)
+ {
+ shown = false;
+ }
+ }
+}
+
+eOsdError cHdffOsdRaw::CanHandleAreas(const tArea *Areas, int NumAreas)
+{
+ eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
+ if (Result == oeOk)
+ {
+ for (int i = 0; i < NumAreas; i++)
+ {
+ if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8
+ && (Areas[i].bpp != 32 || !gHdffSetup.TrueColorOsd))
+ return oeBppNotSupported;
+ }
+ }
+ return Result;
+}
+
+eOsdError cHdffOsdRaw::SetAreas(const tArea *Areas, int NumAreas)
+{
+ for (int i = 0; i < NumAreas; i++)
+ {
+ //printf("SetAreas %d: %d %d %d %d %d\n", i, Areas[i].x1, Areas[i].y1, Areas[i].x2, Areas[i].y2, Areas[i].bpp);
+ }
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ return cOsd::SetAreas(Areas, NumAreas);
+}
+
+void cHdffOsdRaw::Flush(void)
+{
+ if (!Active())
+ return;
+ //struct timeval start;
+ //struct timeval end;
+ //struct timezone timeZone;
+ //gettimeofday(&start, &timeZone);
+
+ bool render = false;
+ if (IsTrueColor())
+ {
+ LOCK_PIXMAPS;
+ while (cPixmapMemory *pm = RenderPixmaps())
+ {
+ int w = pm->ViewPort().Width();
+ int h = pm->ViewPort().Height();
+ int d = w * sizeof(tColor);
+ int Chunk = MAX_BITMAP_SIZE / w / sizeof(tColor);
+ if (Chunk > h)
+ Chunk = h;
+ for (int y = 0; y < h; y += Chunk)
+ {
+ int hc = Chunk;
+ if (y + hc > h)
+ hc = h - y;
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay,
+ Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y() + y,
+ pm->Data() + y * d, w, hc, hc * d,
+ HDFF::colorTypeARGB8888, InvalidHandle);
+ }
+ delete pm;
+ render = true;
+ }
+ }
+ else
+ {
+ uint8_t * buffer = new uint8_t[MAX_BITMAP_SIZE];
+ if (!buffer)
+ return;
+ cBitmap * bitmap;
+ for (int i = 0; (bitmap = GetBitmap(i)) != NULL; i++)
+ {
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+ if (!shown || bitmap->Dirty(x1, y1, x2, y2))
+ {
+ if (!shown)
+ {
+ x2 = bitmap->Width() - 1;
+ y2 = bitmap->Height() - 1;
+ }
+ // commit colors:
+ int numColors;
+ const tColor * colors = bitmap->Colors(numColors);
+ if (colors)
+ {
+ for (int c = 0; c < numColors; c++)
+ mBitmapColors[c] = colors[c];
+ if (mBitmapPalette == InvalidHandle)
+ {
+ mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF::colorTypeClut8,
+ HDFF::colorFormatARGB, numColors, mBitmapColors);
+ }
+ else
+ {
+ mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette,
+ HDFF::colorFormatARGB, 0, numColors, mBitmapColors);
+ }
+ }
+ // commit modified data:
+ int width = x2 - x1 + 1;
+ int height = y2 - y1 + 1;
+ int chunk = MAX_BITMAP_SIZE / width;
+ if (chunk > height)
+ chunk = height;
+ for (int y = 0; y < height; y += chunk)
+ {
+ int hc = chunk;
+ if (y + hc > height)
+ hc = height - y;
+ for (int r = 0; r < hc; r++)
+ memcpy(buffer + r * width, bitmap->Data(x1, y1 + y + r), width);
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay,
+ Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1 + y,
+ buffer, width, hc, hc * width,
+ HDFF::colorTypeClut8, mBitmapPalette);
+ }
+ render = true;
+ }
+ bitmap->Clean();
+ }
+ delete[] buffer;
+ }
+ if (render)
+ {
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ //gettimeofday(&end, &timeZone);
+ //int timeNeeded = end.tv_usec - start.tv_usec;
+ //timeNeeded += (end.tv_sec - start.tv_sec) * 1000000;
+ //printf("time = %d\n", timeNeeded);
+ }
+ shown = true;
+}
+
+
+
+
+cHdffOsdProvider::cHdffOsdProvider(HDFF::cHdffCmdIf * HdffCmdIf)
+{
+ mHdffCmdIf = HdffCmdIf;
+}
+
+cOsd *cHdffOsdProvider::CreateOsd(int Left, int Top, uint Level)
+{
+ //printf("CreateOsd %d %d %d\n", Left, Top, Level);
+ if (gHdffSetup.HighLevelOsd)
+ return new cHdffOsd(Left, Top, mHdffCmdIf, Level);
+ else
+ return new cHdffOsdRaw(Left, Top, mHdffCmdIf, Level);
+}
+
+bool cHdffOsdProvider::ProvidesTrueColor(void)
+{
+ return gHdffSetup.TrueColorOsd && !gHdffSetup.HighLevelOsd;
+}