mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
More improvements.
This commit is contained in:
2
.github/workflows/eepp-linux-build-check.yml
vendored
2
.github/workflows/eepp-linux-build-check.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
tar xvzf premake-5.0.0-beta2-linux.tar.gz
|
||||
- name: Build
|
||||
run: |
|
||||
./premake5 gmake2
|
||||
./premake5 --with-text-shaper gmake2
|
||||
cd make/linux
|
||||
make all -j$(nproc) -e config=release_x86_64
|
||||
- name: Unit Tests
|
||||
|
||||
2
.github/workflows/eepp-macos-build-check.yml
vendored
2
.github/workflows/eepp-macos-build-check.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
brew install wget SDL2 premake
|
||||
- name: Build
|
||||
run: |
|
||||
premake5 gmake2
|
||||
premake5 --with-text-shaper gmake2
|
||||
make -C make/macosx/ -e config=release_arm64
|
||||
- name: Unit Tests
|
||||
run: |
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Create project
|
||||
shell: powershell
|
||||
run: |
|
||||
./premake5.exe --windows-vc-build vs2022
|
||||
./premake5.exe --windows-vc-build --with-text-shaper vs2022
|
||||
- name: Build
|
||||
shell: cmd
|
||||
run: |
|
||||
|
||||
@@ -174,7 +174,7 @@ class EE_API FontTrueType : public Font {
|
||||
|
||||
Uint32 getGlyphIndex( const Uint32& codePoint ) const;
|
||||
|
||||
Glyph loadGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, bool italic,
|
||||
Glyph loadGlyphByIndex( Uint32 codePoint, unsigned int characterSize, bool bold, bool italic,
|
||||
Float outlineThickness, Page& page, const Float& maxWidth = 0.f ) const;
|
||||
|
||||
Rect findGlyphRect( Page& page, unsigned int width, unsigned int height ) const;
|
||||
@@ -214,6 +214,7 @@ class EE_API FontTrueType : public Font {
|
||||
bool mIsItalic{ false };
|
||||
mutable UnorderedMap<unsigned int, unsigned int> mClosestCharacterSize;
|
||||
mutable UnorderedMap<Uint32, Uint32> mCodePointIndexCache;
|
||||
mutable UnorderedMap<Uint64, Float> mKerningCache;
|
||||
FontHinting mHinting{ FontHinting::Full };
|
||||
FontAntialiasing mAntialiasing{ FontAntialiasing::Grayscale };
|
||||
FontTrueType* mFontBold{ nullptr };
|
||||
|
||||
27
premake4.lua
27
premake4.lua
@@ -167,6 +167,7 @@ newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanit
|
||||
newoption { trigger = "address-sanitizer", description = "Compile with AddressSanitizer." }
|
||||
newoption { trigger = "time-trace", description = "Compile with time trace." }
|
||||
newoption { trigger = "disable-static-build", description = "Disables eepp static build project, this is just a helper to avoid rebuilding twice eepp while developing the library." }
|
||||
newoption { trigger = "with-text-shaper", description = "Enables text-shaping capabilities by relying on harfbuzz." }
|
||||
newoption {
|
||||
trigger = "with-backend",
|
||||
description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.",
|
||||
@@ -741,8 +742,12 @@ function add_static_links()
|
||||
links { "freetype-static", "libpng-static" }
|
||||
end
|
||||
|
||||
links { "harfbuzz-static",
|
||||
"SOIL2-static",
|
||||
if _OPTIONS["with-text-shaper"] then
|
||||
links { "harfbuzz-static" }
|
||||
defines { "EE_TEXT_SHAPER_ENABLED" }
|
||||
end
|
||||
|
||||
links { "SOIL2-static",
|
||||
"libzip-static",
|
||||
"jpeg-compressor-static",
|
||||
"zlib-static",
|
||||
@@ -1110,14 +1115,16 @@ solution "eepp"
|
||||
includedirs { "src/thirdparty/freetype2/include", "src/thirdparty/libpng" }
|
||||
build_base_configuration( "freetype" )
|
||||
|
||||
project "harfbuzz-static"
|
||||
kind "StaticLib"
|
||||
language "C++"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/thirdparty/")
|
||||
defines { "HAVE_CONFIG_H" }
|
||||
files { "src/thirdparty/harfbuzz/**.cc" }
|
||||
includedirs { "src/thirdparty/freetype2/include", "src/thirdparty/harfbuzz" }
|
||||
build_base_cpp_configuration( "harfbuzz" )
|
||||
if _OPTIONS["with-text-shaper"] then
|
||||
project "harfbuzz-static"
|
||||
kind "StaticLib"
|
||||
language "C++"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/thirdparty/")
|
||||
defines { "HAVE_CONFIG_H" }
|
||||
files { "src/thirdparty/harfbuzz/**.cc" }
|
||||
includedirs { "src/thirdparty/freetype2/include", "src/thirdparty/harfbuzz" }
|
||||
build_base_cpp_configuration( "harfbuzz" )
|
||||
end
|
||||
|
||||
project "chipmunk-static"
|
||||
kind "StaticLib"
|
||||
|
||||
@@ -15,6 +15,7 @@ newoption { trigger = "thread-sanitizer", description = "Compile with ThreadSani
|
||||
newoption { trigger = "address-sanitizer", description = "Compile with AddressSanitizer." }
|
||||
newoption { trigger = "time-trace", description = "Compile with time tracing." }
|
||||
newoption { trigger = "disable-static-build", description = "Disables eepp static build project, this is just a helper to avoid rebuilding twice eepp while developing the library." }
|
||||
newoption { trigger = "with-text-shaper", description = "Enables text-shaping capabilities by relying on harfbuzz." }
|
||||
newoption {
|
||||
trigger = "with-backend",
|
||||
description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.",
|
||||
@@ -497,8 +498,12 @@ function add_static_links()
|
||||
links { "freetype-static", "libpng-static" }
|
||||
end
|
||||
|
||||
links { "harfbuzz-static",
|
||||
"SOIL2-static",
|
||||
if _OPTIONS["with-text-shaper"] then
|
||||
links { "harfbuzz-static" }
|
||||
defines { "EE_TEXT_SHAPER_ENABLED" }
|
||||
end
|
||||
|
||||
links { "SOIL2-static",
|
||||
"chipmunk-static",
|
||||
"libzip-static",
|
||||
"jpeg-compressor-static",
|
||||
|
||||
@@ -14,3 +14,4 @@
|
||||
#define DR_FLAC_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define ECODE_USE_BACKWARD
|
||||
#define EE_TEXT_SHAPER_ENABLED
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 13.0.1, 2024-05-10T21:21:06. -->
|
||||
<!-- Written by QtCreator 13.0.2, 2024-06-13T02:20:10. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
@@ -116,7 +116,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">19</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">8</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">../../make/linux</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
@@ -193,7 +193,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--with-debug-symbols gmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--with-debug-symbols --with-text-shaper gmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">premake4</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}../../../</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
|
||||
|
||||
@@ -22,8 +22,10 @@ using namespace EE::Window;
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef EE_TEXT_SHAPER_ENABLED
|
||||
#include <harfbuzz/hb-ft.h>
|
||||
#include <harfbuzz/hb.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -240,8 +242,9 @@ bool FontTrueType::loadFromPack( Pack* pack, std::string filePackPath ) {
|
||||
bool FontTrueType::setFontFace( void* _face ) {
|
||||
FT_Face face = (FT_Face)_face;
|
||||
mFace = face;
|
||||
#ifdef EE_TEXT_SHAPER_ENABLED
|
||||
mHBFont = hb_ft_font_create( static_cast<FT_Face>( face ), NULL );
|
||||
|
||||
#endif
|
||||
mIsMonospaceComplete = mIsMonospace = FT_IS_FIXED_WIDTH( face );
|
||||
mIsColorEmojiFont = checkIsColorEmojiFont( face );
|
||||
mIsEmojiFont = FT_Get_Char_Index( face, 0x1F600 ) != 0;
|
||||
@@ -334,8 +337,8 @@ const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSiz
|
||||
static_cast<FontTrueType*>( FontManager::instance()->getColorEmojiFont() );
|
||||
if ( ( idx = fontEmoji->getGlyphIndex( codePoint ) ) ) {
|
||||
return fontEmoji->getGlyphByIndex( idx, characterSize, bold, italic,
|
||||
outlineThickness, getPage( characterSize ),
|
||||
maxWidth );
|
||||
0 /* outline thickness won't work here */,
|
||||
getPage( characterSize ), maxWidth );
|
||||
}
|
||||
} else if ( !mIsEmojiFont && FontManager::instance()->getEmojiFont() != nullptr &&
|
||||
FontManager::instance()->getEmojiFont()->getType() == FontType::TTF ) {
|
||||
@@ -420,8 +423,8 @@ const Glyph& FontTrueType::getGlyphByIndex( Uint32 index, unsigned int character
|
||||
return it->second;
|
||||
} else {
|
||||
// Not found: we have to load it
|
||||
Glyph glyph =
|
||||
loadGlyph( index, characterSize, bold, italic, outlineThickness, page, maxWidth );
|
||||
Glyph glyph = loadGlyphByIndex( index, characterSize, bold, italic, outlineThickness, page,
|
||||
maxWidth );
|
||||
|
||||
return glyphs.emplace( key, glyph ).first->second;
|
||||
}
|
||||
@@ -564,12 +567,15 @@ Float FontTrueType::getKerning( Uint32 first, Uint32 second, unsigned int charac
|
||||
// Get the kerning vector
|
||||
FT_Vector kerning;
|
||||
kerning.x = kerning.y = 0;
|
||||
if ( FT_HAS_KERNING( face ) )
|
||||
FT_Get_Kerning( face, index1, index2, FT_KERNING_UNFITTED, &kerning );
|
||||
|
||||
// X advance is already in pixels for bitmap fonts
|
||||
if ( !FT_IS_SCALABLE( face ) )
|
||||
return static_cast<Float>( kerning.x );
|
||||
if ( glyph1.font == glyph2.font ) {
|
||||
if ( FT_HAS_KERNING( face ) )
|
||||
FT_Get_Kerning( face, index1, index2, FT_KERNING_UNFITTED, &kerning );
|
||||
|
||||
// X advance is already in pixels for bitmap fonts
|
||||
if ( !FT_IS_SCALABLE( face ) )
|
||||
return static_cast<Float>( kerning.x );
|
||||
}
|
||||
|
||||
// Return the X advance
|
||||
return std::floor(
|
||||
@@ -588,6 +594,11 @@ Float FontTrueType::getKerningFromGlyphIndex( Uint32 index1, Uint32 index2,
|
||||
if ( index1 == 0 || index2 == 0 || isMonospace() )
|
||||
return 0.f;
|
||||
|
||||
auto pair = static_cast<Uint64>( index1 ) << 32 | index2;
|
||||
auto found = mKerningCache.find( pair );
|
||||
if ( found != mKerningCache.end() )
|
||||
return found->second;
|
||||
|
||||
FT_Face face = static_cast<FT_Face>( mFace );
|
||||
|
||||
if ( face && setCurrentSize( characterSize ) ) {
|
||||
@@ -604,15 +615,20 @@ Float FontTrueType::getKerningFromGlyphIndex( Uint32 index1, Uint32 index2,
|
||||
FT_Get_Kerning( face, index1, index2, FT_KERNING_UNFITTED, &kerning );
|
||||
|
||||
// X advance is already in pixels for bitmap fonts
|
||||
if ( !FT_IS_SCALABLE( face ) )
|
||||
if ( !FT_IS_SCALABLE( face ) ) {
|
||||
mKerningCache.insert( { pair, static_cast<Float>( kerning.x ) } );
|
||||
return static_cast<Float>( kerning.x );
|
||||
}
|
||||
|
||||
// Return the X advance
|
||||
return std::floor(
|
||||
( secondLsbDelta - firstRsbDelta + static_cast<float>( kerning.x ) + 32 ) /
|
||||
static_cast<float>( 1 << 6 ) );
|
||||
Float val =
|
||||
std::floor( ( secondLsbDelta - firstRsbDelta + static_cast<float>( kerning.x ) + 32 ) /
|
||||
static_cast<float>( 1 << 6 ) );
|
||||
mKerningCache.insert( { pair, val } );
|
||||
return val;
|
||||
} else {
|
||||
// Invalid font, or no kerning
|
||||
mKerningCache.insert( { pair, 0.f } );
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
@@ -728,8 +744,10 @@ void FontTrueType::cleanup() {
|
||||
mCallbacks.clear();
|
||||
mNumCallBacks = 0;
|
||||
|
||||
#ifdef EE_TEXT_SHAPER_ENABLED
|
||||
if ( mHBFont )
|
||||
hb_font_destroy( (hb_font_t*)mHBFont );
|
||||
#endif
|
||||
|
||||
// Destroy the stroker
|
||||
if ( mStroker )
|
||||
@@ -797,8 +815,9 @@ fontSetRenderOptions( FT_Library library, FontAntialiasing antialiasing, FontHin
|
||||
return FT_RENDER_MODE_NORMAL;
|
||||
}
|
||||
|
||||
Glyph FontTrueType::loadGlyph( Uint32 index, unsigned int characterSize, bool bold, bool /*italic*/,
|
||||
Float outlineThickness, Page& page, const Float& maxWidth ) const {
|
||||
Glyph FontTrueType::loadGlyphByIndex( Uint32 index, unsigned int characterSize, bool bold,
|
||||
bool /*italic*/, Float outlineThickness, Page& page,
|
||||
const Float& maxWidth ) const {
|
||||
// The glyph to return
|
||||
Glyph glyph;
|
||||
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <limits>
|
||||
|
||||
#ifdef EE_TEXT_SHAPER_ENABLED
|
||||
#include <harfbuzz/hb-ft.h>
|
||||
#include <harfbuzz/hb.h>
|
||||
#endif
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
@@ -79,6 +81,7 @@ class TextShapeRun {
|
||||
bool mIsNewLine{ false };
|
||||
FontStyleConfig& mConfig;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string Text::styleFlagToString( const Uint32& flags ) {
|
||||
@@ -218,7 +221,7 @@ static inline void drawGlyph( BatchRenderer* BR, GlyphDrawable* gd, const Vector
|
||||
}
|
||||
}
|
||||
|
||||
static inline void idrawUnderline( Font* font, Float fontSize, const Color& fontColor,
|
||||
static inline void _drawUnderline( Font* font, Float fontSize, const Color& fontColor,
|
||||
const Vector2f& cpos, const Uint32& style, BatchRenderer* BR,
|
||||
Float outlineThickness, const Vector2f& pos, Float width,
|
||||
const Color& shadowColor, const Vector2f& shadowOffset,
|
||||
@@ -253,7 +256,7 @@ void Text::drawUnderline( const Vector2f& pos, Float width, Font* font, Float fo
|
||||
const Color& outlineColor, const Color& shadowColor,
|
||||
const Vector2f& shadowOffset ) {
|
||||
BatchRenderer* BR = GlobalBatchRenderer::instance();
|
||||
idrawUnderline( font, fontSize, fontColor, pos, style, BR, outlineThickness, pos, width,
|
||||
_drawUnderline( font, fontSize, fontColor, pos, style, BR, outlineThickness, pos, width,
|
||||
shadowColor, shadowOffset, outlineColor );
|
||||
}
|
||||
|
||||
@@ -329,7 +332,7 @@ Sizef Text::draw( const StringType& string, const Vector2f& pos, Font* font, Flo
|
||||
}
|
||||
case '\n': {
|
||||
if ( style & Text::Underlined ) {
|
||||
idrawUnderline( font, fontSize, fontColor, cpos, style, BR, outlineThickness,
|
||||
_drawUnderline( font, fontSize, fontColor, cpos, style, BR, outlineThickness,
|
||||
pos, width, shadowColor, shadowOffset, outlineColor );
|
||||
}
|
||||
if ( style & Text::StrikeThrough ) {
|
||||
@@ -378,7 +381,7 @@ Sizef Text::draw( const StringType& string, const Vector2f& pos, Font* font, Flo
|
||||
}
|
||||
|
||||
if ( ( style & Text::Underlined ) && width != 0 ) {
|
||||
idrawUnderline( font, fontSize, fontColor, cpos, style, BR, outlineThickness, pos, width,
|
||||
_drawUnderline( font, fontSize, fontColor, cpos, style, BR, outlineThickness, pos, width,
|
||||
shadowColor, shadowOffset, outlineColor );
|
||||
}
|
||||
|
||||
@@ -1302,6 +1305,7 @@ void Text::ensureGeometryUpdate() {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef EE_TEXT_SHAPER_ENABLED
|
||||
if ( mFontStyleConfig.Font->getType() == FontType::TTF ) {
|
||||
FontTrueType* rFont = static_cast<FontTrueType*>( mFontStyleConfig.Font );
|
||||
hb_buffer_t* hbBuffer = hb_buffer_create();
|
||||
@@ -1339,25 +1343,54 @@ void Text::ensureGeometryUpdate() {
|
||||
hb_glyph_info_t curGlyph = glyphInfo[i];
|
||||
hb_glyph_position_t curGlyphPos = glyphPos[i];
|
||||
|
||||
x += rFont->getKerningFromGlyphIndex(
|
||||
prevGlyphIndex, curGlyph.codepoint, mFontStyleConfig.CharacterSize, bold,
|
||||
reqItalic, mFontStyleConfig.OutlineThickness );
|
||||
|
||||
Float currentX = x + ( curGlyphPos.x_offset / 64.f );
|
||||
Float currentY = y + ( curGlyphPos.y_offset / 64.f );
|
||||
|
||||
// Apply the outline
|
||||
if ( mFontStyleConfig.OutlineThickness != 0 ) {
|
||||
const Glyph& glyph = font->getGlyphByIndex(
|
||||
curGlyph.codepoint, mFontStyleConfig.CharacterSize, bold, reqItalic,
|
||||
mFontStyleConfig.OutlineThickness,
|
||||
rFont->getPage( mFontStyleConfig.CharacterSize ), 0 );
|
||||
|
||||
Float left = glyph.bounds.Left;
|
||||
Float top = glyph.bounds.Top;
|
||||
Float right = glyph.bounds.Left + glyph.bounds.Right;
|
||||
Float bottom = glyph.bounds.Top + glyph.bounds.Bottom;
|
||||
|
||||
// Add the outline glyph to the vertices
|
||||
if ( glyph.bounds.Right > 0 && glyph.bounds.Bottom > 0 ) {
|
||||
addGlyphQuad( mOutlineVertices, Vector2f( currentX, currentY ), glyph,
|
||||
italic, mFontStyleConfig.OutlineThickness, centerDiffX );
|
||||
}
|
||||
|
||||
// Update the current bounds with the outlined glyph bounds
|
||||
minX = std::min( minX, x + left - italic * bottom -
|
||||
mFontStyleConfig.OutlineThickness );
|
||||
maxX = std::max( maxX,
|
||||
x + right - italic * top - mFontStyleConfig.OutlineThickness );
|
||||
minY = std::min( minY, y + top - mFontStyleConfig.OutlineThickness );
|
||||
maxY = std::max( maxY, y + bottom - mFontStyleConfig.OutlineThickness );
|
||||
if ( mCachedWidthNeedUpdate ) {
|
||||
maxW = std::max( maxW, x + glyph.advance - italic * top -
|
||||
mFontStyleConfig.OutlineThickness );
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the current glyph's description
|
||||
const Glyph& glyph = font->getGlyphByIndex(
|
||||
curGlyph.codepoint, mFontStyleConfig.CharacterSize, bold, italic, 0,
|
||||
curGlyph.codepoint, mFontStyleConfig.CharacterSize, bold, reqItalic, 0,
|
||||
rFont->getPage( mFontStyleConfig.CharacterSize ), 0 );
|
||||
|
||||
if ( prevGlyphIndex != 0 ) {
|
||||
x += rFont->getKerningFromGlyphIndex( prevGlyphIndex, curGlyph.codepoint,
|
||||
mFontStyleConfig.CharacterSize, bold,
|
||||
italic, 0 );
|
||||
}
|
||||
|
||||
Float left = glyph.bounds.Left;
|
||||
Float top = glyph.bounds.Top;
|
||||
Float right = glyph.bounds.Left + glyph.bounds.Right;
|
||||
Float bottom = glyph.bounds.Top + glyph.bounds.Bottom;
|
||||
|
||||
Float currentX = x + ( curGlyphPos.x_offset / 64.f );
|
||||
Float currentY = y + ( curGlyphPos.y_offset / 64.f );
|
||||
|
||||
// Add a quad for the current character
|
||||
if ( glyph.bounds.Right > 0 && glyph.bounds.Bottom > 0 ) {
|
||||
addGlyphQuad( mVertices, Vector2f( currentX, currentY ), glyph, italic, 0,
|
||||
@@ -1385,7 +1418,7 @@ void Text::ensureGeometryUpdate() {
|
||||
}
|
||||
|
||||
// If we're using the underlined style, add the last line
|
||||
if ( underlined ) {
|
||||
if ( underlined && run.runIsNewLine() ) {
|
||||
addLine( mVertices, x, y, underlineOffset, underlineThickness, 0, centerDiffX );
|
||||
|
||||
if ( mFontStyleConfig.OutlineThickness != 0 )
|
||||
@@ -1394,7 +1427,7 @@ void Text::ensureGeometryUpdate() {
|
||||
}
|
||||
|
||||
// If we're using the strike through style, add the last line across all characters
|
||||
if ( strikeThrough ) {
|
||||
if ( strikeThrough && run.runIsNewLine() ) {
|
||||
addLine( mVertices, x, y, strikeThroughOffset, underlineThickness, 0, centerDiffX );
|
||||
|
||||
if ( mFontStyleConfig.OutlineThickness != 0 )
|
||||
@@ -1428,6 +1461,7 @@ void Text::ensureGeometryUpdate() {
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( std::size_t i = 0; i < size; ++i ) {
|
||||
Uint32 curChar = mString[i];
|
||||
@@ -1514,7 +1548,7 @@ void Text::ensureGeometryUpdate() {
|
||||
if ( mFontStyleConfig.OutlineThickness != 0 ) {
|
||||
const Glyph& glyph =
|
||||
mFontStyleConfig.Font->getGlyph( curChar, mFontStyleConfig.CharacterSize, bold,
|
||||
italic, mFontStyleConfig.OutlineThickness );
|
||||
reqItalic, mFontStyleConfig.OutlineThickness );
|
||||
|
||||
Float left = glyph.bounds.Left;
|
||||
Float top = glyph.bounds.Top;
|
||||
@@ -1615,9 +1649,10 @@ void Text::ensureColorUpdate() {
|
||||
|
||||
if ( mContainsColorEmoji ) {
|
||||
auto positions = Font::emojiCodePointsPositions( mString );
|
||||
for ( const auto& position : positions )
|
||||
for ( const auto& position : positions ) {
|
||||
setFillColor( Color( 255, 255, 255, mFontStyleConfig.FontColor.a ), position,
|
||||
position );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1752,7 +1787,7 @@ void Text::setFillColor( const Color& color, Uint32 from, Uint32 to ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( rto == s ) {
|
||||
if ( to == s ) {
|
||||
if ( underlined ) {
|
||||
lpos++;
|
||||
Uint32 pos = lpos * GLi->quadVertexs();
|
||||
@@ -1932,21 +1967,18 @@ void Text::addGlyphQuad( std::vector<VertexCoords>& vertices, Vector2f position,
|
||||
Uint32 Text::getTotalVertices() {
|
||||
bool underlined = ( mFontStyleConfig.Style & Underlined ) != 0;
|
||||
bool strikeThrough = ( mFontStyleConfig.Style & StrikeThrough ) != 0;
|
||||
size_t sl = mString.size();
|
||||
size_t sv = sl * GLi->quadVertexs();
|
||||
|
||||
String::StringBaseType* c = &mString[0];
|
||||
size_t sv = mString.size() * GLi->quadVertexs();
|
||||
Uint32 skiped = 0;
|
||||
bool lineHasChars = false;
|
||||
|
||||
while ( '\0' != *c ) {
|
||||
for ( const auto& ch : mString ) {
|
||||
lineHasChars = true;
|
||||
|
||||
if ( ' ' == *c || '\n' == *c || '\t' == *c || '\r' == *c ) {
|
||||
if ( ' ' == ch || '\n' == ch || '\t' == ch || '\r' == ch ) {
|
||||
lineHasChars = false;
|
||||
skiped++;
|
||||
|
||||
if ( '\n' == *c ) {
|
||||
if ( '\n' == ch ) {
|
||||
if ( underlined )
|
||||
skiped--;
|
||||
|
||||
@@ -1954,8 +1986,6 @@ Uint32 Text::getTotalVertices() {
|
||||
skiped--;
|
||||
}
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
if ( lineHasChars ) {
|
||||
|
||||
Reference in New Issue
Block a user