Skip to content

Commit b488e8c

Browse files
committed
HAX: load fnt files (???)
1 parent a1ba9f7 commit b488e8c

File tree

3 files changed

+149
-19
lines changed

3 files changed

+149
-19
lines changed

src/renderer/atlas/AtlasEngine.api.cpp

Lines changed: 145 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -526,17 +526,156 @@ void AtlasEngine::_resolveTransparencySettings() noexcept
526526
}
527527
}
528528

529-
#include "../../pixfont/vga_rgba.c"
529+
namespace
530+
{
531+
// For now we're only using fixed pitch single color fonts, but the rest
532+
// of the flags are included here for completeness.
533+
static constexpr DWORD DFF_FIXED = 0x0001;
534+
static constexpr DWORD DFF_PROPORTIONAL = 0x0002;
535+
static constexpr DWORD DFF_1COLOR = 0x0010;
536+
static constexpr DWORD DFF_16COLOR = 0x0020;
537+
static constexpr DWORD DFF_256COLOR = 0x0040;
538+
static constexpr DWORD DFF_RGBCOLOR = 0x0080;
539+
540+
#pragma pack(push, 1)
541+
struct GLYPHENTRY
542+
{
543+
WORD geWidth;
544+
DWORD geOffset;
545+
};
546+
547+
struct FONTINFO
548+
{
549+
WORD dfVersion;
550+
DWORD dfSize;
551+
CHAR dfCopyright[60];
552+
WORD dfType;
553+
WORD dfPoints;
554+
WORD dfVertRes;
555+
WORD dfHorizRes;
556+
WORD dfAscent;
557+
WORD dfInternalLeading;
558+
WORD dfExternalLeading;
559+
BYTE dfItalic;
560+
BYTE dfUnderline;
561+
BYTE dfStrikeOut;
562+
WORD dfWeight;
563+
BYTE dfCharSet;
564+
WORD dfPixWidth;
565+
WORD dfPixHeight;
566+
BYTE dfPitchAndFamily;
567+
WORD dfAvgWidth;
568+
WORD dfMaxWidth;
569+
BYTE dfFirstChar;
570+
BYTE dfLastChar;
571+
BYTE dfDefaultChar;
572+
BYTE dfBreakChar;
573+
WORD dfWidthBytes;
574+
DWORD dfDevice;
575+
DWORD dfFace;
576+
DWORD dfBitsPointer;
577+
DWORD dfBitsOffset;
578+
BYTE dfReserved;
579+
DWORD dfFlags;
580+
WORD dfAspace;
581+
WORD dfBspace;
582+
WORD dfCspace;
583+
DWORD dfColorPointer;
584+
DWORD dfReserved1[4];
585+
// Character table follows
586+
// Face name follows
587+
};
588+
589+
}
590+
591+
BitmapFontInfo loadBitmapFont(wil::zwstring_view path)
592+
{
593+
wil::unique_hfile fontFile{ CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr) };
594+
THROW_LAST_ERROR_IF(!fontFile);
595+
BY_HANDLE_FILE_INFORMATION fi;
596+
GetFileInformationByHandle(fontFile.get(), &fi);
597+
598+
auto fileData{ std::make_unique_for_overwrite<std::byte[]>(fi.nFileSizeLow) };
599+
DWORD dwRead{ 0 };
600+
THROW_IF_WIN32_BOOL_FALSE(ReadFile(fontFile.get(), fileData.get(), fi.nFileSizeLow, &dwRead, nullptr));
601+
602+
const auto header = reinterpret_cast<const FONTINFO*>(fileData.get());
603+
auto numGlyphs{ header->dfLastChar - header->dfFirstChar + 1 }; // there is always a sentinel entry
604+
std::span<const GLYPHENTRY> glyphEntries{ reinterpret_cast<const GLYPHENTRY*>(fileData.get() + sizeof(FONTINFO)), gsl::narrow_cast<size_t>(numGlyphs) };
605+
606+
WORD maxPixWidth = 0;
607+
std::for_each(std::begin(glyphEntries), std::end(glyphEntries), [&](auto&& ge) {
608+
maxPixWidth = std::max(maxPixWidth, ge.geWidth);
609+
});
610+
611+
auto rgbaBitmapSize{ (16 * maxPixWidth) * (16 * header->dfPixHeight) };
612+
std::vector<uint8_t> rgbaBitmap;
613+
rgbaBitmap.resize(rgbaBitmapSize * sizeof(uint32_t));
614+
auto exploded = reinterpret_cast<uint32_t*>(rgbaBitmap.data());
615+
616+
auto didx = header->dfFirstChar;
617+
const auto stride = 16 * maxPixWidth;
618+
for (auto&& ge : glyphEntries)
619+
{
620+
// characters are stored end to end, scanline 0 ... N 0 ... N
621+
// we need to transform that into 0 0 0 0 1 1 1 1 2 2 2 2 ...
622+
623+
// bitmap offset plus currently glyph number-rows
624+
auto sgstart = reinterpret_cast<uint8_t*>(fileData.get()) + ge.geOffset;
625+
auto dgstart = exploded + ((didx % 16) * maxPixWidth) + (((didx / 16) * header->dfPixHeight) * stride);
626+
for (int y = 0; y < header->dfPixHeight; ++y)
627+
{
628+
auto scancol = 0;
629+
auto width = ge.geWidth;
630+
while (width)
631+
{
632+
auto row = sgstart[y + (scancol * header->dfPixHeight)];
633+
auto drstart = dgstart + (scancol * 8);
634+
auto cw = std::min<WORD>(width, 8);
635+
for (int i = 0; i < cw; ++i)
636+
{
637+
*drstart++ = 0xFFFFFFFF * ((row >> (7 - i)) & 1);
638+
}
639+
scancol++;
640+
width -= cw;
641+
}
642+
dgstart += stride;
643+
}
644+
++didx;
645+
}
646+
647+
#if 0
648+
auto w = CreateFile(L"c:\\src\\terminal\\dev\\image.bin", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS, 0, nullptr);
649+
WriteFile(w, rgbaBitmap.data(), (DWORD)rgbaBitmap.size(), nullptr, nullptr);
650+
CloseHandle(w);
651+
#endif
652+
653+
return BitmapFontInfo{
654+
.bitmap = std::move(rgbaBitmap),
655+
.glyphSize = { maxPixWidth, header->dfPixHeight },
656+
.bitmapSizeInCharacters = { 16, 16 },
657+
.glyphResidence = {
658+
0xFFFFFFFFFFFFFFFFULL,
659+
0xFFFFFFFFFFFFFFFFULL,
660+
0xFFFFFFFFFFFFFFFFULL,
661+
0xFFFFFFFFFFFFFFFFULL,
662+
},
663+
.invalidGlyphBitmapIndex = header->dfDefaultChar,
664+
};
665+
}
530666

