mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-04-10 19:15:13 +00:00
Changed the text shaping function to return the segment vector
This commit is contained in:
parent
9e7b02291b
commit
b3ac8b6320
|
@ -24,7 +24,6 @@ Font::Font(float size, const std::string& path)
|
||||||
, mFontSize {size}
|
, mFontSize {size}
|
||||||
, mLetterHeight {0.0f}
|
, mLetterHeight {0.0f}
|
||||||
, mMaxGlyphHeight {static_cast<int>(std::round(size))}
|
, mMaxGlyphHeight {static_cast<int>(std::round(size))}
|
||||||
, mTextHash {0}
|
|
||||||
{
|
{
|
||||||
if (mFontSize < 3.0f) {
|
if (mFontSize < 3.0f) {
|
||||||
mFontSize = 3.0f;
|
mFontSize = 3.0f;
|
||||||
|
@ -96,14 +95,17 @@ std::shared_ptr<Font> Font::get(float size, const std::string& path)
|
||||||
|
|
||||||
glm::vec2 Font::sizeText(std::string text, float lineSpacing)
|
glm::vec2 Font::sizeText(std::string text, float lineSpacing)
|
||||||
{
|
{
|
||||||
|
if (text == "")
|
||||||
|
return glm::vec2 {0.0f, getHeight(lineSpacing)};
|
||||||
|
|
||||||
const float lineHeight {getHeight(lineSpacing)};
|
const float lineHeight {getHeight(lineSpacing)};
|
||||||
float lineWidth {0.0f};
|
float lineWidth {0.0f};
|
||||||
float highestWidth {0.0f};
|
float highestWidth {0.0f};
|
||||||
float y {lineHeight};
|
float y {lineHeight};
|
||||||
|
|
||||||
shapeText(text);
|
std::vector<ShapeSegment> segmentsHB {std::move(shapeText(text))};
|
||||||
|
|
||||||
for (auto& segment : mSegmentsHB) {
|
for (auto& segment : segmentsHB) {
|
||||||
for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) {
|
for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) {
|
||||||
const unsigned int character {segment.glyphIndexes[i]};
|
const unsigned int character {segment.glyphIndexes[i]};
|
||||||
Glyph* glyph {nullptr};
|
Glyph* glyph {nullptr};
|
||||||
|
@ -141,9 +143,9 @@ int Font::loadGlyphs(const std::string& text)
|
||||||
{
|
{
|
||||||
mMaxGlyphHeight = static_cast<int>(std::round(mFontSize));
|
mMaxGlyphHeight = static_cast<int>(std::round(mFontSize));
|
||||||
|
|
||||||
shapeText(text);
|
std::vector<ShapeSegment> segmentsHB {std::move(shapeText(text))};
|
||||||
|
|
||||||
for (auto& segment : mSegmentsHB) {
|
for (auto& segment : segmentsHB) {
|
||||||
for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) {
|
for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) {
|
||||||
const unsigned int character {segment.glyphIndexes[i]};
|
const unsigned int character {segment.glyphIndexes[i]};
|
||||||
Glyph* glyph {nullptr};
|
Glyph* glyph {nullptr};
|
||||||
|
@ -202,9 +204,9 @@ TextCache* Font::buildTextCache(const std::string& text,
|
||||||
// Vertices by texture.
|
// Vertices by texture.
|
||||||
std::map<FontTexture*, std::vector<Renderer::Vertex>> vertMap;
|
std::map<FontTexture*, std::vector<Renderer::Vertex>> vertMap;
|
||||||
|
|
||||||
shapeText(text);
|
std::vector<ShapeSegment> segmentsHB {std::move(shapeText(text))};
|
||||||
|
|
||||||
for (auto& segment : mSegmentsHB) {
|
for (auto& segment : segmentsHB) {
|
||||||
for (size_t cursor {0}; cursor < segment.glyphIndexes.size(); ++cursor) {
|
for (size_t cursor {0}; cursor < segment.glyphIndexes.size(); ++cursor) {
|
||||||
const unsigned int character {segment.glyphIndexes[cursor]};
|
const unsigned int character {segment.glyphIndexes[cursor]};
|
||||||
Glyph* glyph {nullptr};
|
Glyph* glyph {nullptr};
|
||||||
|
@ -338,13 +340,13 @@ std::string Font::wrapText(const std::string& text,
|
||||||
// There are also many instances where this hack will not lead to correct results.
|
// There are also many instances where this hack will not lead to correct results.
|
||||||
float totalWidth {0.0f};
|
float totalWidth {0.0f};
|
||||||
bool skipAbbreviation {false};
|
bool skipAbbreviation {false};
|
||||||
shapeText(text);
|
std::vector<ShapeSegment> segmentsHB {std::move(shapeText(text))};
|
||||||
|
|
||||||
for (auto& segment : mSegmentsHB)
|
for (auto& segment : segmentsHB)
|
||||||
totalWidth += segment.glyphsWidth;
|
totalWidth += segment.glyphsWidth;
|
||||||
|
|
||||||
if (totalWidth <= maxLength ||
|
if (totalWidth <= maxLength ||
|
||||||
(mSegmentsHB.size() == 1 && mSegmentsHB.front().glyphsWidth <= maxLength))
|
(segmentsHB.size() == 1 && segmentsHB.front().glyphsWidth <= maxLength))
|
||||||
skipAbbreviation = true;
|
skipAbbreviation = true;
|
||||||
|
|
||||||
for (size_t i {0}; i < text.length(); ++i) {
|
for (size_t i {0}; i < text.length(); ++i) {
|
||||||
|
@ -469,10 +471,10 @@ glm::vec2 Font::getWrappedTextCursorOffset(const std::string& wrappedText,
|
||||||
size_t cursor {0};
|
size_t cursor {0};
|
||||||
|
|
||||||
// TEMPORARY - enable this code when shaped text is properly wrapped in wrapText().
|
// TEMPORARY - enable this code when shaped text is properly wrapped in wrapText().
|
||||||
// shapeText(wrappedText);
|
// std::vector<ShapeSegment> segmentsHB {std::move(shapeText(wrappedText))};
|
||||||
// size_t totalPos {0};
|
// size_t totalPos {0};
|
||||||
|
|
||||||
// for (auto& segment : mSegmentsHB) {
|
// for (auto& segment : segmentsHB) {
|
||||||
// if (totalPos > stop)
|
// if (totalPos > stop)
|
||||||
// break;
|
// break;
|
||||||
// for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) {
|
// for (size_t i {0}; i < segment.glyphIndexes.size(); ++i) {
|
||||||
|
@ -740,17 +742,9 @@ void Font::initLibrary()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::shapeText(const std::string& text)
|
std::vector<Font::ShapeSegment> Font::shapeText(const std::string& text)
|
||||||
{
|
{
|
||||||
// Calculate the hash value for the string to make sure we're not shaping the same
|
std::vector<ShapeSegment> segmentsHB;
|
||||||
// text repeatedly.
|
|
||||||
const size_t hashValue {std::hash<std::string> {}(text)};
|
|
||||||
if (hashValue == mTextHash)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mTextHash = hashValue;
|
|
||||||
mSegmentsHB.clear();
|
|
||||||
|
|
||||||
hb_font_t* lastFont {nullptr};
|
hb_font_t* lastFont {nullptr};
|
||||||
unsigned int lastCursor {0};
|
unsigned int lastCursor {0};
|
||||||
unsigned int byteLength {0};
|
unsigned int byteLength {0};
|
||||||
|
@ -809,15 +803,15 @@ void Font::shapeText(const std::string& text)
|
||||||
if (!shapeSegment)
|
if (!shapeSegment)
|
||||||
segment.substring = text.substr(lastFlushPos, textCursor - lastFlushPos);
|
segment.substring = text.substr(lastFlushPos, textCursor - lastFlushPos);
|
||||||
|
|
||||||
mSegmentsHB.emplace_back(std::move(segment));
|
segmentsHB.emplace_back(std::move(segment));
|
||||||
|
|
||||||
lastFlushPos = textCursor;
|
lastFlushPos = textCursor;
|
||||||
}
|
}
|
||||||
lastFont = currGlyph->fontHB;
|
lastFont = currGlyph->fontHB;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSegmentsHB.empty())
|
if (segmentsHB.empty())
|
||||||
return;
|
return segmentsHB;
|
||||||
|
|
||||||
size_t cursor {0};
|
size_t cursor {0};
|
||||||
size_t length {0};
|
size_t length {0};
|
||||||
|
@ -827,7 +821,7 @@ void Font::shapeText(const std::string& text)
|
||||||
|
|
||||||
// Step 2, shape text.
|
// Step 2, shape text.
|
||||||
|
|
||||||
for (auto& segment : mSegmentsHB) {
|
for (auto& segment : segmentsHB) {
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
length = 0;
|
length = 0;
|
||||||
segment.glyphIndexes.clear();
|
segment.glyphIndexes.clear();
|
||||||
|
@ -868,6 +862,8 @@ void Font::shapeText(const std::string& text)
|
||||||
segment.glyphIndexes.emplace_back(character);
|
segment.glyphIndexes.emplace_back(character);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return segmentsHB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::rebuildTextures()
|
void Font::rebuildTextures()
|
||||||
|
|
|
@ -208,7 +208,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Shape text using HarfBuzz.
|
// Shape text using HarfBuzz.
|
||||||
void shapeText(const std::string& text);
|
std::vector<ShapeSegment> shapeText(const std::string& text);
|
||||||
|
|
||||||
// Completely recreate the texture data for all textures based on mGlyphs information.
|
// Completely recreate the texture data for all textures based on mGlyphs information.
|
||||||
void rebuildTextures();
|
void rebuildTextures();
|
||||||
|
@ -238,7 +238,6 @@ private:
|
||||||
std::vector<std::unique_ptr<FontTexture>> mTextures;
|
std::vector<std::unique_ptr<FontTexture>> mTextures;
|
||||||
std::map<unsigned int, Glyph> mGlyphMap;
|
std::map<unsigned int, Glyph> mGlyphMap;
|
||||||
std::map<std::pair<unsigned int, hb_font_t*>, Glyph> mGlyphMapByIndex;
|
std::map<std::pair<unsigned int, hb_font_t*>, Glyph> mGlyphMapByIndex;
|
||||||
std::vector<ShapeSegment> mSegmentsHB;
|
|
||||||
|
|
||||||
const std::string mPath;
|
const std::string mPath;
|
||||||
hb_font_t* mFontHB;
|
hb_font_t* mFontHB;
|
||||||
|
@ -248,7 +247,6 @@ private:
|
||||||
float mFontSize;
|
float mFontSize;
|
||||||
float mLetterHeight;
|
float mLetterHeight;
|
||||||
int mMaxGlyphHeight;
|
int mMaxGlyphHeight;
|
||||||
size_t mTextHash;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used to store a sort of "pre-rendered" string.
|
// Used to store a sort of "pre-rendered" string.
|
||||||
|
|
Loading…
Reference in a new issue