Skip to content

Commit 34e3168

Browse files
committed
Far improved font rendering and metrics
1 parent 55015d6 commit 34e3168

File tree

9 files changed

+356
-310
lines changed

9 files changed

+356
-310
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
22

33
SET(SG_VERSION_MAJOR "0")
44
SET(SG_VERSION_MINOR "7")
5-
SET(SG_VERSION_PATCH "8")
5+
SET(SG_VERSION_PATCH "9")
66

77
#ADD_DEFINITIONS(
88
# "-DSG_VERSION_MAJOR=${SG_VERSION_MAJOR}"

include/siege/backend/fonts/chars.h

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
/*
2-
Copyright (c) 2007 SIEGE Development Team
3-
All rights reserved.
4-
5-
This file is part of libSIEGE.
6-
7-
This software is copyrighted work licensed under the terms of the
8-
2-clause BSD license. Please consult the file "license.txt" for
9-
details.
10-
11-
If you did not recieve the file with this program, please email
12-
Tim Chas <darkuranium@gmail.com>.
13-
*/
2+
* Copyright (c) 2007 SIEGE Development Team
3+
* All rights reserved.
4+
*
5+
* This file is part of libSIEGE.
6+
*
7+
* This software is copyrighted work licensed under the terms of the
8+
* 2-clause BSD license. Please consult the file "license.txt" for
9+
* details.
10+
*
11+
* If you did not recieve the file with this program, please email
12+
* Tim Chas <darkuranium@gmail.com>.
13+
*/
1414

1515
#ifndef __SIEGE_BACKEND_FONTS_CHARS_H__
1616
#define __SIEGE_BACKEND_FONTS_CHARS_H__
@@ -25,8 +25,9 @@
2525
extern "C"
2626
{
2727
#endif
28-
SGuint SG_EXPORT SG_FPTR(sgmFontsCharsCreate)(void* face, SGuint* chars, SGuint charnum, float* width, float* height, float* prex, float* prey, float* postx, float* posty, SGuint* datawidth, SGuint* dataheight, void** data);
29-
SGuint SG_EXPORT SG_FPTR(sgmFontsCharsFreeData)(void* data);
28+
SGenum SG_EXPORT SG_FPTR(sgmFontsCharsCreate)(void* face, const SGdchar* chars, size_t numchars, float* width, float* height, float* prex, float* prey, float* postx, float* posty, size_t* datawidth, size_t* dataheight, void** data);
29+
SGenum SG_EXPORT SG_FPTR(sgmFontsCharsFreeData)(void* data);
30+
SGenum SG_EXPORT SG_FPTR(sgmFontsCharsGetKerning)(void* face, const SGdchar* chars, size_t numchars, float* kerning);
3031
#ifdef __cplusplus
3132
}
3233
#endif

include/siege/backend/fonts/face.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* This file is part of libSIEGE.
66
*
77
* This software is copyrighted work licensed under the terms of the
8-
* 2-clause BSD license. Please consult the file "license.txt" for
8+
* 2-clause BSD license. Please consult the file "COPYING.txt" for
99
* details.
1010
*
1111
* If you did not recieve the file with this program, please email
@@ -27,9 +27,9 @@ extern "C"
2727
{
2828
#endif
2929
SGenum SG_EXPORT SG_FPTR(sgmFontsFaceCreate)(void** face, SGStream* stream);
30-
SGuint SG_EXPORT SG_FPTR(sgmFontsFaceDestroy)(void* face);
31-
SGuint SG_EXPORT SG_FPTR(sgmFontsFaceSetHeight)(void* face, float height);
32-
//SGuint SG_EXPORT sgmFontsFaceGetHeight(void* face, float* height);
30+
SGenum SG_EXPORT SG_FPTR(sgmFontsFaceDestroy)(void* face);
31+
SGenum SG_EXPORT SG_FPTR(sgmFontsFaceSetHeight)(void* face, float height, SGuint dpi);
32+
SGenum SG_EXPORT SG_FPTR(sgmFontsFaceGetMetrics)(void* face, float* ascent, float* descent, float* linegap);
3333
#ifdef __cplusplus
3434
}
3535
#endif

include/siege/common.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ typedef double SGdouble;
137137
/// @{
138138
#define SG_VERSION_MAJOR 0
139139
#define SG_VERSION_MINOR 7
140-
#define SG_VERSION_PATCH 8
140+
#define SG_VERSION_PATCH 9
141141
/**
142142
* \brief Version string
143143
*

include/siege/graphics/font.h

+11-45
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ typedef struct SGCharInfo
7474
* \name Bitmap size
7575
*/
7676
/// @{
77-
SGuint dwidth;
78-
SGuint dheight;
77+
size_t dwidth;
78+
size_t dheight;
7979
/// @}
8080

