PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/TeXmacs-1.0.7.11-src/src/Graphics/Fonts/compound_font.cpp

#
C++ | 178 lines | 135 code | 20 blank | 23 comment | 25 complexity | 9d27b60d551a13609bc55fb563daf5ce MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception
  1. /******************************************************************************
  2. * MODULE : compound_font.cpp
  3. * DESCRIPTION: fonts which are agglomerated from several other fonts.
  4. * COPYRIGHT : (C) 2005 Joris van der Hoeven
  5. *******************************************************************************
  6. * This software falls under the GNU general public license version 3 or later.
  7. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  8. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
  9. ******************************************************************************/
  10. #include "font.hpp"
  11. #include "charmap.hpp"
  12. #include "convert.hpp"
  13. /******************************************************************************
  14. * The compound font class
  15. ******************************************************************************/
  16. static tree
  17. map_car (tree t) {
  18. int i, n= N(t);
  19. tree r (TUPLE, n);
  20. for (i=0; i<n; i++)
  21. r[i]= t[i][0];
  22. return r;
  23. }
  24. struct compound_font_rep: font_rep {
  25. scheme_tree def;
  26. array<font> fn;
  27. charmap cm;
  28. compound_font_rep (string name, scheme_tree def, array<font> fn);
  29. void advance (string s, int& pos, string& r, int& ch);
  30. void get_extents (string s, metric& ex);
  31. void draw (renderer ren, string s, SI x, SI y);
  32. glyph get_glyph (string s);
  33. double get_left_slope (string s);
  34. double get_right_slope (string s);
  35. SI get_left_correction (string s);
  36. SI get_right_correction (string s);
  37. };
  38. compound_font_rep::compound_font_rep (
  39. string name, scheme_tree def2, array<font> fn2):
  40. font_rep (name, fn2[0]),
  41. def (def2), fn (fn2), cm (load_charmap (map_car (def)))
  42. {}
  43. void
  44. compound_font_rep::advance (string s, int& pos, string& r, int& ch) {
  45. cm->advance (s, pos, r, ch);
  46. //cout << "(r,ch)= (" << r << "," << ch << ")\n";
  47. if (ch>0 && is_nil (fn[ch])) {
  48. tree t= def[ch][1];
  49. if (is_tuple (t, "virtual", 3))
  50. fn[ch]= virtual_font (this, as_string(t[1]), as_int(t[2]), as_int(t[3]));
  51. else fn[ch]= find_font (t);
  52. ASSERT (!is_nil (fn[ch]), "font not found");
  53. //fn[ch]->copy_math_pars (fn[0]);
  54. }
  55. }
  56. /******************************************************************************
  57. * Getting extents and drawing strings
  58. ******************************************************************************/
  59. static string empty_string ("");
  60. void
  61. compound_font_rep::get_extents (string s, metric& ex) {
  62. int i=0, n= N(s);
  63. fn[0]->get_extents (empty_string, ex);
  64. while (i < n) {
  65. int nr;
  66. string r= s;
  67. metric ey;
  68. advance (s, i, r, nr);
  69. if (nr >= 0) {
  70. fn[nr]->get_extents (r, ey);
  71. ex->y1= min (ex->y1, ey->y1);
  72. ex->y2= max (ex->y2, ey->y2);
  73. ex->x3= min (ex->x3, ex->x2 + ey->x3);
  74. ex->y3= min (ex->y3, ey->y3);
  75. ex->x4= max (ex->x4, ex->x2 + ey->x4);
  76. ex->y4= max (ex->y4, ey->y4);
  77. ex->x2 += ey->x2;
  78. }
  79. }
  80. }
  81. void
  82. compound_font_rep::draw (renderer ren, string s, SI x, SI y) {
  83. int i=0, n= N(s);
  84. while (i < n) {
  85. int nr;
  86. string r= s;
  87. metric ey;
  88. advance (s, i, r, nr);
  89. if (nr >= 0) {
  90. fn[nr]->draw (ren, r, x, y);
  91. if (i < n) {
  92. fn[nr]->get_extents (r, ey);
  93. x += ey->x2;
  94. }
  95. }
  96. }
  97. }
  98. /******************************************************************************
  99. * Other routines for fonts
  100. ******************************************************************************/
  101. glyph
  102. compound_font_rep::get_glyph (string s) {
  103. int i=0, n= N(s), nr;
  104. if (n == 0) return fn[0]->get_glyph (s);
  105. string r= s;
  106. advance (s, i, r, nr);
  107. if (nr<0) return glyph ();
  108. return fn[nr]->get_glyph (r);
  109. }
  110. double
  111. compound_font_rep::get_left_slope (string s) {
  112. int i=0, n= N(s), nr;
  113. if (n == 0) return fn[0]->get_left_slope (s);
  114. string r= s;
  115. advance (s, i, r, nr);
  116. nr= max (nr, 0);
  117. return fn[nr]->get_left_slope (r);
  118. }
  119. double
  120. compound_font_rep::get_right_slope (string s) {
  121. int i=0, n= N(s), nr;
  122. if (n == 0) return fn[0]->get_right_slope (s);
  123. string r= s;
  124. while (i<n) advance (s, i, r, nr);
  125. nr= max (nr, 0);
  126. return fn[nr]->get_right_slope (r);
  127. }
  128. SI
  129. compound_font_rep::get_left_correction (string s) {
  130. int i=0, n= N(s), nr;
  131. if (n == 0) return fn[0]->get_left_correction (s);
  132. string r= s;
  133. advance (s, i, r, nr);
  134. nr= max (nr, 0);
  135. return fn[nr]->get_left_correction (r);
  136. }
  137. SI
  138. compound_font_rep::get_right_correction (string s) {
  139. int i=0, n= N(s), nr;
  140. if (n == 0) return fn[0]->get_right_correction (s);
  141. string r= s;
  142. while (i<n) advance (s, i, r, nr);
  143. nr= max (nr, 0);
  144. return fn[nr]->get_right_correction (r);
  145. }
  146. /******************************************************************************
  147. * User interface
  148. ******************************************************************************/
  149. font
  150. compound_font (scheme_tree def) {
  151. string name= tree_to_scheme (def);
  152. if (font::instances->contains (name))
  153. return font (name);
  154. array<font> fn (N(def));
  155. fn[0]= find_font (def[0][1]);
  156. if (is_nil (fn[0])) return font ();
  157. return make (font, name, tm_new<compound_font_rep> (name, def, fn));
  158. }