src/platform/3ds/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 "util/png-io.h"
9#include "util/vfs.h"
10#include "icons.h"
11
12#include "ctr-gpu.h"
13
14#define CELL_HEIGHT 16
15#define CELL_WIDTH 16
16#define FONT_SIZE 0.52f
17
18struct GUIFont {
19 C3D_Tex* sheets;
20 C3D_Tex icons;
21};
22
23struct GUIFont* GUIFontCreate(void) {
24 fontEnsureMapped();
25 struct GUIFont* guiFont = malloc(sizeof(struct GUIFont));
26 if (!guiFont) {
27 return 0;
28 }
29 C3D_Tex* tex;
30
31 TGLP_s* glyphInfo = fontGetGlyphInfo();
32 guiFont->sheets = malloc(sizeof(*guiFont->sheets) * glyphInfo->nSheets);
33
34 int i;
35 for (i = 0; i < glyphInfo->nSheets; ++i) {
36 tex = &guiFont->sheets[i];
37 tex->data = fontGetGlyphSheetTex(i);
38 tex->fmt = glyphInfo->sheetFmt;
39 tex->size = glyphInfo->sheetSize;
40 tex->width = glyphInfo->sheetWidth;
41 tex->height = glyphInfo->sheetHeight;
42 tex->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) | GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE);
43 }
44
45 tex = &guiFont->icons;
46 C3D_TexInitVRAM(tex, 256, 64, GPU_RGBA5551);
47
48 GSPGPU_FlushDataCache(icons, icons_size);
49 GX_RequestDma((u32*) icons, tex->data, icons_size);
50 gspWaitForDMA();
51
52 return guiFont;
53}
54
55void GUIFontDestroy(struct GUIFont* font) {
56 free(font->sheets);
57 C3D_TexDelete(&font->icons);
58 free(font);
59}
60
61unsigned GUIFontHeight(const struct GUIFont* font) {
62 UNUSED(font);
63 return fontGetInfo()->lineFeed * FONT_SIZE;
64}
65
66unsigned GUIFontGlyphWidth(const struct GUIFont* font, uint32_t glyph) {
67 UNUSED(font);
68 int index = fontGlyphIndexFromCodePoint(glyph);
69 charWidthInfo_s* info = fontGetCharWidthInfo(index);
70 if (info) {
71 return info->charWidth * FONT_SIZE;
72 }
73 return 0;
74}
75
76void GUIFontIconMetrics(const struct GUIFont* font, enum GUIIcon icon, unsigned* w, unsigned* h) {
77 UNUSED(font);
78 if (icon >= GUI_ICON_MAX) {
79 if (w) {
80 *w = 0;
81 }
82 if (h) {
83 *h = 0;
84 }
85 } else {
86 if (w) {
87 *w = defaultIconMetrics[icon].width;
88 }
89 if (h) {
90 *h = defaultIconMetrics[icon].height;
91 }
92 }
93}
94
95void GUIFontDrawGlyph(const struct GUIFont* font, int glyph_x, int glyph_y, uint32_t color, uint32_t glyph) {
96 int index = fontGlyphIndexFromCodePoint(glyph);
97 fontGlyphPos_s data;
98 fontCalcGlyphPos(&data, index, 0, 1.0, 1.0);
99
100 C3D_Tex* tex = &font->sheets[data.sheetIndex];
101 ctrActivateTexture(tex);
102
103 float width = data.texcoord.right - data.texcoord.left;
104 float height = data.texcoord.top - data.texcoord.bottom;
105 u16 x = glyph_x;
106 u16 y = glyph_y + tex->height * height / 8;
107 u16 u = tex->width * data.texcoord.left;
108 u16 v = tex->height * data.texcoord.bottom;
109
110 ctrAddRectScaled(color, x, y, tex->width * width * FONT_SIZE, tex->height * height * -FONT_SIZE, u, v, tex->width * width, tex->height * height);
111}
112
113void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) {
114 ctrActivateTexture(&font->icons);
115
116 if (icon >= GUI_ICON_MAX) {
117 return;
118 }
119
120 struct GUIIconMetric metric = defaultIconMetrics[icon];
121 switch (align & GUI_ALIGN_HCENTER) {
122 case GUI_ALIGN_HCENTER:
123 x -= metric.width / 2;
124 break;
125 case GUI_ALIGN_RIGHT:
126 x -= metric.width;
127 break;
128 }
129 switch (align & GUI_ALIGN_VCENTER) {
130 case GUI_ALIGN_VCENTER:
131 y -= metric.height / 2;
132 break;
133 case GUI_ALIGN_BOTTOM:
134 y -= metric.height;
135 break;
136 }
137 switch (orient) {
138 case GUI_ORIENT_HMIRROR:
139 ctrAddRectScaled(color, x + metric.width, y, -metric.width, metric.height, metric.x, metric.y, metric.width, metric.height);
140 break;
141 case GUI_ORIENT_VMIRROR:
142 ctrAddRectScaled(color, x, y + metric.height, metric.width, -metric.height, metric.x, metric.y, metric.width, metric.height);
143 break;
144 case GUI_ORIENT_0:
145 default:
146 // TODO: Rotation
147 ctrAddRect(color, x, y, metric.x, metric.y, metric.width, metric.height);
148 break;
149 }
150}
151
152void GUIFontDrawIconSize(const struct GUIFont* font, int x, int y, int w, int h, uint32_t color, enum GUIIcon icon) {
153 ctrActivateTexture(&font->icons);
154
155 if (icon >= GUI_ICON_MAX) {
156 return;
157 }
158
159 struct GUIIconMetric metric = defaultIconMetrics[icon];
160 ctrAddRectScaled(color, x, y, w ? w : metric.width, h ? h : metric.height, metric.x, metric.y, metric.width, metric.height);
161}