/// <summary> /// This will get the width of a character. /// </summary> /// <param name="name">The character to get the width for.</param> /// <returns>The width of the character.</returns> public float GetCharacterWidth(string name) { float result = 0; CharMetric metric = charMetricsMap[name]; if (metric != null) { result = metric.Wx; } return(result); }
/// <summary> /// This will get the width of a character. /// </summary> /// <param name="name">The character to get the width for.</param> /// <returns>The width of the character.</returns> public float GetCharacterHeight(string name) { float result = 0; CharMetric metric = charMetricsMap[name]; if (metric != null) { result = metric.Wy; if (result == 0) { result = metric.BoundingBox.Height; } } return(result); }
/// <summary> /// This will parse a single CharMetric object from the stream. /// </summary> /// <returns>The next char metric in the stream.</returns> /// <exception cref="IOException">If there is an error reading from the stream.</exception> private CharMetric ParseCharMetric() { CharMetric charMetric = new CharMetric(); string metrics = ReadLine(); StringTokenizer metricsTokenizer = new StringTokenizer(metrics); try { while (metricsTokenizer.HasMoreTokens()) { string nextCommand = metricsTokenizer.NextToken(); if (nextCommand.Equals(CHARMETRICS_C)) { charMetric.CharacterCode = int.Parse(metricsTokenizer.NextToken()); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_CH)) { //Is the hex string <FF> or FF, the spec is a little //unclear, wait and see if it breaks anything. // charMetric.CharacterCode = int.Parse( metricsTokenizer.NextToken(), BITS_IN_HEX ); charMetric.CharacterCode = int.Parse(string.Empty, System.Globalization.NumberStyles.AllowHexSpecifier); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_WX)) { charMetric.Wx = float.Parse(metricsTokenizer.NextToken()); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_W0X)) { charMetric.W0x = float.Parse(metricsTokenizer.NextToken()); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_W1X)) { charMetric.W1x = float.Parse(metricsTokenizer.NextToken()); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_WY)) { charMetric.Wy = float.Parse(metricsTokenizer.NextToken()); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_W0Y)) { charMetric.W0y = float.Parse(metricsTokenizer.NextToken()); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_W1Y)) { charMetric.W1y = float.Parse(metricsTokenizer.NextToken()); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_W)) { charMetric.W = new float[2] { float.Parse(metricsTokenizer.NextToken()), float.Parse(metricsTokenizer.NextToken()) }; VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_W0)) { charMetric.W0 = new float[2] { float.Parse(metricsTokenizer.NextToken()), float.Parse(metricsTokenizer.NextToken()) }; VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_W1)) { charMetric.W1 = new float[2] { float.Parse(metricsTokenizer.NextToken()), float.Parse(metricsTokenizer.NextToken()) }; VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_VV)) { charMetric.Vv = new float[2] { float.Parse(metricsTokenizer.NextToken()), float.Parse(metricsTokenizer.NextToken()) }; VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_N)) { charMetric.Name = metricsTokenizer.NextToken(); VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_B)) { charMetric.BoundingBox = new BoundingBox { LowerLeftX = float.Parse(metricsTokenizer.NextToken()), LowerLeftY = float.Parse(metricsTokenizer.NextToken()), UpperRightX = float.Parse(metricsTokenizer.NextToken()), UpperRightY = float.Parse(metricsTokenizer.NextToken()) }; VerifySemicolon(metricsTokenizer); } else if (nextCommand.Equals(CHARMETRICS_L)) { charMetric.Ligatures.Add(new Ligature { Successor = metricsTokenizer.NextToken(), CurrentLigature = metricsTokenizer.NextToken() }); VerifySemicolon(metricsTokenizer); } else { throw new IOException("Unknown CharMetrics command '" + nextCommand + "'"); } } } catch (FormatException e) { throw new IOException("Error: Corrupt AFM document:" + e); } return(charMetric); }
/// <summary> /// This will parse a font metrics item. /// </summary> /// <returns>The parse font metrics item.<returns> /// <exception cref="IOException">If there is an error reading the AFM file.</exception> private FontMetrics ParseFontMetric(bool reducedDataset) { FontMetrics fontMetrics = new FontMetrics(); string startFontMetrics = ReadString(); if (!START_FONT_METRICS.Equals(startFontMetrics)) { throw new IOException("Error: The AFM file should start with " + START_FONT_METRICS + " and not '" + startFontMetrics + "'"); } fontMetrics.AfmVersion = ReadFloat(); string nextCommand; bool charMetricsRead = false; while (!END_FONT_METRICS.Equals((nextCommand = ReadString()))) { if (FONT_NAME.Equals(nextCommand)) { fontMetrics.FontName = ReadLine(); } else if (FULL_NAME.Equals(nextCommand)) { fontMetrics.FullName = ReadLine(); } else if (FAMILY_NAME.Equals(nextCommand)) { fontMetrics.FamilyName = ReadLine(); } else if (WEIGHT.Equals(nextCommand)) { fontMetrics.Weight = ReadLine(); } else if (FONT_BBOX.Equals(nextCommand)) { fontMetrics.FontBBox = new BoundingBox { LowerLeftX = ReadFloat(), LowerLeftY = ReadFloat(), UpperRightX = ReadFloat(), UpperRightY = ReadFloat() }; } else if (VERSION.Equals(nextCommand)) { fontMetrics.FontVersion = ReadLine(); } else if (NOTICE.Equals(nextCommand)) { fontMetrics.Notice = ReadLine(); } else if (ENCODING_SCHEME.Equals(nextCommand)) { fontMetrics.EncodingScheme = ReadLine(); } else if (MAPPING_SCHEME.Equals(nextCommand)) { fontMetrics.MappingScheme = ReadInt(); } else if (ESC_CHAR.Equals(nextCommand)) { fontMetrics.EscChar = ReadInt(); } else if (CHARACTER_SET.Equals(nextCommand)) { fontMetrics.CharacterSet = ReadLine(); } else if (CHARACTERS.Equals(nextCommand)) { fontMetrics.Characters = ReadInt(); } else if (IS_BASE_FONT.Equals(nextCommand)) { fontMetrics.IsBaseFont = Readbool(); } else if (V_VECTOR.Equals(nextCommand)) { fontMetrics.VVector = new float[2] { ReadFloat(), ReadFloat() }; } else if (IS_FIXED_V.Equals(nextCommand)) { fontMetrics.IsFixedV = Readbool(); } else if (CAP_HEIGHT.Equals(nextCommand)) { fontMetrics.CapHeight = ReadFloat(); } else if (X_HEIGHT.Equals(nextCommand)) { fontMetrics.XHeight = ReadFloat(); } else if (ASCENDER.Equals(nextCommand)) { fontMetrics.Ascender = ReadFloat(); } else if (DESCENDER.Equals(nextCommand)) { fontMetrics.Descender = ReadFloat(); } else if (STD_HW.Equals(nextCommand)) { fontMetrics.StandardHorizontalWidth = ReadFloat(); } else if (STD_VW.Equals(nextCommand)) { fontMetrics.StandardVerticalWidth = ReadFloat(); } else if (COMMENT.Equals(nextCommand)) { fontMetrics.AddComment(ReadLine()); } else if (UNDERLINE_POSITION.Equals(nextCommand)) { fontMetrics.UnderlinePosition = ReadFloat(); } else if (UNDERLINE_THICKNESS.Equals(nextCommand)) { fontMetrics.UnderlineThickness = ReadFloat(); } else if (ITALIC_ANGLE.Equals(nextCommand)) { fontMetrics.ItalicAngle = ReadFloat(); } else if (CHAR_WIDTH.Equals(nextCommand)) { fontMetrics.CharWidth = new float[2] { ReadFloat(), ReadFloat() }; } else if (IS_FIXED_PITCH.Equals(nextCommand)) { fontMetrics.FixedPitch = Readbool(); } else if (START_CHAR_METRICS.Equals(nextCommand)) { int count = ReadInt(); List <CharMetric> charMetrics = new List <CharMetric>(count); for (int i = 0; i < count; i++) { CharMetric charMetric = ParseCharMetric(); charMetrics.Add(charMetric); } string end = ReadString(); if (!end.Equals(END_CHAR_METRICS)) { throw new IOException("Error: Expected '" + END_CHAR_METRICS + "' actual '" + end + "'"); } charMetricsRead = true; fontMetrics.CharMetrics = charMetrics.AsReadOnly(); } else if (!reducedDataset && START_COMPOSITES.Equals(nextCommand)) { int count = ReadInt(); for (int i = 0; i < count; i++) { Composite part = ParseComposite(); fontMetrics.AddComposite(part); } string end = ReadString(); if (!end.Equals(END_COMPOSITES)) { throw new IOException("Error: Expected '" + END_COMPOSITES + "' actual '" + end + "'"); } } else if (!reducedDataset && START_KERN_DATA.Equals(nextCommand)) { ParseKernData(fontMetrics); } else { if (reducedDataset && charMetricsRead) { break; } throw new IOException("Unknown AFM key '" + nextCommand + "'"); } } return(fontMetrics); }