13 #include <sys/ioctl.h> 15 #include <sys/unistd.h> 25 double p = V * (1 - S);
26 double q = V * (1 - S * f);
27 double t = V * (1 - S * (1 - f));
45 double f = fabs(
constrain(Factor, -1.0, 1.0));
46 double w = Factor > 0 ? f * 0xFF : 0;
47 return (Color & 0xFF000000) |
48 (
min(0xFF,
int((1 - f) * ((Color >> 16) & 0xFF) + w + 0.5)) << 16) |
49 (
min(0xFF,
int((1 - f) * ((Color >> 8) & 0xFF) + w + 0.5)) << 8) |
50 (
min(0xFF,
int((1 - f) * ( Color & 0xFF) + w + 0.5)) );
65 for (
int alphaA = 0; alphaA < 255; alphaA++) {
66 int range = (alphaA == 255 ? 255 : 254);
67 for (
int alphaB = 0; alphaB < 256; alphaB++) {
68 int alphaO_x_range = 255 * alphaA + alphaB * (range - alphaA);
71 int factorA = (256 * 255 * alphaA + alphaO_x_range / 2) / alphaO_x_range;
72 int factorB = (256 * alphaB * (range - alphaA) + alphaO_x_range / 2) / alphaO_x_range;
83 tColor Alpha = (ColorFg & 0xFF000000) >> 24;
86 uint16_t *lut = &
AlphaLutFactors[Alpha][(ColorBg & 0xFF000000) >> 24][0];
88 | (((((ColorFg & 0x00FF00FF) * lut[0] + (ColorBg & 0x00FF00FF) * lut[1])) & 0xFF00FF00)
89 | ((((ColorFg & 0x0000FF00) * lut[0] + (ColorBg & 0x0000FF00) * lut[1])) & 0x00FF0000)) >> 8);
97 tColor RB = (Color & 0x00FF00FF) * Alpha;
98 RB = ((RB + ((RB >> 8) & 0x00FF00FF) + 0x00800080) >> 8) & 0x00FF00FF;
99 tColor AG = ((Color >> 8) & 0x00FF00FF) * Alpha;
100 AG = ((AG + ((AG >> 8) & 0x00FF00FF) + 0x00800080)) & 0xFF00FF00;
106 tColor Alpha = (ColorFg & 0xFF000000) >> 24;
109 Alpha = ((Alpha + ((Alpha >> 8) & 0x000000FF) + 0x00000080) >> 8) & 0x000000FF;
111 return Multiply(ColorFg, Alpha) + Multiply(ColorBg, 255 - Alpha);
120 SetAntiAliasGranularity(10, 10);
133 int ColorsPerBlend = ColorsForBlending / BlendColors + 2;
134 antiAliasGranularity = double(
MAXNUMCOLORS - 1) / (ColorsPerBlend - 1);
147 for (
int i = 0; i < numColors; i++) {
148 if (color[i] == Color)
152 int i = ClosestColor(Color, 4);
156 if (numColors < maxColors) {
157 color[numColors++] = Color;
159 return numColors - 1;
162 return ClosestColor(Color);
168 maxColors = 1 << bpp;
174 if (Index < maxColors) {
175 if (numColors <= Index) {
176 numColors = Index + 1;
180 modified |= color[Index] != Color;
181 color[Index] = Color;
187 NumColors = numColors;
188 return numColors ? color : NULL;
193 for (
int i = 0; i < Palette.
numColors; i++) {
195 if (ColorFg || ColorBg) {
197 case 0: Color = ColorBg;
break;
198 case 1: Color = ColorFg;
break;
202 int n = Index(Color);
210 for (
int i = 0; i < Palette.
numColors; i++)
211 SetColor(i, Palette.
color[i]);
218 if (antiAliasGranularity > 0)
219 Level = uint8_t(
int(Level / antiAliasGranularity + 0.5) * antiAliasGranularity);
220 int Af = (ColorFg & 0xFF000000) >> 24;
221 int Rf = (ColorFg & 0x00FF0000) >> 16;
222 int Gf = (ColorFg & 0x0000FF00) >> 8;
223 int Bf = (ColorFg & 0x000000FF);
224 int Ab = (ColorBg & 0xFF000000) >> 24;
225 int Rb = (ColorBg & 0x00FF0000) >> 16;
226 int Gb = (ColorBg & 0x0000FF00) >> 8;
227 int Bb = (ColorBg & 0x000000FF);
228 int A = (Ab + (Af - Ab) * Level / 0xFF) & 0xFF;
229 int R = (Rb + (Rf - Rb) * Level / 0xFF) & 0xFF;
230 int G = (Gb + (Gf - Gb) * Level / 0xFF) & 0xFF;
231 int B = (Bb + (Bf - Bb) * Level / 0xFF) & 0xFF;
232 return (A << 24) | (R << 16) | (G << 8) | B;
239 int A1 = (Color & 0xFF000000) >> 24;
240 int R1 = (Color & 0x00FF0000) >> 16;
241 int G1 = (Color & 0x0000FF00) >> 8;
242 int B1 = (Color & 0x000000FF);
243 for (
int i = 0; i < numColors && d > 0; i++) {
244 int A2 = (color[i] & 0xFF000000) >> 24;
245 int R2 = (color[i] & 0x00FF0000) >> 16;
246 int G2 = (color[i] & 0x0000FF00) >> 8;
247 int B2 = (color[i] & 0x000000FF);
250 diff = (abs(A1 - A2) << 1) + (abs(R1 - R2) << 1) + (abs(G1 - G2) << 1) + (abs(B1 - B2) << 1);
256 return d <= MaxDiff ? n : -1;
311 esyslog(
"ERROR: can't allocate bitmap!");
321 return 0 <= x && x <
width && 0 <= y && y <
height;
330 return x1 <= 0 && y1 <= 0 && x2 >=
width - 1 && y2 >=
height - 1;
339 return !(x2 < 0 || x1 >=
width || y2 < 0 || y1 >=
height);
365 FILE *f = fopen(FileName,
"r");
373 while ((s = ReadLine.
Read(f)) != NULL) {
376 if (strcmp(s,
"/* XPM */") != 0) {
377 esyslog(
"ERROR: invalid header in XPM file '%s'", FileName);
382 else if (*s++ ==
'"') {
385 if (4 != sscanf(s,
"%d %d %d %d", &w, &h, &n, &c)) {
386 esyslog(
"ERROR: faulty 'values' line in XPM file '%s'", FileName);
391 Xpm =
MALLOC(
char *, lines);
392 memset(Xpm, 0, lines *
sizeof(
char*));
394 char *q = strchr(s,
'"');
396 esyslog(
"ERROR: missing quotes in XPM file '%s'", FileName);
402 Xpm[index++] = strdup(s);
404 esyslog(
"ERROR: too many lines in XPM file '%s'", FileName);
414 esyslog(
"ERROR: too few lines in XPM file '%s'", FileName);
417 for (
int i = 0; i < index; i++)
424 esyslog(
"ERROR: can't open XPM file '%s'", FileName);
432 const char *
const *p = Xpm;
434 if (4 != sscanf(*p,
"%d %d %d %d", &w, &h, &n, &c)) {
435 esyslog(
"ERROR: faulty 'values' line in XPM: '%s'", *p);
439 esyslog(
"ERROR: too many colors in XPM: %d", n);
443 while (1 << (1 << b) < (IgnoreNone ? n - 1 : n))
448 for (
int i = 0; i < n; i++) {
449 const char *s = *++p;
450 if (
int(strlen(s)) < c) {
451 esyslog(
"ERROR: faulty 'colors' line in XPM: '%s'", s);
456 esyslog(
"ERROR: unknown color key in XPM: '%c'", *s);
460 if (strcasecmp(s,
"none") == 0) {
467 esyslog(
"ERROR: unknown color code in XPM: '%c'", *s);
470 tColor color = strtoul(++s, NULL, 16) | 0xFF000000;
471 SetColor((IgnoreNone && i > NoneColorIndex) ? i - 1 : i, color);
473 for (
int y = 0; y < h; y++) {
474 const char *s = *++p;
475 if (
int(strlen(s)) != w * c) {
476 esyslog(
"ERROR: faulty pixel line in XPM: %d '%s'", y, s);
479 for (
int x = 0; x < w; x++) {
480 for (
int i = 0; i <= n; i++) {
482 esyslog(
"ERROR: undefined pixel color in XPM: %d %d '%s'", x, y, s);
485 if (strncmp(Xpm[i + 1], s, c) == 0) {
486 if (i == NoneColorIndex)
488 SetIndex(x, y, (IgnoreNone && i > NoneColorIndex) ? i - 1 : i);
542 for (
int ix = 0; ix < Bitmap.
width; ix++) {
543 for (
int iy = 0; iy < Bitmap.
height; iy++) {
544 if (!Overlay || Bitmap.
bitmap[Bitmap.
width * iy + ix] != 0)
551 Take(Bitmap, &Indexes, ColorFg, ColorBg);
552 for (
int ix = 0; ix < Bitmap.
width; ix++) {
553 for (
int iy = 0; iy < Bitmap.
height; iy++) {
554 if (!Overlay || Bitmap.
bitmap[Bitmap.
width * iy + ix] != 0)
565 int w = Font->
Width(s);
568 int cw = Width ? Width : w;
569 int ch = Height ? Height : h;
570 if (!
Intersects(x, y, x + cw - 1, y + ch - 1))
574 if (Width || Height) {
577 if ((Alignment &
taLeft) != 0) {
581 else if ((Alignment &
taRight) != 0) {
589 x += (Width - w) / 2;
593 if ((Alignment &
taTop) != 0)
595 else if ((Alignment &
taBottom) != 0) {
601 y += (Height - h) / 2;
607 Font->
DrawText(
this, x, y, s, ColorFg, ColorBg, limit);
614 if (
Covers(x1, y1, x2, y2))
625 for (
int y = y1; y <= y2; y++) {
626 for (
int x = x1; x <= x2; x++)
639 int cx = (x1 + x2) / 2;
640 int cy = (y1 + y2) / 2;
641 switch (abs(Quadrants)) {
642 case 0: rx /= 2; ry /= 2;
break;
643 case 1: cx = x1; cy = y2;
break;
644 case 2: cx = x2; cy = y2;
break;
645 case 3: cx = x2; cy = y1;
break;
646 case 4: cx = x1; cy = y1;
break;
647 case 5: cx = x1; ry /= 2;
break;
648 case 6: cy = y2; rx /= 2;
break;
649 case 7: cx = x2; ry /= 2;
break;
650 case 8: cy = y1; rx /= 2;
break;
653 int TwoASquare =
max(1, 2 * rx * rx);
654 int TwoBSquare =
max(1, 2 * ry * ry);
657 int XChange = ry * ry * (1 - 2 * rx);
658 int YChange = rx * rx;
659 int EllipseError = 0;
660 int StoppingX = TwoBSquare * rx;
662 while (StoppingX >= StoppingY) {
665 case 1:
DrawRectangle(cx, cy - y, cx + x, cy - y, Color);
break;
667 case 2:
DrawRectangle(cx - x, cy - y, cx, cy - y, Color);
break;
668 case 3:
DrawRectangle(cx - x, cy + y, cx, cy + y, Color);
break;
669 case 4:
DrawRectangle(cx, cy + y, cx + x, cy + y, Color);
break;
671 case 6:
DrawRectangle(cx - x, cy - y, cx + x, cy - y, Color);
if (Quadrants == 6)
break;
672 case 8:
DrawRectangle(cx - x, cy + y, cx + x, cy + y, Color);
break;
673 case -1:
DrawRectangle(cx + x, cy - y, x2, cy - y, Color);
break;
674 case -2:
DrawRectangle(x1, cy - y, cx - x, cy - y, Color);
break;
675 case -3:
DrawRectangle(x1, cy + y, cx - x, cy + y, Color);
break;
676 case -4:
DrawRectangle(cx + x, cy + y, x2, cy + y, Color);
break;
680 StoppingY += TwoASquare;
681 EllipseError += YChange;
682 YChange += TwoASquare;
683 if (2 * EllipseError + XChange > 0) {
685 StoppingX -= TwoBSquare;
686 EllipseError += XChange;
687 XChange += TwoBSquare;
693 YChange = rx * rx * (1 - 2 * ry);
696 StoppingY = TwoASquare * ry;
697 while (StoppingX <= StoppingY) {
700 case 1:
DrawRectangle(cx, cy - y, cx + x, cy - y, Color);
break;
702 case 2:
DrawRectangle(cx - x, cy - y, cx, cy - y, Color);
break;
703 case 3:
DrawRectangle(cx - x, cy + y, cx, cy + y, Color);
break;
704 case 4:
DrawRectangle(cx, cy + y, cx + x, cy + y, Color);
break;
706 case 6:
DrawRectangle(cx - x, cy - y, cx + x, cy - y, Color);
if (Quadrants == 6)
break;
707 case 8:
DrawRectangle(cx - x, cy + y, cx + x, cy + y, Color);
break;
708 case -1:
DrawRectangle(cx + x, cy - y, x2, cy - y, Color);
break;
709 case -2:
DrawRectangle(x1, cy - y, cx - x, cy - y, Color);
break;
710 case -3:
DrawRectangle(x1, cy + y, cx - x, cy + y, Color);
break;
711 case -4:
DrawRectangle(cx + x, cy + y, x2, cy + y, Color);
break;
715 StoppingX += TwoBSquare;
716 EllipseError += XChange;
717 XChange += TwoBSquare;
718 if (2 * EllipseError + YChange > 0) {
720 StoppingY -= TwoASquare;
721 EllipseError += YChange;
722 YChange += TwoASquare;
731 bool upper = Type & 0x01;
732 bool falling = Type & 0x02;
733 bool vertical = Type & 0x04;
735 for (
int y = y1; y <= y2; y++) {
736 double c = cos((y - y1) * M_PI / (y2 - y1 + 1));
739 int x = int((x2 - x1 + 1) * c / 2);
740 if (upper && !falling || !upper && falling)
747 for (
int x = x1; x <= x2; x++) {
748 double c = cos((x - x1) * M_PI / (x2 - x1 + 1));
751 int y = int((y2 - y1 + 1) * c / 2);
767 int NewBpp = Palette.
Bpp();
768 if (
Bpp() == 4 && NewBpp == 2) {
771 bitmap[i] = (p >> 2) | ((p & 0x03) != 0);
774 else if (
Bpp() == 8) {
778 bitmap[i] = (p >> 6) | ((p & 0x30) != 0);
781 else if (NewBpp == 4) {
806 int MaxNewColors = (NewBpp == 4) ? 16 : 4;
808 for (
int i = 0; i < MaxNewColors; i++) {
811 for (
int n = 0; n < NumOldColors; n++) {
820 NewPalette.
SetColor(i, Colors[Index]);
826 for (
int n = 0; n < NumOldColors; n++) {
828 Map[n] = NewPalette.
Index(Colors[n]);
845 if (!AntiAlias || FactorX <= 1.0 && FactorY <= 1.0) {
850 for (
int y = 0; y < b->
Height(); y++) {
854 for (
int x = 0; x < b->
Width(); x++) {
855 *Dest++ = SourceRow[SourceX >> 16];
859 DestRow += b->
Width();
867 for (
int y = 0; y < b->
Height(); y++) {
869 int sy =
min(SourceY >> 16,
Height() - 2);
870 uint8_t BlendY = 0xFF - ((SourceY >> 8) & 0xFF);
871 for (
int x = 0; x < b->
Width(); x++) {
872 int sx =
min(SourceX >> 16,
Width() - 2);
873 uint8_t BlendX = 0xFF - ((SourceX >> 8) & 0xFF);
892 point.Shift(-Dx, -Dy);
898 return Left() <= Point.
X() &&
899 Top() <= Point.
Y() &&
900 Right() >= Point.
X() &&
901 Bottom() >= Point.
Y();
906 return Left() <= Rect.
Left() &&
907 Top() <= Rect.
Top() &&
908 Right() >= Rect.
Right() &&
909 Bottom() >= Rect.
Bottom();
914 return !(Left() > Rect.
Right() ||
916 Right() < Rect.
Left() ||
917 Bottom() < Rect.
Top());
923 if (!IsEmpty() && !Rect.
IsEmpty()) {
939 SetRight(
max(Right(), Rect.
Right()));
941 SetLeft(
min(Left(), Rect.
Left()));
942 SetTop(
min(Top(), Rect.
Top()));
948 Set(Point.
X(), Point.
Y(), 1, 1);
950 SetRight(
max(Right(), Point.
X()));
951 SetBottom(
max(Bottom(), Point.
Y()));
952 SetLeft(
min(Left(), Point.
X()));
953 SetTop(
min(Top(), Point.
Y()));
972 esyslog(
"ERROR: pixmap layer %d limited to %d", Layer, layer);
993 if (layer >= 0 && viewPort.Contains(Point))
994 dirtyViewPort.Combine(Point);
1001 MarkViewPortDirty(viewPort);
1003 MarkViewPortDirty(Rect.
Shifted(viewPort.Point()));
1008 if (drawPort.Contains(Point)) {
1009 dirtyDrawPort.Combine(Point);
1011 MarkViewPortDirty(viewPort);
1013 MarkViewPortDirty(Point.
Shifted(viewPort.Point()));
1019 dirtyViewPort = dirtyDrawPort =
cRect();
1032 MarkViewPortDirty(viewPort);
1035 else if (Layer >= 0) {
1037 MarkViewPortDirty(viewPort);
1048 if (Alpha != alpha) {
1049 MarkViewPortDirty(viewPort);
1059 if (drawPort.Point() !=
cPoint(0, 0) || drawPort.Width() < viewPort.Width() || drawPort.Height() < viewPort.Height())
1060 MarkViewPortDirty(viewPort);
1069 if (Rect != viewPort) {
1071 MarkViewPortDirty(viewPort);
1073 MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
1076 MarkViewPortDirty(viewPort);
1078 MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
1086 if (Point != drawPort.Point()) {
1089 MarkViewPortDirty(viewPort);
1091 MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
1093 drawPort.SetPoint(Point);
1095 MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
1109 size = Image.
Size();
1110 int l = size.
Width() * size.Height() *
sizeof(
tColor);
1112 memcpy(data, Image.
Data(), l);
1118 int l = size.
Width() * size.Height() *
sizeof(
tColor);
1121 memcpy(data, Data, l);
1149 :
cPixmap(Layer, ViewPort, DrawPort)
1197 Source.
Shift(Delta);
1200 if (Pixmap->
Layer() == 0)
1201 Copy(Pixmap, Source, Dest);
1203 Render(Pixmap, Source, Dest);
1220 if (Pixmap->
Layer() == 0)
1221 Copy(Pixmap, Source, Dest);
1223 Render(Pixmap, Source, Dest);
1238 ps -= Point.
Y() * ws;
1242 for (
int y = r.
Height(); y-- > 0; ) {
1263 if (
DrawPort().Size().Contains(Point)) {
1279 bool UseColors = ColorFg || ColorBg;
1282 for (
int y = r.
Top(); y <= r.
Bottom(); y++) {
1284 for (
int x = r.
Left(); x <= r.
Right(); x++) {
1285 tIndex Index = *Bitmap.
Data(x - Point.
X(), y - Point.
Y());
1286 if (Index || !Overlay) {
1288 *cd = Index ? ColorFg : ColorBg;
1290 *cd = Bitmap.
Color(Index);
1306 int w = Font->
Width(s);
1309 int cw = Width ? Width : w;
1310 int ch = Height ? Height : h;
1311 cRect r(x, y, cw, ch);
1314 if (Width || Height) {
1317 if ((Alignment &
taLeft) != 0) {
1321 else if ((Alignment &
taRight) != 0) {
1329 x += (Width - w) / 2;
1333 if ((Alignment &
taTop) != 0)
1335 else if ((Alignment &
taBottom) != 0) {
1341 y += (Height - h) / 2;
1345 Font->
DrawText(
this, x, y, s, ColorFg, ColorBg, limit);
1359 for (
int y = r.
Height(); y-- > 0; ) {
1365 for (
int x = r.
Width(); x-- > 0; ) {
1383 int x1 = Rect.
Left();
1384 int y1 = Rect.
Top();
1385 int x2 = Rect.
Right();
1389 int cx = (x1 + x2) / 2;
1390 int cy = (y1 + y2) / 2;
1391 switch (abs(Quadrants)) {
1392 case 0: rx /= 2; ry /= 2;
break;
1393 case 1: cx = x1; cy = y2;
break;
1394 case 2: cx = x2; cy = y2;
break;
1395 case 3: cx = x2; cy = y1;
break;
1396 case 4: cx = x1; cy = y1;
break;
1397 case 5: cx = x1; ry /= 2;
break;
1398 case 6: cy = y2; rx /= 2;
break;
1399 case 7: cx = x2; ry /= 2;
break;
1400 case 8: cy = y1; rx /= 2;
break;
1403 int TwoASquare =
max(1, 2 * rx * rx);
1404 int TwoBSquare =
max(1, 2 * ry * ry);
1407 int XChange = ry * ry * (1 - 2 * rx);
1408 int YChange = rx * rx;
1409 int EllipseError = 0;
1410 int StoppingX = TwoBSquare * rx;
1412 while (StoppingX >= StoppingY) {
1413 switch (Quadrants) {
1421 case 6:
DrawRectangle(
cRect(cx - x, cy - y, 2 * x + 1, 1), Color);
if (Quadrants == 6)
break;
1430 StoppingY += TwoASquare;
1431 EllipseError += YChange;
1432 YChange += TwoASquare;
1433 if (2 * EllipseError + XChange > 0) {
1435 StoppingX -= TwoBSquare;
1436 EllipseError += XChange;
1437 XChange += TwoBSquare;
1443 YChange = rx * rx * (1 - 2 * ry);
1446 StoppingY = TwoASquare * ry;
1447 while (StoppingX <= StoppingY) {
1448 switch (Quadrants) {
1456 case 6:
DrawRectangle(
cRect(cx - x, cy - y, 2 * x + 1, 1), Color);
if (Quadrants == 6)
break;
1465 StoppingX += TwoBSquare;
1466 EllipseError += XChange;
1467 XChange += TwoBSquare;
1468 if (2 * EllipseError + YChange > 0) {
1470 StoppingY -= TwoASquare;
1471 EllipseError += YChange;
1472 YChange += TwoASquare;
1484 bool upper = Type & 0x01;
1485 bool falling = Type & 0x02;
1486 bool vertical = Type & 0x04;
1487 int x1 = Rect.
Left();
1488 int y1 = Rect.
Top();
1489 int x2 = Rect.
Right();
1491 int w = Rect.
Width();
1494 for (
int y = y1; y <= y2; y++) {
1495 double c = cos((y - y1) * M_PI / h);
1498 int x = (x1 + x2) / 2 +
int(w * c / 2);
1499 if (upper && !falling || !upper && falling)
1506 for (
int x = x1; x <= x2; x++) {
1507 double c = cos((x - x1) * M_PI / w);
1510 int y = (y1 + y2) / 2 +
int(h * c / 2);
1525 if (
const cPixmapMemory *pm = dynamic_cast<const cPixmapMemory *>(Pixmap)) {
1532 int a = pm->Alpha();
1533 int ws = pm->DrawPort().
Width();
1537 for (
int y = d.
Height(); y-- > 0; ) {
1540 for (
int x = d.
Width(); x-- > 0; ) {
1559 if (
const cPixmapMemory *pm = dynamic_cast<const cPixmapMemory *>(Pixmap)) {
1566 int ws = pm->DrawPort().
Width();
1571 for (
int y = d.
Height(); y-- > 0; ) {
1587 if (&Source == &cRect::Null)
1602 for (
int y = d.
Height(); y-- > 0; ) {
1632 "bpp not supported",
1650 isTrueColor =
false;
1659 for (
int i = 0; i < Osds.Size(); i++) {
1660 if (Osds[i]->level > level) {
1661 Osds.Insert(
this, i);
1671 for (
int i = 0; i < numBitmaps; i++)
1675 for (
int i = 0; i < pixmaps.Size(); i++)
1677 for (
int i = 0; i < Osds.Size(); i++) {
1678 if (Osds[i] ==
this) {
1681 Osds[0]->SetActive(
true);
1699 for (
int i = 0; i < numBitmaps; i++)
1700 bitmaps[i]->SetAntiAliasGranularity(FixedColors, BlendColors);
1705 return Area < numBitmaps ? (isTrueColor ? bitmaps[0] : bitmaps[Area]) : NULL;
1713 if (AddPixmap(Pixmap))
1724 for (
int i = 1; i < pixmaps.Size(); i++) {
1725 if (pixmaps[i] == Pixmap) {
1726 if (Pixmap->
Layer() >= 0)
1733 esyslog(
"ERROR: attempt to destroy an unregistered pixmap");
1741 for (
int i = 0; i < pixmaps.Size(); i++) {
1743 return pixmaps[i] = Pixmap;
1745 pixmaps.Append(Pixmap);
1757 for (
int i = 0; i < pixmaps.Size(); i++) {
1758 if (
cPixmap *pm = pixmaps[i]) {
1759 if (!pm->DirtyViewPort().IsEmpty()) {
1761 d.
Combine(pm->DirtyViewPort());
1770 static cRect OldDirty;
1773 OldDirty = NewDirty;
1775 Pixmap = CreatePixmap(-1, d);
1780 for (
int i = 0; i < pixmaps.Size(); i++) {
1781 if (
cPixmap *pm = pixmaps[i]) {
1782 if (pm->Layer() ==
Layer)
1789 static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF };
1790 static int DirtyIndicatorIndex = 0;
1791 DirtyIndicator.
Fill(DirtyIndicatorColors[DirtyIndicatorIndex]);
1792 DirtyIndicatorIndex = 1 - DirtyIndicatorIndex;
1806 for (
int i = 0; i < NumAreas; i++) {
1807 if (Areas[i].x1 > Areas[i].x2 || Areas[i].y1 > Areas[i].y2 || Areas[i].x1 < 0 || Areas[i].y1 < 0)
1809 for (
int j = i + 1; j < NumAreas; j++) {
1810 if (Areas[i].Intersects(Areas[j])) {
1815 if (Areas[i].bpp == 32) {
1825 eOsdError Result = CanHandleAreas(Areas, NumAreas);
1826 if (Result ==
oeOk) {
1828 delete bitmaps[--numBitmaps];
1829 for (
int i = 0; i < pixmaps.Size(); i++) {
1834 isTrueColor = NumAreas == 1 && Areas[0].
bpp == 32;
1836 width = Areas[0].
x2 - Areas[0].
x1 + 1;
1837 height = Areas[0].
y2 - Areas[0].
y1 + 1;
1838 cPixmap *Pixmap = CreatePixmap(0,
cRect(Areas[0].x1, Areas[0].y1, width, height));
1840 bitmaps[numBitmaps++] =
new cBitmap(10, 10, 8);
1843 for (
int i = 0; i < NumAreas; i++) {
1844 bitmaps[numBitmaps++] =
new cBitmap(Areas[i].Width(), Areas[i].Height(), Areas[i].bpp, Areas[i].x1, Areas[i].y1);
1845 width =
max(width, Areas[i].x2 + 1);
1846 height =
max(height, Areas[i].y2 + 1);
1859 cRect r(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
1861 savedPixmap->Copy(pixmaps[0], r,
cPoint(0, 0));
1865 savedBitmap =
new cBitmap(x2 - x1 + 1, y2 - y1 + 1, 8, x1, y1);
1866 for (
int i = 0; i < numBitmaps; i++)
1867 savedBitmap->DrawBitmap(bitmaps[i]->X0(), bitmaps[i]->Y0(), *bitmaps[i]);
1875 pixmaps[0]->Copy(savedPixmap, savedPixmap->DrawPort(), savedPixmap->ViewPort().Point());
1882 DrawBitmap(savedBitmap->X0(), savedBitmap->Y0(), *savedBitmap);
1893 if (Area < numBitmaps) {
1894 bitmaps[Area]->Take(Palette);
1903 pixmaps[0]->DrawImage(Point, Image);
1909 pixmaps[0]->DrawImage(Point, ImageHandle);
1915 pixmaps[0]->DrawPixel(
cPoint(x, y), Color);
1917 for (
int i = 0; i < numBitmaps; i++)
1925 pixmaps[0]->DrawBitmap(
cPoint(x, y), Bitmap, ColorFg, ColorBg, Overlay);
1927 for (
int i = 0; i < numBitmaps; i++)
1928 bitmaps[i]->
DrawBitmap(x, y, Bitmap, ColorFg, ColorBg, ReplacePalette, Overlay);
1936 b = b->
Scaled(FactorX, FactorY, AntiAlias);
1945 pixmaps[0]->DrawText(
cPoint(x, y), s, ColorFg, ColorBg, Font, Width, Height, Alignment);
1947 for (
int i = 0; i < numBitmaps; i++)
1948 bitmaps[i]->
DrawText(x, y, s, ColorFg, ColorBg, Font, Width, Height, Alignment);
1955 pixmaps[0]->DrawRectangle(
cRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), Color);
1957 for (
int i = 0; i < numBitmaps; i++)
1965 pixmaps[0]->DrawEllipse(
cRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), Color, Quadrants);
1967 for (
int i = 0; i < numBitmaps; i++)
1968 bitmaps[i]->
DrawEllipse(x1, y1, x2, y2, Color, Quadrants);
1975 pixmaps[0]->DrawSlope(
cRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), Color, Type);
1977 for (
int i = 0; i < numBitmaps; i++)
1978 bitmaps[i]->
DrawSlope(x1, y1, x2, y2, Color, Type);
2010 esyslog(
"ERROR: attempt to open OSD while it is already open - using dummy OSD!");
2011 else if (osdProvider) {
2012 cOsd *ActiveOsd = cOsd::Osds.
Size() ? cOsd::Osds[0] : NULL;
2013 cOsd *Osd = osdProvider->CreateOsd(Left, Top, Level);
2014 if (Osd == cOsd::Osds[0]) {
2022 esyslog(
"ERROR: no OSD provider available - using dummy OSD!");
2023 return new cOsd(Left, Top, 999);
2033 if (Width != oldWidth || Height != oldHeight || !
DoubleEqual(Aspect, oldAspect) || Force) {
2048 dsyslog(
"OSD size changed to %dx%d @ %g", Width, Height, Aspect);
2056 bool Result = osdState != State;
2064 return osdProvider->ProvidesTrueColor();
2067 esyslog(
"ERROR: no OSD provider available in call to SupportsTrueColor()");
2076 images[i] =
new cImage(Image);
2087 delete images[ImageHandle];
2088 images[ImageHandle] = NULL;
2096 return images[ImageHandle];
2103 return osdProvider->StoreImageData(Image);
2110 osdProvider->DropImageData(ImageHandle);
2124 left = top = width = height = 0;
2134 Set(Osd, Left, Top, Width, Height, Text, Font, ColorFg, ColorBg);
2148 textWrapper.Set(Text, Font, Width);
2149 shown =
min(Total(), height / font->Height());
2150 height = shown * font->Height();
2162 for (
int i = 0; i < shown; i++)
2163 osd->DrawText(left, top + i * font->Height(), textWrapper.GetLine(offset + i), colorFg, colorBg, font, width);
2170 if (CanScrollUp()) {
2171 offset -= Page ? shown : 1;
2178 if (CanScrollDown()) {
2179 offset += Page ? shown : 1;
2180 if (offset + shown > Total())
2181 offset = Total() - shown;
void ReduceBpp(const cPalette &Palette)
Reduces the color depth of the bitmap to that of the given Palette.
virtual void Pan(const cPoint &Dest, const cRect &Source=cRect::Null)
Does the same as Scroll(), but also shifts the draw port accordingly, so that the view port doesn't g...
static uint8_t AlphaLutAlpha[255][256]
void SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
Allows the system to optimize utilization of the limited color palette entries when generating blende...
virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg=0, tColor ColorBg=0, bool Overlay=false)
Sets the pixels in the OSD with the data from the given Bitmap, putting the upper left corner of the ...
void Fill(tIndex Index)
Fills the bitmap data with the given Index.
bool Covers(int x1, int y1, int x2, int y2) const
Returns true if the rectangle defined by the given coordinates completely covers this bitmap...
void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg=0, tColor ColorBg=0, bool ReplacePalette=false, bool Overlay=false)
Sets the pixels in this bitmap with the data from the given Bitmap, putting the upper left corner of ...
static cImage * images[MAXOSDIMAGES]
virtual void SetViewPort(const cRect &Rect)
Sets the pixmap's view port to the given Rect.
void Shift(int Dx, int Dy)
void Clean(void)
Marks the dirty area as clean.
void Reset(void)
Resets the palette, making it contain no colors.
static cOsdProvider * osdProvider
virtual void Scroll(const cPoint &Dest, const cRect &Source=cRect::Null)
Scrolls the data in the pixmap's draw port to the given Dest point.
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas)
Sets the sub-areas to the given areas.
virtual void SetActive(bool On)
Sets this OSD to be the active one.
static const cImage * GetImageData(int ImageHandle)
Gets the image data referenced by ImageHandle.
static const char * OsdErrorTexts[]
bool SetXpm(const char *const Xpm[], bool IgnoreNone=false)
Sets this bitmap to the given XPM data.
virtual void DrawScaledBitmap(int x, int y, const cBitmap &Bitmap, double FactorX, double FactorY, bool AntiAlias=false)
Sets the pixels in the OSD with the data from the given Bitmap, putting the upper left corner of the ...
virtual void DrawPixel(const cPoint &Point, tColor Color)
Sets the pixel at the given Point to the given Color, which is a full 32 bit ARGB value...
static void SetOsdPosition(int Left, int Top, int Width, int Height)
Sets the position and size of the OSD to the given values.
virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest)
Copies the part of the given Pixmap covered by Source into this pixmap at location Dest...
const tColor * Colors(int &NumColors) const
Returns a pointer to the complete color table and stores the number of valid entries in NumColors...
virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg=0, tColor ColorBg=0, bool ReplacePalette=false, bool Overlay=false)
Sets the pixels in the OSD with the data from the given Bitmap, putting the upper left corner of the ...
static void SetFont(eDvbFont Font, const char *Name, int CharHeight)
< Draws the given text into the Pixmap at position (x, y) with the given colors.
const cRect & DrawPort(void) const
Returns the pixmap's draw port, which is relative to the view port.
int Index(tColor Color)
Returns the index of the given Color (the first color has index 0).
virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants=0)
Draws a filled ellipse defined by the upper left (x1, y1) and lower right (x2, y2) corners with the g...
void Set(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg)
tIndex tIndexes[MAXNUMCOLORS]
bool IsEmpty(void) const
Returns true if this rectangle is empty.
void MarkViewPortDirty(const cRect &Rect)
Marks the given rectangle of the view port of this pixmap as dirty.
char FontSml[MAXFONTNAME]
virtual void SetDrawPortPoint(const cPoint &Point, bool Dirty=true)
Sets the pixmap's draw port to the given Point.
void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants=0)
Draws a filled ellipse defined by the upper left (x1, y1) and lower right (x2, y2) corners with the g...
virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
Draws a filled rectangle defined by the upper left (x1, y1) and lower right (x2, y2) corners with the...
tColor Blend(tColor ColorFg, tColor ColorBg, uint8_t Level) const
Determines a color that consists of a linear blend between ColorFg and ColorBg.
virtual void GetOsdSize(int &Width, int &Height, double &PixelAspect)
Returns the Width, Height and PixelAspect ratio the OSD should use to best fit the resolution of the ...
virtual int StoreImageData(const cImage &Image)
Copies the given Image and returns a handle for later reference.
virtual eOsdError SetPalette(const cPalette &Palette, int Area)
Sets the Palette for the given Area (the first area is numbered 0).
virtual void Fill(tColor Color)
Fills the pixmap's draw port with the given Color.
static bool OsdSizeChanged(int &State)
Checks if the OSD size has changed and a currently displayed OSD needs to be redrawn.
virtual void SetAlpha(int Alpha)
Sets the alpha value of this pixmap to the given value.
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)
Draws the given string at coordinates (x, y) with the given foreground and background color and font...
virtual void Flush(void)
Actually commits all data to the OSD hardware.
void Scroll(bool Up, bool Page)
static void Lock(void)
All public member functions of cPixmap set locks as necessary to make sure they are thread-safe (unle...
cPixmap * AddPixmap(cPixmap *Pixmap)
Adds the given Pixmap to the list of currently active pixmaps in this OSD.
const cRect & ViewPort(void) const
Returns the pixmap's view port, which is relative to the OSD's origin.
void SetSize(int Width, int Height)
Sets the size of this bitmap to the given values.
void Combine(const cRect &Rect)
Combines this rectangle with the given Rect.
cRect Shifted(int Dx, int Dy) const
tColor color[MAXNUMCOLORS]
void SetPoint(int X, int Y)
void Replace(const cPalette &Palette)
Replaces the colors of this palette with the colors from the given palette.
bool Dirty(int &x1, int &y1, int &x2, int &y2)
Tells whether there is a dirty area and returns the bounding rectangle of that area (relative to the ...
bool LoadXpm(const char *FileName)
Calls SetXpm() with the data from the file FileName.
const cSize & Size(void) const
class cInitAlphaLut InitAlphaLut
virtual void DestroyPixmap(cPixmap *Pixmap)
Destroys the given Pixmap, which has previously been created by a call to CreatePixmap().
double antiAliasGranularity
static cVector< cOsd * > Osds
bool Intersects(int x1, int y1, int x2, int y2) const
Returns true if the rectangle defined by the given coordinates intersects with this bitmap...
virtual void DrawRectangle(const cRect &Rect, tColor Color)
Draws a filled rectangle with the given Color.
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas)
Checks whether the OSD can display the given set of sub-areas.
const tColor * Data(void) const
char FontOsd[MAXFONTNAME]
void SetBottom(int Bottom)
virtual ~cOsd()
Shuts down the OSD.
void DrawPixel(int x, int y, tColor Color)
Sets the pixel at the given coordinates to the given Color, which is a full 32 bit ARGB value...
void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type)
Draws a "slope" into the rectangle defined by the upper left (x1, y1) and lower right (x2...
bool Contains(const cPoint &Point) const
Returns true if this rectangle contains Point.
void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
Draws a filled rectangle defined by the upper left (x1, y1) and lower right (x2, y2) corners with the...
tColor RgbShade(tColor Color, double Factor)
Returns a brighter (Factor > 0) or darker (Factor < 0) version of the given Color.
tColor AlphaBlend(tColor ColorFg, tColor ColorBg, uint8_t AlphaLayer)
static void UpdateOsdSize(bool Force=false)
Inquires the actual size of the video display and adjusts the OSD and font sizes accordingly.
bool Contains(int x, int y) const
Returns true if this bitmap contains the point (x, y).
static const cCursesFont Font
cRect Intersected(const cRect &Rect) const
Returns the intersection of this rectangle and the given Rect.
The cOsd class is the interface to the "On Screen Display".
virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest)=0
Renders the part of the given Pixmap covered by Source into this pixmap at location Dest...
void SetClean(void)
Resets the "dirty" rectangles of this pixmap.
tColor RgbToColor(uint8_t R, uint8_t G, uint8_t B)
virtual void DrawImage(const cPoint &Point, const cImage &Image)
Draws the given Image into this pixmap at the given Point.
static int IsOpen(void)
Returns true if there is currently a level 0 OSD open.
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)
Draws the given string at coordinates (x, y) with the given foreground and background color and font...
void Clear(void)
Clears the image data by setting all pixels to be fully transparent.
cBitmap * Scaled(double FactorX, double FactorY, bool AntiAlias=false) const
Creates a copy of this bitmap, scaled by the given factors.
virtual void SetTile(bool Tile)
Sets the tile property of this pixmap to the given value.
const cPoint & Point(void) const
void SetColor(int Index, tColor Color)
Sets the palette entry at Index to Color.
void Grow(int Dx, int Dy)
Grows the rectangle by the given number of pixels in either direction.
virtual void DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty)
Draws the Dirty part of the given Pixmap into this pixmap.
void ShrinkBpp(int NewBpp)
Shrinks the color depth of the bitmap to NewBpp by keeping only the 2^NewBpp most frequently used col...
virtual cPixmap * CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort=cRect::Null)
Creates a new true color pixmap on this OSD (see cPixmap for details).
const tIndex * Data(int x, int y) const
Returns the address of the index byte at the given coordinates.
const cSize & Size(void) const
#define TEXT_ALIGN_BORDER
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)
Draws the given string at Point with the given foreground and background color and font...
static bool SupportsTrueColor(void)
Returns true if the current OSD provider is able to handle a true color OSD.
virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest)
Renders the part of the given Pixmap covered by Source into this pixmap at location Dest...
virtual void DrawSlope(const cRect &Rect, tColor Color, int Type)
Draws a "slope" with the given Color into the given rectangle.
void Shift(int Dx, int Dy)
char FontFix[MAXFONTNAME]
virtual void Clear(void)
Clears the pixmap's draw port by setting all pixels to be fully transparent.
#define OSD_LEVEL_DEFAULT
static cDevice * PrimaryDevice(void)
Returns the primary device.
virtual int Width(uint c) const =0
Returns the width of the given character in pixel.
virtual void DrawPixel(int x, int y, tColor Color)
Sets the pixel at the given coordinates to the given Color, which is a full 32 bit ARGB value...
virtual void DrawImage(const cPoint &Point, const cImage &Image)
Draws the given Image on this OSD at the given Point.
#define ALPHA_TRANSPARENT
tColor HsvToColor(double H, double S, double V)
Converts the given Hue (0..360), Saturation (0..1) and Value (0..1) to an RGB tColor value...
void MarkDrawPortDirty(const cRect &Rect)
Marks the given rectangle of the draw port of this pixmap as dirty.
int ClosestColor(tColor Color, int MaxDiff=INT_MAX) const
Returns the index of a color in this palette that is closest to the given Color.
tColor Color(int Index) const
Returns the color at the given Index.
tColor GetColor(int x, int y) const
Returns the color at the given coordinates.
static int StoreImage(const cImage &Image)
Stores the given Image for later use with DrawImage() on an OSD or pixmap.
void Take(const cPalette &Palette, tIndexes *Indexes=NULL, tColor ColorFg=0, tColor ColorBg=0)
Takes the colors from the given Palette and adds them to this palette, using existing entries if poss...
virtual void SetLayer(int Layer)
Sets the layer of this pixmap to the given value.
void Fill(tColor Color)
Fills the image data with the given Color.
cOsd(int Left, int Top, uint Level)
Initializes the OSD with the given coordinates.
virtual int Height(void) const =0
Returns the height of this font in pixel (all characters have the same height).
virtual void RestoreRegion(void)
Restores the region previously saved by a call to SaveRegion().
virtual void Clear(void)=0
Clears the pixmap's draw port by setting all pixels to be fully transparent.
virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants=0)
Draws a filled ellipse with the given Color that fits into the given rectangle.
void SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
Allows the system to optimize utilization of the limited color palette entries when generating blende...
virtual void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type)
Draws a "slope" into the rectangle defined by the upper left (x1, y1) and lower right (x2...
void SetBpp(int Bpp)
Sets the color depth of this palette to the given value.
virtual void DropImageData(int ImageHandle)
Drops the image data referenced by ImageHandle.
static void DropImage(int ImageHandle)
Drops the image referenced by the given ImageHandle.
cPoint Shifted(int Dx, int Dy) const
cPalette(int Bpp=8)
Initializes the palette with the given color depth.
cBitmap(int Width, int Height, int Bpp, int X0=0, int Y0=0)
Creates a bitmap with the given Width, Height and color depth (Bpp).
virtual void SaveRegion(int x1, int y1, int x2, int y2)
Saves the region defined by the given coordinates for later restoration through RestoreRegion().
cPixmap * RenderPixmaps(void)
Renders the dirty part of all pixmaps into a resulting pixmap that shall be displayed on the OSD...
void SetIndex(int x, int y, tIndex Index)
Sets the index at the given coordinates to Index.
cBitmap * GetBitmap(int Area)
Returns a pointer to the bitmap for the given Area, or NULL if no such bitmap exists.
bool Intersects(const cRect &Rect) const
Returns true if this rectangle intersects with Rect.
static void Shutdown(void)
Shuts down the OSD provider facility by deleting the current OSD provider.
static uint16_t AlphaLutFactors[255][256][2]
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const =0
Draws the given text into the Bitmap at position (x, y) with the given colors.
static cOsd * NewOsd(int Left, int Top, uint Level=OSD_LEVEL_DEFAULT)
Returns a pointer to a newly created cOsd object, which will be located at the given coordinates...