GdiFontDefn.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. #pragma warning disable
  9. namespace Svg
  10. {
  11. public class GdiFontDefn : IFontDefn
  12. {
  13. private Font _font;
  14. public float Size
  15. {
  16. get { return _font.Size; }
  17. }
  18. public float SizeInPoints
  19. {
  20. get { return _font.SizeInPoints; }
  21. }
  22. public GdiFontDefn(Font font)
  23. {
  24. _font = font;
  25. }
  26. public void AddStringToPath(ISvgRenderer renderer, GraphicsPath path, string text, PointF location)
  27. {
  28. path.AddString(text, _font.FontFamily, (int)_font.Style, _font.Size, location, StringFormat.GenericTypographic);
  29. }
  30. //Baseline calculation to match http://bobpowell.net/formattingtext.aspx
  31. public float Ascent(ISvgRenderer renderer)
  32. {
  33. var ff = _font.FontFamily;
  34. float ascent = ff.GetCellAscent(_font.Style);
  35. float baselineOffset = _font.SizeInPoints / ff.GetEmHeight(_font.Style) * ascent;
  36. return renderer.DpiY / 72f * baselineOffset;
  37. }
  38. public IList<RectangleF> MeasureCharacters(ISvgRenderer renderer, string text)
  39. {
  40. var g = GetGraphics(renderer);
  41. var regions = new List<RectangleF>();
  42. StringFormat format;
  43. for (int s = 0; s <= (text.Length - 1) / 32; s++)
  44. {
  45. format = StringFormat.GenericTypographic;
  46. format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
  47. format.SetMeasurableCharacterRanges((from r in Enumerable.Range(32 * s, Math.Min(32, text.Length - 32 * s))
  48. select new CharacterRange(r, 1)).ToArray());
  49. regions.AddRange(from r in g.MeasureCharacterRanges(text, _font, new Rectangle(0, 0, 1000, 1000), format)
  50. select r.GetBounds(g));
  51. }
  52. return regions;
  53. }
  54. public SizeF MeasureString(ISvgRenderer renderer, string text)
  55. {
  56. var g = GetGraphics(renderer);
  57. StringFormat format = StringFormat.GenericTypographic.Clone() as StringFormat;
  58. format.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, text.Length)});
  59. format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
  60. Region[] r = g.MeasureCharacterRanges(text, _font, new Rectangle(0, 0, 1000, 1000), format);
  61. RectangleF rect = r[0].GetBounds(g);
  62. return new SizeF(rect.Width, Ascent(renderer));
  63. }
  64. private Graphics _graphics;
  65. private Graphics GetGraphics(object renderer)
  66. {
  67. var provider = renderer as IGraphicsProvider;
  68. if (provider == null)
  69. {
  70. if (_graphics == null)
  71. {
  72. var bmp = new Bitmap(1, 1);
  73. _graphics = Graphics.FromImage(bmp);
  74. }
  75. return _graphics;
  76. }
  77. else
  78. {
  79. return provider.GetGraphics();
  80. }
  81. }
  82. public void Dispose()
  83. {
  84. _font.Dispose();
  85. }
  86. }
  87. }
  88. #pragma warning restore