From f2e64e17527f16966a37c788ca65e1e88bf44907 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 21 Jun 2023 18:59:15 +1000 Subject: [PATCH] Font improvements ?border and ?outline blend nicer when applied to font glyphs --- source/core/StarColor.hpp | 3 +-- source/core/StarFont.cpp | 4 ++-- source/core/StarImageProcessing.cpp | 20 ++++++++++++++++++-- source/core/StarImageProcessing.hpp | 1 + source/rendering/StarFontTextureGroup.cpp | 7 ++++++- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/source/core/StarColor.hpp b/source/core/StarColor.hpp index 33f3374..e2fe2b5 100644 --- a/source/core/StarColor.hpp +++ b/source/core/StarColor.hpp @@ -141,10 +141,9 @@ public: Color& operator+=(Color const& c); Color& operator*=(Color const& c); -private: static float toLinear(float in); static float fromLinear(float in); - +private: Vec4F m_data; }; diff --git a/source/core/StarFont.cpp b/source/core/StarFont.cpp index 66767aa..59a094b 100644 --- a/source/core/StarFont.cpp +++ b/source/core/StarFont.cpp @@ -87,10 +87,10 @@ unsigned Font::width(String::Char c) { Image Font::render(String::Char c) { if (!m_fontImpl) - throw FontException("Font::render called on uninitialzed font."); + throw FontException("Font::render called on uninitialized font."); FT_UInt glyph_index = FT_Get_Char_Index(m_fontImpl->face, c); - if (FT_Load_Glyph(m_fontImpl->face, glyph_index, FT_LOAD_DEFAULT) != 0) + if (FT_Load_Glyph(m_fontImpl->face, glyph_index, FT_LOAD_FORCE_AUTOHINT) != 0) return {}; /* convert to an anti-aliased bitmap */ diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 3e1db89..ebb0947 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -224,6 +224,7 @@ ImageOperation imageOperationFromString(String const& string) { else operation.endColor = operation.startColor; operation.outlineOnly = type == "outline"; + operation.includeTransparent = false; // Currently just here for anti-aliased fonts return operation; @@ -476,7 +477,8 @@ Image processImageOperations(List const& operations, Image image borderImage.forEachPixel([&op, &image, &borderImageSize](int x, int y, Vec4B& pixel) { int pixels = op->pixels; - if (pixel[3] == 0) { + bool includeTransparent = op->includeTransparent; + if (pixel[3] == 0 || (includeTransparent && pixel[3] != 255)) { int dist = std::numeric_limits::max(); for (int j = -pixels; j < pixels + 1; j++) { for (int i = -pixels; i < pixels + 1; i++) { @@ -493,7 +495,21 @@ Image processImageOperations(List const& operations, Image image if (dist < std::numeric_limits::max()) { float percent = (dist - 1) / (2.0f * pixels - 1); - pixel = Vec4B(Vec4F(op->startColor) * (1 - percent) + Vec4F(op->endColor) * percent); + Vec4F color = (Vec4F(op->startColor) * ((1.0f - percent) / 255.0f)) + (Vec4F(op->endColor) * (percent / 255.0f)); + color.clamp(0.0f, 1.0f); + if (pixel[3] != 0) { + float pixelA = byteToFloat(pixel[3]); + if (op->outlineOnly) + color[3] *= (1.0f - pixelA); + else { + float colorA = pixelA * (1.0f - color[3]); + color[0] = Color::fromLinear((Color::toLinear(color[0]) * colorA) + (Color::toLinear(byteToFloat(pixel[0])) * pixelA)); + color[1] = Color::fromLinear((Color::toLinear(color[1]) * colorA) + (Color::toLinear(byteToFloat(pixel[1])) * pixelA)); + color[2] = Color::fromLinear((Color::toLinear(color[2]) * colorA) + (Color::toLinear(byteToFloat(pixel[2])) * pixelA)); + color[3] += colorA; + } + } + pixel = Vec4B(color.piecewiseMultiply(Vec4F::filled(255.0f))); } } else if (op->outlineOnly) { pixel = Vec4B(0, 0, 0, 0); diff --git a/source/core/StarImageProcessing.hpp b/source/core/StarImageProcessing.hpp index e2008b8..bcb5936 100644 --- a/source/core/StarImageProcessing.hpp +++ b/source/core/StarImageProcessing.hpp @@ -102,6 +102,7 @@ struct BorderImageOperation { Vec4B startColor; Vec4B endColor; bool outlineOnly; + bool includeTransparent; }; struct ScaleImageOperation { diff --git a/source/rendering/StarFontTextureGroup.cpp b/source/rendering/StarFontTextureGroup.cpp index 7517c8b..340a389 100644 --- a/source/rendering/StarFontTextureGroup.cpp +++ b/source/rendering/StarFontTextureGroup.cpp @@ -21,7 +21,12 @@ const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Cha Image image = m_font->render(c); if (!processingDirectives.empty()) { Vec2F preSize = Vec2F(image.size()); - image = processImageOperations(parseImageOperations(processingDirectives), image); + auto imageOperations = parseImageOperations(processingDirectives); + for (auto& imageOp : imageOperations) { + if (auto border = imageOp.ptr()) + border->includeTransparent = true; + } + image = processImageOperations(imageOperations, image); res.first->second.processingOffset = preSize - Vec2F(image.size()); } else