font scaling fixes
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
d99ef4d2c2
commit
355e98bb19
|
@ -114,7 +114,8 @@ WELLSPRINGAPI Wellspring_Font* Wellspring_CreateFont(
|
|||
const uint8_t *fontBytes,
|
||||
uint32_t fontBytesLength,
|
||||
const uint8_t *atlasJsonBytes,
|
||||
uint32_t atlasJsonBytesLength
|
||||
uint32_t atlasJsonBytesLength,
|
||||
float *pPixelsPerEm
|
||||
);
|
||||
|
||||
/* Batches are not thread-safe, recommend one batch per thread. */
|
||||
|
@ -128,8 +129,7 @@ WELLSPRINGAPI void Wellspring_StartTextBatch(
|
|||
|
||||
WELLSPRINGAPI uint8_t Wellspring_TextBounds(
|
||||
Wellspring_Font *font,
|
||||
float x,
|
||||
float y,
|
||||
int pixelSize,
|
||||
Wellspring_HorizontalAlignment horizontalAlignment,
|
||||
Wellspring_VerticalAlignment verticalAlignment,
|
||||
const uint8_t *strBytes,
|
||||
|
@ -141,6 +141,7 @@ WELLSPRINGAPI uint8_t Wellspring_Draw(
|
|||
Wellspring_TextBatch *textBatch,
|
||||
float x,
|
||||
float y,
|
||||
int pixelSize,
|
||||
float depth,
|
||||
Wellspring_Color *color,
|
||||
Wellspring_HorizontalAlignment horizontalAlignment,
|
||||
|
|
|
@ -154,8 +154,10 @@ typedef struct Font
|
|||
float ascender;
|
||||
float descender;
|
||||
float lineHeight;
|
||||
float pixelsPerEm;
|
||||
|
||||
float scale;
|
||||
float geometryScale; // all json values are premultiplied by this value, we need it for kerning
|
||||
float kerningScale; // kerning values from stb_tt are in a different scale
|
||||
|
||||
Packer packer;
|
||||
} Font;
|
||||
|
@ -228,7 +230,6 @@ static uint8_t json_object_has_key(const json_object_t *object, const char* name
|
|||
{
|
||||
if (currentElement->next == NULL)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Key %s not found in JSON!", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -349,7 +350,8 @@ Wellspring_Font* Wellspring_CreateFont(
|
|||
const uint8_t* fontBytes,
|
||||
uint32_t fontBytesLength,
|
||||
const uint8_t *atlasJsonBytes,
|
||||
uint32_t atlasJsonBytesLength
|
||||
uint32_t atlasJsonBytesLength,
|
||||
float *pPixelsPerEm
|
||||
) {
|
||||
Font *font = Wellspring_malloc(sizeof(Font));
|
||||
|
||||
|
@ -396,13 +398,13 @@ Wellspring_Font* Wellspring_CreateFont(
|
|||
|
||||
font->packer.width = json_object_get_uint(atlasObject, "width");
|
||||
font->packer.height = json_object_get_uint(atlasObject, "height");
|
||||
font->pixelsPerEm = json_object_get_double(atlasObject, "size");
|
||||
|
||||
font->ascender = json_object_get_double(metricsObject, "ascender");
|
||||
font->descender = json_object_get_double(metricsObject, "descender");
|
||||
font->lineHeight = json_object_get_double(metricsObject, "lineHeight");
|
||||
|
||||
font->geometryScale = font->ascender / stbAscender;
|
||||
font->scale = 1 / (font->ascender - font->descender);
|
||||
font->scale = font->pixelsPerEm * 4 / 3; // converting from "points" (dpi) to pixels
|
||||
|
||||
/* Pack unicode ranges */
|
||||
|
||||
|
@ -459,10 +461,6 @@ Wellspring_Font* Wellspring_CreateFont(
|
|||
packedChar->atlasTop = json_object_get_double(boundsObject, "top");
|
||||
packedChar->atlasBottom = json_object_get_double(boundsObject, "bottom");
|
||||
|
||||
// flip texture coords because the atlas outputs glyphs in OpenGL texture space (lol)
|
||||
packedChar->atlasTop = font->packer.height - packedChar->atlasTop;
|
||||
packedChar->atlasBottom = font->packer.height - packedChar->atlasBottom;
|
||||
|
||||
json_object_t *planeObject = json_object_get_object(currentGlyphObject, "planeBounds");
|
||||
|
||||
packedChar->planeLeft = json_object_get_double(planeObject, "left");
|
||||
|
@ -474,7 +472,14 @@ Wellspring_Font* Wellspring_CreateFont(
|
|||
currentGlyphElement = currentGlyphElement->next;
|
||||
}
|
||||
|
||||
int advanceWidth, bearing;
|
||||
stbtt_GetCodepointHMetrics(&font->fontInfo, font->packer.ranges[0].firstCodepoint, &advanceWidth, &bearing);
|
||||
|
||||
font->kerningScale = font->packer.ranges[0].data[0].xAdvance / advanceWidth;
|
||||
|
||||
Wellspring_free(jsonRoot);
|
||||
|
||||
*pPixelsPerEm = font->pixelsPerEm;
|
||||
return (Wellspring_Font*) font;
|
||||
}
|
||||
|
||||
|
@ -581,8 +586,7 @@ static void GetPackedQuad(PackedChar *charData, float scale, int packerWidth, in
|
|||
|
||||
static uint8_t Wellspring_Internal_TextBounds(
|
||||
Font* font,
|
||||
float x,
|
||||
float y,
|
||||
int pixelSize,
|
||||
Wellspring_HorizontalAlignment horizontalAlignment,
|
||||
Wellspring_VerticalAlignment verticalAlignment,
|
||||
const uint8_t* strBytes,
|
||||
|
@ -597,14 +601,16 @@ static uint8_t Wellspring_Internal_TextBounds(
|
|||
PackedChar* rangeData;
|
||||
Quad charQuad;
|
||||
uint32_t i, j;
|
||||
float x = 0, y = 0;
|
||||
float minX = x;
|
||||
float minY = y;
|
||||
float maxX = x;
|
||||
float maxY = y;
|
||||
float startX = x;
|
||||
float advance = 0;
|
||||
float sizeFactor = pixelSize / font->pixelsPerEm;
|
||||
|
||||
y += Wellspring_INTERNAL_GetVerticalAlignOffset(font, verticalAlignment, font->scale);
|
||||
y += Wellspring_INTERNAL_GetVerticalAlignOffset(font, verticalAlignment, sizeFactor * font->scale);
|
||||
|
||||
for (i = 0; i < strLengthInBytes; i += 1)
|
||||
{
|
||||
|
@ -645,8 +651,8 @@ static uint8_t Wellspring_Internal_TextBounds(
|
|||
if (IsWhitespace(codepoint))
|
||||
{
|
||||
PackedChar *packedChar = rangeData + rangeIndex;
|
||||
x += font->scale * packedChar->xAdvance;
|
||||
maxX += font->scale * packedChar->xAdvance;
|
||||
x += sizeFactor * font->scale * packedChar->xAdvance;
|
||||
maxX += sizeFactor * font->scale * packedChar->xAdvance;
|
||||
previousGlyphIndex = -1;
|
||||
continue;
|
||||
}
|
||||
|
@ -655,12 +661,12 @@ static uint8_t Wellspring_Internal_TextBounds(
|
|||
|
||||
if (previousGlyphIndex != -1)
|
||||
{
|
||||
x += font->geometryScale * font->scale * stbtt_GetGlyphKernAdvance(&font->fontInfo, previousGlyphIndex, glyphIndex);
|
||||
x += sizeFactor * font->kerningScale * font->scale * stbtt_GetGlyphKernAdvance(&font->fontInfo, previousGlyphIndex, glyphIndex);
|
||||
}
|
||||
|
||||
GetPackedQuad(
|
||||
rangeData,
|
||||
font->scale,
|
||||
sizeFactor * font->scale,
|
||||
packer->width,
|
||||
packer->height,
|
||||
rangeIndex,
|
||||
|
@ -700,8 +706,7 @@ static uint8_t Wellspring_Internal_TextBounds(
|
|||
|
||||
uint8_t Wellspring_TextBounds(
|
||||
Wellspring_Font *font,
|
||||
float x,
|
||||
float y,
|
||||
int pixelSize,
|
||||
Wellspring_HorizontalAlignment horizontalAlignment,
|
||||
Wellspring_VerticalAlignment verticalAlignment,
|
||||
const uint8_t* strBytes,
|
||||
|
@ -710,8 +715,7 @@ uint8_t Wellspring_TextBounds(
|
|||
) {
|
||||
return Wellspring_Internal_TextBounds(
|
||||
(Font*) font,
|
||||
x,
|
||||
y,
|
||||
pixelSize,
|
||||
horizontalAlignment,
|
||||
verticalAlignment,
|
||||
strBytes,
|
||||
|
@ -724,6 +728,7 @@ uint8_t Wellspring_Draw(
|
|||
Wellspring_TextBatch *textBatch,
|
||||
float x,
|
||||
float y,
|
||||
int pixelSize,
|
||||
float depth,
|
||||
Wellspring_Color *color,
|
||||
Wellspring_HorizontalAlignment horizontalAlignment,
|
||||
|
@ -745,13 +750,14 @@ uint8_t Wellspring_Draw(
|
|||
uint32_t indexBufferIndex;
|
||||
Wellspring_Rectangle bounds;
|
||||
uint32_t i, j;
|
||||
float sizeFactor = pixelSize / font->pixelsPerEm;
|
||||
|
||||
y += Wellspring_INTERNAL_GetVerticalAlignOffset(font, verticalAlignment, font->scale);
|
||||
y += Wellspring_INTERNAL_GetVerticalAlignOffset(font, verticalAlignment, sizeFactor * font->scale);
|
||||
|
||||
/* FIXME: If we horizontally align, we have to decode and process glyphs twice, very inefficient. */
|
||||
if (horizontalAlignment == WELLSPRING_HORIZONTALALIGNMENT_RIGHT)
|
||||
{
|
||||
if (!Wellspring_Internal_TextBounds(font, x, y, horizontalAlignment, verticalAlignment, strBytes, strLengthInBytes, &bounds))
|
||||
if (!Wellspring_Internal_TextBounds(font, pixelSize, horizontalAlignment, verticalAlignment, strBytes, strLengthInBytes, &bounds))
|
||||
{
|
||||
/* Something went wrong while calculating bounds. */
|
||||
return 0;
|
||||
|
@ -761,7 +767,7 @@ uint8_t Wellspring_Draw(
|
|||
}
|
||||
else if (horizontalAlignment == WELLSPRING_HORIZONTALALIGNMENT_CENTER)
|
||||
{
|
||||
if (!Wellspring_Internal_TextBounds(font, x, y, horizontalAlignment, verticalAlignment, strBytes, strLengthInBytes, &bounds))
|
||||
if (!Wellspring_Internal_TextBounds(font, pixelSize, horizontalAlignment, verticalAlignment, strBytes, strLengthInBytes, &bounds))
|
||||
{
|
||||
/* Something went wrong while calculating bounds. */
|
||||
return 0;
|
||||
|
@ -807,7 +813,7 @@ uint8_t Wellspring_Draw(
|
|||
if (IsWhitespace(codepoint))
|
||||
{
|
||||
PackedChar *packedChar = rangeData + rangeIndex;
|
||||
x += font->scale * packedChar->xAdvance;
|
||||
x += sizeFactor * font->scale * packedChar->xAdvance;
|
||||
previousGlyphIndex = -1;
|
||||
continue;
|
||||
}
|
||||
|
@ -816,12 +822,12 @@ uint8_t Wellspring_Draw(
|
|||
|
||||
if (previousGlyphIndex != -1)
|
||||
{
|
||||
x += font->geometryScale * font->scale * stbtt_GetGlyphKernAdvance(&font->fontInfo, previousGlyphIndex, glyphIndex);
|
||||
x += sizeFactor * font->kerningScale * font->scale * stbtt_GetGlyphKernAdvance(&font->fontInfo, previousGlyphIndex, glyphIndex);
|
||||
}
|
||||
|
||||
GetPackedQuad(
|
||||
rangeData,
|
||||
font->scale,
|
||||
sizeFactor * font->scale,
|
||||
myPacker->width,
|
||||
myPacker->height,
|
||||
rangeIndex,
|
||||
|
|
Loading…
Reference in New Issue