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 "platform/3ds/ctr-gpu.h"
11#include "icons.h"
12#include "font.h"
13
14#define CELL_HEIGHT 16
15#define CELL_WIDTH 16
16#define GLYPH_HEIGHT 12
17
18struct GUIFont {
19 struct ctrTexture texture;
20 struct ctrTexture icons;
21};
22
23struct GUIFont* GUIFontCreate(void) {
24 struct GUIFont* guiFont = malloc(sizeof(struct GUIFont));
25 if (!guiFont) {
26 return 0;
27 }
28
29 struct ctrTexture* tex = &guiFont->texture;
30 ctrTexture_Init(tex);
31 tex->data = vramAlloc(256 * 128 * 2);
32 tex->format = GPU_RGBA5551;
33 tex->width = 256;
34 tex->height = 128;
35
36 GSPGPU_FlushDataCache(font, font_size);
37 GX_RequestDma((u32*) font, tex->data, font_size);
38 gspWaitForDMA();
39
40 tex = &guiFont->icons;
41 ctrTexture_Init(tex);
42 tex->data = vramAlloc(256 * 64 * 2);
43 tex->format = GPU_RGBA5551;
44 tex->width = 256;
45 tex->height = 64;
46
47 GSPGPU_FlushDataCache(icons, icons_size);
48 GX_RequestDma((u32*) icons, tex->data, icons_size);
49 gspWaitForDMA();
50
51 return guiFont;
52}
53
54void GUIFontDestroy(struct GUIFont* font) {
55 vramFree(font->texture.data);
56 vramFree(font->icons.data);
57 free(font);
58}
59
60unsigned GUIFontHeight(const struct GUIFont* font) {
61 UNUSED(font);
62 return GLYPH_HEIGHT;
63}
64
65unsigned GUIFontGlyphWidth(const struct GUIFont* font, uint32_t glyph) {
66 UNUSED(font);
67 if (glyph > 0x7F) {
68 glyph = 0;
69 }
70 return defaultFontMetrics[glyph].width;
71}
72
73void GUIFontIconMetrics(const struct GUIFont* font, enum GUIIcon icon, unsigned* w, unsigned* h) {
74 UNUSED(font);
75 if (icon >= GUI_ICON_MAX) {
76 if (w) {
77 *w = 0;
78 }
79 if (h) {
80 *h = 0;
81 }
82 } else {
83 if (w) {
84 *w = defaultIconMetrics[icon].width;
85 }
86 if (h) {
87 *h = defaultIconMetrics[icon].height;
88 }
89 }
90}
91
92void GUIFontDrawGlyph(const struct GUIFont* font, int glyph_x, int glyph_y, uint32_t color, uint32_t glyph) {
93 ctrActivateTexture(&font->texture);
94
95 if (glyph > 0x7F) {
96 glyph = '?';
97 }
98
99 struct GUIFontGlyphMetric metric = defaultFontMetrics[glyph];
100 u16 x = glyph_x - metric.padding.left;
101 u16 y = glyph_y - GLYPH_HEIGHT;
102 u16 u = (glyph % 16u) * CELL_WIDTH;
103 u16 v = (glyph / 16u) * CELL_HEIGHT;
104
105 ctrAddRect(color, x, y, u, v, CELL_WIDTH, CELL_HEIGHT);
106}
107
108void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) {
109 ctrActivateTexture(&font->icons);
110
111 if (icon >= GUI_ICON_MAX) {
112 return;
113 }
114
115 struct GUIIconMetric metric = defaultIconMetrics[icon];
116 switch (align & GUI_ALIGN_HCENTER) {
117 case GUI_ALIGN_HCENTER:
118 x -= metric.width / 2;
119 break;
120 case GUI_ALIGN_RIGHT:
121 x -= metric.width;
122 break;
123 }
124 switch (align & GUI_ALIGN_VCENTER) {
125 case GUI_ALIGN_VCENTER:
126 y -= metric.height / 2;
127 break;
128 case GUI_ALIGN_BOTTOM:
129 y -= metric.height;
130 break;
131 }
132 switch (orient) {
133 case GUI_ORIENT_HMIRROR:
134 ctrAddRectScaled(color, x + metric.width, y, -metric.width, metric.height, metric.x, metric.y, metric.width, metric.height);
135 break;
136 case GUI_ORIENT_VMIRROR:
137 ctrAddRectScaled(color, x, y + metric.height, metric.width, -metric.height, metric.x, metric.y, metric.width, metric.height);
138 break;
139 case GUI_ORIENT_0:
140 default:
141 // TODO: Rotation
142 ctrAddRect(color, x, y, metric.x, metric.y, metric.width, metric.height);
143 break;
144 }
145}
146
147void GUIFontDrawIconSize(const struct GUIFont* font, int x, int y, int w, int h, uint32_t color, enum GUIIcon icon) {
148 ctrActivateTexture(&font->icons);
149
150 if (icon >= GUI_ICON_MAX) {
151 return;
152 }
153
154 struct GUIIconMetric metric = defaultIconMetrics[icon];
155 ctrAddRectScaled(color, x, y, w ? w : metric.width, h ? h : metric.height, metric.x, metric.y, metric.width, metric.height);
156}