@@ -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
532668try
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));
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
9481076struct 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
0 commit comments