public ushort GetUnitWidthOfString(string s) { var ids = new ushort[s.Length]; var metrics = new HorizontalMetric[s.Length]; var rsbs = new ushort[s.Length]; for (var i = 0; i < s.Length; i++) { ids[i] = cmap.GetGlyphId(s[i]); metrics[i] = hmtx.Metrics[ids[i]]; var glyphData = glyf.GetGlyphData(ids[i]); rsbs[i] = (ushort)(metrics[i].AdvanceWidth - (metrics[i].LeftSideBearing + glyphData.XMax - glyphData.XMin)); } ushort width = 0; for (var i = 0; i < s.Length; i++) { width += metrics[i].AdvanceWidth; width = width.Sum(metrics[i].LeftSideBearing); width += rsbs[i]; } var kerning = GetTotalKernOfString(s); width = width.Sum(kerning); return(width); }
HorizontalMetric[] ParseHmtxTable(Stream stream, BinaryReader reader, TableHeader header, int metricCount, int glyphCount) { stream.Position = header.Offset; var metrics = new HorizontalMetric[glyphCount]; for (int i = 0; i < metricCount; i++) { metrics[i] = new HorizontalMetric() { AdvanceWidth = reader.ReadUInt16(), LeftSideBearing = reader.ReadInt16(), }; } for (int i = metricCount; i < glyphCount; i++) { metrics[i] = new HorizontalMetric() { AdvanceWidth = metrics[metricCount - 1].AdvanceWidth, LeftSideBearing = reader.ReadInt16(), }; } return(metrics); }
public HorizontalMetricsTable Parse(TrueTypeHeaderTable header, TrueTypeDataBytes data, TableRegister.Builder register) { var glyphCount = register.MaximumProfileTable.NumberOfGlyphs; var metricCount = register.HorizontalHeaderTable.NumberOfHeaderMetrics; data.Seek(header.Offset); var bytesRead = 0; var horizontalMetrics = new HorizontalMetric[metricCount]; for (var i = 0; i < metricCount; i++) { var width = data.ReadUnsignedShort(); var lsb = data.ReadSignedShort(); horizontalMetrics[i] = new HorizontalMetric(width, lsb); bytesRead += 4; } int numberNonHorizontal = glyphCount - metricCount; // handle bad fonts with too many hmetrics if (numberNonHorizontal < 0) { numberNonHorizontal = glyphCount; } // The number of entries in the left side bearing field per entry is number of glyphs - number of metrics // For bearings over the metric count, the width is the same as the last width in advanced widths. var additionalLeftSideBearings = new short[numberNonHorizontal]; for (var i = 0; i < additionalLeftSideBearings.Length; i++) { if (bytesRead >= header.Length) { break; } additionalLeftSideBearings[i] = data.ReadSignedShort(); bytesRead += 2; } return(new HorizontalMetricsTable(header, horizontalMetrics, additionalLeftSideBearings)); }
HorizontalMetric[] ParseHmtxTable(Stream stream, BinaryReader reader, TableHeader header, int metricCount, int glyphCount) { stream.Position = header.Offset; var metrics = new HorizontalMetric[glyphCount]; for (int i = 0; i < metricCount; i++) { metrics[i] = new HorizontalMetric() { AdvanceWidth = reader.ReadUInt16(), LeftSideBearing = reader.ReadInt16(), }; } for (int i = metricCount; i < glyphCount; i++) { metrics[i] = new HorizontalMetric() { AdvanceWidth = metrics[metricCount - 1].AdvanceWidth, LeftSideBearing = reader.ReadInt16(), }; } return metrics; }