summaryrefslogtreecommitdiff
path: root/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'bitmap.c')
-rw-r--r--bitmap.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/bitmap.c b/bitmap.c
new file mode 100644
index 0000000..99bc955
--- /dev/null
+++ b/bitmap.c
@@ -0,0 +1,273 @@
+/*
+ * Spider-Arachnid: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id$
+ */
+
+#include "bitmap.h"
+#include <vdr/config.h>
+#include <vdr/osdbase.h>
+#include <vdr/osd.h>
+#include <ctype.h>
+
+// Compatibility to older vdr versions
+#if VDRVERSNUM < 10307
+ #define tColor eDvbColor
+ #define DrawRectangle Fill
+ #define DrawPixel SetPixel
+#endif
+
+
+/** --- class Bitmap ------------------------------------------------------- **/
+
+/** Constructor */
+Bitmap::Bitmap(int width, int height) :
+ cBitmap(width, height, 4)
+{
+}
+
+/** Constructor for a bitmap with frame */
+Bitmap::Bitmap(int width, int height, tColor frameColor, tColor backgroundColor) :
+ cBitmap(width, height, 4)
+{
+ DrawRectangle(0, 0, width - 1, height - 1, backgroundColor);
+ frame(0, 0, width - 1, height - 1, frameColor);
+}
+
+/** Constructor for a bitmap read from an xpm file */
+Bitmap::Bitmap(int width, int height, const char* dir, const char* name) :
+ cBitmap(width, height, 4)
+{
+ char* path;
+ asprintf(&path, "%s/%s.xpm", dir, name);
+ loadXpm(path);
+ free(path);
+}
+
+/** Constructor for a card bitmap read from an xpm file */
+Bitmap::Bitmap(int width, int height, const char* dir,
+ const char* suit, const char* rank) :
+ cBitmap(width, height, 4)
+{
+ char* path;
+ asprintf(&path, "%s/%s_%s.xpm", dir, suit, rank);
+ loadXpm(path);
+ free(path);
+}
+
+/** Write a text into the bitmap */
+void Bitmap::text(const char* text, bool centered)
+{
+ DrawRectangle(0, 0, Width() - 1, Height() - 1, clrWhite);
+ frame(0, 0, Width() - 1, Height() - 1, clrRed);
+
+#if VDRVERSNUM < 10307
+ SetFont(fontOsd);
+ int lineCount;
+ char* wrapper = textWrapper(text, &lineCount);
+ int y = max((Height() - lineCount * cOsd::LineHeight()) / 2, 0);
+ char* line = wrapper;
+ while (*line)
+ {
+ char* newline = strchr(line, '\n');
+ if (newline)
+ *newline = 0;
+ int x = 0;
+ if (centered)
+ x = max((Width() - Width(line)) / 2, 0);
+ Text(x, y, line, clrBlack, clrWhite);
+ if (newline)
+ *newline = '\n';
+ if (!newline)
+ break;
+ line = newline + 1;
+ y += cOsd::LineHeight();
+ }
+ free(wrapper);
+#else
+ const cFont* font = cFont::GetFont(fontOsd);
+ cTextWrapper wrapper(text, font, Width());
+ int y = max((Height() - wrapper.Lines() * font->Height()) / 2, 0);
+ for (int l = 0; l < wrapper.Lines(); ++l, y += font->Height())
+ {
+ int x = 0;
+ if (centered)
+ x = max((Width() - font->Width(wrapper.GetLine(l))) / 2, 0);
+ DrawText(x, y, wrapper.GetLine(l), clrBlack, clrWhite, font);
+ }
+#endif
+}
+
+/** Draw a frame into the bitmap */
+void Bitmap::frame(int x1, int y1, int x2, int y2, tColor frameColor)
+{
+ DrawRectangle(x1, y1, x2, y1 + 1, frameColor);
+ DrawRectangle(x1, y1, x1 + 1, y2, frameColor);
+ DrawRectangle(x1, y2 - 1, x2, y2, frameColor);
+ DrawRectangle(x2 - 1, y1, x2, y2, frameColor);
+}
+
+/** Load a bitmap from an xpm file - taken from ElchiAIO4d patch */
+bool Bitmap::loadXpm(const char* FileName, tColor NoneColor)
+{
+ bool bRet = false;
+ FILE *infile;
+ infile = fopen(FileName, "r");
+ if (infile) {
+ bool ok = true;
+ char buf[512];
+ char *ptr;
+ int state = 0;
+ int width, height, colors, colwidth, cnt = 0;
+ int temp;
+ uint pal[65536];
+
+ while (ok && fgets(buf, sizeof(buf), infile) != NULL) {
+ int len = strlen(buf);
+ ptr = buf;
+ if (ptr[len - 1] == '\n')
+ ptr[--len] = '\0';
+
+ if (state > 0 && strncmp(ptr, "/*", 2) == 0) {
+ continue;
+ }
+
+ switch (state) {
+ case 0:
+ if (strcmp(ptr, "/* XPM */") != 0) {
+ esyslog("ERROR: loading xpm %s failed: invalid header", FileName);
+ ok = false;
+ break;
+ }
+ ++state;
+ break;
+ case 1:
+ ++state;
+ break;
+ case 2:
+ sscanf(ptr, "\"%d %d %d %d\",", &width, &height, &colors, &colwidth);
+ if (colwidth > 2) {
+ esyslog("ERROR: wrong colorwidth in xpm %s", FileName);
+ ok = false;
+ break;
+ }
+ cnt = 0;
+ ++state;
+ break;
+ case 3:
+ ++ptr;
+ temp = 0;
+ for (int i = 0; i < colwidth; ++i) {
+ temp <<= 8;
+ temp += (int)*ptr;
+ ++ptr;
+ }
+ ++ptr;
+ if (strncmp(ptr, "c ", 2) != 0) {
+ esyslog("ERROR: wrong character in xpm %s", FileName);
+ ok = false;
+ break;
+ }
+ ptr += 2;
+ if (*ptr == '#') {
+ int col = strtoul(++ptr, NULL, 16);
+#if VDRVERSNUM < 10307
+ pal[temp] = 0xff000000 | ((col & 0xff) << 16) | (col & 0xff00) | ((col & 0xff0000) >> 16);
+#else
+ pal[temp] = 0xff000000 | col;
+#endif
+ }
+ else {
+ pal[temp] = NoneColor;
+ }
+ if (++cnt == colors) {
+ cnt = 0;
+ ++state;
+ }
+ break;
+ case 4:
+ ++ptr;
+ for (int p = 0; p < width; ++p) {
+ temp = 0;
+ for (int i = 0; i < colwidth; ++i) {
+ temp <<= 8;
+ temp += (int)*ptr;
+ ++ptr;
+ }
+ DrawPixel(p, cnt, (tColor)pal[temp]);
+ }
+ if (++cnt == height) {
+ ++state;
+ bRet = true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ fclose(infile);
+ }
+ return bRet;
+}
+
+#if VDRVERSNUM < 10307
+/** Wrap the text to fit into the bitmap - taken from font.c in VDR 1.3.7 */
+char *Bitmap::textWrapper(const char *Text, int *p_lines)
+{
+ char *text = strdup(Text);
+ int lines = 1;
+
+ char *Blank = NULL;
+ char *Delim = NULL;
+ int w = 0;
+
+ stripspace(text); // strips trailing newlines
+
+ for (char *p = text; *p; ) {
+ if (*p == '\n') {
+ lines++;
+ w = 0;
+ Blank = Delim = NULL;
+ p++;
+ continue;
+ }
+ else if (isspace(*p))
+ Blank = p;
+ int cw = Width(*p);
+ if (w + cw > Width()) {
+ if (Blank) {
+ *Blank = '\n';
+ p = Blank;
+ continue;
+ }
+ else {
+ // Here's the ugly part, where we don't have any whitespace to
+ // punch in a newline, so we need to make room for it:
+ if (Delim)
+ p = Delim + 1; // let's fall back to the most recent delimiter
+ char *s = MALLOC(char, strlen(text) + 2); // The additional '\n' plus the terminating '\0'
+ int l = p - text;
+ strncpy(s, text, l);
+ s[l] = '\n';
+ strcpy(s + l + 1, p);
+ free(text);
+ text = s;
+ p = text + l;
+ continue;
+ }
+ }
+ else
+ w += cw;
+ if (strchr("-.,:;!?_", *p)) {
+ Delim = p;
+ Blank = NULL;
+ }
+ p++;
+ }
+ if (p_lines != NULL)
+ *p_lines = lines;
+ return text;
+}
+#endif