* Load a font file. * * @param filename The name of the font file. * @return The pointer of the allocated memory where the file has been read. */
| 57 | * @return The pointer of the allocated memory where the file has been read. |
| 58 | */ |
| 59 | static Font *Font_LoadFile(const char *filename) |
| 60 | { |
| 61 | uint8 *buf; |
| 62 | Font *f; |
| 63 | uint8 i; |
| 64 | uint16 start; |
| 65 | uint16 dataStart; |
| 66 | uint16 widthList; |
| 67 | uint16 lineList; |
| 68 | |
| 69 | if (!File_Exists(filename)) return NULL; |
| 70 | |
| 71 | buf = (uint8 *)File_ReadWholeFile(filename); |
| 72 | |
| 73 | if (buf[2] != 0x00 || buf[3] != 0x05) { |
| 74 | free(buf); |
| 75 | return NULL; |
| 76 | } |
| 77 | |
| 78 | f = (Font *)calloc(1, sizeof(Font)); |
| 79 | start = READ_LE_UINT16(buf + 4); |
| 80 | dataStart = READ_LE_UINT16(buf + 6); |
| 81 | widthList = READ_LE_UINT16(buf + 8); |
| 82 | lineList = READ_LE_UINT16(buf + 12); |
| 83 | f->height = buf[start + 4]; |
| 84 | f->maxWidth = buf[start + 5]; |
| 85 | f->count = READ_LE_UINT16(buf + 10) - widthList; |
| 86 | f->chars = (FontChar *)calloc(f->count, sizeof(FontChar)); |
| 87 | |
| 88 | for (i = 0; i < f->count; i++) { |
| 89 | FontChar *fc = &f->chars[i]; |
| 90 | uint16 dataOffset; |
| 91 | uint8 x; |
| 92 | uint8 y; |
| 93 | |
| 94 | fc->width = buf[widthList + i]; |
| 95 | fc->unusedLines = buf[lineList + i * 2]; |
| 96 | fc->usedLines = buf[lineList + i * 2 + 1]; |
| 97 | |
| 98 | dataOffset = READ_LE_UINT16(buf + dataStart + i * 2); |
| 99 | if (dataOffset == 0) continue; |
| 100 | |
| 101 | fc->data = (uint8 *)malloc(fc->usedLines * fc->width); |
| 102 | |
| 103 | for (y = 0; y < fc->usedLines; y++) { |
| 104 | for (x = 0; x < fc->width; x++) { |
| 105 | uint8 data = buf[dataOffset + y * ((fc->width + 1) / 2) + x / 2]; |
| 106 | if (x % 2 != 0) data >>= 4; |
| 107 | fc->data[y * fc->width + x] = data & 0xF; |
| 108 | } |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | free(buf); |
| 113 | |
| 114 | return f; |
| 115 | } |
| 116 |
no test coverage detected