vdr
1.7.27
|
00001 /* 00002 * hdffosd.c: Implementation of the DVB HD Full Featured On Screen Display 00003 * 00004 * See the README file for copyright information and how to reach the author. 00005 * 00006 * $Id: hdffosd.c 1.12 2011/12/04 15:31:41 kls Exp $ 00007 */ 00008 00009 #include "hdffosd.h" 00010 #include <linux/dvb/osd.h> 00011 #include <sys/ioctl.h> 00012 #include <sys/time.h> 00013 #include "hdffcmd.h" 00014 #include "setup.h" 00015 00016 #define MAX_NUM_FONTFACES 8 00017 #define MAX_NUM_FONTS 8 00018 #define MAX_BITMAP_SIZE (1024*1024) 00019 00020 typedef struct _tFontFace 00021 { 00022 cString Name; 00023 uint32_t Handle; 00024 } tFontFace; 00025 00026 typedef struct _tFont 00027 { 00028 uint32_t hFontFace; 00029 int Size; 00030 uint32_t Handle; 00031 } tFont; 00032 00033 class cHdffOsd : public cOsd 00034 { 00035 private: 00036 HDFF::cHdffCmdIf * mHdffCmdIf; 00037 int mLeft; 00038 int mTop; 00039 int mDispWidth; 00040 int mDispHeight; 00041 bool shown; 00042 bool mChanged; 00043 bool mBitmapModified; 00044 uint32_t mDisplay; 00045 tFontFace mFontFaces[MAX_NUM_FONTFACES]; 00046 tFont mFonts[MAX_NUM_FONTS]; 00047 uint32_t mBitmapPalette; 00048 uint32_t mBitmapColors[256]; 00049 uint32_t mBitmapNumColors; 00050 00051 protected: 00052 virtual void SetActive(bool On); 00053 public: 00054 cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level); 00055 virtual ~cHdffOsd(); 00056 cBitmap *GetBitmap(int Area); 00057 virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); 00058 virtual eOsdError SetAreas(const tArea *Areas, int NumAreas); 00059 virtual void SaveRegion(int x1, int y1, int x2, int y2); 00060 virtual void RestoreRegion(void); 00061 virtual void DrawPixel(int x, int y, tColor Color); 00062 virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool ReplacePalette = false, bool Overlay = false); 00063 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); 00064 virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color); 00065 virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0); 00066 virtual void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type); 00067 virtual void Flush(void); 00068 }; 00069 00070 cHdffOsd::cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level) 00071 : cOsd(Left, Top, Level) 00072 { 00073 double pixelAspect; 00074 HdffOsdConfig_t config; 00075 00076 //printf("cHdffOsd %d, %d, %d\n", Left, Top, Level); 00077 mHdffCmdIf = pHdffCmdIf; 00078 mLeft = Left; 00079 mTop = Top; 00080 shown = false; 00081 mChanged = false; 00082 mBitmapModified = false; 00083 mBitmapPalette = HDFF_INVALID_HANDLE; 00084 config.FontKerning = false; 00085 config.FontAntialiasing = Setup.AntiAlias ? true : false; 00086 mHdffCmdIf->CmdOsdConfigure(&config); 00087 00088 gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect); 00089 mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF_COLOR_TYPE_ARGB8888); 00090 mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, HDFF_SIZE_FULL_SCREEN, HDFF_SIZE_FULL_SCREEN); 00091 for (int i = 0; i < MAX_NUM_FONTFACES; i++) 00092 { 00093 mFontFaces[i].Name = ""; 00094 mFontFaces[i].Handle = HDFF_INVALID_HANDLE; 00095 } 00096 for (int i = 0; i < MAX_NUM_FONTS; i++) 00097 { 00098 mFonts[i].hFontFace = HDFF_INVALID_HANDLE; 00099 mFonts[i].Size = 0; 00100 mFonts[i].Handle = HDFF_INVALID_HANDLE; 00101 } 00102 } 00103 00104 cHdffOsd::~cHdffOsd() 00105 { 00106 //printf("~cHdffOsd %d %d\n", mLeft, mTop); 00107 SetActive(false); 00108 00109 for (int i = 0; i < MAX_NUM_FONTS; i++) 00110 { 00111 if (mFonts[i].Handle == HDFF_INVALID_HANDLE) 00112 break; 00113 mHdffCmdIf->CmdOsdDeleteFont(mFonts[i].Handle); 00114 } 00115 for (int i = 0; i < MAX_NUM_FONTFACES; i++) 00116 { 00117 if (mFontFaces[i].Handle == HDFF_INVALID_HANDLE) 00118 break; 00119 mHdffCmdIf->CmdOsdDeleteFontFace(mFontFaces[i].Handle); 00120 } 00121 00122 if (mBitmapPalette != HDFF_INVALID_HANDLE) 00123 mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette); 00124 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); 00125 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00126 mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay); 00127 } 00128 00129 cBitmap * cHdffOsd::GetBitmap(int Area) 00130 { 00131 //printf("GetBitmap %d\n", Area); 00132 mChanged = true; 00133 mBitmapModified = true; 00134 return cOsd::GetBitmap(Area); 00135 } 00136 00137 eOsdError cHdffOsd::CanHandleAreas(const tArea *Areas, int NumAreas) 00138 { 00139 eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); 00140 if (Result == oeOk) 00141 { 00142 for (int i = 0; i < NumAreas; i++) 00143 { 00144 if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8) 00145 return oeBppNotSupported; 00146 } 00147 } 00148 return Result; 00149 } 00150 00151 eOsdError cHdffOsd::SetAreas(const tArea *Areas, int NumAreas) 00152 { 00153 for (int i = 0; i < NumAreas; i++) 00154 { 00155 //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); 00156 } 00157 if (shown) 00158 { 00159 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); 00160 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00161 shown = false; 00162 } 00163 return cOsd::SetAreas(Areas, NumAreas); 00164 } 00165 00166 void cHdffOsd::SetActive(bool On) 00167 { 00168 if (On != Active()) 00169 { 00170 cOsd::SetActive(On); 00171 if (On) 00172 { 00173 if (GetBitmap(0)) // only flush here if there are already bitmaps 00174 Flush(); 00175 } 00176 else if (shown) 00177 { 00178 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); 00179 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00180 shown = false; 00181 } 00182 } 00183 } 00184 00185 void cHdffOsd::SaveRegion(int x1, int y1, int x2, int y2) 00186 { 00187 mHdffCmdIf->CmdOsdSaveRegion(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1); 00188 mChanged = true; 00189 mBitmapModified = false; 00190 } 00191 00192 void cHdffOsd::RestoreRegion(void) 00193 { 00194 mHdffCmdIf->CmdOsdRestoreRegion(mDisplay); 00195 mChanged = true; 00196 mBitmapModified = false; 00197 } 00198 00199 void cHdffOsd::DrawPixel(int x, int y, tColor Color) 00200 { 00201 //printf("DrawPixel\n"); 00202 mBitmapModified = false; 00203 } 00204 00205 void cHdffOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay) 00206 { 00207 //printf("DrawBitmap %d %d %d\n", x, y, Overlay); 00208 int i; 00209 int numColors; 00210 const tColor * colors = Bitmap.Colors(numColors); 00211 00212 for (i = 0; i < numColors; i++) 00213 { 00214 mBitmapColors[i] = colors[i]; 00215 if (ColorFg || ColorBg) 00216 { 00217 if (i == 0) 00218 mBitmapColors[i] = ColorBg; 00219 else if (i == 1) 00220 mBitmapColors[i] = ColorFg; 00221 } 00222 } 00223 if (mBitmapPalette == HDFF_INVALID_HANDLE) 00224 { 00225 mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF_COLOR_TYPE_CLUT8, 00226 HDFF_COLOR_FORMAT_ARGB, numColors, mBitmapColors); 00227 } 00228 else 00229 { 00230 mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette, 00231 HDFF_COLOR_FORMAT_ARGB, 0, numColors, mBitmapColors); 00232 } 00233 mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y, 00234 (uint8_t *) Bitmap.Data(0, 0), Bitmap.Width(), Bitmap.Height(), 00235 Bitmap.Width() * Bitmap.Height(), HDFF_COLOR_TYPE_CLUT8, mBitmapPalette); 00236 #if 0 00237 uint32_t * tmpBitmap = new uint32_t[Bitmap.Width() * Bitmap.Height()]; 00238 for (int ix = 0; ix < Bitmap.Width(); ix++) 00239 { 00240 for (int iy = 0; iy < Bitmap.Height(); iy++) 00241 { 00242 const tIndex * pixel = Bitmap.Data(ix, iy); 00243 tColor color = Bitmap.Color(*pixel); 00244 if (!Overlay || *pixel != 0) 00245 { 00246 if (ColorFg || ColorBg) 00247 { 00248 if (*pixel == 0) 00249 color = ColorBg; 00250 else if (*pixel == 1) 00251 color = ColorFg; 00252 } 00253 tmpBitmap[Bitmap.Width() * iy + ix] = color; 00254 } 00255 } 00256 } 00257 mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y, 00258 (uint8_t *) tmpBitmap, Bitmap.Width(), Bitmap.Height(), 00259 Bitmap.Width() * Bitmap.Height() * 4, HDFF::colorTypeARGB8888, InvalidHandle); 00260 delete[] tmpBitmap; 00261 #endif 00262 mChanged = true; 00263 mBitmapModified = false; 00264 } 00265 00266 void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment) 00267 { 00268 int w = Font->Width(s); 00269 int h = Font->Height(); 00270 int limit = 0; 00271 int cw = Width ? Width : w; 00272 int ch = Height ? Height : h; 00273 int i; 00274 int size = Font->Size(); 00275 tFontFace * pFontFace; 00276 tFont * pFont; 00277 00278 if (ColorBg != clrTransparent) 00279 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, mLeft + x, mTop + y, cw, ch, ColorBg); 00280 00281 if (s == NULL) 00282 return; 00283 00284 pFontFace = NULL; 00285 for (i = 0; i < MAX_NUM_FONTFACES; i++) 00286 { 00287 if (mFontFaces[i].Handle == HDFF_INVALID_HANDLE) 00288 break; 00289 00290 if (strcmp(mFontFaces[i].Name, Font->FontName()) == 0) 00291 { 00292 pFontFace = &mFontFaces[i]; 00293 break; 00294 } 00295 } 00296 if (pFontFace == NULL) 00297 { 00298 if (i < MAX_NUM_FONTFACES) 00299 { 00300 cString fontFileName = Font->FontName(); 00301 FILE * fp = fopen(fontFileName, "rb"); 00302 if (fp) 00303 { 00304 fseek(fp, 0, SEEK_END); 00305 long fileSize = ftell(fp); 00306 fseek(fp, 0, SEEK_SET); 00307 if (fileSize > 0) 00308 { 00309 uint8_t * buffer = new uint8_t[fileSize]; 00310 if (buffer) 00311 { 00312 if (fread(buffer, fileSize, 1, fp) == 1) 00313 { 00314 mFontFaces[i].Handle = mHdffCmdIf->CmdOsdCreateFontFace(buffer, fileSize); 00315 if (mFontFaces[i].Handle != HDFF_INVALID_HANDLE) 00316 { 00317 mFontFaces[i].Name = Font->FontName(); 00318 pFontFace = &mFontFaces[i]; 00319 } 00320 } 00321 delete[] buffer; 00322 } 00323 } 00324 fclose(fp); 00325 } 00326 } 00327 } 00328 if (pFontFace == NULL) 00329 return; 00330 00331 pFont = NULL; 00332 for (i = 0; i < MAX_NUM_FONTS; i++) 00333 { 00334 if (mFonts[i].Handle == HDFF_INVALID_HANDLE) 00335 break; 00336 00337 if (mFonts[i].hFontFace == pFontFace->Handle 00338 && mFonts[i].Size == size) 00339 { 00340 pFont = &mFonts[i]; 00341 break; 00342 } 00343 } 00344 if (pFont == NULL) 00345 { 00346 if (i < MAX_NUM_FONTS) 00347 { 00348 mFonts[i].Handle = mHdffCmdIf->CmdOsdCreateFont(pFontFace->Handle, size); 00349 if (mFonts[i].Handle != HDFF_INVALID_HANDLE) 00350 { 00351 mFonts[i].hFontFace = pFontFace->Handle; 00352 mFonts[i].Size = size; 00353 pFont = &mFonts[i]; 00354 } 00355 } 00356 } 00357 if (pFont == NULL) 00358 return; 00359 00360 mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, true, mLeft + x, mTop + y, cw, ch); 00361 00362 if (Width || Height) 00363 { 00364 limit = x + cw;// - mLeft; 00365 if (Width) 00366 { 00367 if ((Alignment & taLeft) != 0) 00368 ; 00369 else if ((Alignment & taRight) != 0) 00370 { 00371 if (w < Width) 00372 x += Width - w; 00373 } 00374 else 00375 { // taCentered 00376 if (w < Width) 00377 x += (Width - w) / 2; 00378 } 00379 } 00380 if (Height) 00381 { 00382 if ((Alignment & taTop) != 0) 00383 ; 00384 else if ((Alignment & taBottom) != 0) 00385 { 00386 if (h < Height) 00387 y += Height - h; 00388 } 00389 else 00390 { // taCentered 00391 if (h < Height) 00392 y += (Height - h) / 2; 00393 } 00394 } 00395 } 00396 //x -= mLeft; 00397 //y -= mTop; 00398 { 00399 uint16_t tmp[1000]; 00400 uint16_t len = 0; 00401 while (*s && (len < (sizeof(tmp) - 1))) 00402 { 00403 int sl = Utf8CharLen(s); 00404 uint sym = Utf8CharGet(s, sl); 00405 s += sl; 00406 tmp[len] = sym; 00407 len++; 00408 } 00409 tmp[len] = 0; 00410 mHdffCmdIf->CmdOsdDrawTextW(mDisplay, pFont->Handle, x + mLeft, y + mTop + h, tmp, ColorFg); 00411 } 00412 //mHdffCmdIf->CmdOsdDrawText(mDisplay, pFont->Handle, x + mLeft, y + mTop + h - 7, s, ColorFg); 00413 mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, false, 0, 0, 0, 0); 00414 //Font->DrawText(this, x, y, s, ColorFg, ColorBg, limit); 00415 mChanged = true; 00416 mBitmapModified = false; 00417 } 00418 00419 void cHdffOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color) 00420 { 00421 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1, Color); 00422 mChanged = true; 00423 mBitmapModified = false; 00424 } 00425 00426 void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants) 00427 { 00428 uint32_t flags; 00429 int cx; 00430 int cy; 00431 int rx; 00432 int ry; 00433 00434 switch (abs(Quadrants)) 00435 { 00436 case 1: 00437 if (Quadrants > 0) 00438 flags = HDFF_DRAW_QUARTER_TOP_RIGHT; 00439 else 00440 flags = HDFF_DRAW_QUARTER_TOP_RIGHT_INVERTED; 00441 cx = x1; 00442 cy = y2; 00443 rx = x2 - x1; 00444 ry = y2 - y1; 00445 break; 00446 case 2: 00447 if (Quadrants > 0) 00448 flags = HDFF_DRAW_QUARTER_TOP_LEFT; 00449 else 00450 flags = HDFF_DRAW_QUARTER_TOP_LEFT_INVERTED; 00451 cx = x2; 00452 cy = y2; 00453 rx = x2 - x1; 00454 ry = y2 - y1; 00455 break; 00456 case 3: 00457 if (Quadrants > 0) 00458 flags = HDFF_DRAW_QUARTER_BOTTOM_LEFT; 00459 else 00460 flags = HDFF_DRAW_QUARTER_BOTTOM_LEFT_INVERTED; 00461 cx = x2; 00462 cy = y1; 00463 rx = x2 - x1; 00464 ry = y2 - y1; 00465 break; 00466 case 4: 00467 if (Quadrants > 0) 00468 flags = HDFF_DRAW_QUARTER_BOTTOM_RIGHT; 00469 else 00470 flags = HDFF_DRAW_QUARTER_BOTTOM_RIGHT_INVERTED; 00471 cx = x1; 00472 cy = y1; 00473 rx = x2 - x1; 00474 ry = y2 - y1; 00475 break; 00476 case 5: 00477 flags = HDFF_DRAW_HALF_RIGHT; 00478 cx = x1; 00479 cy = (y1 + y2) / 2; 00480 rx = x2 - x1; 00481 ry = (y2 - y1) / 2; 00482 break; 00483 case 6: 00484 flags = HDFF_DRAW_HALF_TOP; 00485 cx = (x1 + x2) / 2; 00486 cy = y2; 00487 rx = (x2 - x1) / 2; 00488 ry = y2 - y1; 00489 break; 00490 case 7: 00491 flags = HDFF_DRAW_HALF_LEFT; 00492 cx = x2; 00493 cy = (y1 + y2) / 2; 00494 rx = x2 - x1; 00495 ry = (y2 - y1) / 2; 00496 break; 00497 case 8: 00498 flags = HDFF_DRAW_HALF_BOTTOM; 00499 cx = (x1 + x2) / 2; 00500 cy = y1; 00501 rx = (x2 - x1) / 2; 00502 ry = y2 - y1; 00503 break; 00504 default: 00505 flags = HDFF_DRAW_FULL; 00506 cx = (x1 + x2) / 2; 00507 cy = (y1 + y2) / 2; 00508 rx = (x2 - x1) / 2; 00509 ry = (y2 - y1) / 2; 00510 break; 00511 } 00512 mHdffCmdIf->CmdOsdDrawEllipse(mDisplay, mLeft + cx, mTop + cy, rx, ry, Color, flags); 00513 mChanged = true; 00514 mBitmapModified = false; 00515 } 00516 00517 void cHdffOsd::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type) 00518 { 00519 //printf("DrawSlope\n"); 00520 mChanged = true; 00521 mBitmapModified = false; 00522 } 00523 00524 void cHdffOsd::Flush(void) 00525 { 00526 if (!Active()) 00527 return; 00528 00529 if (!mChanged) 00530 return; 00531 00532 //printf("Flush\n"); 00533 if (mBitmapModified) 00534 { 00535 cBitmap *Bitmap; 00536 for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) 00537 { 00538 DrawBitmap(0, 0, *Bitmap); 00539 } 00540 } 00541 00542 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00543 00544 mChanged = false; 00545 mBitmapModified = false; 00546 } 00547 00548 00549 class cHdffOsdRaw : public cOsd 00550 { 00551 private: 00552 HDFF::cHdffCmdIf * mHdffCmdIf; 00553 int mDispWidth; 00554 int mDispHeight; 00555 bool refresh; 00556 uint32_t mDisplay; 00557 uint32_t mBitmapPalette; 00558 uint32_t mBitmapColors[256]; 00559 uint32_t mBitmapNumColors; 00560 00561 protected: 00562 virtual void SetActive(bool On); 00563 public: 00564 cHdffOsdRaw(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level); 00565 virtual ~cHdffOsdRaw(); 00566 virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); 00567 virtual eOsdError SetAreas(const tArea *Areas, int NumAreas); 00568 virtual void Flush(void); 00569 }; 00570 00571 cHdffOsdRaw::cHdffOsdRaw(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level) 00572 : cOsd(Left, Top, Level) 00573 { 00574 double pixelAspect; 00575 00576 //printf("cHdffOsdRaw %d, %d, %d\n", Left, Top, Level); 00577 mHdffCmdIf = pHdffCmdIf; 00578 refresh = true; 00579 mBitmapPalette = HDFF_INVALID_HANDLE; 00580 mDisplay = HDFF_INVALID_HANDLE; 00581 00582 gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect); 00583 } 00584 00585 cHdffOsdRaw::~cHdffOsdRaw() 00586 { 00587 //printf("~cHdffOsdRaw %d %d\n", Left(), Top()); 00588 if (mDisplay != HDFF_INVALID_HANDLE) 00589 { 00590 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); 00591 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00592 } 00593 if (mBitmapPalette != HDFF_INVALID_HANDLE) 00594 mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette); 00595 mBitmapPalette = HDFF_INVALID_HANDLE; 00596 if (mDisplay != HDFF_INVALID_HANDLE) 00597 mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay); 00598 mDisplay = HDFF_INVALID_HANDLE; 00599 } 00600 00601 void cHdffOsdRaw::SetActive(bool On) 00602 { 00603 if (On != Active()) 00604 { 00605 cOsd::SetActive(On); 00606 if (On) 00607 { 00608 if (mDisplay == HDFF_INVALID_HANDLE) 00609 { 00610 mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF_COLOR_TYPE_ARGB8888); 00611 if (mDisplay != HDFF_INVALID_HANDLE) 00612 mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, HDFF_SIZE_FULL_SCREEN, HDFF_SIZE_FULL_SCREEN); 00613 } 00614 refresh = true; 00615 if (GetBitmap(0)) // only flush here if there are already bitmaps 00616 Flush(); 00617 } 00618 else 00619 { 00620 if (mDisplay != HDFF_INVALID_HANDLE) 00621 { 00622 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); 00623 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00624 } 00625 if (mBitmapPalette != HDFF_INVALID_HANDLE) 00626 mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette); 00627 mBitmapPalette = HDFF_INVALID_HANDLE; 00628 if (mDisplay != HDFF_INVALID_HANDLE) 00629 mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay); 00630 mDisplay = HDFF_INVALID_HANDLE; 00631 } 00632 } 00633 } 00634 00635 eOsdError cHdffOsdRaw::CanHandleAreas(const tArea *Areas, int NumAreas) 00636 { 00637 eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); 00638 if (Result == oeOk) 00639 { 00640 for (int i = 0; i < NumAreas; i++) 00641 { 00642 if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8 00643 && (Areas[i].bpp != 32 || !gHdffSetup.TrueColorOsd)) 00644 return oeBppNotSupported; 00645 } 00646 } 00647 return Result; 00648 } 00649 00650 eOsdError cHdffOsdRaw::SetAreas(const tArea *Areas, int NumAreas) 00651 { 00652 for (int i = 0; i < NumAreas; i++) 00653 { 00654 //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); 00655 } 00656 if (mDisplay != HDFF_INVALID_HANDLE) 00657 { 00658 mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); 00659 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00660 refresh = true; 00661 } 00662 return cOsd::SetAreas(Areas, NumAreas); 00663 } 00664 00665 void cHdffOsdRaw::Flush(void) 00666 { 00667 if (!Active() || (mDisplay == HDFF_INVALID_HANDLE)) 00668 return; 00669 //struct timeval start; 00670 //struct timeval end; 00671 //struct timezone timeZone; 00672 //gettimeofday(&start, &timeZone); 00673 00674 bool render = false; 00675 if (IsTrueColor()) 00676 { 00677 LOCK_PIXMAPS; 00678 while (cPixmapMemory *pm = RenderPixmaps()) 00679 { 00680 int w = pm->ViewPort().Width(); 00681 int h = pm->ViewPort().Height(); 00682 int d = w * sizeof(tColor); 00683 int Chunk = MAX_BITMAP_SIZE / w / sizeof(tColor); 00684 if (Chunk > h) 00685 Chunk = h; 00686 for (int y = 0; y < h; y += Chunk) 00687 { 00688 int hc = Chunk; 00689 if (y + hc > h) 00690 hc = h - y; 00691 mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, 00692 Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y() + y, 00693 pm->Data() + y * d, w, hc, hc * d, 00694 HDFF_COLOR_TYPE_ARGB8888, HDFF_INVALID_HANDLE); 00695 } 00696 delete pm; 00697 render = true; 00698 } 00699 } 00700 else 00701 { 00702 uint8_t * buffer = new uint8_t[MAX_BITMAP_SIZE]; 00703 if (!buffer) 00704 return; 00705 cBitmap * bitmap; 00706 for (int i = 0; (bitmap = GetBitmap(i)) != NULL; i++) 00707 { 00708 int x1 = 0, y1 = 0, x2 = 0, y2 = 0; 00709 if (refresh || bitmap->Dirty(x1, y1, x2, y2)) 00710 { 00711 if (refresh) 00712 { 00713 x2 = bitmap->Width() - 1; 00714 y2 = bitmap->Height() - 1; 00715 } 00716 // commit colors: 00717 int numColors; 00718 const tColor * colors = bitmap->Colors(numColors); 00719 if (colors) 00720 { 00721 for (int c = 0; c < numColors; c++) 00722 mBitmapColors[c] = colors[c]; 00723 if (mBitmapPalette == HDFF_INVALID_HANDLE) 00724 { 00725 mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF_COLOR_TYPE_CLUT8, 00726 HDFF_COLOR_FORMAT_ARGB, numColors, mBitmapColors); 00727 } 00728 else 00729 { 00730 mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette, 00731 HDFF_COLOR_FORMAT_ARGB, 0, numColors, mBitmapColors); 00732 } 00733 } 00734 // commit modified data: 00735 int width = x2 - x1 + 1; 00736 int height = y2 - y1 + 1; 00737 int chunk = MAX_BITMAP_SIZE / width; 00738 if (chunk > height) 00739 chunk = height; 00740 for (int y = 0; y < height; y += chunk) 00741 { 00742 int hc = chunk; 00743 if (y + hc > height) 00744 hc = height - y; 00745 for (int r = 0; r < hc; r++) 00746 memcpy(buffer + r * width, bitmap->Data(x1, y1 + y + r), width); 00747 mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, 00748 Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1 + y, 00749 buffer, width, hc, hc * width, 00750 HDFF_COLOR_TYPE_CLUT8, mBitmapPalette); 00751 } 00752 render = true; 00753 } 00754 bitmap->Clean(); 00755 } 00756 delete[] buffer; 00757 } 00758 if (render) 00759 { 00760 mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); 00761 //gettimeofday(&end, &timeZone); 00762 //int timeNeeded = end.tv_usec - start.tv_usec; 00763 //timeNeeded += (end.tv_sec - start.tv_sec) * 1000000; 00764 //printf("time = %d\n", timeNeeded); 00765 } 00766 refresh = false; 00767 } 00768 00769 00770 00771 00772 cHdffOsdProvider::cHdffOsdProvider(HDFF::cHdffCmdIf * HdffCmdIf) 00773 { 00774 mHdffCmdIf = HdffCmdIf; 00775 } 00776 00777 cOsd *cHdffOsdProvider::CreateOsd(int Left, int Top, uint Level) 00778 { 00779 //printf("CreateOsd %d %d %d\n", Left, Top, Level); 00780 if (gHdffSetup.HighLevelOsd) 00781 return new cHdffOsd(Left, Top, mHdffCmdIf, Level); 00782 else 00783 return new cHdffOsdRaw(Left, Top, mHdffCmdIf, Level); 00784 } 00785 00786 bool cHdffOsdProvider::ProvidesTrueColor(void) 00787 { 00788 return gHdffSetup.TrueColorOsd && !gHdffSetup.HighLevelOsd; 00789 }