SvgFont.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace WMFConverter.Svg
  7. {
  8. /// <summary>
  9. /// Scalable Vector Graphics - Represents a SVG Font object.
  10. /// </summary>
  11. public class SvgFont : SvgObject,Gdi.IGdiFont
  12. {
  13. #region Properties
  14. /// <summary>
  15. /// Object height.
  16. /// </summary>
  17. public int Height
  18. {
  19. get
  20. {
  21. return _height;
  22. }
  23. }
  24. /// <summary>
  25. /// Object width.
  26. /// </summary>
  27. public int Width
  28. {
  29. get
  30. {
  31. return _width;
  32. }
  33. }
  34. /// <summary>
  35. /// Object escapement.
  36. /// </summary>
  37. public int Escapement
  38. {
  39. get
  40. {
  41. return _escapement;
  42. }
  43. }
  44. /// <summary>
  45. /// Object orientation
  46. /// </summary>
  47. public int Orientation
  48. {
  49. get
  50. {
  51. return _orientation;
  52. }
  53. }
  54. /// <summary>
  55. /// Object weight.
  56. /// </summary>
  57. public int Weight
  58. {
  59. get
  60. {
  61. return _weight;
  62. }
  63. }
  64. /// <summary>
  65. /// Italic font.
  66. /// </summary>
  67. public bool IsItalic
  68. {
  69. get
  70. {
  71. return _italic;
  72. }
  73. }
  74. /// <summary>
  75. /// Underlined font.
  76. /// </summary>
  77. public bool IsUnderlined
  78. {
  79. get
  80. {
  81. return _underline;
  82. }
  83. }
  84. /// <summary>
  85. /// Striked font.
  86. /// </summary>
  87. public bool IsStrikedOut
  88. {
  89. get
  90. {
  91. return _strikeout;
  92. }
  93. }
  94. /// <summary>
  95. /// Object charset.
  96. /// </summary>
  97. public int Charset
  98. {
  99. get
  100. {
  101. return _charset;
  102. }
  103. }
  104. /// <summary>
  105. /// Object precision.
  106. /// </summary>
  107. public int OutPrecision
  108. {
  109. get
  110. {
  111. return _outPrecision;
  112. }
  113. }
  114. /// <summary>
  115. /// Object ClipPrecision.
  116. /// </summary>
  117. public int ClipPrecision
  118. {
  119. get
  120. {
  121. return _clipPrecision;
  122. }
  123. }
  124. /// <summary>
  125. /// Font quality.
  126. /// </summary>
  127. public int Quality
  128. {
  129. get
  130. {
  131. return _quality;
  132. }
  133. }
  134. /// <summary>
  135. /// Defines pitch and family.
  136. /// </summary>
  137. public int PitchAndFamily
  138. {
  139. get
  140. {
  141. return _pitchAndFamily;
  142. }
  143. }
  144. /// <summary>
  145. /// Specifies the font name.
  146. /// </summary>
  147. public string FaceName
  148. {
  149. get
  150. {
  151. return _faceName;
  152. }
  153. }
  154. /// <summary>
  155. /// Font language.
  156. /// </summary>
  157. public string Lang
  158. {
  159. get
  160. {
  161. return _lang;
  162. }
  163. }
  164. /// <summary>
  165. /// Font size.
  166. /// </summary>
  167. public int FontSize
  168. {
  169. get
  170. {
  171. return Math.Abs((int)GDI.DC.ToRelativeY(_height * _heightMultiply));
  172. }
  173. }
  174. #endregion
  175. #region Local Variables
  176. private int _height;
  177. private int _width;
  178. private int _escapement;
  179. private int _orientation;
  180. private int _weight;
  181. private bool _italic;
  182. private bool _underline;
  183. private bool _strikeout;
  184. private int _charset;
  185. private int _outPrecision;
  186. private int _clipPrecision;
  187. private int _quality;
  188. private int _pitchAndFamily;
  189. private string _faceName;
  190. private double _heightMultiply = 1.0;
  191. private string _lang;
  192. #endregion
  193. #region Constructors
  194. /// <summary>
  195. /// Default Constructor.
  196. /// </summary>
  197. /// <param name="gdi"></param>
  198. /// <param name="height"></param>
  199. /// <param name="width"></param>
  200. /// <param name="escapement"></param>
  201. /// <param name="orientation"></param>
  202. /// <param name="weight"></param>
  203. /// <param name="italic"></param>
  204. /// <param name="underline"></param>
  205. /// <param name="strikeout"></param>
  206. /// <param name="charset"></param>
  207. /// <param name="outPrecision"></param>
  208. /// <param name="clipPrecision"></param>
  209. /// <param name="quality"></param>
  210. /// <param name="pitchAndFamily"></param>
  211. /// <param name="faceName"></param>
  212. public SvgFont(
  213. SvgGdi gdi,
  214. int height,
  215. int width,
  216. int escapement,
  217. int orientation,
  218. int weight,
  219. bool italic,
  220. bool underline,
  221. bool strikeout,
  222. int charset,
  223. int outPrecision,
  224. int clipPrecision,
  225. int quality,
  226. int pitchAndFamily,
  227. byte[] faceName)
  228. : base (gdi)
  229. {
  230. _height = height;
  231. _width = width;
  232. _escapement = escapement;
  233. _orientation = orientation;
  234. _weight = weight;
  235. _italic = italic;
  236. _underline = underline;
  237. _strikeout = strikeout;
  238. _charset = charset;
  239. _outPrecision = outPrecision;
  240. _clipPrecision = clipPrecision;
  241. _quality = quality;
  242. _pitchAndFamily = pitchAndFamily;
  243. _faceName = WMFConverter.Gdi.GdiUtils.ConvertString(faceName, charset);
  244. // xml:lang
  245. _lang = WMFConverter.Gdi.GdiUtils.GetLanguage(charset);
  246. string emheight = gdi.GetProperty("font-emheight." + _faceName);
  247. if (emheight == null)
  248. {
  249. string alter = gdi.GetProperty("alternative-font." + _faceName);
  250. if (alter != null)
  251. {
  252. emheight = gdi.GetProperty("font-emheight." + alter);
  253. }
  254. }
  255. if (emheight != null)
  256. {
  257. _heightMultiply = Convert.ToDouble(emheight);
  258. }
  259. }
  260. #endregion
  261. #region Public Methods
  262. /// <summary>
  263. ///
  264. /// </summary>
  265. /// <param name="chars"></param>
  266. /// <param name="dx"></param>
  267. /// <returns></returns>
  268. public int[] ValidateDx(byte[] chars, int[] dx)
  269. {
  270. if (dx == null || dx.Length == 0)
  271. {
  272. return null;
  273. }
  274. int[,] area = WMFConverter.Gdi.GdiUtils.GetFirstByteArea(_charset);
  275. if (area == null)
  276. {
  277. return dx;
  278. }
  279. int n = 0;
  280. bool skip = false;
  281. for (int i = 0; i < chars.Length && i < dx.Length; i++)
  282. {
  283. int c = (0xFF & chars[i]);
  284. if (skip)
  285. {
  286. dx[n - 1] += dx[i];
  287. skip = false;
  288. continue;
  289. }
  290. for (int j = 0; j < area.Length; j++)
  291. {
  292. if (area[j,0] <= c && c <= area[j,1])
  293. {
  294. skip = true;
  295. break;
  296. }
  297. }
  298. dx[n++] = dx[i];
  299. }
  300. int[] ndx = new int[n];
  301. Array.Copy(dx, 0, ndx, 0, n);
  302. return ndx;
  303. }
  304. /// <summary>
  305. /// Serves as the default hash function.
  306. /// </summary>
  307. /// <returns></returns>
  308. public override int GetHashCode()
  309. {
  310. int PRIME = 31;
  311. int result = 1;
  312. result = PRIME * result + _charset;
  313. result = PRIME * result + _clipPrecision;
  314. result = PRIME * result + _escapement;
  315. result = PRIME * result + ((_faceName == null) ? 0 : _faceName.GetHashCode());
  316. result = PRIME * result + _height;
  317. result = PRIME * result + (_italic ? 1231 : 1237);
  318. result = PRIME * result + _orientation;
  319. result = PRIME * result + _outPrecision;
  320. result = PRIME * result + _pitchAndFamily;
  321. result = PRIME * result + _quality;
  322. result = PRIME * result + (_strikeout ? 1231 : 1237);
  323. result = PRIME * result + (_underline ? 1231 : 1237);
  324. result = PRIME * result + _weight;
  325. result = PRIME * result + _width;
  326. return result;
  327. }
  328. /// <summary>
  329. /// Determines whether the specified object is equal to the current object.
  330. /// </summary>
  331. /// <param name="obj"></param>
  332. /// <returns></returns>
  333. public override bool Equals(Object obj)
  334. {
  335. if (this == obj)
  336. return true;
  337. if (obj == null)
  338. return false;
  339. if (typeof(SvgFont) != obj.GetType())
  340. return false;
  341. SvgFont other = (SvgFont) obj;
  342. if (_charset != other._charset)
  343. return false;
  344. if (_clipPrecision != other._clipPrecision)
  345. return false;
  346. if (_escapement != other._escapement)
  347. return false;
  348. if (_faceName == null)
  349. {
  350. if (other._faceName != null)
  351. return false;
  352. }
  353. else if (!_faceName.Equals(other._faceName))
  354. return false;
  355. if (_height != other._height)
  356. return false;
  357. if (_italic != other._italic)
  358. return false;
  359. if (_orientation != other._orientation)
  360. return false;
  361. if (_outPrecision != other._outPrecision)
  362. return false;
  363. if (_pitchAndFamily != other._pitchAndFamily)
  364. return false;
  365. if (_quality != other._quality)
  366. return false;
  367. if (_strikeout != other._strikeout)
  368. return false;
  369. if (_underline != other._underline)
  370. return false;
  371. if (_weight != other._weight)
  372. return false;
  373. if (_width != other._width)
  374. return false;
  375. return true;
  376. }
  377. /// <summary>
  378. /// Create inner text element.
  379. /// </summary>
  380. /// <param name="id"></param>
  381. /// <returns></returns>
  382. public System.Xml.XmlText CreateTextNode(string id)
  383. {
  384. return GDI.Document.CreateTextNode("." + id + " { " + ToString() + " }\r\n");
  385. }
  386. /// <summary>
  387. /// Returns a string that represents the current object.
  388. /// </summary>
  389. /// <returns></returns>
  390. public override string ToString()
  391. {
  392. System.Text.StringBuilder buffer = new System.Text.StringBuilder();
  393. // font-style
  394. if (_italic)
  395. buffer.Append("font-style: italic; ");
  396. // font-weight
  397. if (_weight != (int)Gdi.FontFWEnum.FW_DONTCARE && _weight != (int)Gdi.FontFWEnum.FW_NORMAL)
  398. {
  399. if (_weight < 100)
  400. _weight = 100;
  401. else if (_weight > 900)
  402. _weight = 900;
  403. else
  404. _weight = (_weight / 100) * 100;
  405. if (_weight == (int)Gdi.FontFWEnum.FW_BOLD)
  406. buffer.Append("font-weight: bold; ");
  407. else
  408. buffer.Append("font-weight: " + _weight + "; ");
  409. }
  410. int fontSize = FontSize;
  411. if (fontSize != 0)
  412. buffer.Append("font-size: ").Append(fontSize).Append("px; ");
  413. // font-family
  414. List<string> fontList = new List<string>();
  415. if (_faceName.Length != 0)
  416. {
  417. string fontFamily = _faceName;
  418. if (_faceName.ElementAt(0) == '@') fontFamily = _faceName.Substring(1);
  419. fontList.Add(fontFamily);
  420. string altfont = GDI.GetProperty("alternative-font." + fontFamily);
  421. if (altfont != null && altfont.Length != 0)
  422. {
  423. fontList.Add(altfont);
  424. }
  425. }
  426. // int pitch = pitchAndFamily & 0x00000003;
  427. int family = _pitchAndFamily & 0x000000F0;
  428. switch (family)
  429. {
  430. case (int)Gdi.FontFFEnum.FF_DECORATIVE:
  431. fontList.Add("fantasy");
  432. break;
  433. case (int)Gdi.FontFFEnum.FF_MODERN:
  434. fontList.Add("monospace");
  435. break;
  436. case (int)Gdi.FontFFEnum.FF_ROMAN:
  437. fontList.Add("serif");
  438. break;
  439. case (int)Gdi.FontFFEnum.FF_SCRIPT:
  440. fontList.Add("cursive");
  441. break;
  442. case (int)Gdi.FontFFEnum.FF_SWISS:
  443. fontList.Add("sans-serif");
  444. break;
  445. }
  446. if (fontList != null)
  447. if (fontList.Count()>0)
  448. {
  449. buffer.Append("font-family:");
  450. for (int i = 0; i < fontList.Count(); i ++ )
  451. {
  452. string font = fontList[i];
  453. if (font.IndexOf(" ") != -1)
  454. buffer.Append(" \"" + font + "\"");
  455. else
  456. buffer.Append(" " + font);
  457. if (i < fontList.Count())
  458. buffer.Append(",");
  459. }
  460. buffer.Append("; ");
  461. }
  462. // text-decoration
  463. if (_underline || _strikeout)
  464. {
  465. buffer.Append("text-decoration:");
  466. if (_underline)
  467. buffer.Append(" underline");
  468. if (_strikeout)
  469. buffer.Append(" overline");
  470. buffer.Append("; ");
  471. }
  472. if (buffer.Length > 0)
  473. buffer.Length = buffer.Length - 1;
  474. return buffer.ToString();
  475. }
  476. #endregion
  477. }
  478. }