mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 21:11:52 +00:00
use a more complete font did some primitive font substitution logic.
NotoSans was chosen because it contains all Latin, Cyrillic and Greek characters in one file. To test the substitution the separate font files for Armenian and Georgian were also added, even though the languages have not been translated.
This commit is contained in:
parent
3caca15c61
commit
f5c4964902
11 changed files with 107 additions and 24 deletions
|
@ -256,7 +256,7 @@ if( MSVC )
|
|||
# String pooling
|
||||
# Function-level linking
|
||||
# Disable run-time type information
|
||||
set( ALL_C_FLAGS "/GF /Gy /permissive-" )
|
||||
set( ALL_C_FLAGS "/GF /Gy /permissive- /utf-8" )
|
||||
|
||||
if ( HAVE_VULKAN )
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} /DHAVE_VULKAN" )
|
||||
|
|
|
@ -4,5 +4,12 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
std::vector<uint8_t> LoadWidgetFontData(const std::string& name);
|
||||
struct SingleFontData
|
||||
{
|
||||
std::vector<uint8_t> fontdata;
|
||||
std::vector<std::pair<uint32_t, uint32_t>> ranges;
|
||||
int language = -1; // mainly useful if we start supporting Chinese so that we can use another font there than for Japanese.
|
||||
};
|
||||
|
||||
std::vector<SingleFontData> LoadWidgetFontData(const std::string& name);
|
||||
std::vector<uint8_t> LoadWidgetImageData(const std::string& name);
|
||||
|
|
|
@ -149,7 +149,7 @@ private:
|
|||
|
||||
bool select_all_on_focus_gain = false;
|
||||
|
||||
std::shared_ptr<Font> font = Font::Create("Segoe UI", 12.0);
|
||||
std::shared_ptr<Font> font = Font::Create("NotoSans", 12.0);
|
||||
|
||||
template<typename T>
|
||||
static T clamp(T val, T minval, T maxval) { return std::max<T>(std::min<T>(val, maxval), minval); }
|
||||
|
|
|
@ -36,9 +36,9 @@ public:
|
|||
class CanvasFont
|
||||
{
|
||||
public:
|
||||
CanvasFont(const std::string& fontname, double height) : fontname(fontname), height(height)
|
||||
CanvasFont(const std::string& fontname, double height, std::vector<uint8_t>& _data) : fontname(fontname), height(height)
|
||||
{
|
||||
data = LoadWidgetFontData(fontname);
|
||||
data = std::move(_data);
|
||||
loadFont(data.data(), data.size());
|
||||
|
||||
try
|
||||
|
@ -152,6 +152,65 @@ private:
|
|||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
class CanvasFontGroup
|
||||
{
|
||||
public:
|
||||
struct SingleFont
|
||||
{
|
||||
std::unique_ptr<CanvasFont> font;
|
||||
std::vector<std::pair<uint32_t, uint32_t>> ranges;
|
||||
int language; // mainly useful if we start supporting Chinese so that we can use another font there than for Japanese.
|
||||
};
|
||||
CanvasFontGroup(const std::string& fontname, double height) : height(height)
|
||||
{
|
||||
auto fontdata = LoadWidgetFontData(fontname);
|
||||
fonts.resize(fontdata.size());
|
||||
for (size_t i = 0; i < fonts.size(); i++)
|
||||
{
|
||||
fonts[i].font = std::make_unique<CanvasFont>(fontname, height, fontdata[i].fontdata);
|
||||
fonts[i].ranges = std::move(fontdata[i].ranges);
|
||||
fonts[i].language = fontdata[i].language;
|
||||
}
|
||||
}
|
||||
|
||||
CanvasGlyph* getGlyph(uint32_t utfchar)
|
||||
{
|
||||
if (utfchar >= 0x530 && utfchar < 0x590)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
for (auto& fd : fonts)
|
||||
{
|
||||
bool get = false;
|
||||
if (fd.ranges.size() == 0) get = true;
|
||||
else for (auto r : fd.ranges)
|
||||
{
|
||||
if (utfchar >= r.first && utfchar <= r.second)
|
||||
{
|
||||
get = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (get)
|
||||
{
|
||||
auto g = fd.font->getGlyph(utfchar);
|
||||
if (g) return g;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SFT_LMetrics& GetTextMetrics()
|
||||
{
|
||||
return fonts[0].font->textmetrics;
|
||||
}
|
||||
|
||||
double height;
|
||||
std::vector<SingleFont> fonts;
|
||||
|
||||
};
|
||||
|
||||
class BitmapCanvas : public Canvas
|
||||
{
|
||||
public:
|
||||
|
@ -211,7 +270,7 @@ public:
|
|||
|
||||
DisplayWindow* window = nullptr;
|
||||
|
||||
std::unique_ptr<CanvasFont> font;
|
||||
std::unique_ptr<CanvasFontGroup> font;
|
||||
std::unique_ptr<CanvasTexture> whiteTexture;
|
||||
|
||||
Point origin;
|
||||
|
@ -230,7 +289,7 @@ BitmapCanvas::BitmapCanvas(DisplayWindow* window) : window(window)
|
|||
uiscale = window->GetDpiScale();
|
||||
uint32_t white = 0xffffffff;
|
||||
whiteTexture = createTexture(1, 1, &white);
|
||||
font = std::make_unique<CanvasFont>("Segoe UI", 13.0*uiscale);
|
||||
font = std::make_unique<CanvasFontGroup>("NotoSans", 13.0*uiscale);
|
||||
}
|
||||
|
||||
BitmapCanvas::~BitmapCanvas()
|
||||
|
@ -411,7 +470,7 @@ void BitmapCanvas::drawText(const Point& pos, const Colorf& color, const std::st
|
|||
Rect BitmapCanvas::measureText(const std::string& text)
|
||||
{
|
||||
double x = 0.0;
|
||||
double y = font->textmetrics.ascender - font->textmetrics.descender;
|
||||
double y = font->GetTextMetrics().ascender - font->GetTextMetrics().descender;
|
||||
|
||||
UTF8Reader reader(text.data(), text.size());
|
||||
while (!reader.is_end())
|
||||
|
@ -433,8 +492,9 @@ VerticalTextPosition BitmapCanvas::verticalTextAlign()
|
|||
{
|
||||
VerticalTextPosition align;
|
||||
align.top = 0.0f;
|
||||
align.baseline = font->textmetrics.ascender / uiscale;
|
||||
align.bottom = (font->textmetrics.ascender - font->textmetrics.descender) / uiscale;
|
||||
auto tm = font->GetTextMetrics();
|
||||
align.baseline = tm.ascender / uiscale;
|
||||
align.bottom = (tm.ascender - tm.descender) / uiscale;
|
||||
return align;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#include "launcherwindow.h"
|
||||
#include "v_video.h"
|
||||
#include "version.h"
|
||||
|
|
|
@ -12,19 +12,7 @@ void InitWidgetResources(const char* filename)
|
|||
I_FatalError("Unable to open %s", filename);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> LoadWidgetFontData(const std::string& name)
|
||||
{
|
||||
auto lump = WidgetResources->FindEntry("widgets/poppins/poppins-regular.ttf");
|
||||
if (lump == -1)
|
||||
I_FatalError("Unable to find %s", name.c_str());
|
||||
|
||||
auto reader = WidgetResources->GetEntryReader(lump, FileSys::READER_SHARED);
|
||||
std::vector<uint8_t> buffer(reader.GetLength());
|
||||
reader.Read(buffer.data(), buffer.size());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> LoadWidgetImageData(const std::string& name)
|
||||
static std::vector<uint8_t> LoadFile(const std::string& name)
|
||||
{
|
||||
auto lump = WidgetResources->FindEntry(name.c_str());
|
||||
if (lump == -1)
|
||||
|
@ -35,3 +23,32 @@ std::vector<uint8_t> LoadWidgetImageData(const std::string& name)
|
|||
reader.Read(buffer.data(), buffer.size());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// This interface will later require some significant redesign.
|
||||
std::vector<SingleFontData> LoadWidgetFontData(const std::string& name)
|
||||
{
|
||||
std::vector<SingleFontData> returnv;
|
||||
if (!stricmp(name.c_str(), "notosans"))
|
||||
{
|
||||
returnv.resize(3);
|
||||
returnv[2].fontdata = LoadFile("widgets/noto/notosans-regular.ttf");
|
||||
returnv[0].fontdata = LoadFile("widgets/noto/notosansarmenian-regular.ttf");
|
||||
returnv[1].fontdata = LoadFile("widgets/noto/notosansgeorgian-regular.ttf");
|
||||
returnv[0].ranges.push_back(std::make_pair(0x531, 0x58f));
|
||||
returnv[1].ranges.push_back(std::make_pair(0x10a0, 0x10ff));
|
||||
returnv[1].ranges.push_back(std::make_pair(0x1c90, 0x1cbf));
|
||||
returnv[1].ranges.push_back(std::make_pair(0x2d00, 0x2d2f));
|
||||
// todo: load system CJK fonts here
|
||||
return returnv;
|
||||
|
||||
}
|
||||
returnv.resize(1);
|
||||
std::string fn = "widgets/font/" +name + ".ttf";
|
||||
returnv[0].fontdata = LoadFile(fn);
|
||||
return returnv;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> LoadWidgetImageData(const std::string& name)
|
||||
{
|
||||
return LoadFile(name);
|
||||
}
|
||||
|
|
BIN
wadsrc/static/widgets/noto/NotoSans-Regular.ttf
Normal file
BIN
wadsrc/static/widgets/noto/NotoSans-Regular.ttf
Normal file
Binary file not shown.
BIN
wadsrc/static/widgets/noto/NotoSansArmenian-Regular.ttf
Normal file
BIN
wadsrc/static/widgets/noto/NotoSansArmenian-Regular.ttf
Normal file
Binary file not shown.
BIN
wadsrc/static/widgets/noto/NotoSansGeorgian-Regular.ttf
Normal file
BIN
wadsrc/static/widgets/noto/NotoSansGeorgian-Regular.ttf
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue