PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/TeXmacs-1.0.7.11-src/src/Typeset/Boxes/Composite/misc_boxes.cpp

#
C++ | 209 lines | 162 code | 26 blank | 21 comment | 28 complexity | e8743e7358dea628d0eb5fc96b46f7a2 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception
  1. /******************************************************************************
  2. * MODULE : misc.cpp
  3. * DESCRIPTION: Miscellaneous composite boxes
  4. * COPYRIGHT : (C) 1999 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 "Boxes/composite.hpp"
  11. #include "Boxes/construct.hpp"
  12. /******************************************************************************
  13. * A page box contains a main box and decorations
  14. ******************************************************************************/
  15. struct scatter_box_rep: composite_box_rep {
  16. tree page;
  17. box decoration;
  18. scatter_box_rep (path ip, array<box> bs, array<SI> x, array<SI> y);
  19. operator tree ();
  20. int find_child (SI x, SI y, SI delta, bool force);
  21. path find_left_box_path ();
  22. path find_right_box_path ();
  23. selection find_selection (path lbp, path rbp);
  24. };
  25. scatter_box_rep::scatter_box_rep (
  26. path ip2, array<box> bs, array<SI> x, array<SI> y):
  27. composite_box_rep (ip2, bs, x, y)
  28. {
  29. finalize ();
  30. }
  31. scatter_box_rep::operator tree () {
  32. int i, n= N(bs);
  33. tree t (TUPLE, n+1);
  34. t[0]= "scattered";
  35. for (i=0; i<n; i++) t[i+1]= (tree) bs[i];
  36. return t;
  37. }
  38. int
  39. scatter_box_rep::find_child (SI x, SI y, SI delta, bool force) {
  40. int i, n= subnr(), d= MAX_SI, m= -1;
  41. for (i=0; i<n; i++)
  42. if (distance (i, x, y, delta)< d)
  43. if (bs[i]->accessible () || force) {
  44. d= distance (i, x, y, delta);
  45. m= i;
  46. }
  47. return m;
  48. }
  49. path
  50. scatter_box_rep::find_left_box_path () {
  51. return path (0, bs[0]->find_left_box_path ());
  52. }
  53. path
  54. scatter_box_rep::find_right_box_path () {
  55. return path (N(bs)-1, bs[N(bs)-1]->find_right_box_path ());
  56. }
  57. selection
  58. scatter_box_rep::find_selection (path lbp, path rbp) {
  59. if (is_nil (lbp) || is_nil (rbp) || is_atom (lbp) || is_atom (rbp))
  60. return composite_box_rep::find_selection (lbp, rbp);
  61. else {
  62. int i;
  63. selection sel; sel->valid= true;
  64. for (i=lbp->item; i<=rbp->item; i++) {
  65. path lsp= (i==lbp->item? lbp->next: bs[i]->find_left_box_path ());
  66. path rsp= (i==rbp->item? rbp->next: bs[i]->find_right_box_path ());
  67. selection ssel= bs[i]->find_selection (lsp, rsp);
  68. sel->valid= sel->valid && ssel->valid;
  69. sel->rs << translate (ssel->rs, sx(i), sy(i));
  70. if (i==lbp->item) sel->start= ssel->start;
  71. if (i==rbp->item) sel->end = ssel->end ;
  72. }
  73. return sel;
  74. }
  75. }
  76. /******************************************************************************
  77. * A page box contains a main box and decorations
  78. ******************************************************************************/
  79. struct page_box_rep: composite_box_rep {
  80. tree page;
  81. box decoration;
  82. page_box_rep (path ip, tree page, SI w, SI h,
  83. array<box> bs, array<SI> x, array<SI> y, box dec);
  84. operator tree ();
  85. int find_child (SI x, SI y, SI delta, bool force);
  86. void display (renderer ren);
  87. void clear_incomplete (rectangles& rs, SI pixel, int i, int i1, int i2);
  88. void collect_page_numbers (hashmap<string,tree>& h, tree page);
  89. path find_left_box_path ();
  90. path find_right_box_path ();
  91. };
  92. page_box_rep::page_box_rep (path ip2, tree page2, SI w, SI h,
  93. array<box> bs, array<SI> x, array<SI> y, box dec):
  94. composite_box_rep (ip2, bs, x, y), page (page2), decoration (dec)
  95. {
  96. x1= min (x1, 0);
  97. x2= max (x2, w);
  98. y1= -h;
  99. y2= 0;
  100. if (!is_nil (decoration)) {
  101. x3= min (x3, decoration->x0+ decoration->x3);
  102. x4= max (x4, decoration->x0+ decoration->x4);
  103. y3= min (y3, decoration->y0+ decoration->y3);
  104. y4= max (y4, decoration->y0+ decoration->y4);
  105. }
  106. finalize ();
  107. }
  108. page_box_rep::operator tree () {
  109. int i, n= N(bs);
  110. tree t (TUPLE, n+1);
  111. if (is_atomic (page)) t[0]= "page-" * page->label;
  112. else t[0]= "page";
  113. for (i=0; i<n; i++) t[i+1]= (tree) bs[i];
  114. return t;
  115. }
  116. int
  117. page_box_rep::find_child (SI x, SI y, SI delta, bool force) {
  118. int i, n= subnr(), d= MAX_SI, m= -1;
  119. for (i=0; i<n; i++)
  120. if (distance (i, x, y, delta)< d)
  121. if (bs[i]->accessible () || force) {
  122. d= distance (i, x, y, delta);
  123. m= i;
  124. }
  125. return m;
  126. }
  127. void
  128. page_box_rep::display (renderer ren) {
  129. if (!is_nil (decoration)) {
  130. rectangles rs;
  131. decoration->redraw (ren, path (), rs);
  132. }
  133. }
  134. void
  135. page_box_rep::clear_incomplete (
  136. rectangles& rs, SI pixel, int which, int i1, int i2)
  137. {
  138. (void) which; (void) i1; (void) i2;
  139. rectangle r1 (sx3 (0)- 2*pixel, sy3 (0)- 2*pixel,
  140. sx4 (0)+ 2*pixel, sy4 (0)+ 2*pixel);
  141. rectangles extra (rectangle (x1, y1, x2, y2));
  142. // cout << "context= " << extra << "\n";
  143. // cout << "main = " << r1 << "\n";
  144. extra = extra - r1;
  145. if (!is_nil (decoration)) {
  146. int i, n= N (decoration);
  147. for (i=0; i<n; i++) {
  148. box b= decoration [i];
  149. rectangle r (b->x0+ b->x3, b->y0+ b->y3, b->x0+ b->x4, b->y0+ b->y4);
  150. if ((r->x2 > r->x1) && (r->y2 > r->y1)) extra = extra - r;
  151. }
  152. // cout << "extra = " << extra << "\n";
  153. }
  154. rs= extra * rs;
  155. }
  156. void
  157. page_box_rep::collect_page_numbers (hashmap<string,tree>& h, tree dummy) {
  158. (void) dummy;
  159. bs[0]->collect_page_numbers (h, page);
  160. }
  161. path
  162. page_box_rep::find_left_box_path () {
  163. return path (0, bs[0]->find_left_box_path ());
  164. }
  165. path
  166. page_box_rep::find_right_box_path () {
  167. return path (N(bs)-1, bs[N(bs)-1]->find_right_box_path ());
  168. }
  169. /******************************************************************************
  170. * box construction routines
  171. ******************************************************************************/
  172. box
  173. scatter_box (path ip, array<box> bs, array<SI> x, array<SI> y) {
  174. return tm_new<scatter_box_rep> (ip, bs, x, y);
  175. }
  176. box
  177. page_box (path ip, tree page, SI w, SI h,
  178. array<box> bs, array<SI> bs_x, array<SI> bs_y,
  179. array<box> decs, array<SI> decs_x, array<SI> decs_y) {
  180. box dec;
  181. if (N (decs) > 0) dec= composite_box (ip, decs, decs_x, decs_y, false);
  182. return tm_new<page_box_rep> (ip, page, w, h, bs, bs_x, bs_y, dec);
  183. }