public static TTFStringMeasurer Create(TrueTypeFile forfont, CMapEncoding encoding, TypeMeasureOptions options) { HorizontalMetrics table = forfont.Directories["hmtx"].Table as HorizontalMetrics; CMAPTable cmap = forfont.Directories["cmap"].Table as CMAPTable; OS2Table os2 = forfont.Directories["OS/2"].Table as OS2Table; FontHeader head = forfont.Directories["head"].Table as FontHeader; HorizontalHeader hhead = forfont.Directories["hhea"].Table as HorizontalHeader; CMAPSubTable map = cmap.GetOffsetTable(encoding); if (map == null) { encoding = CMapEncoding.Unicode_20; map = cmap.GetOffsetTable(CMapEncoding.Unicode_20); } if (map == null) { encoding = CMapEncoding.MacRoman; map = cmap.GetOffsetTable(CMapEncoding.MacRoman); } return(new TTFStringMeasurer(head.UnitsPerEm, map, os2, hhead, table.HMetrics, forfont, encoding, options)); }
private static FontStyle ConvertStyle(OS2Table os2, HeadTable head) { FontStyle style = FontStyle.Regular; if (os2 != null) { if (os2.FontStyle.HasFlag(OS2Table.FontStyleSelection.BOLD)) { style |= FontStyle.Bold; } if (os2.FontStyle.HasFlag(OS2Table.FontStyleSelection.ITALIC)) { style |= FontStyle.Italic; } } else if (head != null) { if (head.MacStyle.HasFlag(HeadTable.HeadMacStyle.Bold)) { style |= FontStyle.Bold; } if (head.MacStyle.HasFlag(HeadTable.HeadMacStyle.Italic)) { style |= FontStyle.Italic; } } return(style); }
internal FakeFontInstance( NameTable nameTable, MaximumProfileTable maxpTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalHeadTable horizontalHeadTable, HorizontalMetricsTable horizontalMetrics, VerticalHeadTable verticalHeadTable, VerticalMetricsTable verticalMetrics, HeadTable head, KerningTable kern) : base( nameTable, maxpTable, cmap, glyphs, os2, horizontalHeadTable, horizontalMetrics, verticalHeadTable, verticalMetrics, head, kern, null, null, null, null, null, null, null, null) { }
/// <summary> /// read only name entry /// </summary> /// <param name="stream"></param> /// <returns></returns> public PreviewFontInfo ReadPreview(Stream stream) { var little = BitConverter.IsLittleEndian; using (var input = new ByteOrderSwappingBinaryReader(stream)) { ushort majorVersion = input.ReadUInt16(); ushort minorVersion = input.ReadUInt16(); ushort tableCount = input.ReadUInt16(); ushort searchRange = input.ReadUInt16(); ushort entrySelector = input.ReadUInt16(); ushort rangeShift = input.ReadUInt16(); var tables = new TableEntryCollection(); for (int i = 0; i < tableCount; i++) { tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input))); } NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); return(new PreviewFontInfo( nameEntry.FontName, nameEntry.FontSubFamily, Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table) )); } }
internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input) { var rd = new EntriesReaderHelper(tables, input); NameEntry nameEntry = rd.Read(new NameEntry()); OS2Table os2Table = rd.Read(new OS2Table()); //for preview, read ONLY script list from gsub and gpos (set OnlyScriptList). Meta metaTable = rd.Read(new Meta()); GSUB gsub = rd.Read(new GSUB() { OnlyScriptList = true }); GPOS gpos = rd.Read(new GPOS() { OnlyScriptList = true }); Cmap cmap = rd.Read(new Cmap()); //gsub and gpos contains actual script_list that are in the typeface Languages langs = new Languages(); langs.Update(os2Table, metaTable, cmap, gsub, gpos); return(new PreviewFontInfo( nameEntry, os2Table, langs)); }
private void EnsureOS2Table() { if (os2 == null) { os2 = (OS2Table)GetTable(TableNames.Os2); } }
internal static FontInstance LoadFont(FontReader reader) { // https://www.microsoft.com/typography/otspec/recom.htm#TableOrdering // recomended order HeadTable head = reader.GetTable <HeadTable>(); // head - not saving but loading in suggested order reader.GetTable <HoizontalHeadTable>(); // hhea reader.GetTable <MaximumProfileTable>(); // maxp OS2Table os2 = reader.GetTable <OS2Table>(); // OS/2 HorizontalMetricsTable horizontalMetrics = reader.GetTable <HorizontalMetricsTable>(); // hmtx // LTSH - Linear threshold data // VDMX - Vertical device metrics // hdmx - Horizontal device metrics CMapTable cmap = reader.GetTable <CMapTable>(); // cmap // fpgm - Font Program // prep - Control Value Program // cvt - Control Value Table reader.GetTable <IndexLocationTable>(); // loca GlyphTable glyphs = reader.GetTable <GlyphTable>(); // glyf KerningTable kern = reader.GetTable <KerningTable>(); // kern - Kerning NameTable nameTable = reader.GetTable <NameTable>(); // name // post - PostScript information // gasp - Grid-fitting/Scan-conversion (optional table) // PCLT - PCL 5 data // DSIG - Digital signature return(new FontInstance(nameTable, cmap, glyphs, os2, horizontalMetrics, head, kern)); }
protected double GetLineHeight(FontUnitType units, OS2Table os2, HorizontalHeader hhead, FontHeader header, double emsize) { double h; bool useTypo; if (units == FontUnitType.UseFontPreference) { useTypo = (os2.Version >= OS2TableVersion.OpenType15) && ((os2.Selection & FontSelection.UseTypographicSizes) > 0); } else if (units == FontUnitType.UseHeadMetrics) { useTypo = false; } else if (null == os2) { useTypo = false; } else { useTypo = true; } if (useTypo) { h = ((double)(os2.TypoAscender - os2.TypoDescender + os2.TypoLineGap) / ((double)header.UnitsPerEm) * emsize); } else { h = ((double)(hhead.Ascender - hhead.Descender + hhead.LineGap) / ((double)header.UnitsPerEm) * emsize); } return(h); }
/// <summary> /// Reads a <see cref="FontDescription" /> from the specified stream. /// </summary> /// <param name="reader">The reader.</param> /// <returns> /// a <see cref="FontDescription" />. /// </returns> internal static FontDescription LoadDescription(FontReader reader) { HeadTable head = reader.GetTable <HeadTable>(); OS2Table os2 = reader.GetTable <OS2Table>(); NameTable nameTable = reader.GetTable <NameTable>(); return(new FontDescription(nameTable, os2, head)); }
/// <summary> /// Reads a <see cref="FontDescription" /> from the specified stream. /// </summary> /// <param name="reader">The reader.</param> /// <returns> /// a <see cref="FontDescription" />. /// </returns> internal static FontDescription LoadDescription(FontReader reader) { // NOTE: These fields are read in their optimized order // https://docs.microsoft.com/en-gb/typography/opentype/spec/recom#optimized-table-ordering HeadTable head = reader.GetTable <HeadTable>(); OS2Table os2 = reader.GetTable <OS2Table>(); NameTable nameTable = reader.GetTable <NameTable>(); return(new FontDescription(nameTable, os2, head)); }
private InstalledTypeface(NameEntry nameTable, OS2Table os2Table, Languages languages, string fontPath) { _nameEntry = nameTable; _os2Table = os2Table; FontPath = fontPath; Languages = languages; var fsSelection = new OS2FsSelection(os2Table.fsSelection); TypefaceStyle = fsSelection.IsItalic ? TypefaceStyle.Italic : TypefaceStyle.Regular; }
public void ShouldReturnNullWhenTableCouldNotBeFound() { var writer = new BigEndianBinaryWriter(); writer.WriteTrueTypeFileHeader(); using (System.IO.MemoryStream stream = writer.GetStream()) { Assert.Null(OS2Table.Load(new FontReader(stream))); } }
internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input) { NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); return(new PreviewFontInfo( nameEntry.TypographicFamilyName ?? nameEntry.FontName, nameEntry.TypographyicSubfamilyName ?? nameEntry.FontSubFamily, os2Table.usWeightClass, Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table))); }
internal void SetBasicTypefaceTables(OS2Table os2Table, NameEntry nameEntry, Head head, HorizontalMetrics horizontalMetrics) { OS2Table = os2Table; _nameEntry = nameEntry; Head = head; Bounds = head.Bounds; UnitsPerEm = head.UnitsPerEm; _hMetrics = horizontalMetrics; }
internal FakeFontInstance( NameTable nameTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalHeadTable horizontalHeadTable, HorizontalMetricsTable horizontalMetrics, HeadTable head, KerningTable kern) : base(nameTable, cmap, glyphs, os2, horizontalHeadTable, horizontalMetrics, head, kern, null, null) { }
public OS2Table(OS2Table versionLessthan5Table, ushort lowerOpticalPointSize, ushort upperOpticalPointSize) : this(versionLessthan5Table, versionLessthan5Table.codePageRange1, versionLessthan5Table.codePageRange2, versionLessthan5Table.heightX, versionLessthan5Table.capHeight, versionLessthan5Table.defaultChar, versionLessthan5Table.breakChar, versionLessthan5Table.maxContext) { this.lowerOpticalPointSize = lowerOpticalPointSize; this.upperOpticalPointSize = upperOpticalPointSize; }
private TTFStringMeasurer(int unitsPerEm, CMAPSubTable offsets, OS2Table oS2, HorizontalHeader hheader, List <HMetric> metrics, TrueTypeFile font, CMapEncoding encoding, TypeMeasureOptions options) { this._unitsPerEm = unitsPerEm; this._offsets = offsets; this._os2 = oS2; this._metrics = metrics; this._lookup = new Dictionary <char, HMetric>(); this._options = options; this._fontUseTypo = (oS2.Version >= OS2TableVersion.OpenType15) && ((oS2.Selection & FontSelection.UseTypographicSizes) > 0); this._hheader = hheader; this._fontfile = font; this._cMapEncoding = encoding; }
internal PreviewFontInfo( NameEntry nameEntry, OS2Table os2Table, Languages langs) { NameEntry = nameEntry; OS2Table = os2Table; Languages = langs; Name = nameEntry.FontName; SubFamilyName = nameEntry.FontSubFamily; OS2TranslatedStyle = Extensions.TypefaceExtensions.TranslateOS2FontStyle(os2Table); OS2FsSelection = Extensions.TypefaceExtensions.TranslateOS2FsSelection(os2Table); }
internal Typeface( NameEntry nameEntry, Bounds bounds, ushort unitsPerEm, Glyph[] glyphs, HorizontalMetrics horizontalMetrics, OS2Table os2Table) { _nameEntry = nameEntry; _bounds = bounds; _unitsPerEm = unitsPerEm; _glyphs = glyphs; _horizontalMetrics = horizontalMetrics; OS2Table = os2Table; }
/// <summary> /// Initializes a new instance of the <see cref="FontDescription" /> class. /// </summary> /// <param name="nameTable">The name table.</param> /// <param name="cmap">The cmap.</param> /// <param name="glyphs">The glyphs.</param> /// <param name="os2">The os2.</param> /// <param name="horizontalMetrics">The horizontal metrics.</param> /// <param name="head">The head.</param> /// <param name="kern">The kern.</param> internal FontInstance(NameTable nameTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalMetricsTable horizontalMetrics, HeadTable head, KerningTable kern) { this.cmap = cmap; this.os2 = os2; this.glyphs = glyphs; this.horizontalMetrics = horizontalMetrics; this.head = head; this.glyphCache = new GlyphInstance[this.glyphs.GlyphCount]; // https://www.microsoft.com/typography/otspec/recom.htm#tad this.LineHeight = os2.TypoAscender - os2.TypoDescender + os2.TypoLineGap; this.EmSize = this.head.UnitsPerEm; this.kerning = kern; this.Description = new FontDescription(nameTable, os2, head); }
internal Typeface( NameEntry nameEntry, Bounds bounds, ushort unitsPerEm, CFFTable cffTable, HorizontalMetrics horizontalMetrics, OS2Table os2Table) { _nameEntry = nameEntry; _bounds = bounds; _unitsPerEm = unitsPerEm; _cffTable = cffTable; _horizontalMetrics = horizontalMetrics; OS2Table = os2Table; //------ _glyphs = _cffTable.Cff1FontSet._fonts[0]._glyphs; }
internal static TranslatedOS2FontStyle TranslatedOS2FontStyle(OS2Table os2Table) { //@prepare's note, please note:=> this is not real value, this is 'translated' value from OS2.fsSelection //https://www.microsoft.com/typography/otspec/os2.htm //Bit # macStyle bit C definition Description //0 bit 1 ITALIC Font contains italic or oblique characters, otherwise they are upright. //1 UNDERSCORE Characters are underscored. //2 NEGATIVE Characters have their foreground and background reversed. //3 OUTLINED Outline(hollow) characters, otherwise they are solid. //4 STRIKEOUT Characters are overstruck. //5 bit 0 BOLD Characters are emboldened. //6 REGULAR Characters are in the standard weight / style for the font. //7 USE_TYPO_METRICS If set, it is strongly recommended to use OS / 2.sTypoAscender - OS / 2.sTypoDescender + OS / 2.sTypoLineGap as a value for default line spacing for this font. //8 WWS The font has ‘name’ table strings consistent with a weight / width / slope family without requiring use of ‘name’ IDs 21 and 22. (Please see more detailed description below.) //9 OBLIQUE Font contains oblique characters. //10–15 < reserved > Reserved; set to 0. ushort fsSelection = os2Table.fsSelection; TranslatedOS2FontStyle result = Extensions.TranslatedOS2FontStyle.UNSET; if ((fsSelection & 0x1) != 0) { result |= Extensions.TranslatedOS2FontStyle.ITALIC; } if (((fsSelection >> 5) & 0x1) != 0) { result |= Extensions.TranslatedOS2FontStyle.BOLD; } if (((fsSelection >> 6) & 0x1) != 0) { result |= Extensions.TranslatedOS2FontStyle.REGULAR; } if (((fsSelection >> 9) & 0x1) != 0) { result |= Extensions.TranslatedOS2FontStyle.OBLIQUE; } return(result); }
public OS2Table(OS2Table version0Table, ushort codePageRange1, ushort codePageRange2, short heightX, short capHeight, ushort defaultChar, ushort breakChar, ushort maxContext) : this( version0Table.averageCharWidth, version0Table.weightClass, version0Table.widthClass, version0Table.styleType, version0Table.subscriptXSize, version0Table.subscriptYSize, version0Table.subscriptXOffset, version0Table.subscriptYOffset, version0Table.superscriptXSize, version0Table.superscriptYSize, version0Table.superscriptXOffset, version0Table.superscriptYOffset, version0Table.strikeoutSize, version0Table.strikeoutPosition, version0Table.familyClass, version0Table.panose, version0Table.unicodeRange1, version0Table.unicodeRange2, version0Table.unicodeRange3, version0Table.unicodeRange4, version0Table.tag, version0Table.FontStyle, version0Table.firstCharIndex, version0Table.lastCharIndex, version0Table.TypoAscender, version0Table.TypoDescender, version0Table.TypoLineGap, version0Table.winAscent, version0Table.winDescent) { this.codePageRange1 = codePageRange1; this.codePageRange2 = codePageRange2; this.heightX = heightX; this.capHeight = capHeight; this.defaultChar = defaultChar; this.breakChar = breakChar; this.maxContext = maxContext; }
internal Typeface( NameEntry nameEntry, Bounds bounds, ushort unitsPerEm, Glyph[] glyphs, CharacterMap[] cmaps, HorizontalMetrics horizontalMetrics, OS2Table os2Table) { _nameEntry = nameEntry; _bounds = bounds; _unitsPerEm = unitsPerEm; _glyphs = glyphs; _cmaps = cmaps; _horizontalMetrics = horizontalMetrics; OS2Table = os2Table; //--------------------------------------------------- //cmap - Character To Glyph Index Mapping Table //--------------------------------------------------- //This table defines the mapping of character codes to the glyph index values used in the font. It may contain more than one subtable, in order to support more than one character encoding scheme.Character codes that do not correspond to any glyph in the font should be mapped to glyph index 0.The glyph at this location must be a special glyph representing a missing character, commonly known as .notdef. //The table header indicates the character encodings for which subtables are present.Each subtable is in one of seven possible formats and begins with a format code indicating the format used. //The platform ID and platform - specific encoding ID in the header entry(and, in the case of the Macintosh platform, the language field in the subtable itself) are used to specify a particular 'cmap' encoding.The header entries must be sorted first by platform ID, then by platform - specific encoding ID, and then by the language field in the corresponding subtable.Each platform ID, platform - specific encoding ID, and subtable language combination may appear only once in the 'cmap' table. //When building a Unicode font for Windows, the platform ID should be 3 and the encoding ID should be 1.When building a symbol font for Windows, the platform ID should be 3 and the encoding ID should be 0.When building a font that will be used on the Macintosh, the platform ID should be 1 and the encoding ID should be 0. //All Microsoft Unicode BMP encodings(Platform ID = 3, Encoding ID = 1) must provide at least a Format 4 'cmap' subtable.If the font is meant to support supplementary(non - BMP) Unicode characters, it will additionally need a Format 12 subtable with a platform encoding ID 10.The contents of the Format 12 subtable need to be a superset of the contents of the Format 4 subtable.Microsoft strongly recommends using a BMP Unicode 'cmap' for all fonts. However, some other encodings that appear in current fonts follow: //Windows Encodings //Platform ID Encoding ID Description //3 0 Symbol //3 1 Unicode BMP(UCS - 2) //3 2 ShiftJIS //3 3 PRC //3 4 Big5 //3 5 Wansung //3 6 Johab //3 7 Reserved //3 8 Reserved //3 9 Reserved //3 10 Unicode UCS - 4 //--------------------------------------------------- }
internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input) { NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); return(new PreviewFontInfo( nameEntry.FontName, nameEntry.FontSubFamily, nameEntry.TypographicFamilyName, nameEntry.TypographyicSubfamilyName, os2Table.usWeightClass, Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table)) { PostScriptName = nameEntry.PostScriptName, UniqueFontIden = nameEntry.UniqueFontIden, VersionString = nameEntry.VersionString, UnicodeRange1 = os2Table.ulUnicodeRange1, UnicodeRange2 = os2Table.ulUnicodeRange2, UnicodeRange3 = os2Table.ulUnicodeRange3, UnicodeRange4 = os2Table.ulUnicodeRange4, }); }
internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input) { var rd = new EntriesReaderHelper(tables, input); NameEntry nameEntry = rd.Read(new NameEntry()); OS2Table os2Table = rd.Read(new OS2Table()); //for preview, read ONLY script list from gsub and gpos (set OnlyScriptList). Meta metaTable = rd.Read(new Meta()); GSUB gsub = rd.Read(new GSUB() { OnlyScriptList = true }); GPOS gpos = rd.Read(new GPOS() { OnlyScriptList = true }); //gsub and gpos contains actual script_list that are in the typeface Languages langs = new Languages(); langs.Update(os2Table, metaTable, gsub, gpos); return(new PreviewFontInfo( nameEntry.FontName, nameEntry.FontSubFamily, nameEntry.TypographicFamilyName, nameEntry.TypographyicSubfamilyName, os2Table.usWeightClass, langs, Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table)) { PostScriptName = nameEntry.PostScriptName, UniqueFontIden = nameEntry.UniqueFontIden, VersionString = nameEntry.VersionString }); }
/// <summary> /// Initializes a new instance of the <see cref="FontInstance"/> class. /// </summary> /// <param name="nameTable">The name table.</param> /// <param name="cmap">The cmap.</param> /// <param name="glyphs">The glyphs.</param> /// <param name="os2">The os2.</param> /// <param name="horizontalHeadTable">The horizontal head table.</param> /// <param name="horizontalMetrics">The horizontal metrics.</param> /// <param name="head">The head.</param> /// <param name="kern">The kern.</param> /// <param name="colrTable">The COLR table</param> /// <param name="cpalTable">The CPAL table</param> internal FontInstance( NameTable nameTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalHeadTable horizontalHeadTable, HorizontalMetricsTable horizontalMetrics, HeadTable head, KerningTable kern, ColrTable?colrTable, CpalTable?cpalTable) { this.cmap = cmap; this.os2 = os2; this.glyphs = glyphs; this.horizontalMetrics = horizontalMetrics; this.head = head; this.glyphCache = new GlyphInstance[this.glyphs.GlyphCount]; if (!(colrTable is null)) { this.colorGlyphCache = new GlyphInstance[this.glyphs.GlyphCount][]; } bool useTypoMetrics = os2.FontStyle.HasFlag(OS2Table.FontStyleSelection.USE_TYPO_METRICS); // https://www.microsoft.com/typography/otspec/recom.htm#tad this.Ascender = useTypoMetrics ? os2.TypoAscender : horizontalHeadTable.Ascender; this.Descender = useTypoMetrics ? os2.TypoDescender : horizontalHeadTable.Descender; this.LineGap = useTypoMetrics ? os2.TypoLineGap : horizontalHeadTable.LineGap; this.LineHeight = this.Ascender - this.Descender + this.LineGap; this.EmSize = this.head.UnitsPerEm; this.kerning = kern; this.colrTable = colrTable; this.cpalTable = cpalTable; this.Description = new FontDescription(nameTable, os2, head); }
public TtfTypeface Read(Stream stream, ReadFlags readFlags = ReadFlags.Full) { var little = BitConverter.IsLittleEndian; using (var input = new ByteOrderSwappingBinaryReader(stream)) { ushort majorVersion = input.ReadUInt16(); ushort minorVersion = input.ReadUInt16(); ushort tableCount = input.ReadUInt16(); ushort searchRange = input.ReadUInt16(); ushort entrySelector = input.ReadUInt16(); ushort rangeShift = input.ReadUInt16(); var tables = new TableEntryCollection(); for (int i = 0; i < tableCount; i++) { tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input))); } //------------------------------------------------------------------ OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); Head header = ReadTableIfExists(tables, input, new Head()); MaxProfile maximumProfile = ReadTableIfExists(tables, input, new MaxProfile()); HorizontalHeader horizontalHeader = ReadTableIfExists(tables, input, new HorizontalHeader()); HorizontalMetrics horizontalMetrics = ReadTableIfExists(tables, input, new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount)); //-------------- Cmap cmaps = ReadTableIfExists(tables, input, new Cmap()); GlyphLocations glyphLocations = ReadTableIfExists(tables, input, new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations)); Glyf glyf = ReadTableIfExists(tables, input, new Glyf(glyphLocations)); //-------------- Gasp gaspTable = ReadTableIfExists(tables, input, new Gasp()); VerticalDeviceMetrics vdmx = ReadTableIfExists(tables, input, new VerticalDeviceMetrics()); //-------------- PostTable postTable = ReadTableIfExists(tables, input, new PostTable()); Kern kern = ReadTableIfExists(tables, input, new Kern()); //-------------- //advanced typography GDEF gdef = ReadTableIfExists(tables, input, new GDEF()); GSUB gsub = ReadTableIfExists(tables, input, new GSUB()); GPOS gpos = ReadTableIfExists(tables, input, new GPOS()); BASE baseTable = ReadTableIfExists(tables, input, new BASE()); COLR colr = ReadTableIfExists(tables, input, new COLR()); CPAL cpal = ReadTableIfExists(tables, input, new CPAL()); VerticalHeader vhea = ReadTableIfExists(tables, input, new VerticalHeader()); if (vhea != null) { VerticalMatric vmtx = ReadTableIfExists(tables, input, new VerticalMatric(vhea.NumOfLongVerMetrics)); } EBLCTable fontBmpTable = ReadTableIfExists(tables, input, new EBLCTable()); //--------------------------------------------- //about truetype instruction init //--------------------------------------------- var typeface = new TtfTypeface( nameEntry, header.Bounds, header.UnitsPerEm, glyf.Glyphs, horizontalMetrics, os2Table); //---------------------------- typeface.CmapTable = cmaps; typeface.KernTable = kern; typeface.GaspTable = gaspTable; typeface.MaxProfile = maximumProfile; typeface.HheaTable = horizontalHeader; //---------------------------- FpgmTable fpgmTable = ReadTableIfExists(tables, input, new FpgmTable()); //control values table CvtTable cvtTable = ReadTableIfExists(tables, input, new CvtTable()); if (cvtTable != null) { typeface.ControlValues = cvtTable.controlValues; } if (fpgmTable != null) { typeface.FpgmProgramBuffer = fpgmTable.programBuffer; } PrepTable propProgramTable = ReadTableIfExists(tables, input, new PrepTable()); if (propProgramTable != null) { typeface.PrepProgramBuffer = propProgramTable.programBuffer; } //------------------------- typeface.LoadOpenFontLayoutInfo( gdef, gsub, gpos, baseTable, colr, cpal); return(typeface); } }
public static OS2Table Load(BinaryReader reader) { // Version 1.0 // Type | Name | Comments // -------|------------------------|----------------------- // uint16 |version | 0x0005 // int16 |xAvgCharWidth | // uint16 |usWeightClass | // uint16 |usWidthClass | // uint16 |fsType | // int16 |ySubscriptXSize | // int16 |ySubscriptYSize | // int16 |ySubscriptXOffset | // int16 |ySubscriptYOffset | // int16 |ySuperscriptXSize | // int16 |ySuperscriptYSize | // int16 |ySuperscriptXOffset | // int16 |ySuperscriptYOffset | // int16 |yStrikeoutSize | // int16 |yStrikeoutPosition | // int16 |sFamilyClass | // uint8 |panose[10] | // uint32 |ulUnicodeRange1 | Bits 0–31 // uint32 |ulUnicodeRange2 | Bits 32–63 // uint32 |ulUnicodeRange3 | Bits 64–95 // uint32 |ulUnicodeRange4 | Bits 96–127 // Tag |achVendID | // uint16 |fsSelection | // uint16 |usFirstCharIndex | // uint16 |usLastCharIndex | // int16 |sTypoAscender | // int16 |sTypoDescender | // int16 |sTypoLineGap | // uint16 |usWinAscent | // uint16 |usWinDescent | // uint32 |ulCodePageRange1 | Bits 0–31 // uint32 |ulCodePageRange2 | Bits 32–63 // int16 |sxHeight | // int16 |sCapHeight | // uint16 |usDefaultChar | // uint16 |usBreakChar | // uint16 |usMaxContext | // uint16 |usLowerOpticalPointSize | // uint16 |usUpperOpticalPointSize | ushort version = reader.ReadUInt16(); // assert 0x0005 short averageCharWidth = reader.ReadInt16(); ushort weightClass = reader.ReadUInt16(); ushort widthClass = reader.ReadUInt16(); ushort styleType = reader.ReadUInt16(); short subscriptXSize = reader.ReadInt16(); short subscriptYSize = reader.ReadInt16(); short subscriptXOffset = reader.ReadInt16(); short subscriptYOffset = reader.ReadInt16(); short superscriptXSize = reader.ReadInt16(); short superscriptYSize = reader.ReadInt16(); short superscriptXOffset = reader.ReadInt16(); short superscriptYOffset = reader.ReadInt16(); short strikeoutSize = reader.ReadInt16(); short strikeoutPosition = reader.ReadInt16(); short familyClass = reader.ReadInt16(); byte[] panose = reader.ReadUInt8Array(10); uint unicodeRange1 = reader.ReadUInt32(); // Bits 0–31 uint unicodeRange2 = reader.ReadUInt32(); // Bits 32–63 uint unicodeRange3 = reader.ReadUInt32(); // Bits 64–95 uint unicodeRange4 = reader.ReadUInt32(); // Bits 96–127 string tag = reader.ReadTag(); FontStyleSelection fontStyle = reader.ReadUInt16 <FontStyleSelection>(); ushort firstCharIndex = reader.ReadUInt16(); ushort lastCharIndex = reader.ReadUInt16(); short typoAscender = reader.ReadInt16(); short typoDescender = reader.ReadInt16(); short typoLineGap = reader.ReadInt16(); ushort winAscent = reader.ReadUInt16(); ushort winDescent = reader.ReadUInt16(); var version0Table = new OS2Table( averageCharWidth, weightClass, widthClass, styleType, subscriptXSize, subscriptYSize, subscriptXOffset, subscriptYOffset, superscriptXSize, superscriptYSize, superscriptXOffset, superscriptYOffset, strikeoutSize, strikeoutPosition, familyClass, panose, unicodeRange1, unicodeRange2, unicodeRange3, unicodeRange4, tag, fontStyle, firstCharIndex, lastCharIndex, typoAscender, typoDescender, typoLineGap, winAscent, winDescent); if (version == 0) { return(version0Table); } ushort codePageRange1 = 0; ushort codePageRange2 = 0; short heightX = 0; short capHeight = 0; ushort defaultChar = 0; ushort breakChar = 0; ushort maxContext = 0; codePageRange1 = reader.ReadUInt16(); // Bits 0–31 codePageRange2 = reader.ReadUInt16(); // Bits 32–63 heightX = reader.ReadInt16(); capHeight = reader.ReadInt16(); defaultChar = reader.ReadUInt16(); breakChar = reader.ReadUInt16(); maxContext = reader.ReadUInt16(); var versionLessthan5Table = new OS2Table( version0Table, codePageRange1, codePageRange2, heightX, capHeight, defaultChar, breakChar, maxContext); if (version < 5) { return(versionLessthan5Table); } ushort lowerOpticalPointSize = reader.ReadUInt16(); ushort upperOpticalPointSize = reader.ReadUInt16(); return(new OS2Table( versionLessthan5Table, lowerOpticalPointSize, upperOpticalPointSize)); }
internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryReader input) { OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); Head header = ReadTableIfExists(tables, input, new Head()); MaxProfile maximumProfile = ReadTableIfExists(tables, input, new MaxProfile()); HorizontalHeader horizontalHeader = ReadTableIfExists(tables, input, new HorizontalHeader()); HorizontalMetrics horizontalMetrics = ReadTableIfExists(tables, input, new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount)); //--- PostTable postTable = ReadTableIfExists(tables, input, new PostTable()); CFFTable ccf = ReadTableIfExists(tables, input, new CFFTable()); //-------------- Cmap cmaps = ReadTableIfExists(tables, input, new Cmap()); GlyphLocations glyphLocations = ReadTableIfExists(tables, input, new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations)); Glyf glyf = ReadTableIfExists(tables, input, new Glyf(glyphLocations)); //-------------- Gasp gaspTable = ReadTableIfExists(tables, input, new Gasp()); VerticalDeviceMetrics vdmx = ReadTableIfExists(tables, input, new VerticalDeviceMetrics()); //-------------- Kern kern = ReadTableIfExists(tables, input, new Kern()); //-------------- //advanced typography GDEF gdef = ReadTableIfExists(tables, input, new GDEF()); GSUB gsub = ReadTableIfExists(tables, input, new GSUB()); GPOS gpos = ReadTableIfExists(tables, input, new GPOS()); BASE baseTable = ReadTableIfExists(tables, input, new BASE()); COLR colr = ReadTableIfExists(tables, input, new COLR()); CPAL cpal = ReadTableIfExists(tables, input, new CPAL()); VerticalHeader vhea = ReadTableIfExists(tables, input, new VerticalHeader()); if (vhea != null) { VerticalMetrics vmtx = ReadTableIfExists(tables, input, new VerticalMetrics(vhea.NumOfLongVerMetrics)); } //test math table MathTable mathtable = ReadTableIfExists(tables, input, new MathTable()); EBLCTable fontBmpTable = ReadTableIfExists(tables, input, new EBLCTable()); //--------------------------------------------- //about truetype instruction init //--------------------------------------------- Typeface typeface = null; bool isPostScriptOutline = false; if (glyf == null) { //check if this is cff table ? if (ccf == null) { //TODO: review here throw new NotSupportedException(); } //... //PostScript outline font isPostScriptOutline = true; typeface = new Typeface( nameEntry, header.Bounds, header.UnitsPerEm, ccf, horizontalMetrics, os2Table); } else { typeface = new Typeface( nameEntry, header.Bounds, header.UnitsPerEm, glyf.Glyphs, horizontalMetrics, os2Table); } //---------------------------- typeface.CmapTable = cmaps; typeface.KernTable = kern; typeface.GaspTable = gaspTable; typeface.MaxProfile = maximumProfile; typeface.HheaTable = horizontalHeader; //---------------------------- if (!isPostScriptOutline) { FpgmTable fpgmTable = ReadTableIfExists(tables, input, new FpgmTable()); //control values table CvtTable cvtTable = ReadTableIfExists(tables, input, new CvtTable()); if (cvtTable != null) { typeface.ControlValues = cvtTable._controlValues; } if (fpgmTable != null) { typeface.FpgmProgramBuffer = fpgmTable._programBuffer; } PrepTable propProgramTable = ReadTableIfExists(tables, input, new PrepTable()); if (propProgramTable != null) { typeface.PrepProgramBuffer = propProgramTable._programBuffer; } } //------------------------- typeface.LoadOpenFontLayoutInfo( gdef, gsub, gpos, baseTable, colr, cpal); //------------ //test { SvgTable svgTable = ReadTableIfExists(tables, input, new SvgTable()); if (svgTable != null) { typeface._svgTable = svgTable; } } typeface.PostTable = postTable; if (mathtable != null) { var mathGlyphLoader = new MathGlyphLoader(); mathGlyphLoader.LoadMathGlyph(typeface, mathtable); } #if DEBUG //test //int found = typeface.GetGlyphIndexByName("Uacute"); if (typeface.IsCffFont) { //optional typeface.UpdateAllCffGlyphBounds(); } #endif return(typeface); }