Skip to content

Commit fd35839

Browse files
committed
Properly implement bitmap font kerning
1 parent a6676fd commit fd35839

File tree

1 file changed

+31
-58
lines changed

1 file changed

+31
-58
lines changed

components/fontloader/fontloader.cpp

+31-58
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,8 @@ namespace Gui
363363
Point bottom_right;
364364
float width;
365365
float height;
366-
float u2; // appears unused, always 0
367-
float kerning;
366+
float kerningLeft;
367+
float kerningRight;
368368
float ascent;
369369
} GlyphInfo;
370370

@@ -564,6 +564,12 @@ namespace Gui
564564
additional.emplace(69, 0x0401); // Ё (Cyrillic Capital Letter Io) => E (latin capital E)
565565
additional.emplace(137, 0x0451); // ё (Cyrillic Small Letter Io) => ë (latin small E-diaeresis)
566566

567+
// ASCII vertical bar, use this as text input cursor
568+
additional.emplace(124, MyGUI::FontCodeType::Cursor);
569+
570+
// Underscore, use for NotDefined marker (used for glyphs not existing in the font)
571+
additional.emplace(95, MyGUI::FontCodeType::NotDefined);
572+
567573
for (int i = 0; i < 256; i++)
568574
{
569575
float x1 = data[i].top_left.x * width;
@@ -573,64 +579,31 @@ namespace Gui
573579

574580
ToUTF8::Utf8Encoder encoder(mEncoding);
575581
unsigned long unicodeVal = getUnicode(i, encoder, mEncoding);
582+
const std::string coord = MyGUI::utility::toString(x1) + " " + MyGUI::utility::toString(y1) + " "
583+
+ MyGUI::utility::toString(w) + " " + MyGUI::utility::toString(h);
584+
float advance = data[i].width + data[i].kerningRight;
585+
// Yes MyGUI, we really do want an advance of 0 sometimes, thank you.
586+
if (advance == 0.f && data[i].width != 0.f)
587+
advance = std::numeric_limits<float>::min();
588+
const std::string bearing = MyGUI::utility::toString(data[i].kerningLeft) + ' '
589+
+ MyGUI::utility::toString((fontSize - data[i].ascent));
590+
const MyGUI::IntSize size(static_cast<int>(data[i].width), static_cast<int>(data[i].height));
576591

577592
MyGUI::xml::ElementPtr code = codes->createChild("Code");
578593
code->addAttribute("index", unicodeVal);
579-
code->addAttribute("coord",
580-
MyGUI::utility::toString(x1) + " " + MyGUI::utility::toString(y1) + " " + MyGUI::utility::toString(w)
581-
+ " " + MyGUI::utility::toString(h));
582-
code->addAttribute("advance", data[i].width);
583-
code->addAttribute("bearing",
584-
MyGUI::utility::toString(data[i].kerning) + " "
585-
+ MyGUI::utility::toString((fontSize - data[i].ascent)));
586-
code->addAttribute(
587-
"size", MyGUI::IntSize(static_cast<int>(data[i].width), static_cast<int>(data[i].height)));
594+
code->addAttribute("coord", coord);
595+
code->addAttribute("advance", advance);
596+
code->addAttribute("bearing", bearing);
597+
code->addAttribute("size", size);
588598

589599
for (auto [it, end] = additional.equal_range(i); it != end; ++it)
590600
{
591601
code = codes->createChild("Code");
592602
code->addAttribute("index", it->second);
593-
code->addAttribute("coord",
594-
MyGUI::utility::toString(x1) + " " + MyGUI::utility::toString(y1) + " "
595-
+ MyGUI::utility::toString(w) + " " + MyGUI::utility::toString(h));
596-
code->addAttribute("advance", data[i].width);
597-
code->addAttribute("bearing",
598-
MyGUI::utility::toString(data[i].kerning) + " "
599-
+ MyGUI::utility::toString((fontSize - data[i].ascent)));
600-
code->addAttribute(
601-
"size", MyGUI::IntSize(static_cast<int>(data[i].width), static_cast<int>(data[i].height)));
602-
}
603-
604-
// ASCII vertical bar, use this as text input cursor
605-
if (i == 124)
606-
{
607-
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
608-
cursorCode->addAttribute("index", MyGUI::FontCodeType::Cursor);
609-
cursorCode->addAttribute("coord",
610-
MyGUI::utility::toString(x1) + " " + MyGUI::utility::toString(y1) + " "
611-
+ MyGUI::utility::toString(w) + " " + MyGUI::utility::toString(h));
612-
cursorCode->addAttribute("advance", data[i].width);
613-
cursorCode->addAttribute("bearing",
614-
MyGUI::utility::toString(data[i].kerning) + " "
615-
+ MyGUI::utility::toString((fontSize - data[i].ascent)));
616-
cursorCode->addAttribute(
617-
"size", MyGUI::IntSize(static_cast<int>(data[i].width), static_cast<int>(data[i].height)));
618-
}
619-
620-
// Underscore, use for NotDefined marker (used for glyphs not existing in the font)
621-
if (i == 95)
622-
{
623-
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
624-
cursorCode->addAttribute("index", MyGUI::FontCodeType::NotDefined);
625-
cursorCode->addAttribute("coord",
626-
MyGUI::utility::toString(x1) + " " + MyGUI::utility::toString(y1) + " "
627-
+ MyGUI::utility::toString(w) + " " + MyGUI::utility::toString(h));
628-
cursorCode->addAttribute("advance", data[i].width);
629-
cursorCode->addAttribute("bearing",
630-
MyGUI::utility::toString(data[i].kerning) + " "
631-
+ MyGUI::utility::toString((fontSize - data[i].ascent)));
632-
cursorCode->addAttribute(
633-
"size", MyGUI::IntSize(static_cast<int>(data[i].width), static_cast<int>(data[i].height)));
603+
code->addAttribute("coord", coord);
604+
code->addAttribute("advance", advance);
605+
code->addAttribute("bearing", bearing);
606+
code->addAttribute("size", size);
634607
}
635608
}
636609

@@ -639,12 +612,12 @@ namespace Gui
639612
omitted.push_back(MyGUI::FontCodeType::SelectedBack);
640613
for (const UnicodeIndex index : omitted)
641614
{
642-
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
643-
cursorCode->addAttribute("index", index);
644-
cursorCode->addAttribute("coord", "0 0 0 0");
645-
cursorCode->addAttribute("advance", "0");
646-
cursorCode->addAttribute("bearing", "0 0");
647-
cursorCode->addAttribute("size", "0 0");
615+
MyGUI::xml::ElementPtr code = codes->createChild("Code");
616+
code->addAttribute("index", index);
617+
code->addAttribute("coord", "0 0 0 0");
618+
code->addAttribute("advance", "0");
619+
code->addAttribute("bearing", "0 0");
620+
code->addAttribute("size", "0 0");
648621
}
649622

650623
// Register the font with MyGUI

0 commit comments

Comments
 (0)