8181
/**
@@ -116,15 +116,21 @@ typedef struct SGFont
116116
*/
117117
void* handle;
118118
float height; /// < Height of the font
119+
SGuint dpi;
119120
/// @}
120121

122+
float ascent;
123+
float descent;
124+
float linegap;
125+
121126
// char, wchar_t, utf8, utf16
122127
SGConv* conv[4];
123128

124129
/**
125130
* \name Preloaded characters
126131
*/
127132
/// @{
133+
size_t npreload;
128134
SGuint numchars; /// < The number of characters
129135
SGCharInfo* chars; /// < The characters themselves
130136
/// @}
@@ -156,7 +162,7 @@ SGdchar* SG_EXPORT _sgFontU8ToU32(SGFont* font, const SGchar* text);
156162
SGdchar* SG_EXPORT _sgFontWToU32(SGFont* font, const wchar_t* text);
157163
SGdchar* SG_EXPORT _sgFontToU32(SGFont* font, const char* text);
158164

159-
SGFont* SG_EXPORT sgFontCreateStream(SGStream* stream, SGbool delstream, float height, SGuint preload);
165+
SGFont* SG_EXPORT sgFontCreateStream(SGStream* stream, SGbool delstream, float height, SGuint dpi, SGuint preload);
160166
/// @{
161167
/**
162168
* \brief Load a font
@@ -177,48 +183,8 @@ SGFont* SG_EXPORT sgFontCreate(const char* fname, float height, SGuint preload);
177183
void SG_EXPORT sgFontDestroy(SGFont* font);
178184
/// @}
179185

180-
/* resize functions temporarily removed */
181-
182-
/**
183-
* \name Resizing
184-
*/
185-
/// @{
186-
/**
187-
* \brief Resize the font, force duplication.
188-
*
189-
* \param font The font to resize
190-
* \param height New font height
191-
*
192-
* \return A copy of the font, with the height \a height.
193-
*
194-
* This resizes the font and forces for it to be duplicated even
195-
* if the character data for the new size has already been created.
196-
*
197-
* It is roughly equivalent to:
198-
* \code
199-
* sgFontCreate(font->fname, font->height, font->preload);
200-
* \endcode
201-
*
202-
* \see sgFontResize
203-
*/
204-
205-
//SGFont* SG_EXPORT sgFontResizeCopy(SGFont* font, float height);
206-
/**
207-
* \brief Resize the font, duplicating only if necessarry.
208-
*
209-
* \param font The font to resize
210-
* \param height New font height
211-
*
212-
* \return A new font if one had to be created;
213-
* otherwise a previously-created font.
214-
*
215-
* This function is similar to sgFontResizeCopy(), only it
216-
* does not allocate a new font if it doesn't have to.
217-
*
218-
* \see sgFontResizeCopy
219-
*/
220-
//SGFont* SG_EXPORT sgFontResize(SGFont* font, float height);
221-
/// @}
186+
void SG_EXPORT sgFontClearCache(SGFont* font);
187+
void SG_EXPORT sgFontSetHeight(SGFont* font, float height, SGuint dpi);
222188

