src/platform/wii/gui-font.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "util/gui/font.h"
7#include "util/gui/font-metrics.h"
8#include "font.h"
9
10#include <ogc/tpl.h>
11
12#define GLYPH_HEIGHT 12
13#define CELL_HEIGHT 16
14#define CELL_WIDTH 16
15
16struct GUIFont {
17 TPLFile tdf;
18};
19
20struct GUIFont* GUIFontCreate(void) {
21 struct GUIFont* guiFont = malloc(sizeof(struct GUIFont));
22 if (!guiFont) {
23 return 0;
24 }
25
26 // libogc's TPL code modifies and frees this itself...
27 void* fontTpl = memalign(32, font_size);
28 if (!fontTpl) {
29 free(guiFont);
30 return 0;
31 }
32 memcpy(fontTpl, font, font_size);
33 TPL_OpenTPLFromMemory(&guiFont->tdf, fontTpl, font_size);
34 return guiFont;
35}
36
37void GUIFontDestroy(struct GUIFont* font) {
38 TPL_CloseTPLFile(&font->tdf);
39 free(font);
40}
41
42int GUIFontHeight(const struct GUIFont* font) {
43 UNUSED(font);
44 return GLYPH_HEIGHT;
45}
46
47void GUIFontPrintf(const struct GUIFont* font, int x, int y, enum GUITextAlignment align, uint32_t color, const char* text, ...) {
48 UNUSED(align); // TODO
49 char buffer[256];
50 va_list args;
51 va_start(args, text);
52 int len = vsnprintf(buffer, sizeof(buffer), text, args);
53 va_end(args);
54 int i;
55 GXTexObj tex;
56 // Grumble grumble, libogc is bad about const-correctness
57 struct GUIFont* ncfont = font;
58 TPL_GetTexture(&ncfont->tdf, 0, &tex);
59 GX_LoadTexObj(&tex, GX_TEXMAP0);
60
61 GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
62 GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
63
64 for (i = 0; i < len; ++i) {
65 char c = buffer[i];
66 if (c > 0x7F) {
67 c = 0;
68 }
69 struct GUIFontGlyphMetric metric = defaultFontMetrics[c];
70 s16 tx = (c & 15) * CELL_WIDTH + metric.padding.left;
71 s16 ty = (c >> 4) * CELL_HEIGHT + metric.padding.top;
72 GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
73 GX_Position2s16(x, y - GLYPH_HEIGHT + metric.padding.top);
74 GX_TexCoord2f32(tx / 256.f, ty / 128.f);
75
76 GX_Position2s16(x + CELL_WIDTH - (metric.padding.left + metric.padding.right), y - GLYPH_HEIGHT + metric.padding.top);
77 GX_TexCoord2f32((tx + CELL_WIDTH - (metric.padding.left + metric.padding.right)) / 256.f, ty / 128.f);
78
79 GX_Position2s16(x + CELL_WIDTH - (metric.padding.left + metric.padding.right), y - GLYPH_HEIGHT + CELL_HEIGHT - metric.padding.bottom);
80 GX_TexCoord2f32((tx + CELL_WIDTH - (metric.padding.left + metric.padding.right)) / 256.f, (ty + CELL_HEIGHT - (metric.padding.top + metric.padding.bottom)) / 128.f);
81
82 GX_Position2s16(x, y - GLYPH_HEIGHT + CELL_HEIGHT - metric.padding.bottom);
83 GX_TexCoord2f32(tx / 256.f, (ty + CELL_HEIGHT - (metric.padding.top + metric.padding.bottom)) / 128.f);
84 GX_End();
85 x += metric.width;
86 }
87}