531667
[[nodiscard]] HRESULT AtlasEngine::_updateFont(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, const std::unordered_map<std::wstring_view, float>& features, const std::unordered_map<std::wstring_view, float>& axes) noexcept
532668
try
533669
{
670+
if (fontInfoDesired.GetFaceName().find_last_of(L'.') != std::wstring::npos)
534671
{
535672
const auto font = _api.s.write()->font.write();
536673
float scale = (float)font->dpi / 96.f;
674+
font->bitmapFontInfo = loadBitmapFont(fontInfoDesired.GetFaceName());
675+
scale = 1.0f;
537676
font->cellSize = {
538-
gsl::narrow<u16>(lrintf(10.f * scale)),
539-
gsl::narrow<u16>(lrintf(20.f * scale)),
677+
gsl::narrow<u16>(lrintf(font->bitmapFontInfo.glyphSize.x * scale)),
678+
gsl::narrow<u16>(lrintf(font->bitmapFontInfo.glyphSize.y * scale)),
540679
};
541680
const auto& cs = font->cellSize;
542681
auto lineWidth = gsl::narrow<u16>(lrintf(1.f * scale));
@@ -557,18 +696,6 @@ try
557696
font->builtinGlyphs = true;
558697
font->colorGlyphs = false;
559698
font->thinLineWidth = lineWidth;
560-
const auto buf = reinterpret_cast<const uint8_t*>(&font_rgb[0]);
561-
font->bitmapFontInfo = BitmapFontInfo{
562-
.bitmap = { buf, buf + font_rgb_len },
563-
.glyphSize = { 10, 20 },
564-
.bitmapSizeInCharacters = { 32, 8 },
565-
.glyphResidence = {
566-
0xFFFFFFFFFFFFFFFFULL,
567-
0xFFFFFFFFFFFFFFFFULL,
568-
0xFFFFFFFFFFFFFFFFULL,
569-
0xFFFFFFFFFFFFFFFFULL,
570-
},
571-
};
572699
fontInfo.SetFromEngine(L"VGA 8x16", FF_MODERN, 400, false, { font->cellSize.x, font->cellSize.y }, { 10, 20 });
573700
return S_OK;
574701
}
@@ -945,6 +1072,7 @@ void AtlasEngine::_resolveFontMetrics(const FontInfoDesired& fontInfoDesired, Fo
9451072
return true;
9461073
}
9471074

1075+
#if 0
9481076
struct bdflex
9491077
{
9501078
enum tok
@@ -998,6 +1126,7 @@ struct bdflex
9981126
}
9991127
int e()
10001128
{
1001-
bdflex::*(bdflex::*)(int);
1129+
bdflex::* (bdflex::*)(int);
10021130
}
10031131
};
1132+
#endif

src/renderer/atlas/BackendD3D.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -679,12 +679,12 @@ void BackendD3D::_debugUpdateShaders(const RenderingPayload& p) noexcept
679679
struct FileVS
680680
{
681681
std::wstring_view filename;
682-
wil::com_ptr<ID3D11VertexShader> BackendD3D::*target;
682+
wil::com_ptr<ID3D11VertexShader> BackendD3D::* target;
683683
};
684684
struct FilePS
685685
{
686686
std::wstring_view filename;
687-
wil::com_ptr<ID3D11PixelShader> BackendD3D::*target;
687+
wil::com_ptr<ID3D11PixelShader> BackendD3D::* target;
688688
};
689689

690690
static constexpr std::array filesVS{
@@ -1722,7 +1722,7 @@ BackendD3D::ShadingType BackendD3D::_drawVGA816Glyph(const RenderingPayload& p,
17221722
const D2D1_RECT_U fillr{
17231723
0, 0, size.width, size.height
17241724
};
1725-
/* we have the entire bitmap right now, why not just blast the entire thing into D2D bitmap? */
1725+
/* we have the entire bitmap right now, why not just blast the entire thing into D2D bitmap? */
17261726
_vgaBitmap->CopyFromMemory(&fillr, bfi.bitmap.data(), size.width * sizeof(u32));
17271727
}
17281728

src/renderer/atlas/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ namespace Microsoft::Console::Render::Atlas
352352
u16x2 glyphSize;
353353
u16x2 bitmapSizeInCharacters;
354354
std::array<uint64_t, 256 / 64> glyphResidence;
355+
u16 invalidGlyphBitmapIndex;
355356
};
356357

357358
struct FontSettings

0 commit comments

Comments
 (0)