Back to index

texmacs  1.0.7.15
misc_boxes.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : misc.cpp
00004 * DESCRIPTION: Miscellaneous composite boxes
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "Boxes/composite.hpp"
00013 #include "Boxes/construct.hpp"
00014 
00015 /******************************************************************************
00016 * A page box contains a main box and decorations
00017 ******************************************************************************/
00018 
00019 struct scatter_box_rep: composite_box_rep {
00020   tree page;
00021   box  decoration;
00022 
00023   scatter_box_rep (path ip, array<box> bs, array<SI> x, array<SI> y);
00024   operator tree ();
00025   int       find_child (SI x, SI y, SI delta, bool force);
00026   path      find_left_box_path ();
00027   path      find_right_box_path ();
00028   selection find_selection (path lbp, path rbp);
00029 };
00030 
00031 scatter_box_rep::scatter_box_rep (
00032   path ip2, array<box> bs, array<SI> x, array<SI> y):
00033     composite_box_rep (ip2, bs, x, y)
00034 {
00035   finalize ();
00036 }
00037 
00038 scatter_box_rep::operator tree () {
00039   int i, n= N(bs);
00040   tree t (TUPLE, n+1);
00041   t[0]= "scattered";
00042   for (i=0; i<n; i++) t[i+1]= (tree) bs[i];
00043   return t;
00044 }
00045 
00046 int
00047 scatter_box_rep::find_child (SI x, SI y, SI delta, bool force) {
00048   int i, n= subnr(), d= MAX_SI, m= -1;
00049   for (i=0; i<n; i++)
00050     if (distance (i, x, y, delta)< d)
00051       if (bs[i]->accessible () || force) {
00052        d= distance (i, x, y, delta);
00053        m= i;
00054       }
00055   return m;
00056 }
00057 
00058 path
00059 scatter_box_rep::find_left_box_path () {
00060   return path (0, bs[0]->find_left_box_path ());
00061 }
00062 
00063 path
00064 scatter_box_rep::find_right_box_path () {
00065   return path (N(bs)-1, bs[N(bs)-1]->find_right_box_path ());
00066 }
00067 
00068 selection
00069 scatter_box_rep::find_selection (path lbp, path rbp) {
00070   if (is_nil (lbp) || is_nil (rbp) || is_atom (lbp) || is_atom (rbp))
00071     return composite_box_rep::find_selection (lbp, rbp);
00072   else {
00073     int i;
00074     selection sel; sel->valid= true;
00075     for (i=lbp->item; i<=rbp->item; i++) {
00076       path lsp= (i==lbp->item? lbp->next: bs[i]->find_left_box_path  ());
00077       path rsp= (i==rbp->item? rbp->next: bs[i]->find_right_box_path ());
00078       selection ssel= bs[i]->find_selection (lsp, rsp);
00079       sel->valid= sel->valid && ssel->valid;
00080       sel->rs << translate (ssel->rs, sx(i), sy(i));
00081       if (i==lbp->item) sel->start= ssel->start;
00082       if (i==rbp->item) sel->end  = ssel->end  ;
00083     }
00084     return sel;
00085   }
00086 }
00087 
00088 /******************************************************************************
00089 * A page box contains a main box and decorations
00090 ******************************************************************************/
00091 
00092 struct page_box_rep: composite_box_rep {
00093   tree page;
00094   box  decoration;
00095 
00096   page_box_rep (path ip, tree page, SI w, SI h,
00097               array<box> bs, array<SI> x, array<SI> y, box dec);
00098   operator tree ();
00099   int find_child (SI x, SI y, SI delta, bool force);
00100   void display (renderer ren);
00101   void clear_incomplete (rectangles& rs, SI pixel, int i, int i1, int i2);
00102   void collect_page_numbers (hashmap<string,tree>& h, tree page);
00103   path find_left_box_path ();
00104   path find_right_box_path ();
00105 };
00106 
00107 page_box_rep::page_box_rep (path ip2, tree page2, SI w, SI h,
00108                          array<box> bs, array<SI> x, array<SI> y, box dec):
00109   composite_box_rep (ip2, bs, x, y), page (page2), decoration (dec)
00110 {
00111   x1= min (x1, 0);
00112   x2= max (x2, w);
00113   y1= -h;
00114   y2= 0;
00115   if (!is_nil (decoration)) {
00116     x3= min (x3, decoration->x0+ decoration->x3);
00117     x4= max (x4, decoration->x0+ decoration->x4);
00118     y3= min (y3, decoration->y0+ decoration->y3);
00119     y4= max (y4, decoration->y0+ decoration->y4);
00120   }
00121   finalize ();
00122 }
00123 
00124 page_box_rep::operator tree () {
00125   int i, n= N(bs);
00126   tree t (TUPLE, n+1);
00127   if (is_atomic (page)) t[0]= "page-" * page->label;
00128   else t[0]= "page";
00129   for (i=0; i<n; i++) t[i+1]= (tree) bs[i];
00130   return t;
00131 }
00132 
00133 int
00134 page_box_rep::find_child (SI x, SI y, SI delta, bool force) {
00135   int i, n= subnr(), d= MAX_SI, m= -1;
00136   for (i=0; i<n; i++)
00137     if (distance (i, x, y, delta)< d)
00138       if (bs[i]->accessible () || force) {
00139        d= distance (i, x, y, delta);
00140        m= i;
00141       }
00142   return m;
00143 }
00144 
00145 void
00146 page_box_rep::display (renderer ren) {
00147   if (!is_nil (decoration)) {
00148     rectangles rs;
00149     decoration->redraw (ren, path (), rs);
00150   }
00151 }
00152 
00153 void
00154 page_box_rep::clear_incomplete (
00155   rectangles& rs, SI pixel, int which, int i1, int i2)
00156 {
00157   (void) which; (void) i1; (void) i2;
00158   rectangle r1 (sx3 (0)- 2*pixel, sy3 (0)- 2*pixel,
00159               sx4 (0)+ 2*pixel, sy4 (0)+ 2*pixel);
00160   rectangles extra (rectangle (x1, y1, x2, y2));
00161   // cout << "context= " << extra << "\n";
00162   // cout << "main   = " << r1 << "\n";
00163   extra = extra - r1;
00164 
00165   if (!is_nil (decoration)) {
00166     int i, n= N (decoration);
00167     for (i=0; i<n; i++) {
00168       box b= decoration [i];
00169       rectangle r (b->x0+ b->x3, b->y0+ b->y3, b->x0+ b->x4, b->y0+ b->y4);
00170       if ((r->x2 > r->x1) && (r->y2 > r->y1)) extra = extra - r;
00171     }
00172     // cout << "extra  = " << extra << "\n";
00173   }
00174   rs= extra * rs;
00175 }
00176 
00177 void
00178 page_box_rep::collect_page_numbers (hashmap<string,tree>& h, tree dummy) {
00179   (void) dummy;
00180   bs[0]->collect_page_numbers (h, page);
00181 }
00182 
00183 path
00184 page_box_rep::find_left_box_path () {
00185   return path (0, bs[0]->find_left_box_path ());
00186 }
00187 
00188 path
00189 page_box_rep::find_right_box_path () {
00190   return path (N(bs)-1, bs[N(bs)-1]->find_right_box_path ());
00191 }
00192 
00193 /******************************************************************************
00194 * box construction routines
00195 ******************************************************************************/
00196 
00197 box
00198 scatter_box (path ip, array<box> bs, array<SI> x, array<SI> y) {
00199   return tm_new<scatter_box_rep> (ip, bs, x, y);
00200 }
00201 
00202 box
00203 page_box (path ip, tree page, SI w, SI h,
00204          array<box> bs, array<SI> bs_x, array<SI> bs_y,
00205          array<box> decs, array<SI> decs_x, array<SI> decs_y) {
00206   box dec;
00207   if (N (decs) > 0) dec= composite_box (ip, decs, decs_x, decs_y, false);
00208   return tm_new<page_box_rep> (ip, page, w, h, bs, bs_x, bs_y, dec);
00209 }