SpriteFontBase.IFontStashRenderer.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. using FontStashSharp.Interfaces;
  2. using System.Text;
  3. using System;
  4. #if MONOGAME || FNA
  5. using Microsoft.Xna.Framework;
  6. #elif STRIDE
  7. using Stride.Core.Mathematics;
  8. using Stride.Graphics;
  9. #else
  10. using System.Numerics;
  11. using Matrix = System.Numerics.Matrix3x2;
  12. using Color = Veldrid.RgbaFloat;
  13. #endif
  14. namespace FontStashSharp
  15. {
  16. public partial class SpriteFontBase
  17. {
  18. private void RenderStyle(IFontStashRenderer renderer, TextStyle textStyle, Vector2 pos,
  19. int lineHeight, int ascent, Color color, ref Matrix transformation, float rotation, Vector2 scale, float layerDepth)
  20. {
  21. if (textStyle == TextStyle.None || pos.X == 0)
  22. {
  23. return;
  24. }
  25. #if MONOGAME || FNA || STRIDE
  26. var white = GetWhite(renderer.GraphicsDevice);
  27. #else
  28. var white = GetWhite(renderer.TextureManager);
  29. #endif
  30. var start = Vector2.Zero;
  31. if (textStyle == TextStyle.Strikethrough)
  32. {
  33. start.Y = pos.Y - ascent - FontSystemDefaults.TextStyleLineHeight / 2 + lineHeight / 2;
  34. }
  35. else
  36. {
  37. start.Y = pos.Y + 1;
  38. }
  39. start = start.Transform(ref transformation);
  40. scale.X *= pos.X;
  41. scale.Y *= FontSystemDefaults.TextStyleLineHeight;
  42. renderer.Draw(white, start, null, color, rotation, scale, layerDepth);
  43. }
  44. private float DrawText(IFontStashRenderer renderer, TextColorSource source, Vector2 position,
  45. Vector2? sourceScale, float rotation, Vector2 origin,
  46. float layerDepth, float characterSpacing, float lineSpacing, TextStyle textStyle)
  47. {
  48. if (renderer == null)
  49. {
  50. throw new ArgumentNullException(nameof(renderer));
  51. }
  52. #if MONOGAME || FNA || STRIDE
  53. if (renderer.GraphicsDevice == null)
  54. {
  55. throw new ArgumentNullException("renderer.GraphicsDevice can't be null.");
  56. }
  57. #else
  58. if (renderer.TextureManager == null)
  59. {
  60. throw new ArgumentNullException("renderer.TextureManager can't be null.");
  61. }
  62. #endif
  63. if (source.IsNull) return 0.0f;
  64. Matrix transformation;
  65. var scale = sourceScale ?? Utility.DefaultScale;
  66. Prepare(position, ref scale, rotation, origin, out transformation);
  67. int ascent, lineHeight;
  68. PreDraw(source.TextSource, out ascent, out lineHeight);
  69. var pos = new Vector2(0, ascent);
  70. FontGlyph prevGlyph = null;
  71. Color? firstColor = null;
  72. while (true)
  73. {
  74. int codepoint;
  75. Color color;
  76. if (!source.GetNextCodepoint(out codepoint))
  77. break;
  78. if (codepoint == '\n')
  79. {
  80. if (textStyle != TextStyle.None && firstColor != null)
  81. {
  82. RenderStyle(renderer, textStyle, pos,
  83. lineHeight, ascent, firstColor.Value, ref transformation,
  84. rotation, scale, layerDepth);
  85. }
  86. pos.X = 0.0f;
  87. pos.Y += lineHeight + lineSpacing;
  88. prevGlyph = null;
  89. continue;
  90. }
  91. #if MONOGAME || FNA || STRIDE
  92. var glyph = GetGlyph(renderer.GraphicsDevice, codepoint);
  93. #else
  94. var glyph = GetGlyph(renderer.TextureManager, codepoint);
  95. #endif
  96. if (glyph == null)
  97. {
  98. continue;
  99. }
  100. if (prevGlyph != null)
  101. {
  102. pos.X += characterSpacing;
  103. pos.X += GetKerning(glyph, prevGlyph);
  104. }
  105. if (!glyph.IsEmpty)
  106. {
  107. color = source.GetNextColor();
  108. firstColor = color;
  109. var p = pos + new Vector2(glyph.RenderOffset.X, glyph.RenderOffset.Y);
  110. p = p.Transform(ref transformation);
  111. renderer.Draw(glyph.Texture,
  112. p,
  113. glyph.TextureRectangle,
  114. color,
  115. rotation,
  116. scale,
  117. layerDepth);
  118. }
  119. pos.X += glyph.XAdvance;
  120. prevGlyph = glyph;
  121. }
  122. if (textStyle != TextStyle.None && firstColor != null)
  123. {
  124. RenderStyle(renderer, textStyle, pos,
  125. lineHeight, ascent, firstColor.Value, ref transformation,
  126. rotation, scale, layerDepth);
  127. }
  128. return position.X + pos.X;
  129. }
  130. /// <summary>
  131. /// Draws a text
  132. /// </summary>
  133. /// <param name="renderer">A renderer</param>
  134. /// <param name="text">The text which will be drawn</param>
  135. /// <param name="position">The drawing location on screen</param>
  136. /// <param name="color">A color mask</param>
  137. /// <param name="rotation">A rotation of this text in radians</param>
  138. /// <param name="origin">Center of the rotation</param>
  139. /// <param name="scale">A scaling of this text. Null means the scaling is (1, 1)</param>
  140. /// <param name="layerDepth">A depth of the layer of this string</param>
  141. /// <param name="characterSpacing">A character spacing</param>
  142. /// <param name="lineSpacing">A line spacing</param>
  143. public float DrawText(IFontStashRenderer renderer, string text, Vector2 position, Color color,
  144. Vector2? scale = null, float rotation = 0, Vector2 origin = default(Vector2),
  145. float layerDepth = 0.0f, float characterSpacing = 0.0f, float lineSpacing = 0.0f,
  146. TextStyle textStyle = TextStyle.None) =>
  147. DrawText(renderer, new TextColorSource(text, color), position, scale, rotation, origin, layerDepth, characterSpacing, lineSpacing, textStyle);
  148. /// <summary>
  149. /// Draws a text
  150. /// </summary>
  151. /// <param name="renderer">A renderer</param>
  152. /// <param name="text">The text which will be drawn</param>
  153. /// <param name="position">The drawing location on screen</param>
  154. /// <param name="colors">Colors of glyphs</param>
  155. /// <param name="rotation">A rotation of this text in radians</param>
  156. /// <param name="origin">Center of the rotation</param>
  157. /// <param name="scale">A scaling of this text. Null means the scaling is (1, 1)</param>
  158. /// <param name="layerDepth">A depth of the layer of this string</param>
  159. /// <param name="characterSpacing">A character spacing</param>
  160. /// <param name="lineSpacing">A line spacing</param>
  161. public float DrawText(IFontStashRenderer renderer, string text, Vector2 position, Color[] colors,
  162. Vector2? scale = null, float rotation = 0, Vector2 origin = default(Vector2),
  163. float layerDepth = 0.0f, float characterSpacing = 0.0f, float lineSpacing = 0.0f,
  164. TextStyle textStyle = TextStyle.None) =>
  165. DrawText(renderer, new TextColorSource(text, colors), position, scale, rotation, origin, layerDepth, characterSpacing, lineSpacing, textStyle);
  166. /// <summary>
  167. /// Draws a text
  168. /// </summary>
  169. /// <param name="renderer">A renderer</param>
  170. /// <param name="text">The text which will be drawn</param>
  171. /// <param name="position">The drawing location on screen</param>
  172. /// <param name="color">A color mask</param>
  173. /// <param name="rotation">A rotation of this text in radians</param>
  174. /// <param name="origin">Center of the rotation</param>
  175. /// <param name="scale">A scaling of this text. Null means the scaling is (1, 1)</param>
  176. /// <param name="layerDepth">A depth of the layer of this string</param>
  177. /// <param name="characterSpacing">A character spacing</param>
  178. /// <param name="lineSpacing">A line spacing</param>
  179. public float DrawText(IFontStashRenderer renderer, StringSegment text, Vector2 position, Color color,
  180. Vector2? scale = null, float rotation = 0, Vector2 origin = default(Vector2),
  181. float layerDepth = 0.0f, float characterSpacing = 0.0f, float lineSpacing = 0.0f,
  182. TextStyle textStyle = TextStyle.None) =>
  183. DrawText(renderer, new TextColorSource(text, color), position, scale, rotation, origin, layerDepth, characterSpacing, lineSpacing, textStyle);
  184. /// <summary>
  185. /// Draws a text
  186. /// </summary>
  187. /// <param name="renderer">A renderer</param>
  188. /// <param name="text">The text which will be drawn</param>
  189. /// <param name="position">The drawing location on screen</param>
  190. /// <param name="colors">Colors of glyphs</param>
  191. /// <param name="rotation">A rotation of this text in radians</param>
  192. /// <param name="origin">Center of the rotation</param>
  193. /// <param name="scale">A scaling of this text. Null means the scaling is (1, 1)</param>
  194. /// <param name="layerDepth">A depth of the layer of this string</param>
  195. /// <param name="characterSpacing">A character spacing</param>
  196. /// <param name="lineSpacing">A line spacing</param>
  197. public float DrawText(IFontStashRenderer renderer, StringSegment text, Vector2 position, Color[] colors,
  198. Vector2? scale = null, float rotation = 0, Vector2 origin = default(Vector2),
  199. float layerDepth = 0.0f, float characterSpacing = 0.0f, float lineSpacing = 0.0f,
  200. TextStyle textStyle = TextStyle.None) =>
  201. DrawText(renderer, new TextColorSource(text, colors), position, scale, rotation, origin, layerDepth, characterSpacing, lineSpacing, textStyle);
  202. /// <summary>
  203. /// Draws a text
  204. /// </summary>
  205. /// <param name="renderer">A renderer</param>
  206. /// <param name="text">The text which will be drawn</param>
  207. /// <param name="position">The drawing location on screen</param>
  208. /// <param name="color">A color mask</param>
  209. /// <param name="rotation">A rotation of this text in radians</param>
  210. /// <param name="origin">Center of the rotation</param>
  211. /// <param name="scale">A scaling of this text. Null means the scaling is (1, 1)</param>
  212. /// <param name="layerDepth">A depth of the layer of this string</param>
  213. /// <param name="characterSpacing">A character spacing</param>
  214. /// <param name="lineSpacing">A line spacing</param>
  215. public float DrawText(IFontStashRenderer renderer, StringBuilder text, Vector2 position, Color color,
  216. Vector2? scale = null, float rotation = 0, Vector2 origin = default(Vector2),
  217. float layerDepth = 0.0f, float characterSpacing = 0.0f, float lineSpacing = 0.0f,
  218. TextStyle textStyle = TextStyle.None) =>
  219. DrawText(renderer, new TextColorSource(text, color), position, scale, rotation, origin, layerDepth, characterSpacing, lineSpacing, textStyle);
  220. /// <summary>
  221. /// Draws a text
  222. /// </summary>
  223. /// <param name="renderer">A renderer</param>
  224. /// <param name="text">The text which will be drawn</param>
  225. /// <param name="position">The drawing location on screen</param>
  226. /// <param name="colors">Colors of glyphs</param>
  227. /// <param name="rotation">A rotation of this text in radians</param>
  228. /// <param name="origin">Center of the rotation</param>
  229. /// <param name="scale">A scaling of this text. Null means the scaling is (1, 1)</param>
  230. /// <param name="layerDepth">A depth of the layer of this string</param>
  231. /// <param name="characterSpacing">A character spacing</param>
  232. /// <param name="lineSpacing">A line spacing</param>
  233. public float DrawText(IFontStashRenderer renderer, StringBuilder text, Vector2 position, Color[] colors,
  234. Vector2? scale = null, float rotation = 0, Vector2 origin = default(Vector2),
  235. float layerDepth = 0.0f, float characterSpacing = 0.0f, float lineSpacing = 0.0f,
  236. TextStyle textStyle = TextStyle.None) =>
  237. DrawText(renderer, new TextColorSource(text, colors), position, scale, rotation, origin, layerDepth, characterSpacing, lineSpacing, textStyle);
  238. }
  239. }