Project Alice
Loading...
Searching...
No Matches
bmfont.cpp
Go to the documentation of this file.
1/*
2BASIC bm_font example implementation with Kerning, for C++ and OpenGL 2.0
3
4This is free and unencumbered software released into the public domain.
5
6Anyone is free to copy, modify, publish, use, compile, sell, or
7distribute this software, either in source code form or as a compiled
8binary, for any purpose, commercial or non-commercial, and by any
9means.
10
11In jurisdictions that recognize copyright laws, the author or authors
12of this software dedicate any and all copyright interest in the
13software to the public domain. We make this dedication for the benefit
14of the public at large and to the detriment of our heirs and
15successors. We intend this dedication to be an overt act of
16relinquishment in perpetuity of all present and future rights to this
17software under copyright law.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25OTHER DEALINGS IN THE SOFTWARE.
26
27For more information, please refer to <http://unlicense.org/>
28--------------------------------------------------------------------------------
29These editors can be used to generate BMFonts:
30 • http://www.angelcode.com/products/bmfont/ (free, windows)
31 • http://glyphdesigner.71squared.com/ (commercial, mac os x)
32 • http://www.n4te.com/hiero/hiero.jnlp (free, java, multiplatform)
33 • http://slick.cokeandcode.com/demos/hiero.jnlp (free, java, multiplatform)
34
35Some code below based on code snippets from this gamedev posting:
36
37http://www.gamedev.net/topic/330742-quick-tutorial-variable-width-bitmap-fonts/
38
39Although I'm giving this away, I'd appreciate an email with fixes or better code!
40
41aaedev@gmail.com 2012
42*/
43
44#include <stdio.h>
45#include <stdlib.h>
46#include <glew.h>
47#include <string>
48#include <stdarg.h>
49#include "bmfont.hpp"
50#include "texture.hpp"
51#include "fonts.hpp"
52#include "system_state.hpp"
53
54#ifdef _WIN64
55#pragma warning(disable : 4996)
56#endif
57
58#include "parsers.hpp"
59
60namespace parsers {
65 int32_t first = 0;
66 int32_t second = 0;
67
69};
71 void x(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
72 context.font.chars[context.char_id].x = value;
73 }
74 void y(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
75 context.font.chars[context.char_id].y = value;
76 }
77 void xadvance(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
78 context.font.chars[context.char_id].x_advance = value;
79 }
80 void xoffset(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
81 context.font.chars[context.char_id].x_offset = value;
82 }
83 void yoffset(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
84 context.font.chars[context.char_id].y_offset = value;
85 }
86 void page(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
87 context.font.chars[context.char_id].page = value;
88 }
89 void width(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
90 context.font.chars[context.char_id].width = value;
91 }
92 void height(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
93 context.font.chars[context.char_id].height = value;
94 }
95 void first(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
96 context.first = value;
97 }
98 void second(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
99 context.second = value;
100 }
101 void amount(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
102 uint16_t index = (uint16_t(context.first) << 8) | uint16_t(context.second);
103 context.font.kernings.insert_or_assign(index, value);
104 }
105 void id(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
106 context.char_id = uint8_t(value);
107 }
108 void lineheight(association_type, int32_t value, error_handler& err, int32_t line, bmfont_file_context& context) {
109 context.font.line_height = value;
110 }
112 assert(context.font.line_height >= 0);
113 }
114};
115}
116#include "bmfont_defs_generated.hpp"
117
118namespace text {
119
121 auto content = simple_fs::view_contents(f);
125 parsers::token_generator gen(content.data, content.data + content.file_size);
126 parsers::bmfont_file_context bmfont_file_context(context, *this);
127 parsers::parse_bmfont_file(gen, err, bmfont_file_context);
128 return true;
129}
130
132 uint16_t index = (uint16_t(first) << 8) | uint16_t(second);
133 if(auto it = kernings.find(index); it != kernings.end())
134 return it->second;
135 else
136 return 0;
137}
138
139float bm_font::get_string_width(sys::state& state, char const* string, uint32_t count) const {
140 float total = 0.f;
141 for(uint32_t i = 0; i < count; ++i) {
142 auto ch = uint8_t(string[i]);
143 if(i != 0 && ch == 0xC3 && uint8_t(string[i + 1]) == 0xA3) {
144 ch = 0xA3;
145 i++;
146 } else if(ch == 0xA4) {
147 ch = 0xA3;
148 }
149 if(i != count - 1) {
150 total += get_kerning_pair(ch, string[i + 1]);
151 }
152 total += chars[ch].x_advance * (ch == 0xA3 ? 0.25f : 1.f);
153 }
154 return total;
155}
156
158 if(ftexid)
159 glDeleteTextures(1, &ftexid);
160}
161
162bm_font const& get_bm_font(sys::state& state, uint16_t font_handle) {
163 if(auto it = state.font_collection.bitmap_fonts.find(font_handle); it != state.font_collection.bitmap_fonts.end()) {
164 return it->second;
165 } else {
166 auto fit = state.font_collection.font_names.find(font_handle);
167 assert(fit != state.font_collection.font_names.end());
168 auto fname = [&]() {
169 auto sv = state.to_string_view(fit->second);
170 if(sv == "Main_14")
171 return std::string("garamond_14");
172 if(sv == "Main_14_plain")
173 return std::string("garamond_14");
174 if(sv == "Main_14_grey")
175 return std::string("garamond_14_bold");
176 if(sv == "Main_14_black")
177 return std::string("garamond_14_bold");
178 if(sv == "Main_14_red")
179 return std::string("garamond_14_bold");
180 if(sv == "Main_14_bold")
181 return std::string("garamond_14_bold");
182 if(sv == "Main_14_orange")
183 return std::string("garamond_14_bold");
184 if(sv == "Main_14_eu")
185 return std::string("garamond_14");
186 if(sv == "tahoma_60")
187 return std::string("mapfont_56");
188 if(sv == "mapfont_56_small")
189 return std::string("vic_22_bl");
190 if(sv == "ToolTip_Font")
191 return std::string("garamond_16");
192 if(sv == "FPS_Font")
193 return std::string("Arial14");
194 return std::string(sv);
195 }();
196
197 auto root = get_root(state.common_fs);
198 auto gfx_dir = open_directory(root, NATIVE("gfx"));
199 auto font_dir = open_directory(gfx_dir, NATIVE("fonts"));
200 auto font_def = open_file(font_dir, simple_fs::win1250_to_native(fname + ".fnt"));
201 auto font_image = open_file(font_dir, simple_fs::win1250_to_native(fname + ".tga"));
202 if(!bool(font_def) || !bool(font_image)) {
203 auto result = state.font_collection.bitmap_fonts.insert_or_assign(font_handle, bm_font());
204 return result.first->second;
205 }
206 auto result = state.font_collection.bitmap_fonts.insert_or_assign(font_handle, bm_font(state, *font_def, *font_image));
207 return result.first->second;
208 }
209}
210
211} // namespace text
std::string file_name
Definition: parsers.hpp:61
ankerl::unordered_dense::map< uint16_t, int32_t > kernings
Definition: bmfont.hpp:88
GLuint ftexid
Definition: bmfont.hpp:96
int32_t line_height
Definition: bmfont.hpp:89
bool parse_font(sys::state &state, simple_fs::file &f)
Definition: bmfont.cpp:120
float get_string_width(sys::state &state, char const *, uint32_t) const
Definition: bmfont.cpp:139
int get_kerning_pair(char, char) const
Definition: bmfont.cpp:131
std::array< char_descriptor, 256 > chars
Definition: bmfont.hpp:87
#define assert(condition)
Definition: debug.h:74
association_type
Definition: parsers.hpp:28
native_string win1250_to_native(std::string_view data_in)
native_string get_full_name(directory const &f)
std::string native_to_utf8(native_string_view data_in)
file_contents view_contents(file const &f)
Definition: bmfont.cpp:118
bm_font const & get_bm_font(sys::state &state, uint16_t font_handle)
Definition: bmfont.cpp:162
#define NATIVE(X)
uint uint32_t
uchar uint8_t
text::bm_font & font
Definition: bmfont.cpp:63
scenario_building_context & outer_context
Definition: bmfont.cpp:62
bmfont_file_context(scenario_building_context &outer_context, text::bm_font &font)
Definition: bmfont.cpp:68
void height(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:92
void page(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:86
void first(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:95
void xadvance(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:77
void x(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:71
void y(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:74
void xoffset(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:80
void finish(bmfont_file_context &context)
Definition: bmfont.cpp:111
void yoffset(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:83
void amount(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:101
void width(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:89
void lineheight(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:108
void id(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:105
void second(association_type, int32_t value, error_handler &err, int32_t line, bmfont_file_context &context)
Definition: bmfont.cpp:98