[video member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Parsing and Updating Font Metadata" vod_platform=youtube id=uvPbmPLfArQ annotator=Miblo] [0:01][Recap and set the stage for the day, assuming that our certificates are not about to expire][:speech] [2:34][Recall Windows' rule for antialiasing fonts (up to 353px high), and set up to parse and update :font metadata][:speech] [4:33][Address the "hhfont creates corrupt PNG for "space" glyph" issue[ref site=GitHub page="HandmadeHero / cpp / hhfont creates corrupt PNG for \"space\" glyph" url=https://github.com/HandmadeHero/cpp/issues/94]][:"file format" :research] [7:39][Check out test.hht with the determination to augment it with richer :font metadata][:"file format" :parsing :research] [9:18][Determine to break up ParseTopLevelBlock() into bundles of uniform operations, and permit such things as calling UpdateAssetMetadata() for many individual glyphs][:parsing :research] [12:07][Introduce HandleCommonFields() for ParseTopLevelBlock() to call for many block types][:parsing] [16:05][Extract the "default" block :parsing out of ParseTopLevelBlock() for its caller ParseHHT() to perform, introducing ParseDefaultBlock()] [24:05][Extract the "font" block :parsing out of ParseTopLevelBlock(), introducing ParseFontBlock() and RequireIdentifier()] [28:45][Introduce RequireField() to compress out the field :parsing code] [30:07][Continue to implement ParseFontBlock() calling RequireField() and setting the Font header][:parsing] [34:24][Enable ParseFontBlock() to handle the Glyph and HorizontalAdvance arrays][:parsing] [40:19][Consult @Molly][:speech] [44:38][Continue to enable ParseFontBlock() to handle Glyph metadata, introducing ImportGlyph()][:parsing] [51:40][Enable ParseFontBlock() to handle the HorizontalAdvance metadata for every Glyph][:parsing] [54:16][Enable ParseFontBlock() to handle the rest of the Glyph metadata, including code point and alignment points][:parsing] [1:03:47][Introduce UpdateSingleAssetMetadata() for ParseFontBlock() to call][:"asset system" :parsing] [1:12:20][Change UpdateSingleAssetMetadata() to take an asset_file rather than asset_source_file, and additionally take an Errors stream and FileBaseName, for ParseFontBlock() to pass][:"asset system" :parsing] [1:17:52][Consider how to import glyphs specially, since they lack an asset index][:"asset system" :speech] [1:21:47][Introduce a synthetic asset file in ParseFontBlock() to denote our font assets][:"asset system" :parsing] [1:29:26][Set up ParseFontBlock() to rebuild differing glyph arrays, introducing BlockDiffers()][:parsing] [1:44:19][Implement BlockDiffers()] [1:48:50][Fix compile errors] [1:53:52][Stub out ImportGlyph() and a version of GetOrCreateAssetSourceFile() that takes the BaseName as a string][:parsing] [1:57:51][Q&A][:speech] [1:58:09][@sahfortv][Q: In NeedsFullRebuild shouldn't DataSize not be equal?][:parsing] [1:58:20][Fix typo in the NeedsFullRebuild setting in ParseFontBlock()][:parsing] [2:00:01][Wrap it up][:speech] [/video]