brw1

Dependencies:   mbed

Committer:
reiniermarcel
Date:
Mon Nov 30 11:13:18 2015 +0000
Revision:
0:a115ff47d1c1
ok

Who changed what in which revision?

UserRevisionLine numberNew contents of line
reiniermarcel 0:a115ff47d1c1 1 /* mbed GraphicsDisplay Display Library Base Class
reiniermarcel 0:a115ff47d1c1 2 * Copyright (c) 2007-2009 sford
reiniermarcel 0:a115ff47d1c1 3 * Released under the MIT License: http://mbed.org/license/mit
reiniermarcel 0:a115ff47d1c1 4 *
reiniermarcel 0:a115ff47d1c1 5 * Derivative work by D.Smart 2014
reiniermarcel 0:a115ff47d1c1 6 */
reiniermarcel 0:a115ff47d1c1 7
reiniermarcel 0:a115ff47d1c1 8 #include "GraphicsDisplay.h"
reiniermarcel 0:a115ff47d1c1 9 #include "Bitmap.h"
reiniermarcel 0:a115ff47d1c1 10 #include "string.h"
reiniermarcel 0:a115ff47d1c1 11
reiniermarcel 0:a115ff47d1c1 12 //#define DEBUG "GD"
reiniermarcel 0:a115ff47d1c1 13 // ...
reiniermarcel 0:a115ff47d1c1 14 // INFO("Stuff to show %d", var); // new-line is automatically appended
reiniermarcel 0:a115ff47d1c1 15 //
reiniermarcel 0:a115ff47d1c1 16 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
reiniermarcel 0:a115ff47d1c1 17 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
reiniermarcel 0:a115ff47d1c1 18 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
reiniermarcel 0:a115ff47d1c1 19 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
reiniermarcel 0:a115ff47d1c1 20 static void HexDump(char * title, uint8_t * p, int count)
reiniermarcel 0:a115ff47d1c1 21 {
reiniermarcel 0:a115ff47d1c1 22 int i;
reiniermarcel 0:a115ff47d1c1 23 char buf[100] = "0000: ";
reiniermarcel 0:a115ff47d1c1 24
reiniermarcel 0:a115ff47d1c1 25 if (*title)
reiniermarcel 0:a115ff47d1c1 26 INFO("%s", title);
reiniermarcel 0:a115ff47d1c1 27 for (i=0; i<count; ) {
reiniermarcel 0:a115ff47d1c1 28 sprintf(buf + strlen(buf), "%02X ", *(p+i));
reiniermarcel 0:a115ff47d1c1 29 if ((++i & 0x0F) == 0x00) {
reiniermarcel 0:a115ff47d1c1 30 INFO("%s", buf);
reiniermarcel 0:a115ff47d1c1 31 if (i < count)
reiniermarcel 0:a115ff47d1c1 32 sprintf(buf, "%04X: ", i);
reiniermarcel 0:a115ff47d1c1 33 else
reiniermarcel 0:a115ff47d1c1 34 buf[0] = '\0';
reiniermarcel 0:a115ff47d1c1 35 }
reiniermarcel 0:a115ff47d1c1 36 }
reiniermarcel 0:a115ff47d1c1 37 if (strlen(buf))
reiniermarcel 0:a115ff47d1c1 38 INFO("%s", buf);
reiniermarcel 0:a115ff47d1c1 39 }
reiniermarcel 0:a115ff47d1c1 40 #else
reiniermarcel 0:a115ff47d1c1 41 #define INFO(x, ...)
reiniermarcel 0:a115ff47d1c1 42 #define WARN(x, ...)
reiniermarcel 0:a115ff47d1c1 43 #define ERR(x, ...)
reiniermarcel 0:a115ff47d1c1 44 #define HexDump(a, b, c)
reiniermarcel 0:a115ff47d1c1 45 #endif
reiniermarcel 0:a115ff47d1c1 46
reiniermarcel 0:a115ff47d1c1 47 #ifdef LOCALFONT
reiniermarcel 0:a115ff47d1c1 48 const unsigned char FONT8x8[97][8] = {
reiniermarcel 0:a115ff47d1c1 49 0x08, 0x08, 0x08, 0X00, 0X00, 0X00, 0X00, 0X00, // columns, rows, num_bytes_per_char
reiniermarcel 0:a115ff47d1c1 50 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // space 0x20
reiniermarcel 0:a115ff47d1c1 51 0x30, 0x78, 0x78, 0x30, 0x30, 0X00, 0x30, 0X00, // !
reiniermarcel 0:a115ff47d1c1 52 0x6C, 0x6C, 0x6C, 0X00, 0X00, 0X00, 0X00, 0X00, // "
reiniermarcel 0:a115ff47d1c1 53 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0X00, // #
reiniermarcel 0:a115ff47d1c1 54 0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0X00, // $
reiniermarcel 0:a115ff47d1c1 55 0X00, 0x63, 0x66, 0x0C, 0x18, 0x33, 0x63, 0X00, // %
reiniermarcel 0:a115ff47d1c1 56 0x1C, 0x36, 0x1C, 0x3B, 0x6E, 0x66, 0x3B, 0X00, // &
reiniermarcel 0:a115ff47d1c1 57 0x30, 0x30, 0x60, 0X00, 0X00, 0X00, 0X00, 0X00, // '
reiniermarcel 0:a115ff47d1c1 58 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0X00, // (
reiniermarcel 0:a115ff47d1c1 59 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0X00, // )
reiniermarcel 0:a115ff47d1c1 60 0X00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0X00, 0X00, // *
reiniermarcel 0:a115ff47d1c1 61 0X00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0X00, 0X00, // +
reiniermarcel 0:a115ff47d1c1 62 0X00, 0X00, 0X00, 0X00, 0X00, 0x18, 0x18, 0x30, // ,
reiniermarcel 0:a115ff47d1c1 63 0X00, 0X00, 0X00, 0x7E, 0X00, 0X00, 0X00, 0X00, // -
reiniermarcel 0:a115ff47d1c1 64 0X00, 0X00, 0X00, 0X00, 0X00, 0x18, 0x18, 0X00, // .
reiniermarcel 0:a115ff47d1c1 65 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0X00, // / (forward slash)
reiniermarcel 0:a115ff47d1c1 66 0x3E, 0x63, 0x63, 0x6B, 0x63, 0x63, 0x3E, 0X00, // 0 0x30
reiniermarcel 0:a115ff47d1c1 67 0x18, 0x38, 0x58, 0x18, 0x18, 0x18, 0x7E, 0X00, // 1
reiniermarcel 0:a115ff47d1c1 68 0x3C, 0x66, 0x06, 0x1C, 0x30, 0x66, 0x7E, 0X00, // 2
reiniermarcel 0:a115ff47d1c1 69 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0X00, // 3
reiniermarcel 0:a115ff47d1c1 70 0x0E, 0x1E, 0x36, 0x66, 0x7F, 0x06, 0x0F, 0X00, // 4
reiniermarcel 0:a115ff47d1c1 71 0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0X00, // 5
reiniermarcel 0:a115ff47d1c1 72 0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0X00, // 6
reiniermarcel 0:a115ff47d1c1 73 0x7E, 0x66, 0x06, 0x0C, 0x18, 0x18, 0x18, 0X00, // 7
reiniermarcel 0:a115ff47d1c1 74 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0X00, // 8
reiniermarcel 0:a115ff47d1c1 75 0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0X00, // 9
reiniermarcel 0:a115ff47d1c1 76 0X00, 0x18, 0x18, 0X00, 0X00, 0x18, 0x18, 0X00, // :
reiniermarcel 0:a115ff47d1c1 77 0X00, 0x18, 0x18, 0X00, 0X00, 0x18, 0x18, 0x30, // ;
reiniermarcel 0:a115ff47d1c1 78 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0X00, // <
reiniermarcel 0:a115ff47d1c1 79 0X00, 0X00, 0x7E, 0X00, 0X00, 0x7E, 0X00, 0X00, // =
reiniermarcel 0:a115ff47d1c1 80 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0X00, // >
reiniermarcel 0:a115ff47d1c1 81 0x3C, 0x66, 0x06, 0x0C, 0x18, 0X00, 0x18, 0X00, // ?
reiniermarcel 0:a115ff47d1c1 82 0x3E, 0x63, 0x6F, 0x69, 0x6F, 0x60, 0x3E, 0X00, // @ 0x40
reiniermarcel 0:a115ff47d1c1 83 0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0X00, // A
reiniermarcel 0:a115ff47d1c1 84 0x7E, 0x33, 0x33, 0x3E, 0x33, 0x33, 0x7E, 0X00, // B
reiniermarcel 0:a115ff47d1c1 85 0x1E, 0x33, 0x60, 0x60, 0x60, 0x33, 0x1E, 0X00, // C
reiniermarcel 0:a115ff47d1c1 86 0x7C, 0x36, 0x33, 0x33, 0x33, 0x36, 0x7C, 0X00, // D
reiniermarcel 0:a115ff47d1c1 87 0x7F, 0x31, 0x34, 0x3C, 0x34, 0x31, 0x7F, 0X00, // E
reiniermarcel 0:a115ff47d1c1 88 0x7F, 0x31, 0x34, 0x3C, 0x34, 0x30, 0x78, 0X00, // F
reiniermarcel 0:a115ff47d1c1 89 0x1E, 0x33, 0x60, 0x60, 0x67, 0x33, 0x1F, 0X00, // G
reiniermarcel 0:a115ff47d1c1 90 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0X00, // H
reiniermarcel 0:a115ff47d1c1 91 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // I
reiniermarcel 0:a115ff47d1c1 92 0x0F, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0X00, // J
reiniermarcel 0:a115ff47d1c1 93 0x73, 0x33, 0x36, 0x3C, 0x36, 0x33, 0x73, 0X00, // K
reiniermarcel 0:a115ff47d1c1 94 0x78, 0x30, 0x30, 0x30, 0x31, 0x33, 0x7F, 0X00, // L
reiniermarcel 0:a115ff47d1c1 95 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0X00, // M
reiniermarcel 0:a115ff47d1c1 96 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63, 0x63, 0X00, // N
reiniermarcel 0:a115ff47d1c1 97 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0X00, // O
reiniermarcel 0:a115ff47d1c1 98 0x7E, 0x33, 0x33, 0x3E, 0x30, 0x30, 0x78, 0X00, // P 0x50
reiniermarcel 0:a115ff47d1c1 99 0x3C, 0x66, 0x66, 0x66, 0x6E, 0x3C, 0x0E, 0X00, // Q
reiniermarcel 0:a115ff47d1c1 100 0x7E, 0x33, 0x33, 0x3E, 0x36, 0x33, 0x73, 0X00, // R
reiniermarcel 0:a115ff47d1c1 101 0x3C, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x3C, 0X00, // S
reiniermarcel 0:a115ff47d1c1 102 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // T
reiniermarcel 0:a115ff47d1c1 103 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7E, 0X00, // U
reiniermarcel 0:a115ff47d1c1 104 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0X00, // V
reiniermarcel 0:a115ff47d1c1 105 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0X00, // W
reiniermarcel 0:a115ff47d1c1 106 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0X00, // X
reiniermarcel 0:a115ff47d1c1 107 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0X00, // Y
reiniermarcel 0:a115ff47d1c1 108 0x7F, 0x63, 0x46, 0x0C, 0x19, 0x33, 0x7F, 0X00, // Z
reiniermarcel 0:a115ff47d1c1 109 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0X00, // [
reiniermarcel 0:a115ff47d1c1 110 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0X00, // \ (back slash)
reiniermarcel 0:a115ff47d1c1 111 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0X00, // ]
reiniermarcel 0:a115ff47d1c1 112 0x08, 0x1C, 0x36, 0x63, 0X00, 0X00, 0X00, 0X00, // ^
reiniermarcel 0:a115ff47d1c1 113 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0xFF, // _
reiniermarcel 0:a115ff47d1c1 114 0x18, 0x18, 0x0C, 0X00, 0X00, 0X00, 0X00, 0X00, // ` 0x60
reiniermarcel 0:a115ff47d1c1 115 0X00, 0X00, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0X00, // a
reiniermarcel 0:a115ff47d1c1 116 0x70, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x6E, 0X00, // b
reiniermarcel 0:a115ff47d1c1 117 0X00, 0X00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0X00, // c
reiniermarcel 0:a115ff47d1c1 118 0x0E, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3B, 0X00, // d
reiniermarcel 0:a115ff47d1c1 119 0X00, 0X00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0X00, // e
reiniermarcel 0:a115ff47d1c1 120 0x1C, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0X00, // f
reiniermarcel 0:a115ff47d1c1 121 0X00, 0X00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x7C, // g
reiniermarcel 0:a115ff47d1c1 122 0x70, 0x30, 0x36, 0x3B, 0x33, 0x33, 0x73, 0X00, // h
reiniermarcel 0:a115ff47d1c1 123 0x18, 0X00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0X00, // i
reiniermarcel 0:a115ff47d1c1 124 0x06, 0X00, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, // j
reiniermarcel 0:a115ff47d1c1 125 0x70, 0x30, 0x33, 0x36, 0x3C, 0x36, 0x73, 0X00, // k
reiniermarcel 0:a115ff47d1c1 126 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // l
reiniermarcel 0:a115ff47d1c1 127 0X00, 0X00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0X00, // m
reiniermarcel 0:a115ff47d1c1 128 0X00, 0X00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0X00, // n
reiniermarcel 0:a115ff47d1c1 129 0X00, 0X00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0X00, // o
reiniermarcel 0:a115ff47d1c1 130 0X00, 0X00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78, // p
reiniermarcel 0:a115ff47d1c1 131 0X00, 0X00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F, // q
reiniermarcel 0:a115ff47d1c1 132 0X00, 0X00, 0x6E, 0x3B, 0x33, 0x30, 0x78, 0X00, // r
reiniermarcel 0:a115ff47d1c1 133 0X00, 0X00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0X00, // s
reiniermarcel 0:a115ff47d1c1 134 0x08, 0x18, 0x3E, 0x18, 0x18, 0x1A, 0x0C, 0X00, // t
reiniermarcel 0:a115ff47d1c1 135 0X00, 0X00, 0x66, 0x66, 0x66, 0x66, 0x3B, 0X00, // u
reiniermarcel 0:a115ff47d1c1 136 0X00, 0X00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0X00, // v
reiniermarcel 0:a115ff47d1c1 137 0X00, 0X00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0X00, // w
reiniermarcel 0:a115ff47d1c1 138 0X00, 0X00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0X00, // x
reiniermarcel 0:a115ff47d1c1 139 0X00, 0X00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x7C, // y
reiniermarcel 0:a115ff47d1c1 140 0X00, 0X00, 0x7E, 0x4C, 0x18, 0x32, 0x7E, 0X00, // z
reiniermarcel 0:a115ff47d1c1 141 0x0E, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0E, 0X00, // {
reiniermarcel 0:a115ff47d1c1 142 0x0C, 0x0C, 0x0C, 0X00, 0x0C, 0x0C, 0x0C, 0X00, // |
reiniermarcel 0:a115ff47d1c1 143 0x70, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x70, 0X00, // }
reiniermarcel 0:a115ff47d1c1 144 0x3B, 0x6E, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // ~
reiniermarcel 0:a115ff47d1c1 145 0x1C, 0x36, 0x36, 0x1C, 0X00, 0X00, 0X00, 0X00 // DEL
reiniermarcel 0:a115ff47d1c1 146 };
reiniermarcel 0:a115ff47d1c1 147 #endif // LOCALFONT
reiniermarcel 0:a115ff47d1c1 148
reiniermarcel 0:a115ff47d1c1 149 char mytolower(char a) {
reiniermarcel 0:a115ff47d1c1 150 if (a >= 'A' && a <= 'Z')
reiniermarcel 0:a115ff47d1c1 151 return (a - 'A' + 'a');
reiniermarcel 0:a115ff47d1c1 152 else
reiniermarcel 0:a115ff47d1c1 153 return a;
reiniermarcel 0:a115ff47d1c1 154 }
reiniermarcel 0:a115ff47d1c1 155 /// mystrnicmp exists because not all compiler libraries have this function.
reiniermarcel 0:a115ff47d1c1 156 ///
reiniermarcel 0:a115ff47d1c1 157 /// Some have strnicmp, others _strnicmp, and others have C++ methods, which
reiniermarcel 0:a115ff47d1c1 158 /// is outside the scope of this C-portable set of functions.
reiniermarcel 0:a115ff47d1c1 159 ///
reiniermarcel 0:a115ff47d1c1 160 /// @param l is a pointer to the string on the left
reiniermarcel 0:a115ff47d1c1 161 /// @param r is a pointer to the string on the right
reiniermarcel 0:a115ff47d1c1 162 /// @param n is the number of characters to compare
reiniermarcel 0:a115ff47d1c1 163 /// @returns -1 if l < r
reiniermarcel 0:a115ff47d1c1 164 /// @returns 0 if l == r
reiniermarcel 0:a115ff47d1c1 165 /// @returns +1 if l > r
reiniermarcel 0:a115ff47d1c1 166 ///
reiniermarcel 0:a115ff47d1c1 167 int mystrnicmp(const char *l, const char *r, size_t n) {
reiniermarcel 0:a115ff47d1c1 168 int result = 0;
reiniermarcel 0:a115ff47d1c1 169
reiniermarcel 0:a115ff47d1c1 170 if (n != 0) {
reiniermarcel 0:a115ff47d1c1 171 do {
reiniermarcel 0:a115ff47d1c1 172 result = mytolower(*l++) - mytolower(*r++);
reiniermarcel 0:a115ff47d1c1 173 } while ((result == 0) && (*l != '\0') && (--n > 0));
reiniermarcel 0:a115ff47d1c1 174 }
reiniermarcel 0:a115ff47d1c1 175 if (result < -1)
reiniermarcel 0:a115ff47d1c1 176 result = -1;
reiniermarcel 0:a115ff47d1c1 177 else if (result > 1)
reiniermarcel 0:a115ff47d1c1 178 result = 1;
reiniermarcel 0:a115ff47d1c1 179 return result;
reiniermarcel 0:a115ff47d1c1 180 }
reiniermarcel 0:a115ff47d1c1 181
reiniermarcel 0:a115ff47d1c1 182
reiniermarcel 0:a115ff47d1c1 183 GraphicsDisplay::GraphicsDisplay(const char *name)
reiniermarcel 0:a115ff47d1c1 184 : TextDisplay(name)
reiniermarcel 0:a115ff47d1c1 185 {
reiniermarcel 0:a115ff47d1c1 186 font = NULL;
reiniermarcel 0:a115ff47d1c1 187 }
reiniermarcel 0:a115ff47d1c1 188
reiniermarcel 0:a115ff47d1c1 189 RetCode_t GraphicsDisplay::set_font(const unsigned char * _font)
reiniermarcel 0:a115ff47d1c1 190 {
reiniermarcel 0:a115ff47d1c1 191 font = _font; // trusting them, but it might be good to put some checks in here...
reiniermarcel 0:a115ff47d1c1 192 return noerror;
reiniermarcel 0:a115ff47d1c1 193 }
reiniermarcel 0:a115ff47d1c1 194
reiniermarcel 0:a115ff47d1c1 195 #ifdef LOCALFONT
reiniermarcel 0:a115ff47d1c1 196 int GraphicsDisplay::character(int x, int y, int value)
reiniermarcel 0:a115ff47d1c1 197 {
reiniermarcel 0:a115ff47d1c1 198 if (value <= 0x1F && value >= 7F)
reiniermarcel 0:a115ff47d1c1 199 return 0;
reiniermarcel 0:a115ff47d1c1 200
reiniermarcel 0:a115ff47d1c1 201 return blitbit(x, y, FONT8X8[0][0], FONT8X8[0][1],
reiniermarcel 0:a115ff47d1c1 202 (char *)&(FONT8x8[value - 0x1F][0]));
reiniermarcel 0:a115ff47d1c1 203 }
reiniermarcel 0:a115ff47d1c1 204 #else
reiniermarcel 0:a115ff47d1c1 205 int GraphicsDisplay::character(int x, int y, int c)
reiniermarcel 0:a115ff47d1c1 206 {
reiniermarcel 0:a115ff47d1c1 207 unsigned int offset;
reiniermarcel 0:a115ff47d1c1 208 const unsigned char * charRecord;
reiniermarcel 0:a115ff47d1c1 209
reiniermarcel 0:a115ff47d1c1 210 if (c <= 0x1F || c >= 0x7F)
reiniermarcel 0:a115ff47d1c1 211 return 0;
reiniermarcel 0:a115ff47d1c1 212 offset = font[0]; // bytes / char
reiniermarcel 0:a115ff47d1c1 213 charRecord = &font[((c - ' ') * offset) + 4]; // start of char bitmap
reiniermarcel 0:a115ff47d1c1 214 return fontblit(x, y, font, charRecord);
reiniermarcel 0:a115ff47d1c1 215 }
reiniermarcel 0:a115ff47d1c1 216 #endif
reiniermarcel 0:a115ff47d1c1 217
reiniermarcel 0:a115ff47d1c1 218 RetCode_t GraphicsDisplay::window(loc_t x, loc_t y, dim_t w, dim_t h)
reiniermarcel 0:a115ff47d1c1 219 {
reiniermarcel 0:a115ff47d1c1 220 // current pixel location
reiniermarcel 0:a115ff47d1c1 221 _x = x;
reiniermarcel 0:a115ff47d1c1 222 _y = y;
reiniermarcel 0:a115ff47d1c1 223 // window settings
reiniermarcel 0:a115ff47d1c1 224 _x1 = x;
reiniermarcel 0:a115ff47d1c1 225 _x2 = x + w - 1;
reiniermarcel 0:a115ff47d1c1 226 _y1 = y;
reiniermarcel 0:a115ff47d1c1 227 _y2 = y + h - 1;
reiniermarcel 0:a115ff47d1c1 228 return noerror;
reiniermarcel 0:a115ff47d1c1 229 }
reiniermarcel 0:a115ff47d1c1 230
reiniermarcel 0:a115ff47d1c1 231 RetCode_t GraphicsDisplay::WindowMax(void)
reiniermarcel 0:a115ff47d1c1 232 {
reiniermarcel 0:a115ff47d1c1 233 return window(0,0, width(),height());
reiniermarcel 0:a115ff47d1c1 234 }
reiniermarcel 0:a115ff47d1c1 235
reiniermarcel 0:a115ff47d1c1 236 RetCode_t GraphicsDisplay::_putp(color_t color)
reiniermarcel 0:a115ff47d1c1 237 {
reiniermarcel 0:a115ff47d1c1 238 pixel(_x, _y, color);
reiniermarcel 0:a115ff47d1c1 239 // update pixel location based on window settings
reiniermarcel 0:a115ff47d1c1 240 _x++;
reiniermarcel 0:a115ff47d1c1 241 if(_x > _x2) {
reiniermarcel 0:a115ff47d1c1 242 _x = _x1;
reiniermarcel 0:a115ff47d1c1 243 _y++;
reiniermarcel 0:a115ff47d1c1 244 if(_y > _y2) {
reiniermarcel 0:a115ff47d1c1 245 _y = _y1;
reiniermarcel 0:a115ff47d1c1 246 }
reiniermarcel 0:a115ff47d1c1 247 }
reiniermarcel 0:a115ff47d1c1 248 return noerror;
reiniermarcel 0:a115ff47d1c1 249 }
reiniermarcel 0:a115ff47d1c1 250
reiniermarcel 0:a115ff47d1c1 251 RetCode_t GraphicsDisplay::fill(int x, int y, int w, int h, color_t color)
reiniermarcel 0:a115ff47d1c1 252 {
reiniermarcel 0:a115ff47d1c1 253 return fillrect(x,y, x+w, y+h, color);
reiniermarcel 0:a115ff47d1c1 254 }
reiniermarcel 0:a115ff47d1c1 255
reiniermarcel 0:a115ff47d1c1 256 RetCode_t GraphicsDisplay::cls(uint16_t layers)
reiniermarcel 0:a115ff47d1c1 257 {
reiniermarcel 0:a115ff47d1c1 258 return fill(0, 0, width(), height(), _background);
reiniermarcel 0:a115ff47d1c1 259 }
reiniermarcel 0:a115ff47d1c1 260
reiniermarcel 0:a115ff47d1c1 261 RetCode_t GraphicsDisplay::blit(int x, int y, int w, int h, const int * color)
reiniermarcel 0:a115ff47d1c1 262 {
reiniermarcel 0:a115ff47d1c1 263 window(x, y, w, h);
reiniermarcel 0:a115ff47d1c1 264 _StartGraphicsStream();
reiniermarcel 0:a115ff47d1c1 265 for (int i=0; i<w*h; i++) {
reiniermarcel 0:a115ff47d1c1 266 _putp(color[i]);
reiniermarcel 0:a115ff47d1c1 267 }
reiniermarcel 0:a115ff47d1c1 268 _EndGraphicsStream();
reiniermarcel 0:a115ff47d1c1 269 return WindowMax();
reiniermarcel 0:a115ff47d1c1 270 }
reiniermarcel 0:a115ff47d1c1 271
reiniermarcel 0:a115ff47d1c1 272 #ifdef LOCALFONT
reiniermarcel 0:a115ff47d1c1 273 int GraphicsDisplay::blitbit(int x, int y, int w, int h, const char * color)
reiniermarcel 0:a115ff47d1c1 274 {
reiniermarcel 0:a115ff47d1c1 275 _foreground = 0xFFFF;
reiniermarcel 0:a115ff47d1c1 276 INFO("blitbit(%d,%d, %d,%d, %02X) [%04X,%04X]", x,y, w,h, *color, _foreground, _background);
reiniermarcel 0:a115ff47d1c1 277 INFO("%lu %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
reiniermarcel 0:a115ff47d1c1 278 color,
reiniermarcel 0:a115ff47d1c1 279 color[0], color[1], color[2], color[3], color[4], color[5], color[6], color[7],
reiniermarcel 0:a115ff47d1c1 280 color[8], color[9], color[10], color[11], color[12], color[13], color[14], color[15]);
reiniermarcel 0:a115ff47d1c1 281 window(x, y, w, h);
reiniermarcel 0:a115ff47d1c1 282 _StartGraphicsStream();
reiniermarcel 0:a115ff47d1c1 283 for (int i = 0; i < w*h; i++) {
reiniermarcel 0:a115ff47d1c1 284 char byte = color[i >> 3];
reiniermarcel 0:a115ff47d1c1 285 int offset = i & 0x7;
reiniermarcel 0:a115ff47d1c1 286 if (offset == 0)
reiniermarcel 0:a115ff47d1c1 287 INFO(" %2d = %02X", i>>3, byte);
reiniermarcel 0:a115ff47d1c1 288 int c = ((byte << offset) & 0x80) ? _foreground : _background;
reiniermarcel 0:a115ff47d1c1 289 _putp(c);
reiniermarcel 0:a115ff47d1c1 290 }
reiniermarcel 0:a115ff47d1c1 291 _EndGraphicsStream();
reiniermarcel 0:a115ff47d1c1 292 WindowMax();
reiniermarcel 0:a115ff47d1c1 293 return w;
reiniermarcel 0:a115ff47d1c1 294 }
reiniermarcel 0:a115ff47d1c1 295 #endif
reiniermarcel 0:a115ff47d1c1 296
reiniermarcel 0:a115ff47d1c1 297
reiniermarcel 0:a115ff47d1c1 298 int GraphicsDisplay::fontblit(int x, int y, const unsigned char * fontTable, const unsigned char * fontChar)
reiniermarcel 0:a115ff47d1c1 299 {
reiniermarcel 0:a115ff47d1c1 300 //int fontWidth = font[1]; // get hor size of font
reiniermarcel 0:a115ff47d1c1 301 int fontHeight = font[2]; // get vert size of font
reiniermarcel 0:a115ff47d1c1 302 int bytesPerLine = font[3]; // bytes per line
reiniermarcel 0:a115ff47d1c1 303 int charWidth = fontChar[0]; // width of this character
reiniermarcel 0:a115ff47d1c1 304 int px, py;
reiniermarcel 0:a115ff47d1c1 305
reiniermarcel 0:a115ff47d1c1 306 //INFO("(%d,%d) %lu, %lu %X/%X", x,y, fontTable, fontChar, _foreground, _background);
reiniermarcel 0:a115ff47d1c1 307 //INFO("char size (%d,%d)", charWidth, fontHeight);
reiniermarcel 0:a115ff47d1c1 308 //HexDump("char", (uint8_t *)fontChar, 32);
reiniermarcel 0:a115ff47d1c1 309 //INFO("(f,b) = (%04X,%04X)", _foreground, _background)
reiniermarcel 0:a115ff47d1c1 310 window(x, y, charWidth, fontHeight);
reiniermarcel 0:a115ff47d1c1 311 _StartGraphicsStream();
reiniermarcel 0:a115ff47d1c1 312 //INFO("(f,b) = (%04X,%04X)", _foreground, _background)
reiniermarcel 0:a115ff47d1c1 313 for (py = 0; py < fontHeight; py++) {
reiniermarcel 0:a115ff47d1c1 314 int bitmask = 1 << (py & 7);
reiniermarcel 0:a115ff47d1c1 315
reiniermarcel 0:a115ff47d1c1 316 for (px = 0; px < charWidth; px++) {
reiniermarcel 0:a115ff47d1c1 317 int offset = (py / 8) + px * bytesPerLine;
reiniermarcel 0:a115ff47d1c1 318 unsigned char byte = fontChar[offset + 1]; // skip the char's # bits wide value
reiniermarcel 0:a115ff47d1c1 319 color_t c = (byte & bitmask) ? _foreground : _background;
reiniermarcel 0:a115ff47d1c1 320 //INFO("(%2d,%2d) %02X & %02X => %04X [%04X,%04X]", px, py, byte, bitmask, c, _foreground, _background);
reiniermarcel 0:a115ff47d1c1 321 //pixel(x+px, y+py, c);
reiniermarcel 0:a115ff47d1c1 322 _putp(c);
reiniermarcel 0:a115ff47d1c1 323 }
reiniermarcel 0:a115ff47d1c1 324 }
reiniermarcel 0:a115ff47d1c1 325 _EndGraphicsStream();
reiniermarcel 0:a115ff47d1c1 326 WindowMax();
reiniermarcel 0:a115ff47d1c1 327 return charWidth;
reiniermarcel 0:a115ff47d1c1 328 }
reiniermarcel 0:a115ff47d1c1 329
reiniermarcel 0:a115ff47d1c1 330 // BMP Color Palette is BGRx
reiniermarcel 0:a115ff47d1c1 331 // BBBB BBBB GGGG GGGG RRRR RRRR 0000 0000
reiniermarcel 0:a115ff47d1c1 332 // RGB16 is
reiniermarcel 0:a115ff47d1c1 333 // RRRR RGGG GGGB BBBB
reiniermarcel 0:a115ff47d1c1 334 // swap to little endian
reiniermarcel 0:a115ff47d1c1 335 // GGGB BBBB RRRR RGGG
reiniermarcel 0:a115ff47d1c1 336 color_t GraphicsDisplay::RGBQuadToRGB16(RGBQUAD * colorPalette, uint16_t i)
reiniermarcel 0:a115ff47d1c1 337 {
reiniermarcel 0:a115ff47d1c1 338 color_t c;
reiniermarcel 0:a115ff47d1c1 339
reiniermarcel 0:a115ff47d1c1 340 c = ((colorPalette[i].rgbBlue >> 3) << 0);
reiniermarcel 0:a115ff47d1c1 341 c |= ((colorPalette[i].rgbGreen >> 2) << 5);
reiniermarcel 0:a115ff47d1c1 342 c |= ((colorPalette[i].rgbRed >> 3) << 11);
reiniermarcel 0:a115ff47d1c1 343 return c;
reiniermarcel 0:a115ff47d1c1 344 }
reiniermarcel 0:a115ff47d1c1 345
reiniermarcel 0:a115ff47d1c1 346 /// RRRR RGGG GGGB BBBB
reiniermarcel 0:a115ff47d1c1 347 RGBQUAD GraphicsDisplay::RGB16ToRGBQuad(color_t c)
reiniermarcel 0:a115ff47d1c1 348 {
reiniermarcel 0:a115ff47d1c1 349 RGBQUAD q;
reiniermarcel 0:a115ff47d1c1 350
reiniermarcel 0:a115ff47d1c1 351 memset(&q, 0, sizeof(q));
reiniermarcel 0:a115ff47d1c1 352 q.rgbBlue = ((c & 0x001F) << 3) | (c & 0x07); /* Blue value */
reiniermarcel 0:a115ff47d1c1 353 q.rgbGreen = ((c & 0x07E0) >> 3) | ((c >> 7) & 0x03); /* Green value */
reiniermarcel 0:a115ff47d1c1 354 q.rgbRed = ((c & 0xF800) >> 8) | ((c >> 11) & 0x07); /* Red value */
reiniermarcel 0:a115ff47d1c1 355 q.rgbReserved = 0;
reiniermarcel 0:a115ff47d1c1 356 return q;
reiniermarcel 0:a115ff47d1c1 357 }
reiniermarcel 0:a115ff47d1c1 358
reiniermarcel 0:a115ff47d1c1 359 RetCode_t GraphicsDisplay::_RenderBitmap(loc_t x, loc_t y, uint32_t fileOffset, FILE * Image)
reiniermarcel 0:a115ff47d1c1 360 {
reiniermarcel 0:a115ff47d1c1 361 BITMAPINFOHEADER BMP_Info;
reiniermarcel 0:a115ff47d1c1 362 RGBQUAD * colorPalette = NULL;
reiniermarcel 0:a115ff47d1c1 363 int colorCount;
reiniermarcel 0:a115ff47d1c1 364 uint8_t * lineBuffer = NULL;
reiniermarcel 0:a115ff47d1c1 365 color_t * pixelBuffer = NULL;
reiniermarcel 0:a115ff47d1c1 366 uint16_t BPP_t;
reiniermarcel 0:a115ff47d1c1 367 uint32_t PixelWidth, PixelHeight;
reiniermarcel 0:a115ff47d1c1 368 unsigned int i, offset;
reiniermarcel 0:a115ff47d1c1 369 int padd,j;
reiniermarcel 0:a115ff47d1c1 370 #ifdef DEBUG
reiniermarcel 0:a115ff47d1c1 371 uint32_t start_data;
reiniermarcel 0:a115ff47d1c1 372 #endif
reiniermarcel 0:a115ff47d1c1 373
reiniermarcel 0:a115ff47d1c1 374 // Now, Read the bitmap info header
reiniermarcel 0:a115ff47d1c1 375 fread(&BMP_Info, 1, sizeof(BMP_Info), Image);
reiniermarcel 0:a115ff47d1c1 376 HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info));
reiniermarcel 0:a115ff47d1c1 377 BPP_t = BMP_Info.biBitCount;
reiniermarcel 0:a115ff47d1c1 378 INFO("biBitCount %04X", BPP_t);
reiniermarcel 0:a115ff47d1c1 379 if (BPP_t != 4 && BPP_t != 8 && BPP_t != 16 && BPP_t != 24) { // Support 4, 8, 16, 24-bits per pixel
reiniermarcel 0:a115ff47d1c1 380 fclose(Image);
reiniermarcel 0:a115ff47d1c1 381 return(not_supported_format);
reiniermarcel 0:a115ff47d1c1 382 }
reiniermarcel 0:a115ff47d1c1 383
reiniermarcel 0:a115ff47d1c1 384 PixelHeight = BMP_Info.biHeight;
reiniermarcel 0:a115ff47d1c1 385 PixelWidth = BMP_Info.biWidth;
reiniermarcel 0:a115ff47d1c1 386 INFO("(%d,%d) (%d,%d) (%d,%d)", x,y, PixelWidth,PixelHeight, width(), height());
reiniermarcel 0:a115ff47d1c1 387 if (PixelHeight > height() + y || PixelWidth > width() + x) {
reiniermarcel 0:a115ff47d1c1 388 fclose(Image);
reiniermarcel 0:a115ff47d1c1 389 return(image_too_big);
reiniermarcel 0:a115ff47d1c1 390 }
reiniermarcel 0:a115ff47d1c1 391 if (BMP_Info.biBitCount <= 8) {
reiniermarcel 0:a115ff47d1c1 392 int paletteSize;
reiniermarcel 0:a115ff47d1c1 393 // Read the color palette
reiniermarcel 0:a115ff47d1c1 394 colorCount = 1 << BMP_Info.biBitCount;
reiniermarcel 0:a115ff47d1c1 395 paletteSize = sizeof(RGBQUAD) * colorCount;
reiniermarcel 0:a115ff47d1c1 396 colorPalette = (RGBQUAD *)malloc(paletteSize);
reiniermarcel 0:a115ff47d1c1 397 if (colorPalette == NULL) {
reiniermarcel 0:a115ff47d1c1 398 fclose(Image);
reiniermarcel 0:a115ff47d1c1 399 return(not_enough_ram);
reiniermarcel 0:a115ff47d1c1 400 }
reiniermarcel 0:a115ff47d1c1 401 fread(colorPalette, 1, paletteSize, Image);
reiniermarcel 0:a115ff47d1c1 402 HexDump("Color Palette", (uint8_t *)colorPalette, paletteSize);
reiniermarcel 0:a115ff47d1c1 403 }
reiniermarcel 0:a115ff47d1c1 404
reiniermarcel 0:a115ff47d1c1 405 int lineBufSize = ((BPP_t * PixelWidth + 7)/8);
reiniermarcel 0:a115ff47d1c1 406 INFO("BPP_t %d, PixelWidth %d, lineBufSize %d", BPP_t, PixelWidth, lineBufSize);
reiniermarcel 0:a115ff47d1c1 407 lineBuffer = (uint8_t *)malloc(lineBufSize);
reiniermarcel 0:a115ff47d1c1 408 if (lineBuffer == NULL) {
reiniermarcel 0:a115ff47d1c1 409 free(colorPalette);
reiniermarcel 0:a115ff47d1c1 410 fclose(Image);
reiniermarcel 0:a115ff47d1c1 411 return(not_enough_ram);
reiniermarcel 0:a115ff47d1c1 412 }
reiniermarcel 0:a115ff47d1c1 413 pixelBuffer = (color_t *)malloc(PixelWidth * sizeof(color_t));
reiniermarcel 0:a115ff47d1c1 414 if (pixelBuffer == NULL) {
reiniermarcel 0:a115ff47d1c1 415 free(lineBuffer);
reiniermarcel 0:a115ff47d1c1 416 if (colorPalette)
reiniermarcel 0:a115ff47d1c1 417 free(colorPalette);
reiniermarcel 0:a115ff47d1c1 418 fclose(Image);
reiniermarcel 0:a115ff47d1c1 419 return(not_enough_ram);
reiniermarcel 0:a115ff47d1c1 420 }
reiniermarcel 0:a115ff47d1c1 421
reiniermarcel 0:a115ff47d1c1 422 // the Raw Data records are padded to a multiple of 4 bytes
reiniermarcel 0:a115ff47d1c1 423 int recordSize = 2;
reiniermarcel 0:a115ff47d1c1 424 if (BPP_t == 4) {
reiniermarcel 0:a115ff47d1c1 425 recordSize = 1;
reiniermarcel 0:a115ff47d1c1 426 } else if (BPP_t == 8) {
reiniermarcel 0:a115ff47d1c1 427 recordSize = 1;
reiniermarcel 0:a115ff47d1c1 428 } else if (BPP_t == 16) {
reiniermarcel 0:a115ff47d1c1 429 recordSize = 2;
reiniermarcel 0:a115ff47d1c1 430 } else if (BPP_t == 24) {
reiniermarcel 0:a115ff47d1c1 431 recordSize = 3;
reiniermarcel 0:a115ff47d1c1 432 }
reiniermarcel 0:a115ff47d1c1 433 padd = -1;
reiniermarcel 0:a115ff47d1c1 434 do {
reiniermarcel 0:a115ff47d1c1 435 padd++;
reiniermarcel 0:a115ff47d1c1 436 } while ((PixelWidth * recordSize + padd) % 4 != 0);
reiniermarcel 0:a115ff47d1c1 437
reiniermarcel 0:a115ff47d1c1 438 // Define window for top to bottom and left to right so writing auto-wraps
reiniermarcel 0:a115ff47d1c1 439 window(x,y, PixelWidth,PixelHeight);
reiniermarcel 0:a115ff47d1c1 440 SetGraphicsCursor(x, y);
reiniermarcel 0:a115ff47d1c1 441 _StartGraphicsStream();
reiniermarcel 0:a115ff47d1c1 442
reiniermarcel 0:a115ff47d1c1 443 //start_data = BMP_Header.bfOffBits;
reiniermarcel 0:a115ff47d1c1 444 HexDump("Raw Data", (uint8_t *)&start_data, 32);
reiniermarcel 0:a115ff47d1c1 445 INFO("(%d,%d) (%d,%d), [%d,%d]", x,y, PixelWidth,PixelHeight, lineBufSize, padd);
reiniermarcel 0:a115ff47d1c1 446 for (j = PixelHeight - 1; j >= 0; j--) { //Lines bottom up
reiniermarcel 0:a115ff47d1c1 447 offset = fileOffset + j * (lineBufSize + padd); // start of line
reiniermarcel 0:a115ff47d1c1 448 fseek(Image, offset, SEEK_SET);
reiniermarcel 0:a115ff47d1c1 449 fread(lineBuffer, 1, lineBufSize, Image); // read a line - slow !
reiniermarcel 0:a115ff47d1c1 450 //INFO("offset: %6X", offset);
reiniermarcel 0:a115ff47d1c1 451 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
reiniermarcel 0:a115ff47d1c1 452 if (BPP_t == 4) {
reiniermarcel 0:a115ff47d1c1 453 uint8_t dPix = lineBuffer[i/2];
reiniermarcel 0:a115ff47d1c1 454 if ((i & 1) == 0)
reiniermarcel 0:a115ff47d1c1 455 dPix >>= 4;
reiniermarcel 0:a115ff47d1c1 456 dPix &= 0x0F;
reiniermarcel 0:a115ff47d1c1 457 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, dPix);
reiniermarcel 0:a115ff47d1c1 458 } else if (BPP_t == 8) {
reiniermarcel 0:a115ff47d1c1 459 pixelBuffer[i] = RGBQuadToRGB16(colorPalette, lineBuffer[i]);
reiniermarcel 0:a115ff47d1c1 460 } else if (BPP_t == 16) {
reiniermarcel 0:a115ff47d1c1 461 pixelBuffer[i] = lineBuffer[i];
reiniermarcel 0:a115ff47d1c1 462 } else if (BPP_t == 24) {
reiniermarcel 0:a115ff47d1c1 463 color_t color;
reiniermarcel 0:a115ff47d1c1 464 color = RGB(lineBuffer[i*3+2], lineBuffer[i*3+1], lineBuffer[i*3+0]);
reiniermarcel 0:a115ff47d1c1 465 pixelBuffer[i] = color;
reiniermarcel 0:a115ff47d1c1 466 }
reiniermarcel 0:a115ff47d1c1 467 }
reiniermarcel 0:a115ff47d1c1 468 pixelStream(pixelBuffer, PixelWidth, x, y++);
reiniermarcel 0:a115ff47d1c1 469 }
reiniermarcel 0:a115ff47d1c1 470 _EndGraphicsStream();
reiniermarcel 0:a115ff47d1c1 471 WindowMax();
reiniermarcel 0:a115ff47d1c1 472 free(pixelBuffer); // don't leak memory
reiniermarcel 0:a115ff47d1c1 473 free(lineBuffer);
reiniermarcel 0:a115ff47d1c1 474 if (colorPalette)
reiniermarcel 0:a115ff47d1c1 475 free(colorPalette);
reiniermarcel 0:a115ff47d1c1 476 return (noerror);
reiniermarcel 0:a115ff47d1c1 477 }
reiniermarcel 0:a115ff47d1c1 478
reiniermarcel 0:a115ff47d1c1 479
reiniermarcel 0:a115ff47d1c1 480 RetCode_t GraphicsDisplay::RenderImageFile(loc_t x, loc_t y, const char *FileName)
reiniermarcel 0:a115ff47d1c1 481 {
reiniermarcel 0:a115ff47d1c1 482 if (mystrnicmp(FileName + strlen(FileName) - 4, ".bmp", 4) == 0) {
reiniermarcel 0:a115ff47d1c1 483 return RenderBitmapFile(x,y,FileName);
reiniermarcel 0:a115ff47d1c1 484 } else if (mystrnicmp(FileName + strlen(FileName) - 4, ".ico", 4) == 0) {
reiniermarcel 0:a115ff47d1c1 485 return RenderIconFile(x,y,FileName);
reiniermarcel 0:a115ff47d1c1 486 } else {
reiniermarcel 0:a115ff47d1c1 487 return not_supported_format;
reiniermarcel 0:a115ff47d1c1 488 }
reiniermarcel 0:a115ff47d1c1 489 }
reiniermarcel 0:a115ff47d1c1 490
reiniermarcel 0:a115ff47d1c1 491 RetCode_t GraphicsDisplay::RenderBitmapFile(loc_t x, loc_t y, const char *Name_BMP)
reiniermarcel 0:a115ff47d1c1 492 {
reiniermarcel 0:a115ff47d1c1 493 BITMAPFILEHEADER BMP_Header;
reiniermarcel 0:a115ff47d1c1 494
reiniermarcel 0:a115ff47d1c1 495 INFO("Opening {%s}", Name_BMP);
reiniermarcel 0:a115ff47d1c1 496 FILE *Image = fopen(Name_BMP, "rb");
reiniermarcel 0:a115ff47d1c1 497 if (!Image) {
reiniermarcel 0:a115ff47d1c1 498 return(file_not_found);
reiniermarcel 0:a115ff47d1c1 499 }
reiniermarcel 0:a115ff47d1c1 500
reiniermarcel 0:a115ff47d1c1 501 fread(&BMP_Header, 1, sizeof(BMP_Header), Image); // get the BMP Header
reiniermarcel 0:a115ff47d1c1 502 INFO("bfType %04X", BMP_Header.bfType);
reiniermarcel 0:a115ff47d1c1 503 HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header));
reiniermarcel 0:a115ff47d1c1 504 if (BMP_Header.bfType != BF_TYPE) {
reiniermarcel 0:a115ff47d1c1 505 fclose(Image);
reiniermarcel 0:a115ff47d1c1 506 return(not_bmp_format);
reiniermarcel 0:a115ff47d1c1 507 }
reiniermarcel 0:a115ff47d1c1 508 RetCode_t rt = _RenderBitmap(x, y, BMP_Header.bfOffBits, Image);
reiniermarcel 0:a115ff47d1c1 509 if (rt != noerror) {
reiniermarcel 0:a115ff47d1c1 510 return rt;
reiniermarcel 0:a115ff47d1c1 511 } else {
reiniermarcel 0:a115ff47d1c1 512 fclose(Image);
reiniermarcel 0:a115ff47d1c1 513 return (noerror);
reiniermarcel 0:a115ff47d1c1 514 }
reiniermarcel 0:a115ff47d1c1 515 }
reiniermarcel 0:a115ff47d1c1 516
reiniermarcel 0:a115ff47d1c1 517 RetCode_t GraphicsDisplay::RenderIconFile(loc_t x, loc_t y, const char *Name_ICO)
reiniermarcel 0:a115ff47d1c1 518 {
reiniermarcel 0:a115ff47d1c1 519 ICOFILEHEADER ICO_Header;
reiniermarcel 0:a115ff47d1c1 520 ICODIRENTRY ICO_DirEntry;
reiniermarcel 0:a115ff47d1c1 521
reiniermarcel 0:a115ff47d1c1 522 INFO("Opening {%s}", Name_ICO);
reiniermarcel 0:a115ff47d1c1 523 FILE *Image = fopen(Name_ICO, "rb");
reiniermarcel 0:a115ff47d1c1 524 if (!Image) {
reiniermarcel 0:a115ff47d1c1 525 return(file_not_found);
reiniermarcel 0:a115ff47d1c1 526 }
reiniermarcel 0:a115ff47d1c1 527
reiniermarcel 0:a115ff47d1c1 528 fread(&ICO_Header, 1, sizeof(ICO_Header), Image); // get the BMP Header
reiniermarcel 0:a115ff47d1c1 529 HexDump("ICO_Header", (uint8_t *)&ICO_Header, sizeof(ICO_Header));
reiniermarcel 0:a115ff47d1c1 530 if (ICO_Header.Reserved_zero != 0
reiniermarcel 0:a115ff47d1c1 531 || ICO_Header.icType != IC_TYPE
reiniermarcel 0:a115ff47d1c1 532 || ICO_Header.icImageCount == 0) {
reiniermarcel 0:a115ff47d1c1 533 fclose(Image);
reiniermarcel 0:a115ff47d1c1 534 return(not_ico_format);
reiniermarcel 0:a115ff47d1c1 535 }
reiniermarcel 0:a115ff47d1c1 536
reiniermarcel 0:a115ff47d1c1 537 // Read ONLY the first of n possible directory entries.
reiniermarcel 0:a115ff47d1c1 538 fread(&ICO_DirEntry, 1, sizeof(ICO_DirEntry), Image);
reiniermarcel 0:a115ff47d1c1 539 HexDump("ICO_DirEntry", (uint8_t *)&ICO_DirEntry, sizeof(ICO_DirEntry));
reiniermarcel 0:a115ff47d1c1 540 INFO("biBitCount %04X", ICO_DirEntry.biBitCount);
reiniermarcel 0:a115ff47d1c1 541 if (ICO_DirEntry.biBitCount != 0) { // Expecting this to be zero for ico
reiniermarcel 0:a115ff47d1c1 542 fclose(Image);
reiniermarcel 0:a115ff47d1c1 543 return(not_supported_format);
reiniermarcel 0:a115ff47d1c1 544 }
reiniermarcel 0:a115ff47d1c1 545
reiniermarcel 0:a115ff47d1c1 546 RetCode_t rt = _RenderBitmap(x, y, ICO_DirEntry.bfOffBits, Image);
reiniermarcel 0:a115ff47d1c1 547 if (rt == noerror) {
reiniermarcel 0:a115ff47d1c1 548 fclose(Image);
reiniermarcel 0:a115ff47d1c1 549 return (noerror);
reiniermarcel 0:a115ff47d1c1 550 } else {
reiniermarcel 0:a115ff47d1c1 551 return rt;
reiniermarcel 0:a115ff47d1c1 552 }
reiniermarcel 0:a115ff47d1c1 553 }
reiniermarcel 0:a115ff47d1c1 554
reiniermarcel 0:a115ff47d1c1 555 int GraphicsDisplay::columns()
reiniermarcel 0:a115ff47d1c1 556 {
reiniermarcel 0:a115ff47d1c1 557 return width() / 8;
reiniermarcel 0:a115ff47d1c1 558 }
reiniermarcel 0:a115ff47d1c1 559
reiniermarcel 0:a115ff47d1c1 560 int GraphicsDisplay::rows()
reiniermarcel 0:a115ff47d1c1 561 {
reiniermarcel 0:a115ff47d1c1 562 return height() / 8;
reiniermarcel 0:a115ff47d1c1 563 }