public Glyph GetGlyphData(ushort glyphId) { if (GlyphCache.ContainsKey(glyphId)) { return(GlyphCache[glyphId]); } var dataOffset = font.loca.Offsets[glyphId]; var reader = new TrueTypeReader(Data); reader.Seek(dataOffset); var glyph = new Glyph() { NumberOfContours = reader.ReadShort(), XMin = reader.ReadFWord(), YMin = reader.ReadFWord(), XMax = reader.ReadFWord(), YMax = reader.ReadFWord() }; reader.Dispose(); GlyphCache[glyphId] = glyph; return(glyph); }
public override void Process(TrueTypeFont font) { var reader = new TrueTypeReader(Data); Version = reader.ReadUShort(); NumberOfTables = reader.ReadUShort(); Subtables = new List <KerningSubtableBase>(NumberOfTables); for (var t = 0; t < NumberOfTables; t++) { var subtableOffset = reader.Position; var version = reader.ReadUShort(); var length = reader.ReadUShort(); var coverage = reader.ReadUShort(); var subtableType = ImplementationTypeAttribute.GetTypeFromEnumValue(typeof(KerningSubtableType), GetSubtypeFromCoverage(coverage)); var subtable = Activator.CreateInstance(subtableType) as KerningSubtableBase; subtable.ReadData(reader, (uint)subtableOffset, length); Subtables.Add(subtable); } ProcessSubtables(font); reader.Dispose(); }
public override void Process(TrueTypeFont font) { var reader = new TrueTypeReader(Data); var version = reader.ReadUShort(); var length = reader.ReadUShort(); var coverage = reader.ReadUShort(); NumberOfPairs = reader.ReadUShort(); SearchRange = reader.ReadUShort(); EntrySelector = reader.ReadUShort(); RangeShift = reader.ReadUShort(); Kernpairs = new Dictionary <uint, short>(NumberOfPairs); for (var i = 0; i < NumberOfPairs; i++) { var glyphPair = reader.ReadULong(); var kernUnits = reader.ReadFWord(); Kernpairs[glyphPair] = kernUnits; } reader.Dispose(); }
public override void Process(TrueTypeFont font) { var reader = new TrueTypeReader(Data); Version = reader.ReadFixed(); NumberOfGlyphs = reader.ReadUShort(); reader.Dispose(); }
public override void Process(TrueTypeFont font) { var reader = new TrueTypeReader(Data); var format = reader.ReadUShort(); var length = reader.ReadUShort(); var version = reader.ReadUShort(); DoubleSegCount = reader.ReadUShort(); SearchRange = reader.ReadUShort(); EntrySelector = reader.ReadUShort(); RangeShift = reader.ReadUShort(); EndCounts = new ushort[SegCount]; for (var i = 0; i < SegCount; i++) { EndCounts[i] = reader.ReadUShort(); } ReservedPad = reader.ReadUShort(); StartCounts = new ushort[SegCount]; for (var i = 0; i < SegCount; i++) { StartCounts[i] = reader.ReadUShort(); } IdDeltas = new ushort[SegCount]; for (var i = 0; i < SegCount; i++) { IdDeltas[i] = reader.ReadUShort(); } IdRangeOffsets = new ushort[SegCount]; IdRangeOffsetPositions = new long[SegCount]; for (var i = 0; i < SegCount; i++) { IdRangeOffsetPositions[i] = reader.Position; IdRangeOffsets[i] = reader.ReadUShort(); } reader.Dispose(); }
public override void Process(TrueTypeFont font) { var reader = new TrueTypeReader(Data); Version = reader.ReadUShort(); EncodingTableCount = reader.ReadUShort(); EncodingTables = new List <EncodingTableEntry>(EncodingTableCount); for (var i = 0; i < EncodingTableCount; i++) { EncodingTables.Add(new EncodingTableEntry() { Platform = (Platform)reader.ReadUShort(), Encoding = (Encoding)reader.ReadUShort(), Offset = reader.ReadULong() }); } foreach (var encodingTable in EncodingTables) { reader.Seek(encodingTable.Offset); var format = (CmapSubtableType)reader.ReadUShort(); var length = reader.ReadUShort(); var subtableProcessorType = ImplementationTypeAttribute.GetTypeFromEnumValue(typeof(CmapSubtableType), format); if (subtableProcessorType == null) { continue; } var subtableProcessor = Activator.CreateInstance(subtableProcessorType) as CharacterToGlyphSubtableBase; subtableProcessor.EncodingTableEntry = encodingTable; subtableProcessor.ReadData(reader, encodingTable.Offset, length); Subtables.Add(subtableProcessor); } ProcessSubtables(font); reader.Dispose(); }
public override void ReadData(TrueTypeReader reader, uint offset, uint length) { // This weirdness is because some fonts have a malformed subtable header that lists the length incorrectly. // The actual length can be calculated by peaking the number of kern pairs, and calculating it back. reader.Seek(offset); var version = reader.ReadUShort(); var len = reader.ReadUShort(); var coverage = reader.ReadUShort(); var numberOfPairs = reader.ReadUShort(); var kernpairLength = numberOfPairs * BytesPerKernpair; var calculatedLength = kernpairLength + BytesInHeader; if (calculatedLength != len) { Debug.WriteLine("ERROR: Detected kern subtable length does not match specified value. Using detected value."); } base.ReadData(reader, offset, (uint)calculatedLength); }
public override void Process(TrueTypeFont font) { if (font.hhea == null) { throw new Exception("Table processing order error. Processing the hmtx table requires the hhea table."); } Metrics = new HorizontalMetric[font.hhea.NumberOfHorizontalMetrics]; var reader = new TrueTypeReader(Data); for (var m = 0; m < Metrics.Length; m++) { Metrics[m] = new HorizontalMetric() { AdvanceWidth = reader.ReadUFWord(), LeftSideBearing = reader.ReadFWord() }; } reader.Dispose(); }
public override void Process(TrueTypeFont font) { var offsetFormat = font.head.IndexToLocFormat; var numberOfGlyphs = Data.Length / ((offsetFormat + 1) * 2); Offsets = new Dictionary <ushort, uint>(numberOfGlyphs); var reader = new TrueTypeReader(Data); for (ushort i = 0; i < numberOfGlyphs; i++) { if ((LocationOffsetFormat)offsetFormat == LocationOffsetFormat.Short) { Offsets[i] = reader.ReadUShort(); } else { Offsets[i] = reader.ReadULong(); } } reader.Dispose(); }
public override void Process(TrueTypeFont font) { var reader = new TrueTypeReader(Data); Version = reader.ReadFixed(); Ascender = reader.ReadFWord(); Descender = reader.ReadFWord(); LineGap = reader.ReadFWord(); AdvanceWidthMax = reader.ReadUFWord(); MinLeftSideBearing = reader.ReadFWord(); MinRightSideBearing = reader.ReadFWord(); XMaxExtent = reader.ReadFWord(); CaretSlopeRise = reader.ReadShort(); CaretSlopeRun = reader.ReadShort(); Reserved0 = reader.ReadShort(); Reserved1 = reader.ReadShort(); Reserved2 = reader.ReadShort(); Reserved3 = reader.ReadShort(); Reserved4 = reader.ReadShort(); MetricDataFormat = reader.ReadShort(); NumberOfHorizontalMetrics = reader.ReadUShort(); reader.Dispose(); }
public override void Process(TrueTypeFont font) { var reader = new TrueTypeReader(Data); Version = reader.ReadFixed(); Revision = reader.ReadFixed(); ChecksumAdjustment = reader.ReadULong(); Magic = reader.ReadULong(); Flags = reader.ReadUShort(); UnitsPerEm = reader.ReadUShort(); DateCreated = reader.ReadLongDateTime(); DateModified = reader.ReadLongDateTime(); XMin = reader.ReadFWord(); YMin = reader.ReadFWord(); XMax = reader.ReadFWord(); YMax = reader.ReadFWord(); MacStyle = reader.ReadUShort(); LowestRecommendedPPEM = reader.ReadUShort(); FontDirectionHint = reader.ReadShort(); IndexToLocFormat = reader.ReadShort(); GlyphDataFormat = reader.ReadShort(); reader.Dispose(); }
public override ushort GetGlyphId(ushort charCode) { ushort glyphId = 0; /// You search for the first endCode that is greater than or equal to the character code you want to map. /// If the corresponding startCode is less than or equal to the character code, then you use the corresponding /// idDelta and idRangeOffset to map the character code to a glyph index (otherwise, the missingGlyph is returned). ushort endCode = 0; int segment = 0; while (true) { endCode = EndCounts[segment]; if (endCode >= charCode) { break; } else { segment++; } } var startCode = StartCounts[segment]; if (startCode <= charCode) { // use idDelta and idRangeOffset to map charcode to glyphindex var idDelta = IdDeltas[segment]; var idRangeOffset = IdRangeOffsets[segment]; if (idRangeOffset == 0) { unchecked { glyphId = (ushort)(idDelta + charCode); } } else { // use glyphIds data var idStreamPosition = idRangeOffset + 2 * (charCode - startCode) + IdRangeOffsetPositions[segment]; ushort readGlyphValue; using (var reader = new TrueTypeReader(base.Data)) { reader.Seek(idStreamPosition); readGlyphValue = reader.ReadUShort(); } if (readGlyphValue != 0) { unchecked { glyphId = (ushort)(idDelta + readGlyphValue); } } } } return(glyphId); }