| 13 | extern Font* mainFont; |
| 14 | |
| 15 | int DrawChar(char character, int x, int y, uint8_t r, uint8_t g, uint8_t b, surface_t* surface, rect_t limits, Font* font){ |
| 16 | if (!isprint(character)) { |
| 17 | return 0; |
| 18 | } |
| 19 | |
| 20 | if(y >= surface->height || x >= surface->width || y >= limits.height || x >= limits.width) return 0; |
| 21 | |
| 22 | if((fontState != 1 && fontState != -1) || !font->face) InitializeFonts(); |
| 23 | if(fontState == -1){ // |
| 24 | character &= 0x7F; |
| 25 | |
| 26 | for(int i = 0; i < 12; i++) { |
| 27 | uint8_t line = font_default[i * 128 + character]; |
| 28 | |
| 29 | for(int j = 0; j < 8; j++) { |
| 30 | if(line & 0x80) |
| 31 | DrawRect(j + x, i + y, 1, 1, r, g, b, surface); |
| 32 | line <<= 1; // Shift line left by one |
| 33 | } |
| 34 | } |
| 35 | return 8; |
| 36 | } |
| 37 | |
| 38 | uint32_t colour_i = 0xFF000000 | (r << 16) | (g << 8) | b; |
| 39 | uint32_t* buffer = (uint32_t*)surface->buffer; |
| 40 | if(int err = FT_Load_Char(font->face, character, FT_LOAD_RENDER)) { |
| 41 | printf("Freetype Error (code: %d, font: %s)\n", err, font->id); |
| 42 | throw new FontException(FontException::FontRenderError, err); |
| 43 | fontState = 0; |
| 44 | return 0; |
| 45 | } |
| 46 | |
| 47 | int maxHeight = font->lineHeight - (font->height - font->face->glyph->bitmap_top); |
| 48 | |
| 49 | if(y + maxHeight >= limits.y + limits.height){ |
| 50 | maxHeight = limits.y + limits.height - y; |
| 51 | } |
| 52 | |
| 53 | if(y + maxHeight >= surface->height){ |
| 54 | maxHeight = surface->height - y; |
| 55 | } |
| 56 | |
| 57 | for(int i = 0; i < static_cast<int>(font->face->glyph->bitmap.rows) && i < maxHeight; i++){ |
| 58 | if(y + i < 0) continue; |
| 59 | |
| 60 | uint32_t yOffset = (i + y + (font->height - font->face->glyph->bitmap_top)) * (surface->width); |
| 61 | for(unsigned int j = 0; j < font->face->glyph->bitmap.width && static_cast<long>(j) + x < surface->width; j++){ |
| 62 | if(x + static_cast<long>(j) < 0) continue; |
| 63 | if(font->face->glyph->bitmap.buffer[i * font->face->glyph->bitmap.width + j] == 255) |
| 64 | buffer[yOffset + (j + x)] = colour_i; |
| 65 | else if(font->face->glyph->bitmap.buffer[i * font->face->glyph->bitmap.width + j] > 0){ |
| 66 | double val = font->face->glyph->bitmap.buffer[i * font->face->glyph->bitmap.width + j] * 1.0 / 255; |
| 67 | buffer[yOffset + (j + x)] = AlphaBlend(buffer[yOffset + (j + x)], r, g, b, val); |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | return font->face->glyph->advance.x >> 6; |
| 72 | } |
no test coverage detected