mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 21:11:52 +00:00
make adjustments to the font substitution and load Japanese and Korean fonts from the Windows font folder.
This commit is contained in:
parent
a016bf1ef2
commit
0838433d1f
3 changed files with 60 additions and 41 deletions
|
@ -7,8 +7,7 @@
|
|||
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::string language;
|
||||
};
|
||||
|
||||
std::vector<SingleFontData> LoadWidgetFontData(const std::string& name);
|
||||
|
|
|
@ -47,7 +47,8 @@ class CanvasFont
|
|||
public:
|
||||
CanvasFont(const std::string& fontname, double height, std::vector<uint8_t>& _data) : fontname(fontname), height(height)
|
||||
{
|
||||
ttf = std::make_unique<TrueTypeFont>(std::make_shared<TrueTypeFontFileData>(_data));
|
||||
auto tdata = std::make_shared<TrueTypeFontFileData>(_data);
|
||||
ttf = std::make_unique<TrueTypeFont>(tdata);
|
||||
textmetrics = ttf->GetTextMetrics(height);
|
||||
}
|
||||
|
||||
|
@ -58,6 +59,7 @@ public:
|
|||
CanvasGlyph* getGlyph(uint32_t utfchar)
|
||||
{
|
||||
uint32_t glyphIndex = ttf->GetGlyphIndex(utfchar);
|
||||
if (glyphIndex == 0) return nullptr;
|
||||
|
||||
auto& glyph = glyphs[glyphIndex];
|
||||
if (glyph)
|
||||
|
@ -266,8 +268,7 @@ 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.
|
||||
std::string language;
|
||||
};
|
||||
CanvasFontGroup(const std::string& fontname, double height) : height(height)
|
||||
{
|
||||
|
@ -276,34 +277,22 @@ public:
|
|||
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)
|
||||
CanvasGlyph* getGlyph(uint32_t utfchar, const char* lang = nullptr)
|
||||
{
|
||||
if (utfchar >= 0x530 && utfchar < 0x590)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
for (auto& fd : fonts)
|
||||
{
|
||||
bool get = false;
|
||||
if (fd.ranges.size() == 0) get = true;
|
||||
else for (auto r : fd.ranges)
|
||||
for (auto& fd : fonts)
|
||||
{
|
||||
if (utfchar >= r.first && utfchar <= r.second)
|
||||
if (i == 1 || lang == nullptr || *lang == 0 || fd.language.empty() || fd.language == lang)
|
||||
{
|
||||
get = true;
|
||||
break;
|
||||
auto g = fd.font->getGlyph(utfchar);
|
||||
if (g) return g;
|
||||
}
|
||||
}
|
||||
if (get)
|
||||
{
|
||||
auto g = fd.font->getGlyph(utfchar);
|
||||
if (g) return g;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -371,6 +360,8 @@ public:
|
|||
int getClipMaxX() const;
|
||||
int getClipMaxY() const;
|
||||
|
||||
void setLanguage(const char* lang) { language = lang; }
|
||||
|
||||
std::unique_ptr<CanvasTexture> createTexture(int width, int height, const void* pixels, ImageFormat format = ImageFormat::B8G8R8A8);
|
||||
|
||||
template<typename T>
|
||||
|
@ -390,6 +381,7 @@ public:
|
|||
std::vector<uint32_t> pixels;
|
||||
|
||||
std::unordered_map<std::shared_ptr<Image>, std::unique_ptr<CanvasTexture>> imageTextures;
|
||||
std::string language;
|
||||
};
|
||||
|
||||
BitmapCanvas::BitmapCanvas(DisplayWindow* window) : window(window)
|
||||
|
@ -557,8 +549,8 @@ void BitmapCanvas::drawText(const Point& pos, const Colorf& color, const std::st
|
|||
UTF8Reader reader(text.data(), text.size());
|
||||
while (!reader.is_end())
|
||||
{
|
||||
CanvasGlyph* glyph = font->getGlyph(reader.character());
|
||||
if (!glyph->texture)
|
||||
CanvasGlyph* glyph = font->getGlyph(reader.character(), language.c_str());
|
||||
if (!glyph || !glyph->texture)
|
||||
{
|
||||
glyph = font->getGlyph(32);
|
||||
}
|
||||
|
@ -583,8 +575,8 @@ Rect BitmapCanvas::measureText(const std::string& text)
|
|||
UTF8Reader reader(text.data(), text.size());
|
||||
while (!reader.is_end())
|
||||
{
|
||||
CanvasGlyph* glyph = font->getGlyph(reader.character());
|
||||
if (!glyph->texture)
|
||||
CanvasGlyph* glyph = font->getGlyph(reader.character(), language.c_str());
|
||||
if (!glyph || !glyph->texture)
|
||||
{
|
||||
glyph = font->getGlyph(32);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
#include <zwidget/core/resourcedata.h>
|
||||
#include "filesystem.h"
|
||||
#include "printf.h"
|
||||
#include "zstring.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
FResourceFile* WidgetResources;
|
||||
|
||||
|
@ -17,11 +23,11 @@ void CloseWidgetResources()
|
|||
if (WidgetResources) delete WidgetResources;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> LoadFile(const std::string& name)
|
||||
static std::vector<uint8_t> LoadFile(const char* name)
|
||||
{
|
||||
auto lump = WidgetResources->FindEntry(name.c_str());
|
||||
auto lump = WidgetResources->FindEntry(name);
|
||||
if (lump == -1)
|
||||
I_FatalError("Unable to find %s", name.c_str());
|
||||
I_FatalError("Unable to find %s", name);
|
||||
|
||||
auto reader = WidgetResources->GetEntryReader(lump, FileSys::READER_SHARED);
|
||||
std::vector<uint8_t> buffer(reader.GetLength());
|
||||
|
@ -29,31 +35,53 @@ static std::vector<uint8_t> LoadFile(const std::string& name)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
// this must be allowed to fail without throwing.
|
||||
static std::vector<uint8_t> LoadDiskFile(const char* name)
|
||||
{
|
||||
std::vector<uint8_t> buffer;
|
||||
FileSys::FileReader lump;
|
||||
if (lump.OpenFile(name))
|
||||
{
|
||||
buffer.resize(lump.GetLength());
|
||||
lump.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
|
||||
returnv.resize(5);
|
||||
returnv[0].fontdata = LoadFile("widgets/noto/notosans-regular.ttf");
|
||||
returnv[1].fontdata = LoadFile("widgets/noto/notosansarmenian-regular.ttf");
|
||||
returnv[2].fontdata = LoadFile("widgets/noto/notosansgeorgian-regular.ttf");
|
||||
#ifdef _WIN32
|
||||
wchar_t wbuffer[256];
|
||||
if (GetWindowsDirectoryW(wbuffer, 256))
|
||||
{
|
||||
FString windir(wbuffer);
|
||||
returnv[3].fontdata = LoadDiskFile((windir + "/fonts/yugothm.ttc").GetChars());
|
||||
returnv[3].language = "ja";
|
||||
returnv[4].fontdata = LoadDiskFile((windir + "/fonts/malgun.ttf").GetChars());
|
||||
returnv[4].language = "ko";
|
||||
// Don't fail if these cannot be found
|
||||
if (returnv[4].fontdata.size() == 0) returnv.erase(returnv.begin() + 4);
|
||||
if (returnv[3].fontdata.size() == 0) returnv.erase(returnv.begin() + 3);
|
||||
}
|
||||
#endif
|
||||
return returnv;
|
||||
|
||||
}
|
||||
returnv.resize(1);
|
||||
std::string fn = "widgets/font/" +name + ".ttf";
|
||||
returnv[0].fontdata = LoadFile(fn);
|
||||
returnv[0].fontdata = LoadFile(fn.c_str());
|
||||
return returnv;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> LoadWidgetImageData(const std::string& name)
|
||||
{
|
||||
return LoadFile(name);
|
||||
return LoadFile(name.c_str());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue