Skip to content

Commit

Permalink
libgui|Font: Implemented stb_truetype rasterization
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Sep 1, 2019
1 parent 71853c4 commit e711d76
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 49 deletions.
2 changes: 1 addition & 1 deletion doomsday/cmake/FindSDL2Libs.cmake
Expand Up @@ -19,7 +19,7 @@ endif ()
if (PKG_CONFIG_FOUND AND NOT IOS)
if (NOT TARGET SDL2)
add_pkgconfig_interface_library (SDL2 OPTIONAL sdl2)
add_pkgconfig_interface_library (SDL2_ttf OPTIONAL SDL2_ttf)
# add_pkgconfig_interface_library (SDL2_ttf OPTIONAL SDL2_ttf)
add_pkgconfig_interface_library (SDL2_mixer OPTIONAL SDL2_mixer)
endif ()

Expand Down
2 changes: 1 addition & 1 deletion doomsday/libs/gui/CMakeLists.txt
Expand Up @@ -58,7 +58,7 @@ endif ()
deng_link_libraries (libgui PUBLIC DengComms)
target_link_libraries (libgui
PUBLIC glbinding::glbinding
PRIVATE SDL2 SDL2_ttf stb assimp
PRIVATE SDL2 stb assimp
)
if (WIN32)
target_link_libraries (libgui PUBLIC opengl32.lib)
Expand Down
10 changes: 4 additions & 6 deletions doomsday/libs/gui/src/text/font.cpp
Expand Up @@ -22,15 +22,13 @@
#include <de/Hash>
#include <de/ThreadLocal>

#if 1
# include "stbttnativefont.h"
namespace de { using PlatformFont = StbTtNativeFont; }
#elif (defined(MACOSX) && defined(MACOS_10_7)) || defined (DE_IOS)
#if 0
//#elif (defined(MACOSX) && defined(MACOS_10_7)) || defined (DE_IOS)
# include "coretextnativefont_macx.h"
namespace de { using PlatformFont = CoreTextNativeFont; }
#else
# include "sdlnativefont.h"
namespace de { using PlatformFont = SdlNativeFont; }
# include "stbttnativefont.h"
namespace de { using PlatformFont = StbTtNativeFont; }
#endif

namespace std {
Expand Down
File renamed without changes.
59 changes: 19 additions & 40 deletions doomsday/libs/gui/src/text/stbttnativefont.cpp
Expand Up @@ -218,31 +218,31 @@ DE_PIMPL(StbTtNativeFont)
* @return Bounding box for the string. The origin (0,0) is at the baseline, at the
* left edge of the first character.
*/
Rectanglef rasterize(const String &text,
Rectanglei rasterize(const String &text,
Image * image,
const Vec2f imageOffset = {},
const Vec2i imageOrigin = {},
Image::Color foreground = {},
Image::Color background = {})
{
if (image)
{
image->fill(background);
}
Rectanglef bounds;
Vec2f pos = imageOffset;
Rectanglei bounds;
float xPos = 0.0f;
int previousUcp = 0;
for (Char ch : text)
{
const int ucp = int(ch.unicode());
if (previousUcp)
{
pos.x += fontScale * stbtt_GetCodepointKernAdvance(font, previousUcp, ucp);
xPos += fontScale * stbtt_GetCodepointKernAdvance(font, previousUcp, ucp);
}

int advance;
int leftSideBearing;
Vec2i glyphPoint[2];
float xShift = pos.x - std::floor(pos.x);
float xShift = xPos - std::floor(xPos);
stbtt_GetCodepointHMetrics(font, ucp, &advance, &leftSideBearing);
stbtt_GetCodepointBitmapBoxSubpixel(font,
ucp,
Expand All @@ -255,7 +255,7 @@ DE_PIMPL(StbTtNativeFont)
&glyphPoint[1].x,
&glyphPoint[1].y);
Rectanglei glyphBounds{glyphPoint[0], glyphPoint[1]};
glyphBounds.move({int(pos.x), 0});
glyphBounds.move({int(xPos), 0});
if (bounds.isNull())
{
bounds = glyphBounds;
Expand All @@ -267,8 +267,6 @@ DE_PIMPL(StbTtNativeFont)

if (image)
{
glyphBounds.move({0, ascent});

// Rasterize the glyph.
Block raster(glyphBounds.area());
stbtt_MakeCodepointBitmapSubpixel(font,
Expand All @@ -285,18 +283,20 @@ DE_PIMPL(StbTtNativeFont)
for (int y = glyphBounds.top(), sy = 0; y < glyphBounds.bottom(); ++y, ++sy)
{
const duint8 *src = &raster[sy * glyphBounds.width()];
duint32 *dst = image->row32(y);
duint32 *dst = image->row32(imageOrigin.y + y);
for (int x = glyphBounds.left(), sx = 0; x < glyphBounds.right(); ++x, ++sx)
{
DE_ASSERT(duint(imageOrigin.x + x) < image->width());
const duint8 cval = src[sx];
dst[x] = Image::packColor(Image::mix(Image::unpackColor(dst[x]),
foreground,
Image::Color(cval, cval, cval, cval)));
duint32 * out = &dst[imageOrigin.x + x];
*out = Image::packColor(Image::mix(Image::unpackColor(*out),
foreground,
Image::Color(cval, cval, cval, cval)));
}
}
}

pos.x += fontScale * advance;
xPos += fontScale * advance;
previousUcp = ucp;
}
return bounds;
Expand Down Expand Up @@ -354,39 +354,18 @@ Rectanglei StbTtNativeFont::nativeFontMeasure(const String &text) const

int StbTtNativeFont::nativeFontWidth(const String &text) const
{
return int(nativeFontMeasure(d->transform(text)).right());
return int(nativeFontMeasure(d->transform(text)).width());
}

Image StbTtNativeFont::nativeFontRasterize(const String & text,
const Image::Color &foreground,
const Image::Color &background) const
{
if (!d->font) return {};
/*
SDL_Surface *pal =
TTF_RenderUTF8_Shaded(d->font,
d->transform(text).c_str(),
SDL_Color{255, 255, 255, 255},
SDL_Color{000, 000, 000, 255});
if (!pal)
{
return {};
}
DE_ASSERT(pal->w && pal->h);
SDL_Surface *rgba = SDL_ConvertSurfaceFormat(pal, SDL_PIXELFORMAT_RGBA32, 0);
SDL_FreeSurface(pal);
SDL_LockSurface(rgba);*/

const Rectanglef bounds = d->rasterize(text, nullptr).toRectanglei();
Image img{Vec2i(ceil(bounds.width()) + 1, ceil(bounds.height()) + 1).toVec2ui(), Image::RGBA_8888};
// img.fill(background);
// Block(rgba->pixels, dsize(rgba->h * rgba->pitch))};
// SDL_UnlockSurface(rgba);
// SDL_FreeSurface(rgba);
// const int comps[4] = {0, 0, 0, 0}; // red channel used for blending each component
// return img.mixed(background, foreground, comps);
d->rasterize(text, &img, -bounds.topLeft, foreground, background);
img.save(Stringf("raster_%p.png", cstr_String(text)));

const Rectanglei bounds = d->rasterize(text, nullptr);
Image img{bounds.size(), Image::RGBA_8888};
d->rasterize(text, &img, -floor(bounds.topLeft).toVec2i(), foreground, background);
return img;
}

Expand Down
2 changes: 1 addition & 1 deletion doomsday/libs/gui/src/text/stbttnativefont.h
Expand Up @@ -25,7 +25,7 @@
namespace de {

/**
* Native font implementation that uses SDL_ttf.
* Native font implementation that uses stb_truetype.
*/
class StbTtNativeFont : public NativeFont
{
Expand Down

0 comments on commit e711d76

Please sign in to comment.