vdr  1.7.31
include/vdr/osd.h
Go to the documentation of this file.
1 /*
2  * osd.h: Abstract On Screen Display layer
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: osd.h 2.17 2012/06/02 10:32:38 kls Exp $
8  */
9 
10 #ifndef __OSD_H
11 #define __OSD_H
12 
13 #include <limits.h>
14 #include <stdio.h>
15 #include <stdint.h>
16 #include "config.h"
17 #include "font.h"
18 #include "thread.h"
19 #include "tools.h"
20 
21 #define OSD_LEVEL_DEFAULT 0
22 #define OSD_LEVEL_SUBTITLES 10
23 
24 #define MAXNUMCOLORS 256
25 #define ALPHA_TRANSPARENT 0x00
26 #define ALPHA_OPAQUE 0xFF
27 #define IS_OPAQUE(c) ((c >> 24) == ALPHA_OPAQUE)
28 #define TEXT_ALIGN_BORDER 10 // fraction of the font height used for sizing border
29 
30 enum {
31  //AARRGGBB
32  clrTransparent = 0x00000000,
33  clrGray50 = 0x7F000000, // 50% gray
34  clrBlack = 0xFF000000,
35  clrRed = 0xFFFC1414,
36  clrGreen = 0xFF24FC24,
37  clrYellow = 0xFFFCC024,
38  clrMagenta = 0xFFB000FC,
39  clrBlue = 0xFF0000FC,
40  clrCyan = 0xFF00FCFC,
41  clrWhite = 0xFFFCFCFC,
42  };
43 
44 enum eOsdError { oeOk, // see also OsdErrorTexts in osd.c
53  };
54 
55 typedef uint32_t tColor; // see also font.h
56 typedef uint8_t tIndex;
57 
58 inline tColor ArgbToColor(uint8_t A, uint8_t R, uint8_t G, uint8_t B)
59 {
60  return (tColor(A) << 24) | (tColor(R) << 16) | (tColor(G) << 8) | B;
61 }
62 
63 inline tColor RgbToColor(uint8_t R, uint8_t G, uint8_t B)
64 {
65  return (tColor(R) << 16) | (tColor(G) << 8) | B;
66 }
67 
68 inline tColor RgbToColor(double R, double G, double B)
69 {
70  return RgbToColor(uint8_t(0xFF * R), uint8_t(0xFF * G), uint8_t(0xFF * B));
71 }
72 
73 tColor RgbShade(tColor Color, double Factor);
80 
81 tColor HsvToColor(double H, double S, double V);
85 
86 tColor AlphaBlend(tColor ColorFg, tColor ColorBg, uint8_t AlphaLayer = ALPHA_OPAQUE);
87 
88 class cPalette {
89 private:
91  int bpp;
93  bool modified;
95 protected:
97 public:
98  cPalette(int Bpp = 8);
100  virtual ~cPalette();
101  void SetAntiAliasGranularity(uint FixedColors, uint BlendColors);
111  int Bpp(void) const { return bpp; }
112  void Reset(void);
114  int Index(tColor Color);
119  tColor Color(int Index) const { return Index < maxColors ? color[Index] : 0; }
122  void SetBpp(int Bpp);
125  void SetColor(int Index, tColor Color);
129  const tColor *Colors(int &NumColors) const;
134  void Take(const cPalette &Palette, tIndexes *Indexes = NULL, tColor ColorFg = 0, tColor ColorBg = 0);
141  void Replace(const cPalette &Palette);
144  tColor Blend(tColor ColorFg, tColor ColorBg, uint8_t Level) const;
150  int ClosestColor(tColor Color, int MaxDiff = INT_MAX) const;
156  };
157 
158 enum eTextAlignment { taCenter = 0x00,
159  taLeft = 0x01,
160  taRight = 0x02,
161  taTop = 0x04,
162  taBottom = 0x08,
163  taBorder = 0x10, // keeps some distance from the left or right alignment edge
165  };
166 
167 class cFont;
168 
169 class cBitmap : public cPalette {
170 private:
172  int x0, y0;
173  int width, height;
175 public:
176  cBitmap(int Width, int Height, int Bpp, int X0 = 0, int Y0 = 0);
181  cBitmap(const char *FileName);
183  cBitmap(const char *const Xpm[]);
185  virtual ~cBitmap();
186  int X0(void) const { return x0; }
187  int Y0(void) const { return y0; }
188  int Width(void) const { return width; }
189  int Height(void) const { return height; }
190  void SetSize(int Width, int Height);
195  bool Contains(int x, int y) const;
197  bool Covers(int x1, int y1, int x2, int y2) const;
200  bool Intersects(int x1, int y1, int x2, int y2) const;
203  bool Dirty(int &x1, int &y1, int &x2, int &y2);
206  void Clean(void);
208  bool LoadXpm(const char *FileName);
211  bool SetXpm(const char *const Xpm[], bool IgnoreNone = false);
221  void SetIndex(int x, int y, tIndex Index);
224  void DrawPixel(int x, int y, tColor Color);
228  void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool ReplacePalette = false, bool Overlay = false);
238  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);
244  void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
249  void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0);
259  void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type);
271  const tIndex *Data(int x, int y) const;
273  tColor GetColor(int x, int y) const { return Color(*Data(x, y)); }
275  void ReduceBpp(const cPalette &Palette);
281  void ShrinkBpp(int NewBpp);
286  cBitmap *Scaled(double FactorX, double FactorY, bool AntiAlias = false);
292  };
293 
294 struct tArea {
295  int x1, y1, x2, y2;
296  int bpp;
297  int Width(void) const { return x2 - x1 + 1; }
298  int Height(void) const { return y2 - y1 + 1; }
299  bool Intersects(const tArea &Area) const { return !(x2 < Area.x1 || x1 > Area.x2 || y2 < Area.y1 || y1 > Area.y2); }
300  };
301 
302 class cPoint {
303 private:
304  int x;
305  int y;
306 public:
307  cPoint(void) { x = y = 0; }
308  cPoint(int X, int Y) { x = X; y = Y; }
309  cPoint(const cPoint &Point) { x = Point.X(); y = Point.Y(); }
310  bool operator==(const cPoint &Point) const { return x == Point.X() && y == Point.Y(); }
311  bool operator!=(const cPoint &Point) const { return !(*this == Point); }
312  cPoint operator-(void) const { return cPoint(-x, -y); }
313  cPoint operator-(const cPoint &Point) const { return cPoint(x - Point.X(), y - Point.Y()); }
314  int X(void) const { return x; }
315  int Y(void) const { return y; }
316  void SetX(int X) { x = X; }
317  void SetY(int Y) { y = Y; }
318  void Set(int X, int Y) { x = X; y = Y; }
319  void Set(const cPoint &Point) { x = Point.X(); y = Point.Y(); }
320  void Shift(int Dx, int Dy) { x += Dx; y += Dy; }
321  void Shift(const cPoint &Dp) { x += Dp.X(); y += Dp.Y(); }
322  cPoint Shifted(int Dx, int Dy) const { cPoint p(*this); p.Shift(Dx, Dy); return p; }
323  cPoint Shifted(const cPoint &Dp) const { cPoint p(*this); p.Shift(Dp); return p; }
324  };
325 
326 class cSize {
327 private:
328  int width;
329  int height;
330 public:
331  cSize(void) { width = height = 0; }
332  cSize(int Width, int Height) { width = Width; height = Height; }
333  cSize(const cSize &Size) { width = Size.Width(); height = Size.Height(); }
334  bool operator==(const cSize &Size) const { return width == Size.Width() && height == Size.Height(); }
335  bool operator!=(const cSize &Size) const { return !(*this == Size); }
336  bool operator<(const cSize &Size) const { return width < Size.Width() && height < Size.Height(); }
337  int Width(void) const { return width; }
338  int Height(void) const { return height; }
339  void SetWidth(int Width) { width = Width; }
340  void SetHeight(int Height) { height = Height; }
341  void Set(int Width, int Height) { width = Width; height = Height; }
342  void Set(const cSize &Size) { width = Size.Width(); height = Size.Height(); }
343  bool Contains(const cPoint &Point) const { return 0 <= Point.X() && 0 <= Point.Y() && Point.X() < width && Point.Y() < height; }
344  void Grow(int Dw, int Dh) { width += 2 * Dw; height += 2 * Dh; }
345  cSize Grown(int Dw, int Dh) const { cSize s(*this); s.Grow(Dw, Dh); return s; }
346  };
347 
348 class cRect {
349 private:
352 public:
353  static const cRect Null;
354  cRect(void): point(0, 0), size(0, 0) {}
355  cRect(int X, int Y, int Width, int Height): point(X, Y), size(Width, Height) {}
356  cRect(const cPoint &Point, const cSize &Size): point(Point), size(Size) {}
357  cRect(const cSize &Size): point(0, 0), size(Size) {}
358  cRect(const cRect &Rect): point(Rect.Point()), size(Rect.Size()) {}
359  bool operator==(const cRect &Rect) const { return point == Rect.Point() && size == Rect.Size(); }
360  bool operator!=(const cRect &Rect) const { return !(*this == Rect); }
361  int X(void) const { return point.X(); }
362  int Y(void) const { return point.Y(); }
363  int Width(void) const { return size.Width(); }
364  int Height(void) const { return size.Height(); }
365  int Left(void) const { return X(); }
366  int Top(void) const { return Y(); }
367  int Right(void) const { return X() + Width() - 1; }
368  int Bottom(void) const { return Y() + Height() - 1; }
369  const cPoint &Point(void) const { return point; }
370  const cSize &Size(void) const { return size; }
371  void Set(int X, int Y, int Width, int Height) { point.Set(X, Y); size.Set(Width, Height); }
372  void Set(cPoint Point, cSize Size) { point.Set(Point); size.Set(Size); }
373  void SetPoint(int X, int Y) { point.Set(X, Y); }
374  void SetPoint(const cPoint &Point) { point.Set(Point); }
375  void SetSize(int Width, int Height) { size.Set(Width, Height); }
376  void SetSize(const cSize &Size) { size.Set(Size); }
377  void SetX(int X) { point.SetX(X); }
378  void SetY(int Y) { point.SetY(Y); }
379  void SetWidth(int Width) { size.SetWidth(Width); }
380  void SetHeight(int Height) { size.SetHeight(Height); }
381  void SetLeft(int Left) { SetWidth(Width() + X() - Left); SetX(Left); }
382  void SetTop(int Top) { SetHeight(Height() + Y() - Top); SetY(Top); }
383  void SetRight(int Right) { SetWidth(Right - X() + 1); }
384  void SetBottom(int Bottom) { SetHeight(Bottom - Y() + 1); }
385  void Shift(int Dx, int Dy) { point.Shift(Dx, Dy); }
386  void Shift(const cPoint &Dp) { point.Shift(Dp); }
387  cRect Shifted(int Dx, int Dy) const { cRect r(*this); r.Shift(Dx, Dy); return r; }
388  cRect Shifted(const cPoint &Dp) const { cRect r(*this); r.Shift(Dp); return r; }
389  void Grow(int Dx, int Dy);
392  cRect Grown(int Dw, int Dh) const { cRect r(*this); r.Grow(Dw, Dh); return r; }
393  bool Contains(const cPoint &Point) const;
395  bool Contains(const cRect &Rect) const;
397  bool Intersects(const cRect &Rect) const;
399  cRect Intersected(const cRect &Rect) const;
401  void Combine(const cRect &Rect);
403  cRect Combined(const cRect &Rect) const { cRect r(*this); r.Combine(Rect); return r; }
406  void Combine(const cPoint &Point);
408  cRect Combined(const cPoint &Point) const { cRect r(*this); r.Combine(Point); return r; }
411  bool IsEmpty(void) const { return Width() <= 0 || Height() <= 0; }
413  };
414 
415 class cImage {
416 private:
419 public:
420  cImage(void);
421  cImage(const cImage &Image);
422  cImage(const cSize &Size, const tColor *Data = NULL);
429  virtual ~cImage();
430  const cSize &Size(void) const { return size; }
431  int Width(void) const { return size.Width(); }
432  int Height(void) const { return size.Height(); }
433  const tColor *Data(void) const { return data; }
434  tColor GetPixel(const cPoint &Point) const { return data[size.Width() * Point.Y() + Point.X()]; }
438  void SetPixel(const cPoint &Point, tColor Color) { data[size.Width() * Point.Y() + Point.X()] = Color; }
442  void Clear(void);
444  void Fill(tColor Color);
446  };
447 
448 #define MAXPIXMAPLAYERS 8
449 
450 class cPixmap {
451  friend class cOsd;
452  friend class cPixmapMutexLock;
453 private:
454  static cMutex mutex;
455  int layer;
456  int alpha;
457  bool tile;
462 protected:
463  virtual ~cPixmap() {}
464  void MarkViewPortDirty(const cRect &Rect);
468  void MarkViewPortDirty(const cPoint &Point);
472  void MarkDrawPortDirty(const cRect &Rect);
478  void MarkDrawPortDirty(const cPoint &Point);
484  void SetClean(void);
486  virtual void DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty);
491 public:
492  cPixmap(void);
493  cPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
521  static void Lock(void) { mutex.Lock(); }
527  static void Unlock(void) { mutex.Unlock(); }
528  int Layer(void) const { return layer; }
529  int Alpha(void) const { return alpha; }
530  bool Tile(void) const { return tile; }
531  const cRect &ViewPort(void) const { return viewPort; }
535  const cRect &DrawPort(void) const { return drawPort; }
539  const cRect &DirtyViewPort(void) const { return dirtyViewPort; }
546  const cRect &DirtyDrawPort(void) const { return dirtyDrawPort; }
553  virtual void SetLayer(int Layer);
560  virtual void SetAlpha(int Alpha);
565  virtual void SetTile(bool Tile);
571  virtual void SetViewPort(const cRect &Rect);
575  virtual void SetDrawPortPoint(const cPoint &Point, bool Dirty = true);
584  virtual void Clear(void) = 0;
587  virtual void Fill(tColor Color) = 0;
590  virtual void DrawImage(const cPoint &Point, const cImage &Image) = 0;
592  virtual void DrawImage(const cPoint &Point, int ImageHandle) = 0;
597  virtual void DrawPixel(const cPoint &Point, tColor Color) = 0;
602  virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false) = 0;
613  virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault) = 0;
619  virtual void DrawRectangle(const cRect &Rect, tColor Color) = 0;
621  virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0) = 0;
630  virtual void DrawSlope(const cRect &Rect, tColor Color, int Type) = 0;
641  virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) = 0;
645  virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) = 0;
650  virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null) = 0;
654  virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null) = 0;
666  };
667 
668 class cPixmapMutexLock : public cMutexLock {
669 public:
671  };
672 
673 #define LOCK_PIXMAPS cPixmapMutexLock PixmapMutexLock
674 
675 // cPixmapMemory is an implementation of cPixmap that uses an array of tColor
676 // values to store the pixmap.
677 
678 class cPixmapMemory : public cPixmap {
679 private:
681  bool panning;
682 public:
683  cPixmapMemory(void);
684  cPixmapMemory(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
685  virtual ~cPixmapMemory();
686  const uint8_t *Data(void) { return (uint8_t *)data; }
687  virtual void Clear(void);
688  virtual void Fill(tColor Color);
689  virtual void DrawImage(const cPoint &Point, const cImage &Image);
690  virtual void DrawImage(const cPoint &Point, int ImageHandle);
691  virtual void DrawPixel(const cPoint &Point, tColor Color);
692  virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false);
693  virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
694  virtual void DrawRectangle(const cRect &Rect, tColor Color);
695  virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0);
696  virtual void DrawSlope(const cRect &Rect, tColor Color, int Type);
697  virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest);
698  virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest);
699  virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null);
700  virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null);
701  };
702 
703 #define MAXOSDAREAS 16
704 #define MAXOSDPIXMAPS 64
705 
716 
717 class cOsd {
718  friend class cOsdProvider;
719 private:
722  static cMutex mutex;
731  uint level;
732  bool active;
733 protected:
734  cOsd(int Left, int Top, uint Level);
754  bool Active(void) { return active; }
755  virtual void SetActive(bool On) { active = On; }
758  const cPixmap * const *Pixmaps(void) { return pixmaps; }
760  int NumPixmaps(void) { return numPixmaps; }
762  cPixmap *AddPixmap(cPixmap *Pixmap);
784 public:
785  virtual ~cOsd();
787  static int OsdLeft(void) { return osdLeft ? osdLeft : Setup.OSDLeft; }
788  static int OsdTop(void) { return osdTop ? osdTop : Setup.OSDTop; }
789  static int OsdWidth(void) { return osdWidth ? osdWidth : Setup.OSDWidth; }
790  static int OsdHeight(void) { return osdHeight ? osdHeight : Setup.OSDHeight; }
791  static void SetOsdPosition(int Left, int Top, int Width, int Height);
796  static int IsOpen(void) { return Osds.Size() && Osds[0]->level == OSD_LEVEL_DEFAULT; }
798  bool IsTrueColor(void) const { return isTrueColor; }
801  int Left(void) { return left; }
802  int Top(void) { return top; }
803  int Width(void) { return width; }
804  int Height(void) { return height; }
805  void SetAntiAliasGranularity(uint FixedColors, uint BlendColors);
816  cBitmap *GetBitmap(int Area);
822  virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
828  virtual void DestroyPixmap(cPixmap *Pixmap);
833  virtual void DrawImage(const cPoint &Point, const cImage &Image);
836  virtual void DrawImage(const cPoint &Point, int ImageHandle);
842  virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
850  virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
862  virtual void SaveRegion(int x1, int y1, int x2, int y2);
866  virtual void RestoreRegion(void);
869  virtual eOsdError SetPalette(const cPalette &Palette, int Area);
872  virtual void DrawPixel(int x, int y, tColor Color);
878  virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool ReplacePalette = false, bool Overlay = false);
889  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);
895  virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
898  virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0);
908  virtual void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type);
920  virtual void Flush(void);
934  };
935 
936 #define MAXOSDIMAGES 64
937 
939  friend class cPixmapMemory;
940 private:
942  static int oldWidth;
943  static int oldHeight;
944  static double oldAspect;
946 protected:
947  virtual cOsd *CreateOsd(int Left, int Top, uint Level) = 0;
950  virtual bool ProvidesTrueColor(void) { return false; }
952  virtual int StoreImageData(const cImage &Image);
963  virtual void DropImageData(int ImageHandle);
965  static const cImage *GetImageData(int ImageHandle);
967 public:
968  cOsdProvider(void);
969  //XXX maybe parameter to make this one "sticky"??? (frame-buffer etc.)
970  virtual ~cOsdProvider();
971  static cOsd *NewOsd(int Left, int Top, uint Level = OSD_LEVEL_DEFAULT);
977  static void UpdateOsdSize(bool Force = false);
982  static bool SupportsTrueColor(void);
984  static int StoreImage(const cImage &Image);
994  static void DropImage(int ImageHandle);
997  static void Shutdown(void);
999  };
1000 
1002 private:
1005  const cFont *font;
1009  void DrawText(void);
1010 public:
1011  cTextScroller(void);
1012  cTextScroller(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg);
1013  void Set(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg);
1014  void Reset(void);
1015  int Left(void) { return left; }
1016  int Top(void) { return top; }
1017  int Width(void) { return width; }
1018  int Height(void) { return height; }
1019  int Total(void) { return textWrapper.Lines(); }
1020  int Offset(void) { return offset; }
1021  int Shown(void) { return shown; }
1022  bool CanScroll(void) { return CanScrollUp() || CanScrollDown(); }
1023  bool CanScrollUp(void) { return offset > 0; }
1024  bool CanScrollDown(void) { return offset + shown < Total(); }
1025  void Scroll(bool Up, bool Page);
1026  };
1027 
1028 #endif //__OSD_H