internal bool ReadTableEntryCollection(Typeface typeface, RestoreTicket ticket, TableEntryCollection tables, BinaryReader input) { if (ticket != null) { return(ReadTableEntryCollectionOnRestoreMode(typeface, ticket, tables, input)); } typeface.SetTableEntryCollection(tables.CloneTableHeaders()); var rd = new EntriesReaderHelper(tables, input); //PART 1: basic information OS2Table os2Table = rd.Read(new OS2Table()); Meta meta = rd.Read(new Meta()); NameEntry nameEntry = rd.Read(new NameEntry()); Head head = rd.Read(new Head()); MaxProfile maxProfile = rd.Read(new MaxProfile()); HorizontalHeader horizontalHeader = rd.Read(new HorizontalHeader()); HorizontalMetrics horizontalMetrics = rd.Read(new HorizontalMetrics(horizontalHeader.NumberOfHMetrics, maxProfile.GlyphCount)); VerticalHeader vhea = rd.Read(new VerticalHeader()); if (vhea != null) { VerticalMetrics vmtx = rd.Read(new VerticalMetrics(vhea.NumOfLongVerMetrics)); } Cmap cmaps = rd.Read(new Cmap()); VerticalDeviceMetrics vdmx = rd.Read(new VerticalDeviceMetrics()); Kern kern = rd.Read(new Kern()); //------------------------------------ //PART 2: glyphs detail //2.1 True type font GlyphLocations glyphLocations = rd.Read(new GlyphLocations(maxProfile.GlyphCount, head.WideGlyphLocations)); Glyf glyf = rd.Read(new Glyf(glyphLocations)); Gasp gaspTable = rd.Read(new Gasp()); COLR colr = rd.Read(new COLR()); CPAL cpal = rd.Read(new CPAL()); //2.2 Cff font PostTable postTable = rd.Read(new PostTable()); CFFTable cff = rd.Read(new CFFTable()); //additional math table (if available) MathTable mathtable = rd.Read(new MathTable()); //------------------------------------ //PART 3: advanced typography GDEF gdef = rd.Read(new GDEF()); GSUB gsub = rd.Read(new GSUB()); GPOS gpos = rd.Read(new GPOS()); BASE baseTable = rd.Read(new BASE()); JSTF jstf = rd.Read(new JSTF()); STAT stat = rd.Read(new STAT()); if (stat != null) { //variable font FVar fvar = rd.Read(new FVar()); if (fvar != null) { GVar gvar = rd.Read(new GVar()); CVar cvar = rd.Read(new CVar()); HVar hvar = rd.Read(new HVar()); MVar mvar = rd.Read(new MVar()); AVar avar = rd.Read(new AVar()); } } bool isPostScriptOutline = false; bool isBitmapFont = false; typeface.SetBasicTypefaceTables(os2Table, nameEntry, head, horizontalMetrics); if (glyf == null) { //check if this is cff table ? if (cff == null) { //check cbdt/cblc ? CBLC cblcTable = rd.Read(new CBLC()); if (cblcTable != null) { CBDT cbdtTable = rd.Read(new CBDT()); //read cbdt //bitmap font BitmapFontGlyphSource bmpFontGlyphSrc = new BitmapFontGlyphSource(cblcTable); bmpFontGlyphSrc.LoadCBDT(cbdtTable); Glyph[] glyphs = bmpFontGlyphSrc.BuildGlyphList(); typeface.SetBitmapGlyphs(glyphs, bmpFontGlyphSrc); isBitmapFont = true; } else { //TODO: EBLC fontBmpTable = rd.Read(new EBLC()); throw new NotSupportedException(); } } else { isPostScriptOutline = true; typeface.SetCffFontSet(cff.Cff1FontSet); } } else { typeface.SetTtfGlyphs(glyf.Glyphs); } //---------------------------- typeface.CmapTable = cmaps; typeface.KernTable = kern; typeface.MaxProfile = maxProfile; typeface.HheaTable = horizontalHeader; //---------------------------- typeface.GaspTable = gaspTable; if (!isPostScriptOutline && !isBitmapFont) { //for true-type font outline FpgmTable fpgmTable = rd.Read(new FpgmTable()); //control values table CvtTable cvtTable = rd.Read(new CvtTable()); PrepTable propProgramTable = rd.Read(new PrepTable()); typeface.ControlValues = cvtTable?._controlValues; typeface.FpgmProgramBuffer = fpgmTable?._programBuffer; typeface.PrepProgramBuffer = propProgramTable?._programBuffer; } //------------------------- typeface.LoadOpenFontLayoutInfo( gdef, gsub, gpos, baseTable, colr, cpal); //------------ typeface.SetSvgTable(rd.Read(new SvgTable())); typeface.PostTable = postTable; if (mathtable != null) { MathGlyphLoader.LoadMathGlyph(typeface, mathtable); } #if DEBUG //test //int found = typeface.GetGlyphIndexByName("Uacute"); if (typeface.IsCffFont) { //optional typeface.UpdateAllCffGlyphBounds(); } #endif typeface.UpdateLangs(meta); typeface.UpdateFrequentlyUsedValues(); return(true); }
bool ReadTableEntryCollectionOnRestoreMode(Typeface typeface, RestoreTicket ticket, TableEntryCollection tables, BinaryReader input) { //RESTORE MODE //check header matches if (!typeface.IsTrimmed() || !typeface.CompareOriginalHeadersWithNewlyLoadOne(tables.CloneTableHeaders())) { return(false); } var rd = new EntriesReaderHelper(tables, input); //PART 1: basic information //.. //------------------------------------ //PART 2: glyphs detail //2.1 True type font GlyphLocations glyphLocations = ticket.HasTtf ? rd.Read(new GlyphLocations(typeface.MaxProfile.GlyphCount, typeface.Head.WideGlyphLocations)) : null; Glyf glyf = ticket.HasTtf ? rd.Read(new Glyf(glyphLocations)) : null; typeface.GaspTable = ticket.GaspTable ? rd.Read(new Gasp()) : null; typeface.SetColorAndPalTable( ticket.COLRTable ? rd.Read(new COLR()) : null, ticket.CPALTable ? rd.Read(new CPAL()) : null); //2.2 Cff font CFFTable cff = ticket.HasCff ? rd.Read(new CFFTable()) : null; bool isPostScriptOutline = false; bool isBitmapFont = false; if (glyf == null) { //check if this is cff table ? if (cff == null) { //check cbdt/cblc ? if (ticket.HasBitmapSource) { //reload only CBDT (embeded bitmap) CBDT cbdt = rd.Read(new CBDT()); typeface._bitmapFontGlyphSource.LoadCBDT(cbdt); //just clone existing glyph isBitmapFont = true; } else { //? throw new NotSupportedException(); } } else { isPostScriptOutline = true; typeface.SetCffFontSet(cff.Cff1FontSet); } } else { typeface.SetTtfGlyphs(glyf.Glyphs); } if (!isPostScriptOutline && !isBitmapFont) { //for true-type font outline FpgmTable fpgmTable = rd.Read(new FpgmTable()); //control values table CvtTable cvtTable = rd.Read(new CvtTable()); PrepTable propProgramTable = rd.Read(new PrepTable()); typeface.ControlValues = cvtTable?._controlValues; typeface.FpgmProgramBuffer = fpgmTable?._programBuffer; typeface.PrepProgramBuffer = propProgramTable?._programBuffer; } if (ticket.HasSvg) { typeface.SetSvgTable(rd.Read(new SvgTable())); } #if DEBUG //test //int found = typeface.GetGlyphIndexByName("Uacute"); if (typeface.IsCffFont) { //optional??? typeface.UpdateAllCffGlyphBounds(); } #endif typeface._typefaceTrimMode = TrimMode.Restored; return(true); }