Permalink
Browse files

Far improved font rendering and metrics

  • Loading branch information...
darkuranium committed Sep 29, 2012
1 parent 55015d6 commit 34e31681738a7b4b479780a8c7069f50acbc6be6
View
@@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
SET(SG_VERSION_MAJOR "0")
SET(SG_VERSION_MINOR "7")
-SET(SG_VERSION_PATCH "8")
+SET(SG_VERSION_PATCH "9")
#ADD_DEFINITIONS(
# "-DSG_VERSION_MAJOR=${SG_VERSION_MAJOR}"
@@ -1,16 +1,16 @@
/*
- Copyright (c) 2007 SIEGE Development Team
- All rights reserved.
-
- This file is part of libSIEGE.
-
- This software is copyrighted work licensed under the terms of the
- 2-clause BSD license. Please consult the file "license.txt" for
- details.
-
- If you did not recieve the file with this program, please email
- Tim Chas <darkuranium@gmail.com>.
-*/
+ * Copyright (c) 2007 SIEGE Development Team
+ * All rights reserved.
+ *
+ * This file is part of libSIEGE.
+ *
+ * This software is copyrighted work licensed under the terms of the
+ * 2-clause BSD license. Please consult the file "license.txt" for
+ * details.
+ *
+ * If you did not recieve the file with this program, please email
+ * Tim Chas <darkuranium@gmail.com>.
+ */
#ifndef __SIEGE_BACKEND_FONTS_CHARS_H__
#define __SIEGE_BACKEND_FONTS_CHARS_H__
@@ -25,8 +25,9 @@
extern "C"
{
#endif
- 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);
- SGuint SG_EXPORT SG_FPTR(sgmFontsCharsFreeData)(void* data);
+ 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);
+ SGenum SG_EXPORT SG_FPTR(sgmFontsCharsFreeData)(void* data);
+ SGenum SG_EXPORT SG_FPTR(sgmFontsCharsGetKerning)(void* face, const SGdchar* chars, size_t numchars, float* kerning);
#ifdef __cplusplus
}
#endif
@@ -5,7 +5,7 @@
* This file is part of libSIEGE.
*
* This software is copyrighted work licensed under the terms of the
- * 2-clause BSD license. Please consult the file "license.txt" for
+ * 2-clause BSD license. Please consult the file "COPYING.txt" for
* details.
*
* If you did not recieve the file with this program, please email
@@ -27,9 +27,9 @@ extern "C"
{
#endif
SGenum SG_EXPORT SG_FPTR(sgmFontsFaceCreate)(void** face, SGStream* stream);
- SGuint SG_EXPORT SG_FPTR(sgmFontsFaceDestroy)(void* face);
- SGuint SG_EXPORT SG_FPTR(sgmFontsFaceSetHeight)(void* face, float height);
- //SGuint SG_EXPORT sgmFontsFaceGetHeight(void* face, float* height);
+ SGenum SG_EXPORT SG_FPTR(sgmFontsFaceDestroy)(void* face);
+ SGenum SG_EXPORT SG_FPTR(sgmFontsFaceSetHeight)(void* face, float height, SGuint dpi);
+ SGenum SG_EXPORT SG_FPTR(sgmFontsFaceGetMetrics)(void* face, float* ascent, float* descent, float* linegap);
#ifdef __cplusplus
}
#endif
View
@@ -137,7 +137,7 @@ typedef double SGdouble;
/// @{
#define SG_VERSION_MAJOR 0
#define SG_VERSION_MINOR 7
-#define SG_VERSION_PATCH 8
+#define SG_VERSION_PATCH 9
/**
* \brief Version string
*
@@ -74,8 +74,8 @@ typedef struct SGCharInfo
* \name Bitmap size
*/
/// @{
- SGuint dwidth;
- SGuint dheight;
+ size_t dwidth;
+ size_t dheight;
/// @}
/**
@@ -116,15 +116,21 @@ typedef struct SGFont
*/
void* handle;
float height; /// < Height of the font
+ SGuint dpi;
/// @}
+ float ascent;
+ float descent;
+ float linegap;
+
// char, wchar_t, utf8, utf16
SGConv* conv[4];
/**
* \name Preloaded characters
*/
/// @{
+ size_t npreload;
SGuint numchars; /// < The number of characters
SGCharInfo* chars; /// < The characters themselves
/// @}
@@ -156,7 +162,7 @@ SGdchar* SG_EXPORT _sgFontU8ToU32(SGFont* font, const SGchar* text);
SGdchar* SG_EXPORT _sgFontWToU32(SGFont* font, const wchar_t* text);
SGdchar* SG_EXPORT _sgFontToU32(SGFont* font, const char* text);
-SGFont* SG_EXPORT sgFontCreateStream(SGStream* stream, SGbool delstream, float height, SGuint preload);
+SGFont* SG_EXPORT sgFontCreateStream(SGStream* stream, SGbool delstream, float height, SGuint dpi, SGuint preload);
/// @{
/**
* \brief Load a font
@@ -177,48 +183,8 @@ SGFont* SG_EXPORT sgFontCreate(const char* fname, float height, SGuint preload);
void SG_EXPORT sgFontDestroy(SGFont* font);
/// @}
-/* resize functions temporarily removed */
-
-/**
- * \name Resizing
- */
-/// @{
-/**
- * \brief Resize the font, force duplication.
- *
- * \param font The font to resize
- * \param height New font height
- *
- * \return A copy of the font, with the height \a height.
- *
- * This resizes the font and forces for it to be duplicated even
- * if the character data for the new size has already been created.
- *
- * It is roughly equivalent to:
- * \code
- * sgFontCreate(font->fname, font->height, font->preload);
- * \endcode
- *
- * \see sgFontResize
- */
-
-//SGFont* SG_EXPORT sgFontResizeCopy(SGFont* font, float height);
-/**
- * \brief Resize the font, duplicating only if necessarry.
- *
- * \param font The font to resize
- * \param height New font height
- *
- * \return A new font if one had to be created;
- * otherwise a previously-created font.
- *
- * This function is similar to sgFontResizeCopy(), only it
- * does not allocate a new font if it doesn't have to.
- *
- * \see sgFontResizeCopy
- */
-//SGFont* SG_EXPORT sgFontResize(SGFont* font, float height);
-/// @}
+void SG_EXPORT sgFontClearCache(SGFont* font);
+void SG_EXPORT sgFontSetHeight(SGFont* font, float height, SGuint dpi);
/**
* \name Printing
@@ -94,28 +94,36 @@ SGenum SG_EXPORT sgmFontsFaceCreate(void** face, SGStream* stream)
return SG_UNKNOWN_ERROR;
return SG_OK;
}
-SGuint SG_EXPORT sgmFontsFaceDestroy(void* face)
+SGenum SG_EXPORT sgmFontsFaceDestroy(void* face)
{
if(face == NULL)
return SG_OK; // SG_INVALID_VALUE
FT_Done_Face(((FontFace*)face)->ftface);
free(face);
return SG_OK;
}
-SGuint SG_EXPORT sgmFontsFaceSetHeight(void* face, float height)
+
+SGenum SG_EXPORT sgmFontsFaceSetHeight(void* face, float height, SGuint dpi)
{
if(face == NULL)
return SG_OK; // SG_INVALID_VALUE
((FontFace*)face)->height = height;
- FT_Set_Char_Size(((FontFace*)face)->ftface, (SGuint)(height * 64), (SGuint)(height * 64), 72, 72);
+ FT_Set_Char_Size(((FontFace*)face)->ftface, (SGuint)(height * 64), (SGuint)(height * 64), dpi, dpi);
return SG_OK;
}
-/*SGuint SG_EXPORT sgmFontsFaceGetHeight(void* face, float* height)
+SGenum SG_EXPORT sgmFontsFaceGetMetrics(void* face, float* ascent, float* descent, float* linegap)
{
- *height = ((FontFace*)face)->height;
+ if(!face) return SG_INVALID_VALUE;
+ FontFace* fface = face;
+
+ *ascent = fface->ftface->size->metrics.ascender / 64.0;
+ *descent = fface->ftface->size->metrics.descender / 64.0;
+ *linegap = fface->ftface->size->metrics.height / 64.0 + *descent - *ascent;
+
return SG_OK;
-}*/
-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)
+}
+
+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)
{
if(face == NULL)
{
@@ -137,8 +145,8 @@ SGuint SG_EXPORT sgmFontsCharsCreate(void* face, SGuint* chars, SGuint charnum,
FT_Glyph glyph;
FT_BitmapGlyph bitmap_glyph;
FT_Bitmap bitmap;
- SGuint i/*, j*/;
- for(i = 0; i < charnum; i++)
+ SGuint i;
+ for(i = 0; i < numchars; i++)
{
ret = FT_Load_Glyph(fface->ftface, FT_Get_Char_Index(fface->ftface, chars[i]), FT_LOAD_DEFAULT);
if(ret)
@@ -160,27 +168,45 @@ SGuint SG_EXPORT sgmFontsCharsCreate(void* face, SGuint* chars, SGuint charnum,
data[i] = malloc(bitmap.width * bitmap.rows);
memcpy(data[i], bitmap.buffer, bitmap.width * bitmap.rows);
- /*for(j = 0; j < bitmap.rows; j++)
- memcpy((char*)data[i] + j * bitmap.width, bitmap.buffer + (bitmap.rows - j - 1) * bitmap.width, bitmap.width);*/
prex[i] = bitmap_glyph->left;
- //prey[i] = -bitmap_glyph->top + bitmap.rows;
prey[i] = -bitmap_glyph->top;
postx[i] = fface->ftface->glyph->advance.x / 64.0;
posty[i] = 0;
- width[i] = fface->ftface->glyph->/*bitmap.width*/advance.x / 64.0;
- height[i] = fface->height;
+ width[i] = fface->ftface->glyph->metrics.width;
+ height[i] = fface->ftface->glyph->metrics.height;
FT_Done_Glyph(glyph);
}
return SG_OK;
}
-
-SGuint SG_EXPORT sgmFontsCharsFreeData(void* data)
+SGenum SG_EXPORT sgmFontsCharsFreeData(void* data)
{
free(data);
return SG_OK;
}
+
+SGenum SG_EXPORT sgmFontsCharsGetKerning(void* face, const SGdchar* chars, size_t numchars, float* kerning)
+{
+ if(!face) return SG_INVALID_VALUE;
+ FontFace* fface = face;
+
+ FT_Vector vec;
+
+ FT_UInt prev = numchars ? FT_Get_Char_Index(fface->ftface, chars[0]) : 0;
+ FT_UInt curr;
+
+ size_t i;
+ for(i = 1; i < numchars; i++)
+ {
+ curr = FT_Get_Char_Index(fface->ftface, chars[i]);
+ FT_Get_Kerning(fface->ftface, prev, curr, FT_KERNING_DEFAULT, &vec);
+ kerning[i-1] = vec.x / 64.0;
+ prev = curr;
+ }
+
+ return SG_OK;
+}
@@ -20,7 +20,7 @@ typedef struct FontFace
{
stbtt_fontinfo info;
void* buf;
- float height;
+ float scale;
} FontFace;
SGenum SG_EXPORT sgmFontsFaceCreate(void** face, SGStream* stream)
@@ -50,6 +50,8 @@ SGenum SG_EXPORT sgmFontsFaceCreate(void** face, SGStream* stream)
goto err;
stbtt_InitFont(&fface->info, fface->buf, 0);
+ fface->scale = 1.0;
+
return SG_OK;
err:
@@ -64,50 +66,74 @@ SGenum SG_EXPORT sgmFontsFaceDestroy(void* face)
free(fface);
return SG_OK;
}
-SGenum SG_EXPORT sgmFontsFaceSetHeight(void* face, float height)
+
+SGenum SG_EXPORT sgmFontsFaceSetHeight(void* face, float height, SGuint dpi)
{
if(!face) return SG_INVALID_VALUE;
FontFace* fface = face;
- fface->height = height;
+ //fface->scale = stbtt_ScaleForPixelHeight(&fface->info, height);
+ fface->scale = stbtt_ScaleForMappingEmToPixels(&fface->info, height * dpi / 72.0);
return SG_OK;
}
-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)
+SGenum SG_EXPORT sgmFontsFaceGetMetrics(void* face, float* ascent, float* descent, float* linegap)
+{
+ if(!face) return SG_INVALID_VALUE;
+ FontFace* fface = face;
+
+ int iasc, idesc, igap;
+ stbtt_GetFontVMetrics(&fface->info, &iasc, &idesc, &igap);
+ *ascent = iasc * fface->scale;
+ *descent = idesc * fface->scale;
+ *linegap = igap * fface->scale;
+
+ return SG_OK;
+}
+
+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)
{
if(!face) return SG_INVALID_VALUE;
FontFace* fface = (FontFace*)face;
- //float scale = stbtt_ScaleForPixelHeight(&fface->info, fface->height);
- float scale = stbtt_ScaleForMappingEmToPixels(&fface->info, fface->height);
int adv, left;
int dw, dh;
int xo, yo;
- int kern = 0;
int glyph;
size_t i;
- for(i = 0; i < charnum; i++)
+ for(i = 0; i < numchars; i++)
{
glyph = stbtt_FindGlyphIndex(&fface->info, chars[i]);
- data[i] = stbtt_GetGlyphBitmap(&fface->info, scale, scale, glyph, &dw, &dh, &xo, &yo);
+ data[i] = stbtt_GetGlyphBitmap(&fface->info, fface->scale, fface->scale, glyph, &dw, &dh, &xo, &yo);
datawidth[i] = dw;
dataheight[i] = dh;
- if(i) kern = stbtt_GetGlyphKernAdvance(&fface->info, chars[i-1], chars[i]);
-
stbtt_GetGlyphHMetrics(&fface->info, glyph, &adv, &left);
- prex[i] = (left + kern) * scale + xo;
+ prex[i] = /*-left * fface->scale * 0.5 + */xo;
prey[i] = yo;
- postx[i] = adv * scale;
+ postx[i] = adv * fface->scale;
posty[i] = 0;
+ width[i] = adv * fface->scale;
+ height[i] = 0; /* TODO */
}
return SG_OK;
}
-
SGenum SG_EXPORT sgmFontsCharsFreeData(void* data)
{
stbtt_FreeBitmap(data, NULL);
return SG_OK;
}
+
+SGenum SG_EXPORT sgmFontsCharsGetKerning(void* face, const SGdchar* chars, size_t numchars, float* kerning)
+{
+ if(!face) return SG_INVALID_VALUE;
+ FontFace* fface = face;
+
+ size_t i;
+ for(i = 1; i < numchars; i++)
+ kerning[i-1] = stbtt_GetCodepointKernAdvance(&fface->info, chars[i-1], chars[i]) * fface->scale;
+
+ return SG_OK;
+}
Oops, something went wrong.

0 comments on commit 34e3168

Please sign in to comment.