/************************ * constructors */ public val_PCLT(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
public void ReadGGC(int indexGlyph, out Composite comp, DIAction dia) { this.m_validator.DIA = dia; comp = null; GConsts.TypeGlyph typeGlyph; this.ReadTypeGlyph(indexGlyph, out typeGlyph, dia); if (typeGlyph != GConsts.TypeGlyph.Composite) { return; } int offsStart, length; if (!this.m_tableLoca.GetValidateEntryGlyf(indexGlyph, out offsStart, out length, this.m_validator, this.m_font)) { return; } MBOBuffer buffer = this.m_tableGlyf.Buffer; uint offsCur = (uint)(offsStart + Table_glyf.FieldOffsets.nextAfterHeader); bool isLast = false; try { Component component; while (!isLast) { ushort flags = buffer.GetUshort(offsCur); isLast = ((flags & (ushort)Table_glyf.MaskFlagComponent.MORE_COMPONENTS) == 0); offsCur += 2; ushort indGlyphCur = buffer.GetUshort(offsCur); // TODO: save component = new Component(indGlyphCur); // TODO: validate indGlyph is in right boundaries // TODO: add Relations to FManager offsCur += 2; bool weHaveAScale = ((flags & (ushort)Table_glyf.MaskFlagComponent.WE_HAVE_A_SCALE) != 0); bool weHaveAnXAndYScale = ((flags & (ushort)Table_glyf.MaskFlagComponent.WE_HAVE_AN_X_AND_Y_SCALE) != 0); bool weHaveATwoByTwo = ((flags & (ushort)Table_glyf.MaskFlagComponent.WE_HAVE_A_TWO_BY_TWO) != 0); int cnt = 0; if (weHaveAScale) { cnt++; } if (weHaveAnXAndYScale) { cnt++; } if (weHaveATwoByTwo) { cnt++; } if (cnt > 1) { this.m_validator.Error(T.T_NULL, E.glyf_E_CompositeAmbigousTransform, (OTTag)"glyf", "Index Component: " + indGlyphCur); return; } if ((flags & (ushort)Table_glyf.MaskFlagComponent.RESERVED) != 0) { this.m_validator.Warning(T.T_NULL, W.glyf_W_CompositeReservedBit, (OTTag)"glyf", "Index Component: " + indGlyphCur); } int arg1, arg2; if ((flags & (ushort)Table_glyf.MaskFlagComponent.ARG_1_AND_2_ARE_WORDS) != 0) { arg1 = (int)buffer.GetShort(offsCur); offsCur += 2; arg2 = (int)buffer.GetShort(offsCur); offsCur += 2; } else { arg1 = (int)buffer.GetSbyte(offsCur); offsCur += 1; arg2 = (int)buffer.GetSbyte(offsCur); offsCur += 1; } // TODO: validate bounding boxes // TODO: check that NOT BOTH shift & knots are initialized, but ONE of them IS initialized // TODO: validate that indKnots (both!) are in the right boundaries // TODO: validate that a single-point contour in any glyph is used as attachment point in at least one other glyph if ((flags & (ushort)Table_glyf.MaskFlagComponent.ARGS_ARE_XY_VALUES) != 0) { component.Shift = new VecD(arg1, arg2); } else { component.IndexKnotAttGlyph = arg1; component.IndexKnotAttComponent = arg2; } // TODO: check that matrix is non-degenerated (if not null) if (weHaveAScale) { OTF2Dot14[,] m = new OTF2Dot14[2, 2]; m[0, 0] = buffer.GetF2Dot14(offsCur); /* * // for debug only - begin * if (indGlyphCur==272) * { * m[0,0]=new OTF2Dot14(30390); * } * // for debug only - end */ offsCur += 2; m[1, 1] = m[0, 0]; component.TrOTF2Dot14 = m; } else if (weHaveAnXAndYScale) { OTF2Dot14[,] m = new OTF2Dot14[2, 2]; m[0, 0] = buffer.GetF2Dot14(offsCur); offsCur += 2; m[1, 1] = buffer.GetF2Dot14(offsCur); offsCur += 2; component.TrOTF2Dot14 = m; } else if (weHaveATwoByTwo) { OTF2Dot14[,] m = new OTF2Dot14[2, 2]; m[0, 0] = buffer.GetF2Dot14(offsCur); offsCur += 2; m[0, 1] = buffer.GetF2Dot14(offsCur); offsCur += 2; m[1, 0] = buffer.GetF2Dot14(offsCur); offsCur += 2; m[1, 1] = buffer.GetF2Dot14(offsCur); offsCur += 2; component.TrOTF2Dot14 = m; } if ((flags & (ushort)Table_glyf.MaskFlagComponent.WE_HAVE_INSTRUCTIONS) != 0) { ushort numInstr = buffer.GetUshort(offsCur); offsCur += 2; if (offsCur + numInstr > buffer.GetLength()) { throw new System.IndexOutOfRangeException(); } } if (comp == null) { comp = new Composite(); } comp.AddComponent(component); } } catch (System.IndexOutOfRangeException) { this.m_validator.Error( E._GEN_E_OffsetExceedsTableLength, (OTTag)"glyf"); if (comp != null) { comp.ClearDestroy(); comp = null; } } }
/************************ * constructors */ public val_name(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
/************************ * constructors */ public val_EBSC(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
public bool Validate() { long StartTicks = DateTime.Now.Ticks; bool bRet = true; m_Validator.OnFileValidationEvent(this, true); for (uint i = 0; i < m_nFonts; i++) { // check to see if user canceled validation if (m_Validator.CancelFlag) { bRet = false; break; } m_Validator.OnFontValidationEvent(i, true); OTFontVal f = GetFont(i); if (f != null) { m_Validator.OnFontParsedEvent(f); if (!f.Validate()) { bRet = false; } } m_Validator.OnFontValidationEvent(i, false); } // build the elapsed time string int nSeconds = (int)((DateTime.Now.Ticks - StartTicks) / (double)10000000); int nHours = nSeconds / 3600; nSeconds = nSeconds - nHours * 3600; int nMins = nSeconds / 60; nSeconds = nSeconds - nMins * 60; string sTime = nHours.ToString() + ":" + nMins.ToString("d2") + ":" + nSeconds.ToString("d2"); m_Validator.Info(T.T_NULL, I._GEN_I_TotalValTime, null, sTime); //Let's try to validate the DSIG table in a TTC, if it exists if (IsCollection()) { if (m_ttch.version >= 0x00010000 && GetTableManager().GetUnaliasedTableName(m_ttch.DsigTag) == "DSIG") { MBOBuffer buf = this.ReadPaddedBuffer(m_ttch.DsigOffset, m_ttch.DsigLength); OTTable table = GetTableManager().CreateTableObject(m_ttch.DsigTag, buf); DirectoryEntry de = new DirectoryEntry(); de.tag = m_ttch.DsigTag; de.offset = m_ttch.DsigOffset; de.length = m_ttch.DsigLength; OTFontVal fontOwner = new OTFontVal(this); bRet &= ValidateTable(table, m_Validator, de, fontOwner); } else { m_Validator.Warning(T.T_NULL, W._FONT_W_MissingRecommendedTable, null, "DSIG"); } // TODO: check m_ttch.version == 0x00010000/0x00020000 } m_Validator.OnFileValidationEvent(this, false); if (m_Validator.CancelFlag) { m_Validator.ApplicationError(T.T_NULL, E._GEN_E_UserCanceled, null, ""); bRet = false; } return(bRet); }
/************************ * constructors */ public val_post(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
/****************** * protected methods */ protected static OffsetTable ReadOffsetTable(OTFileVal file, uint filepos) { // read the Offset Table from the file Validator v = file.GetValidator(); const int SIZEOF_OFFSETTABLE = 12; OffsetTable ot = null; // read the offset table MBOBuffer buf = file.ReadPaddedBuffer(filepos, SIZEOF_OFFSETTABLE); if (buf != null) { if (OTFile.IsValidSfntVersion(buf.GetUint(0))) { ot = new OffsetTable(buf); } else { v.Error(T.T_NULL, E._OFFSET_E_InvalidSFNT, null, "0x" + buf.GetUint(0).ToString("x8")); } } // now read the directory entries if (ot != null) { const int SIZEOF_DIRECTORYENTRY = 16; for (int i = 0; i < ot.numTables; i++) { uint dirFilePos = (uint)(filepos + SIZEOF_OFFSETTABLE + i * SIZEOF_DIRECTORYENTRY); MBOBuffer DirEntBuf = file.ReadPaddedBuffer(dirFilePos, SIZEOF_DIRECTORYENTRY); if (DirEntBuf != null) { DirectoryEntry de = new DirectoryEntry(); de.tag = new OTTag(DirEntBuf.GetBuffer()); de.checkSum = DirEntBuf.GetUint(4); de.offset = DirEntBuf.GetUint(8); de.length = DirEntBuf.GetUint(12); ot.DirectoryEntries.Add(de); if (de.offset > file.GetFileLength()) { v.Error(T.T_NULL, E._DE_E_OffsetPastEOF, de.tag, "0x" + de.offset.ToString("x8")); } } else { break; } } } return(ot); }
/************************ * constructor */ public ClassDefTable(uint offset, MBOBuffer bufTable) { m_offsetClassDefTable = offset; m_bufTable = bufTable; }
public MinMaxTable_val(ushort offset, MBOBuffer bufTable) : base(offset, bufTable) { }
public BaseCoordTable_val(ushort offset, MBOBuffer bufTable) : base(offset, bufTable) { }
public BaseValuesTable_val(ushort offset, MBOBuffer bufTable) : base(offset, bufTable) { }
public BaseTagListTable_val(ushort offset, MBOBuffer bufTable) : base(offset, bufTable) { }
/************************ * constructors */ public val_BASE(OTTag tag, MBOBuffer buf) : base(tag, buf) { m_DataOverlapDetector = new DataOverlapDetector(); }
/************************ * constructor */ public FeatureTable(ushort offset, MBOBuffer bufTable) { m_offsetFeatureTable = offset; m_bufTable = bufTable; }
public Table_meta(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
public SubTable(uint offset, MBOBuffer bufTable) { m_offsetSubTable = offset; m_bufTable = bufTable; }
public DataMap(uint offset, MBOBuffer bufTable) { m_offsetIndex = offset; m_bufTable = bufTable; }
/************************ * constructor */ public ScriptTable(ushort offset, MBOBuffer bufTable) { m_offsetScriptTable = offset; m_bufTable = bufTable; }
public val_SVG(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
/************************ * constructors */ public val_head(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
/************************ * constructors */ public val_VDMX(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
public val_loca(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
public LangSysTable_val(ushort offset, MBOBuffer bufTable) : base(offset, bufTable) { }
public val_glyf(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
public FeatureTable_val(ushort offset, MBOBuffer bufTable) : base(offset, bufTable) { }
/************************ * constructors */ public val_LTSH(OTTag tag, MBOBuffer buf) : base(tag, buf) { }
public LookupTable_val(ushort offset, MBOBuffer bufTable, OTTag tag) : base(offset, bufTable, tag) { }
public void ReadGGO(int indexGlyph, out Outline outl, DIAction dia) { this.m_validator.DIA = dia; outl = null; GConsts.TypeGlyph typeGlyph; this.ReadTypeGlyph(indexGlyph, out typeGlyph, dia); if (typeGlyph != GConsts.TypeGlyph.Simple) { return; } int offsStart, length; if (!this.m_tableLoca.GetValidateEntryGlyf(indexGlyph, out offsStart, out length, this.m_validator, this.m_font)) { return; } MBOBuffer buffer = this.m_tableGlyf.Buffer; int iKnot; ushort[] arrIndKnotEnd; short[] arrXRel, arrYRel; byte[] arrFlag; int numCont; try { numCont = buffer.GetShort((uint)(offsStart + (int)Table_glyf.FieldOffsets.numCont)); arrIndKnotEnd = new ushort [numCont]; for (short iCont = 0; iCont < numCont; iCont++) { arrIndKnotEnd[iCont] = buffer.GetUshort((uint)(offsStart + Table_glyf.FieldOffsets.nextAfterHeader + iCont * 2)); } int numKnot = arrIndKnotEnd[numCont - 1] + 1; uint offsInstrLength = (uint)(offsStart + Table_glyf.FieldOffsets.nextAfterHeader + 2 * numCont); ushort lengthInstr = buffer.GetUshort(offsInstrLength); uint offsInstr = offsInstrLength + 2; uint offsFlag = offsInstr + lengthInstr; arrFlag = new byte [numKnot]; iKnot = 0; // index of flag in array flags uint offsCur = offsFlag; // counter of flag in the file while (iKnot < numKnot) { byte flag = buffer.GetByte(offsCur++); arrFlag[iKnot++] = flag; bool toRepeat = ((flag & (byte)(Table_glyf.MaskFlagKnot.toRepeat)) != 0); if (toRepeat) { byte numRepeat = buffer.GetByte(offsCur++); for (byte iRepeat = 0; iRepeat < numRepeat; iRepeat++) { arrFlag[iKnot++] = flag; } } } arrXRel = new short [numKnot]; arrYRel = new short [numKnot]; // read data for x-coordinates for (iKnot = 0; iKnot < numKnot; iKnot++) { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isXByte)) != 0) { byte xRel = buffer.GetByte(offsCur++); if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isXSameOrPozitive)) != 0) { arrXRel[iKnot] = xRel; } else { arrXRel[iKnot] = (short)(-xRel); } } else { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isXSameOrPozitive)) != 0) { arrXRel[iKnot] = 0; } else { arrXRel[iKnot] = buffer.GetShort(offsCur); offsCur += 2; } } } // read data for y-coordinates for (iKnot = 0; iKnot < numKnot; iKnot++) { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isYByte)) != 0) { byte yRel = buffer.GetByte(offsCur++); if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isYSameOrPozitive)) != 0) { arrYRel[iKnot] = yRel; } else { arrYRel[iKnot] = (short)(-yRel); } } else { if ((arrFlag[iKnot] & (byte)(Table_glyf.MaskFlagKnot.isYSameOrPozitive)) != 0) { arrYRel[iKnot] = 0; } else { arrYRel[iKnot] = buffer.GetShort(offsCur); offsCur += 2; } } } if (offsCur - 2 >= offsStart + length) { throw new System.IndexOutOfRangeException(); } } catch (System.IndexOutOfRangeException) { this.m_validator.Error( E._GEN_E_OffsetExceedsTableLength, (OTTag)"glyf"); return; } try { short xAbs = 0; short yAbs = 0; int indKnotStart, indKnotEnd = -1; outl = new Outline(); for (ushort iCont = 0; iCont < numCont; iCont++) { indKnotStart = indKnotEnd + 1; indKnotEnd = arrIndKnotEnd[iCont]; Contour cont = null; cont = new Contour(); for (iKnot = indKnotStart; iKnot <= indKnotEnd; iKnot++) { xAbs += arrXRel[iKnot]; yAbs += arrYRel[iKnot]; bool isOn = ((arrFlag[iKnot] & ((byte)(Table_glyf.MaskFlagKnot.isOnCurve))) != 0); Knot knot = new Knot(iKnot, xAbs, yAbs, isOn); cont.KnotAdd(knot); } outl.ContourAdd(cont); } } catch { outl.ClearDestroy(); outl = null; } }
public CoverageTable_val(uint offset, MBOBuffer bufTable) : base(offset, bufTable) { }
/************************ * constructor */ public LangSysTable(ushort offset, MBOBuffer bufTable) { m_offsetLangSysTable = offset; m_bufTable = bufTable; }
public ScriptTable_val(ushort offset, MBOBuffer bufTable) : base(offset, bufTable) { }
/************************ * constructor */ public LookupTable(ushort offset, MBOBuffer bufTable, OTTag tag) { m_offsetLookupTable = offset; m_bufTable = bufTable; m_tag = tag; }
public ClassDefFormat2_val(uint offset, MBOBuffer bufTable) : base(offset, bufTable) { }
/************************ * constructor */ public CoverageTable(uint offset, MBOBuffer bufTable) { m_offsetCoverageTable = offset; m_bufTable = bufTable; }
public DeviceTable_val(uint offset, MBOBuffer bufTable) : base(offset, bufTable) { }
public ClassDefFormat2(uint offset, MBOBuffer bufTable) { m_offsetClassDefFormat2 = offset; m_bufTable = bufTable; }
static int Main(string[] args) { if (args.Length == 0) { Console.WriteLine("DSIGInfo [-v] [-v] [-v] fontfile"); return(0); } OTFile f = new OTFile(); Table_DSIG tDSIG = null; string filename = null; verbose = 0; for (int i = 0; i < args.Length; i++) { if ("-v" == args[i]) { verbose++; } else { filename = args[i]; } } if (!f.open(filename)) { Console.WriteLine("Error: Cannot open {0} as font file", filename); return(0); } TTCHeader ttc = null; if (f.IsCollection()) { ttc = f.GetTTCHeader(); if (f.GetTableManager().GetUnaliasedTableName(ttc.DsigTag) == "DSIG") { MBOBuffer buf = f.ReadPaddedBuffer(ttc.DsigOffset, ttc.DsigLength); tDSIG = (Table_DSIG)f.GetTableManager().CreateTableObject(ttc.DsigTag, buf); } for (uint i = 0; i < f.GetNumFonts(); i++) { OTFont fn = f.GetFont(i); Table_DSIG memDSIG = (Table_DSIG)fn.GetTable("DSIG"); if (memDSIG != null) { Console.WriteLine("Warning: DSIG in member font"); break; } } } else { OTFont fn = f.GetFont(0); tDSIG = (Table_DSIG)fn.GetTable("DSIG"); } Console.WriteLine("{0} DSIG table: {1}", filename, (tDSIG == null) ? "Absent" : "Present"); if (tDSIG == null) { return(0); } if (f.IsCollection() && ttc.version != 0x00020000) { Console.WriteLine("Warning: TTC has DSIG but header version is 0x{0}, != 0x00020000", ttc.version.ToString("X8")); } if (tDSIG.usNumSigs != 1) { Console.WriteLine("NumSigs = {0}", tDSIG.usNumSigs); } for (uint v = 0; v < tDSIG.usNumSigs; v++) { Table_DSIG.SignatureBlock sgb; try { sgb = tDSIG.GetSignatureBlock(v); } catch (IndexOutOfRangeException) { Console.WriteLine("Error: Out of Range SignatureBlock {0}", v); break; } SignedCms cms = new SignedCms(); try { cms.Decode(sgb.bSignature); } catch (Exception e) { if (e is NullReferenceException || /* Mono */ e is CryptographicException /* .Net2 */) { Console.WriteLine("Error: Malformed Signature"); break; } Console.WriteLine("Error: Malformed Signature (Unexpected Case 1)"); throw; } if (cms.SignerInfos.Count > 1) { Console.WriteLine("#SignerInfos: {0}", cms.SignerInfos.Count); } foreach (var si in cms.SignerInfos) { Console.WriteLine(si.Certificate); if (Type.GetType("Mono.Runtime") == null) { foreach (var ua in si.UnsignedAttributes) { foreach (var asnd in ua.Values) { try { ASN1 vv = new ASN1(asnd.RawData); ASN1 t = new ASN1(vv[3][1][1].Value); Console.WriteLine("Decoded Signing Time: {0}", ASN1Convert.ToDateTime(t)); } catch (Exception) { /* Nothing to do */ } } } } } Console.WriteLine("#Certificates: {0}", cms.Certificates.Count); #if HAVE_MONO_X509 certs = new Mono.Security.X509.X509CertificateCollection(); //Mono.Security.X509.X509Chain signerChain = new Mono.Security.X509.X509Chain (); #endif foreach (var x509 in cms.Certificates) { #if HAVE_MONO_X509 certs.Add(new Mono.Security.X509.X509Certificate(x509.RawData)); #endif if (verbose > 0) { Console.WriteLine(x509); } else { Console.WriteLine(x509.Subject); } } ; #if HAVE_MONO_X509 Mono.Security.X509.X509Certificate x = new Mono.Security.X509.X509Certificate(cms.SignerInfos[0].Certificate.RawData); Mono.Security.X509.X509Certificate parent = x; while (x != null) // Self-signed is fine - the font bundled CA is self-signed. { parent = x; // last valid x = FindCertificateParent(x); if (x != null && x.Equals(parent)) { break; } } #endif // Windows 10/.net 4.6.x throws here ASN1 spc; try { spc = new ASN1(cms.ContentInfo.Content); } catch (Exception e) { if (e is IndexOutOfRangeException) { Console.WriteLine("Error: Malformed Signature (Win10/.net 4.6.x)"); break; } Console.WriteLine("Error: Malformed Signature (Unexpected Case 2)"); throw; } ASN1 playload_oid = null; ASN1 oid = null; ASN1 digest = null; ASN1 obsolete = null; if (Type.GetType("Mono.Runtime") == null) { // DotNet is much saner! playload_oid = spc[0][0]; obsolete = spc[0][1][0]; oid = spc[1][0][0]; digest = spc[1][1]; } else { playload_oid = spc[0]; obsolete = spc[1][0]; oid = spc[2][0][0]; digest = spc[2][1]; } string algo = ASN1Convert.ToOid(oid); string algoname = (new Oid(algo)).FriendlyName; Console.WriteLine("Digest Algorithm: {0}", algoname); byte[] Value = digest.Value; StringBuilder hexLine_sig = new StringBuilder(); for (int i = 0; i < Value.Length; i++) { hexLine_sig.AppendFormat("{0} ", Value [i].ToString("X2")); } hexLine_sig.AppendFormat(Environment.NewLine); switch (algoname) { case "md5": hash = HashAlgorithm.Create("MD5"); break; case "sha1": hash = HashAlgorithm.Create("SHA1"); break; default: throw new NotImplementedException("Unknown HashAlgorithm: " + algoname); } byte[] cdigest; if (f.IsCollection()) { cdigest = get_TTC_digest(f); } else { cdigest = get_TTF_digest(f); } StringBuilder hexLine = new StringBuilder(); for (int i = 0; i < cdigest.Length; i++) { hexLine.AppendFormat("{0} ", cdigest [i].ToString("X2")); } hexLine.AppendFormat(Environment.NewLine); Console.WriteLine("{0} Signed Digest:\t{1}", algoname.ToUpper(), hexLine_sig); Console.WriteLine("Calculated Digest:\t{0}", hexLine); string root_thumb = ""; #if HAVE_MONO_X509 root_thumb = (new System.Security.Cryptography.X509Certificates.X509Certificate2(parent.RawData)).Thumbprint; Console.WriteLine("ChainEnd Name: {0}", parent.SubjectName); Console.WriteLine("ChainEnd Self-Signed: {0}", parent.IsSelfSigned); #endif Console.WriteLine("ChainEnd: {0}", root_thumb); bool trusted = false; try { string root_id = trusted_roots[root_thumb]; Console.WriteLine("RootID: {0}", root_id); trusted = true; } catch (KeyNotFoundException) {} Console.WriteLine("Trusted: {0}", trusted); } return(0); }
public DeviceTable(uint offset, MBOBuffer bufTable) { m_offsetDeviceTable = offset; m_bufTable = bufTable; }
/************************ * public methods */ public override OTTable CreateTableObject(OTTag tag, MBOBuffer buf) { OTTable table = null; string sName = GetUnaliasedTableName(tag); switch (sName) { case "BASE": table = new val_BASE(tag, buf); break; case "CFF ": table = new val_CFF(tag, buf); break; case "cmap": table = new val_cmap(tag, buf); break; case "cvt ": table = new val_cvt(tag, buf); break; case "DSIG": table = new val_DSIG(tag, buf); break; case "EBDT": table = new val_EBDT(tag, buf); break; case "EBLC": table = new val_EBLC(tag, buf); break; case "EBSC": table = new val_EBSC(tag, buf); break; case "fpgm": table = new val_fpgm(tag, buf); break; case "gasp": table = new val_gasp(tag, buf); break; case "GDEF": table = new val_GDEF(tag, buf); break; case "glyf": table = new val_glyf(tag, buf); break; case "GPOS": table = new val_GPOS(tag, buf); break; case "GSUB": table = new val_GSUB(tag, buf); break; case "hdmx": table = new val_hdmx(tag, buf); break; case "head": table = new val_head(tag, buf); break; case "hhea": table = new val_hhea(tag, buf); break; case "hmtx": table = new val_hmtx(tag, buf); break; case "JSTF": table = new val_JSTF(tag, buf); break; case "kern": table = new val_kern(tag, buf); break; case "loca": table = new val_loca(tag, buf); break; case "LTSH": table = new val_LTSH(tag, buf); break; case "maxp": table = new val_maxp(tag, buf); break; case "name": table = new val_name(tag, buf); break; case "OS/2": table = new val_OS2(tag, buf); break; case "PCLT": table = new val_PCLT(tag, buf); break; case "post": table = new val_post(tag, buf); break; case "prep": table = new val_prep(tag, buf); break; case "SVG ": table = new val_SVG(tag, buf); break; case "VDMX": table = new val_VDMX(tag, buf); break; case "vhea": table = new val_vhea(tag, buf); break; case "vmtx": table = new val_vmtx(tag, buf); break; case "VORG": table = new val_VORG(tag, buf); break; //case "Zapf": table = new val_Zapf(tag, buf); break; default: table = new val__Unknown(tag, buf); break; } return(table); }