diff options
author | Thomas Günther <tom@toms-cafe.de> | 2005-05-15 00:18:18 +0200 |
---|---|---|
committer | Thomas Günther <tom@toms-cafe.de> | 2005-05-15 00:18:18 +0200 |
commit | 1b80a09e835a6cd68d4160f9799a7268e54a5b53 (patch) | |
tree | fa5f92848ed602216ed76ed84980921c9af95a07 /bitmap.c | |
download | vdr-plugin-spider-1b80a09e835a6cd68d4160f9799a7268e54a5b53.tar.gz vdr-plugin-spider-1b80a09e835a6cd68d4160f9799a7268e54a5b53.tar.bz2 |
Initial versionv0.1.0
Diffstat (limited to 'bitmap.c')
-rw-r--r-- | bitmap.c | 273 |
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 |