223189
/**
224190
* \name Printing

src/modules/SGModule-Freetype/load.c

+42-16
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,36 @@ SGenum SG_EXPORT sgmFontsFaceCreate(void** face, SGStream* stream)
9494
return SG_UNKNOWN_ERROR;
9595
return SG_OK;
9696
}
97-
SGuint SG_EXPORT sgmFontsFaceDestroy(void* face)
97+
SGenum SG_EXPORT sgmFontsFaceDestroy(void* face)
9898
{
9999
if(face == NULL)
100100
return SG_OK; // SG_INVALID_VALUE
101101
FT_Done_Face(((FontFace*)face)->ftface);
102102
free(face);
103103
return SG_OK;
104104
}
105-
SGuint SG_EXPORT sgmFontsFaceSetHeight(void* face, float height)
105+
106+
SGenum SG_EXPORT sgmFontsFaceSetHeight(void* face, float height, SGuint dpi)
106107
{
107108
if(face == NULL)
108109
return SG_OK; // SG_INVALID_VALUE
109110
((FontFace*)face)->height = height;
110-
FT_Set_Char_Size(((FontFace*)face)->ftface, (SGuint)(height * 64), (SGuint)(height * 64), 72, 72);
111+
FT_Set_Char_Size(((FontFace*)face)->ftface, (SGuint)(height * 64), (SGuint)(height * 64), dpi, dpi);
111112
return SG_OK;
112113
}
113-
/*SGuint SG_EXPORT sgmFontsFaceGetHeight(void* face, float* height)
114+
SGenum SG_EXPORT sgmFontsFaceGetMetrics(void* face, float* ascent, float* descent, float* linegap)
114115
{
115-
*height = ((FontFace*)face)->height;
116+
if(!face) return SG_INVALID_VALUE;
117+
FontFace* fface = face;
118+
119+
*ascent = fface->ftface->size->metrics.ascender / 64.0;
120+
*descent = fface->ftface->size->metrics.descender / 64.0;
121+
*linegap = fface->ftface->size->metrics.height / 64.0 + *descent - *ascent;
122+
116123
return SG_OK;
117-
}*/
118-
SGuint SG_EXPORT sgmFontsCharsCreate(void* face, SGuint* chars, SGuint charnum, float* width, float* height, float* prex, float* prey, float* postx, float* posty, SGuint* datawidth, SGuint* dataheight, void** data)
124+
}
125+
126+
SGenum SG_EXPORT sgmFontsCharsCreate(void* face, const SGdchar* chars, size_t numchars, float* width, float* height, float* prex, float* prey, float* postx, float* posty, size_t* datawidth, size_t* dataheight, void** data)
119127
{
120128
if(face == NULL)
121129
{
@@ -137,8 +145,8 @@ SGuint SG_EXPORT sgmFontsCharsCreate(void* face, SGuint* chars, SGuint charnum,
137145
FT_Glyph glyph;
138146
FT_BitmapGlyph bitmap_glyph;
139147
FT_Bitmap bitmap;
140-
SGuint i/*, j*/;
141-
for(i = 0; i < charnum; i++)
148+
SGuint i;
149+
for(i = 0; i < numchars; i++)
142150
{
143151
ret = FT_Load_Glyph(fface->ftface, FT_Get_Char_Index(fface->ftface, chars[i]), FT_LOAD_DEFAULT);
144152
if(ret)
@@ -160,27 +168,45 @@ SGuint SG_EXPORT sgmFontsCharsCreate(void* face, SGuint* chars, SGuint charnum,
160168

161169
data[i] = malloc(bitmap.width * bitmap.rows);
162170
memcpy(data[i], bitmap.buffer, bitmap.width * bitmap.rows);
163-
/*for(j = 0; j < bitmap.rows; j++)
164-
memcpy((char*)data[i] + j * bitmap.width, bitmap.buffer + (bitmap.rows - j - 1) * bitmap.width, bitmap.width);*/
165171

166172
prex[i] = bitmap_glyph->left;
167-
//prey[i] = -bitmap_glyph->top + bitmap.rows;
168173
prey[i] = -bitmap_glyph->top;
169174

170175
postx[i] = fface->ftface->glyph->advance.x / 64.0;
171176
posty[i] = 0;
172177

173-
width[i] = fface->ftface->glyph->/*bitmap.width*/advance.x / 64.0;
174-
height[i] = fface->height;
178+
width[i] = fface->ftface->glyph->metrics.width;
179+
height[i] = fface->ftface->glyph->metrics.height;
175180

176181
FT_Done_Glyph(glyph);
177182
}
178183

179184
return SG_OK;
180185
}
181-
182-
SGuint SG_EXPORT sgmFontsCharsFreeData(void* data)
186+
SGenum SG_EXPORT sgmFontsCharsFreeData(void* data)
183187
{
184188
free(data);
185189
return SG_OK;
186190
}
191+
192+
SGenum SG_EXPORT sgmFontsCharsGetKerning(void* face, const SGdchar* chars, size_t numchars, float* kerning)
193+
{
194+
if(!face) return SG_INVALID_VALUE;
195+
FontFace* fface = face;
196+
197+
FT_Vector vec;
198+
199+
FT_UInt prev = numchars ? FT_Get_Char_Index(fface->ftface, chars[0]) : 0;
200+
FT_UInt curr;
201+
202+
size_t i;
203+
for(i = 1; i < numchars; i++)
204+
{
205+
curr = FT_Get_Char_Index(fface->ftface, chars[i]);
206+
FT_Get_Kerning(fface->ftface, prev, curr, FT_KERNING_DEFAULT, &vec);
207+
kerning[i-1] = vec.x / 64.0;
208+
prev = curr;
209+
}
210+
211+
return SG_OK;
212+
}

src/modules/SGModule-STB-TrueType/load.c

+40-14
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ typedef struct FontFace
2020
{
2121
stbtt_fontinfo info;
2222
void* buf;
23-
float height;
23+
float scale;
2424
} FontFace;
2525

2626
SGenum SG_EXPORT sgmFontsFaceCreate(void** face, SGStream* stream)
@@ -50,6 +50,8 @@ SGenum SG_EXPORT sgmFontsFaceCreate(void** face, SGStream* stream)
5050
goto err;
5151
stbtt_InitFont(&fface->info, fface->buf, 0);
5252

53+
fface->scale = 1.0;
54+
5355
return SG_OK;
5456

5557
err:
@@ -64,50 +66,74 @@ SGenum SG_EXPORT sgmFontsFaceDestroy(void* face)
6466
free(fface);
6567
return SG_OK;
6668
}
67-
SGenum SG_EXPORT sgmFontsFaceSetHeight(void* face, float height)
69+
70+
SGenum SG_EXPORT sgmFontsFaceSetHeight(void* face, float height, SGuint dpi)
6871
{
6972
if(!face) return SG_INVALID_VALUE;
7073
FontFace* fface = face;
71-
fface->height = height;
74+
//fface->scale = stbtt_ScaleForPixelHeight(&fface->info, height);
75+
fface->scale = stbtt_ScaleForMappingEmToPixels(&fface->info, height * dpi / 72.0);
7276
return SG_OK;
7377
}
74-
SGenum SG_EXPORT sgmFontsCharsCreate(void* face, SGuint* chars, SGuint charnum, float* width, float* height, float* prex, float* prey, float* postx, float* posty, SGuint* datawidth, SGuint* dataheight, void** data)
78+
SGenum SG_EXPORT sgmFontsFaceGetMetrics(void* face, float* ascent, float* descent, float* linegap)
79+
{
80+
if(!face) return SG_INVALID_VALUE;
81+
FontFace* fface = face;
82+
83+
int iasc, idesc, igap;
84+
stbtt_GetFontVMetrics(&fface->info, &iasc, &idesc, &igap);
85+
*ascent = iasc * fface->scale;
86+
*descent = idesc * fface->scale;
87+
*linegap = igap * fface->scale;
88+
89+
return SG_OK;
90+
}
91+
92+
SGenum SG_EXPORT sgmFontsCharsCreate(void* face, const SGdchar* chars, size_t numchars, float* width, float* height, float* prex, float* prey, float* postx, float* posty, size_t* datawidth, size_t* dataheight, void** data)
7593
{
7694
if(!face) return SG_INVALID_VALUE;
7795

7896
FontFace* fface = (FontFace*)face;
79-
//float scale = stbtt_ScaleForPixelHeight(&fface->info, fface->height);
80-
float scale = stbtt_ScaleForMappingEmToPixels(&fface->info, fface->height);
8197

8298
int adv, left;
8399
int dw, dh;
84100
int xo, yo;
85-
int kern = 0;
86101

87102
int glyph;
88103
size_t i;
89-
for(i = 0; i < charnum; i++)
104+
for(i = 0; i < numchars; i++)
90105
{
91106
glyph = stbtt_FindGlyphIndex(&fface->info, chars[i]);
92107

93-
data[i] = stbtt_GetGlyphBitmap(&fface->info, scale, scale, glyph, &dw, &dh, &xo, &yo);
108+
data[i] = stbtt_GetGlyphBitmap(&fface->info, fface->scale, fface->scale, glyph, &dw, &dh, &xo, &yo);
94109
datawidth[i] = dw;
95110
dataheight[i] = dh;
96111

97-
if(i) kern = stbtt_GetGlyphKernAdvance(&fface->info, chars[i-1], chars[i]);
98-
99112
stbtt_GetGlyphHMetrics(&fface->info, glyph, &adv, &left);
100-
prex[i] = (left + kern) * scale + xo;
113+
prex[i] = /*-left * fface->scale * 0.5 + */xo;
101114
prey[i] = yo;
102-
postx[i] = adv * scale;
115+
postx[i] = adv * fface->scale;
103116
posty[i] = 0;
117+
width[i] = adv * fface->scale;
118+
height[i] = 0; /* TODO */
104119
}
105120

106121
return SG_OK;
107122
}
108-
109123
SGenum SG_EXPORT sgmFontsCharsFreeData(void* data)
110124
{
111125
stbtt_FreeBitmap(data, NULL);
112126
return SG_OK;
113127
}
128+
129+
SGenum SG_EXPORT sgmFontsCharsGetKerning(void* face, const SGdchar* chars, size_t numchars, float* kerning)
130+
{
131+
if(!face) return SG_INVALID_VALUE;
132+
FontFace* fface = face;
133+
134+
size_t i;
135+
for(i = 1; i < numchars; i++)
136+
kerning[i-1] = stbtt_GetCodepointKernAdvance(&fface->info, chars[i-1], chars[i]) * fface->scale;
137+
138+
return SG_OK;
139+
}

0 commit comments

Comments
 (0)