Back to index

texmacs  1.0.7.15
change_boxes.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : change.cpp
00004 * DESCRIPTION: Boxes whose behaviour is changed
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 #include "scheme.hpp"
00015 #include "gui.hpp"
00016 
00017 /******************************************************************************
00018 * changing the behaviour of a box
00019 ******************************************************************************/
00020 
00021 struct change_box_rep: public composite_box_rep {
00022   bool child_flag, big_flag;
00023   change_box_rep (path ip, bool child_flag, bool big_flag= false);
00024   operator tree () { return tree (TUPLE, "change", (tree) bs[0]); }
00025   int find_child (SI x, SI y, SI delta, bool force);
00026   path find_left_box_path () {
00027     return child_flag?
00028       composite_box_rep::find_left_box_path ():
00029       path (0, bs[0]->find_left_box_path ()); }
00030   path find_right_box_path () {
00031     return child_flag?
00032       composite_box_rep::find_right_box_path ():
00033       path (0, bs[0]->find_right_box_path ()); }
00034 
00035   double left_slope () {
00036     return big_flag? bs[0]->left_slope(): box_rep::left_slope(); }
00037   double right_slope () { 
00038     return big_flag? bs[0]->right_slope(): box_rep::right_slope(); }
00039   SI left_correction () {
00040     return big_flag? bs[0]->left_correction():box_rep::left_correction(); }
00041   SI right_correction () {
00042     return big_flag? bs[0]->right_correction():box_rep::right_correction(); }
00043   SI lsub_correction () {
00044     return big_flag? bs[0]->lsub_correction(): box_rep::lsub_correction(); }
00045   SI lsup_correction () {
00046     return big_flag? bs[0]->lsup_correction(): box_rep::lsup_correction(); }
00047   SI rsub_correction () {
00048     return big_flag? bs[0]->rsub_correction(): box_rep::rsub_correction(); }
00049   SI rsup_correction () {
00050     return big_flag? bs[0]->rsup_correction(): box_rep::rsup_correction(); }
00051   SI sub_lo_base (int l) {
00052     return big_flag? bs[0]->sub_lo_base (l): box_rep::sub_lo_base (l); }
00053   SI sub_hi_lim  (int l) {
00054     return big_flag? bs[0]->sub_hi_lim (l): box_rep::sub_hi_lim (l); }
00055   SI sup_lo_lim  (int l) {
00056     return big_flag? bs[0]->sup_lo_lim (l): box_rep::sup_lo_lim (l); }
00057   SI sup_lo_base (int l) {
00058     return big_flag? bs[0]->sup_lo_base (l): box_rep::sup_lo_base (l); }
00059   SI sup_hi_lim  (int l) {
00060     return big_flag? bs[0]->sup_hi_lim (l): box_rep::sup_hi_lim (l); }
00061 
00062   SI get_leaf_offset (string search) {
00063     return sx1(0) + bs[0]->get_leaf_offset (search); }
00064 
00065   gr_selections graphical_select (SI x, SI y, SI dist);
00066   gr_selections graphical_select (SI x1, SI y1, SI x2, SI y2);
00067 };
00068 
00069 change_box_rep::change_box_rep (path ip, bool fl1, bool fl2):
00070   composite_box_rep (ip), child_flag (fl1), big_flag (fl2) {}
00071 
00072 int
00073 change_box_rep::find_child (SI x, SI y, SI delta, bool force) {
00074   if (child_flag) return composite_box_rep::find_child (x, y, delta, force);
00075   return 0;
00076 }
00077 
00078 gr_selections
00079 change_box_rep::graphical_select (SI x, SI y, SI dist) { 
00080 //TODO : Check if it is correct
00081   if (child_flag)
00082     return composite_box_rep::graphical_select (x, y, dist);
00083   else
00084     return bs[0]->graphical_select (x- sx(0), y- sy(0), dist);
00085 }
00086 
00087 gr_selections
00088 change_box_rep::graphical_select (SI x1, SI y1, SI x2, SI y2) {
00089 //TODO : Check if it is correct
00090   if (child_flag)
00091     return composite_box_rep::graphical_select (x1, y1, x2, y2);
00092   else
00093     return bs[0]->graphical_select (x1- sx(0), y1- sy(0),
00094                                 x2- sx(0), y2- sy(0));
00095 }
00096 
00097 /******************************************************************************
00098 * Moving boxes
00099 ******************************************************************************/
00100 
00101 struct move_box_rep: public change_box_rep {
00102   move_box_rep (path ip, box b, SI x, SI y, bool fl1, bool fl2);
00103   int get_type () { return MOVE_BOX; }
00104   operator tree () { return tree (TUPLE, "move", (tree) bs[0]); }
00105 };
00106 
00107 move_box_rep::move_box_rep (path ip, box b, SI x, SI y, bool fl1, bool fl2):
00108   change_box_rep (ip, fl1, fl2)
00109 {
00110   insert (b, x, y);
00111   position ();
00112   finalize ();
00113 }
00114 
00115 struct shift_box_rep: public change_box_rep {
00116   shift_box_rep (path ip, box b, SI x, SI y, bool fl1, bool fl2);
00117   int get_type () { return MOVE_BOX; }
00118   operator tree () { return tree (TUPLE, "shift", (tree) bs[0]); }
00119 };
00120 
00121 shift_box_rep::shift_box_rep (path ip, box b, SI x, SI y, bool fl1, bool fl2):
00122   change_box_rep (ip, fl1, fl2)
00123 {
00124   insert (b, x, y);
00125   position ();
00126   x1 -= x; y1 -= y;
00127   x2 -= x; y2 -= y;
00128   finalize ();
00129 }
00130 
00131 /******************************************************************************
00132 * Resizing boxes
00133 ******************************************************************************/
00134 
00135 struct resize_box_rep: public change_box_rep {
00136   resize_box_rep (path ip, box b, SI x1, SI y1, SI x2, SI y2,
00137                 bool child_flag, bool adjust);
00138   operator tree () { return tree (TUPLE, "resize", (tree) bs[0]); }
00139 };
00140 
00141 resize_box_rep::resize_box_rep (
00142   path ip, box b, SI X1, SI Y1, SI X2, SI Y2, bool child_flag, bool adjust):
00143     change_box_rep (ip, child_flag)
00144 {
00145   insert (b, 0, 0);
00146   position ();
00147   x1= X1; y1= Y1;
00148   x2= X2; y2= Y2;
00149   if (adjust) left_justify ();
00150   finalize ();
00151 }
00152 
00153 struct vcorrect_box_rep: public change_box_rep {
00154   vcorrect_box_rep (path ip, box b, SI top_cor, SI bot_cor);
00155   operator tree () { return tree (TUPLE, "vcorrect", (tree) bs[0]); }
00156 };
00157 
00158 vcorrect_box_rep::vcorrect_box_rep (path ip, box b, SI top_cor, SI bot_cor):
00159   change_box_rep (ip, false, false)
00160 {
00161   insert (b, 0, -top_cor);
00162   position ();
00163   y1 -= bot_cor;
00164   y2 += top_cor;
00165   finalize ();
00166 }
00167 
00168 /******************************************************************************
00169 * Clipped boxes
00170 ******************************************************************************/
00171 
00172 struct clip_box_rep: public change_box_rep {
00173   tree xt, yt;
00174   SI old_clip_x1, old_clip_x2, old_clip_y1, old_clip_y2;
00175 public:
00176   clip_box_rep (path ip, box b, SI x1, SI y1, SI x2, SI y2,
00177               tree xt, tree yt, SI scx, SI scy);
00178   operator tree () { return tree (TUPLE, "clip", (tree) bs[0]); }
00179   int get_type () {
00180     return xt!=UNINIT || yt!=UNINIT? SCROLL_BOX: change_box_rep::get_type(); }
00181   tree get_info (tree in) {
00182     if (in == "scroll-x") return xt;
00183     else if (in == "scroll-y") return yt;
00184     else return box_rep::get_info (in); }
00185   void pre_display (renderer &ren);
00186   void post_display (renderer &ren);
00187   selection find_selection (path lbp, path rbp);
00188 };
00189 
00190 clip_box_rep::clip_box_rep (
00191   path ip, box b, SI X1, SI Y1, SI X2, SI Y2,
00192   tree xt2, tree yt2, SI scx, SI scy):
00193   change_box_rep (ip, true), xt (xt2), yt (yt2)
00194 {
00195   insert (b, scx, scy);
00196   position ();
00197   x1= X1; y1= Y1;
00198   x2= X2; y2= Y2;
00199   // left_justify ();
00200   finalize ();
00201 }
00202 
00203 void
00204 clip_box_rep::pre_display (renderer &ren) {
00205   ren->get_clipping (old_clip_x1, old_clip_y1, old_clip_x2, old_clip_y2);
00206   ren->extra_clipping (x1, y1, x2, y2);
00207 }
00208 
00209 void
00210 clip_box_rep::post_display (renderer &ren) {
00211   ren->set_clipping (
00212     old_clip_x1, old_clip_y1, old_clip_x2, old_clip_y2, true);
00213 }
00214 
00215 selection
00216 clip_box_rep::find_selection (path lbp, path rbp) {
00217   selection sel= change_box_rep::find_selection (lbp, rbp);
00218   return selection (sel->rs & rectangle (x1, y1, x2, y2),
00219                   sel->start, sel->end, sel->valid);
00220 }
00221 
00222 /******************************************************************************
00223 * horizontally repetition of one box inside another one
00224 ******************************************************************************/
00225 
00226 struct repeat_box_rep: public change_box_rep {
00227   repeat_box_rep (path ip, box b, box repeat, SI xoff);
00228   operator tree () { return tree (TUPLE, "repeat", (tree) bs[0]); }
00229 };
00230 
00231 repeat_box_rep::repeat_box_rep (path ip, box b, box repeat, SI xoff):
00232   change_box_rep (ip, false)
00233 {
00234   insert (b, 0, 0);
00235   position ();
00236 
00237   SI width= repeat->w ();
00238   if (width >= PIXEL) {
00239     int i;
00240     int i1= ((xoff+b->x1)/width)-1;
00241     int i2= ((xoff+b->x2)/width)+1;
00242     while (i1*width < (xoff+b->x1)) i1++;
00243     while (i2*width > (xoff+b->x2)) i2--;
00244     for (i=i1; i<i2; i++) {
00245       box bb= move_box (decorate_right (ip), repeat, 0, 0);
00246       insert (bb, i*width-xoff, 0);
00247     }
00248   }
00249 
00250   finalize ();
00251   x1= b->x1; y1= b->y1;
00252   x2= b->x2; y2= b->y2;
00253 }
00254 
00255 /******************************************************************************
00256 * cell boxes for tables
00257 ******************************************************************************/
00258 
00259 struct cell_box_rep: public change_box_rep {
00260   SI    bl, br, bb, bt;
00261   color fg;
00262   tree  bg;
00263   int   alpha;
00264   tree  old_bg;
00265   int   old_a;
00266   cell_box_rep (path ip, box b, SI x0, SI y0, SI x1, SI y1, SI x2, SI y2,
00267               SI bl, SI br, SI bb, SI bt, color fg, tree bg, int alpha);
00268   operator tree () { return tree (TUPLE, "cell", (tree) bs[0]); }
00269   void pre_display (renderer &ren);
00270   void post_display (renderer &ren);
00271 };
00272 
00273 cell_box_rep::cell_box_rep (
00274   path ip, box b, SI X0, SI Y0, SI X1, SI Y1, SI X2, SI Y2,
00275   SI Bl, SI Br, SI Bb, SI Bt, color Fg, tree Bg, int Alpha):
00276   change_box_rep (ip, false),
00277   bl (Bl<<1), br (Br<<1), bb (Bb<<1), bt (Bt<<1),
00278   fg (Fg), bg (Bg), alpha (Alpha)
00279 {
00280   insert (b, X0, Y0);
00281   position ();
00282   x1= X1; y1= Y1;
00283   x2= X2; y2= Y2;
00284   if ((bg != "") || (bl>0) || (br>0) || (bb>0) || (bt>0)) {
00285     // the 4*PIXEL extra space is sufficient for (shrinking factor) <= 8
00286     x3= min (x3, x1 - (bl>>1) - (bl>0? PIXEL<<2: 0));
00287     y3= min (y3, y1 - (bb>>1) - (bb>0? PIXEL<<2: 0));
00288     x4= max (x4, x2 + (br>>1) + (br>0? PIXEL<<2: 0));
00289     y4= max (y4, y2 + (bt>>1) + (bt>0? PIXEL<<2: 0));
00290   }
00291   finalize ();
00292 }
00293 
00294 void
00295 cell_box_rep::pre_display (renderer& ren) {
00296   SI l= bl, r= br, b= bb, t= bt;
00297   SI lx1, rx1, by1, ty1;
00298   SI lx2, rx2, by2, ty2;
00299   if (ren->sfactor > 1) { // correction for screen display only
00300     SI  pixel= ren->pixel;
00301     l= ((l + (pixel - 1)) / pixel) * pixel;
00302     r= ((r + (pixel - 1)) / pixel) * pixel;
00303     b= ((b + (pixel - 1)) / pixel) * pixel;
00304     t= ((t + (pixel - 1)) / pixel) * pixel;
00305   }
00306 
00307   lx1= x1 - (l>>1); lx2= lx1 + l;
00308   by1= y1 - (b>>1); by2= by1 + b;
00309   rx2= x2 + (r>>1); rx1= rx2 - r;
00310   ty2= y2 + (t>>1); ty1= ty2 - t;
00311 
00312   if (bg != "") {
00313     old_bg= ren->get_background_pattern (old_a);
00314     ren->set_background_pattern (bg, alpha);
00315     ren->clear_pattern (lx2, by2, rx1, ty1);
00316   }
00317 
00318   if ((l>0) || (r>0) || (b>0) || (t>0)) {
00319     ren->set_color (fg);
00320     ren->fill (lx1, by1, lx2, ty2);
00321     ren->fill (rx1, by1, rx2, ty2);
00322     ren->fill (lx1, by1, rx2, by2);
00323     ren->fill (lx1, ty1, rx2, ty2);
00324   }
00325 }
00326 
00327 void
00328 cell_box_rep::post_display (renderer& ren) {
00329   if (bg != "")
00330     ren->set_background_pattern (old_bg, old_a);
00331 }
00332 
00333 /******************************************************************************
00334 * Remember boxes
00335 ******************************************************************************/
00336 
00337 class remember_box_rep: public change_box_rep {
00338 public:
00339   rectangles* logs_ptr;
00340   SI          ox, oy;
00341 public:
00342   inline remember_box_rep (path ip, box b):
00343     change_box_rep (ip, true), logs_ptr (NULL)
00344   {
00345     insert (b, 0, 0);
00346     position ();
00347     finalize ();
00348   }
00349   inline ~remember_box_rep () {
00350     if (logs_ptr != NULL) {
00351       rectangles& logs= *logs_ptr;
00352       logs= rectangles (rectangle (ox+x3, oy+y3, ox+x4, oy+y4), logs);
00353       logs= rectangles (rectangle (0, 0, 0, 0), logs);
00354       // cout << "  8=X " << rectangle (ox+x3, oy+y3, ox+x4, oy+y4) << "\n";
00355     }
00356   }
00357   inline void position_at (SI x, SI y, rectangles& logs) {
00358     x += x0; y += y0;
00359     if (logs_ptr == NULL) logs= rectangles (rectangle (0, 0, 0, 0), logs);
00360     else logs= rectangles (rectangle (ox+x3, oy+y3, ox+x4, oy+y4), logs);
00361     ox= x; oy= y;
00362     logs= rectangles (rectangle (ox+x3, oy+y3, ox+x4, oy+y4), logs);
00363     logs_ptr= &logs;
00364   }
00365   inline void display (renderer ren) {
00366     ren->apply_shadow (x1, y1, x2, y2);
00367   }
00368 };
00369 
00370 /******************************************************************************
00371 * Highlight boxes
00372 ******************************************************************************/
00373 
00374 struct highlight_box_rep: public change_box_rep {
00375   SI w, xpad, ypad;
00376   tree bg;
00377   int alpha;
00378   color sun, shad;
00379   tree old_bg;
00380   int old_a;
00381   highlight_box_rep (path ip, box b, SI w, SI xpad, SI ypad,
00382                    tree bg, int alpha, color sun, color shad);
00383   operator tree () { return tree (TUPLE, "highlight", (tree) bs[0]); }
00384   void pre_display (renderer &ren);
00385   void post_display (renderer &ren);
00386   void display (renderer ren);
00387 };
00388 
00389 highlight_box_rep::highlight_box_rep (
00390   path ip, box b, SI w2, SI xp2, SI yp2,
00391   tree bg2, int alpha2, color sun2, color shad2):
00392     change_box_rep (ip, true), w (w2), xpad (xp2), ypad (yp2),
00393     bg (bg2), alpha (alpha2), sun (sun2), shad (shad2)
00394 {
00395   insert (b, w + xpad, 0);
00396   position ();
00397   x1= b->x1;
00398   y1= b->y1 - w - ypad;
00399   x2= b->x2 + 2 * (w + xpad);
00400   y2= b->y2 + w + ypad;
00401   x3= min (x1, b->x3 + w + xpad);
00402   y3= min (y1, b->y3);
00403   x4= max (x2, b->x4 + w + xpad);
00404   y4= max (y2, b->y4);
00405   finalize ();
00406 }
00407 
00408 void
00409 highlight_box_rep::pre_display (renderer& ren) {
00410   old_bg= ren->get_background_pattern (old_a);
00411   ren->set_background_pattern (bg, alpha);
00412   SI W= w;
00413   if (!ren->is_printer ()) {
00414     SI pixel= ren->pixel;
00415     W= ((w + pixel - 1) / pixel) * pixel;
00416   }
00417   ren->clear_pattern (x1+W, y1+W, x2-W, y2-W);
00418 }
00419 
00420 void
00421 highlight_box_rep::post_display (renderer &ren) {
00422   ren->set_background_pattern (old_bg, old_a);
00423 }
00424 
00425 void
00426 highlight_box_rep::display (renderer ren) {
00427   SI W= w;
00428   if (!ren->is_printer ()) {
00429     SI pixel= ren->pixel;
00430     W= ((w + pixel - 1) / pixel) * pixel;
00431   }
00432   ren->set_color (sun);
00433   ren->fill (x1  , y2-W, x2  , y2  );
00434   ren->fill (x1  , y1  , x1+W, y2  );
00435   ren->set_color (shad);
00436   ren->fill (x1+W, y1  , x2  , y1+W);
00437   ren->fill (x2-W, y1  , x2  , y2-W);
00438   ren->triangle (x1, y1, x1+W, y1, x1+W, y1+W);
00439   ren->triangle (x2, y2, x2, y2-W, x2-W, y2-W);
00440 }
00441 
00442 /******************************************************************************
00443 * action boxes
00444 ******************************************************************************/
00445 
00446 struct action_box_rep: public change_box_rep {
00447   tree    filter; // which events are accepted ?
00448   command cmd;    // command to be executed
00449   path    vip;    // store this location before execution
00450   action_box_rep (path ip, box b, tree f, command c, bool ch, path vip);
00451   operator tree () { return tree (TUPLE, "action", bs[0]); }
00452   tree action (tree t, SI x, SI y, SI delta);
00453 };
00454 
00455 action_box_rep::action_box_rep (
00456   path ip, box b, tree filter2, command cmd2, bool child_flag, path vip2):
00457   change_box_rep (ip, child_flag), filter (filter2), cmd (cmd2), vip (vip2)
00458 {
00459   insert (b, 0, 0);
00460   position ();
00461   left_justify ();
00462   finalize ();
00463 }
00464 
00465 tree
00466 action_box_rep::action (tree t, SI x, SI y, SI delta) {
00467   if (t == filter) {
00468     call ("action-set-path", reverse (vip));
00469     // FIXME: we should also reset the action path
00470     cmd ();
00471     return "done";
00472   }
00473   return change_box_rep::action (t, x, y, delta);
00474 }
00475 
00476 /******************************************************************************
00477 * locus boxes
00478 ******************************************************************************/
00479 
00480 struct locus_box_rep: public change_box_rep {
00481   list<string> ids;
00482   SI pixel;
00483   string ref;
00484   string anchor;
00485   locus_box_rep (path ip, box b, list<string> ids, SI pixel);
00486   locus_box_rep (path ip, box b, list<string> ids, SI pixel, string _rep, string _anchor);
00487   operator tree () { return tree (TUPLE, "locus"); }
00488   void loci (SI x, SI y, SI delta, list<string>& ids2, rectangles& rs);
00489   void post_display (renderer &ren);
00490 
00491 };
00492 
00493 locus_box_rep::locus_box_rep (path ip, box b, list<string> ids2, SI pixel2):
00494   change_box_rep (ip, true), ids (ids2), pixel (pixel2)
00495 {
00496   ref = "";
00497   anchor = "";
00498   insert (b, 0, 0);
00499   position ();
00500   left_justify ();
00501   finalize ();
00502 }
00503 
00504 locus_box_rep::locus_box_rep (path ip, box b, list<string> ids2, SI pixel2, string _ref, string _anchor):
00505   change_box_rep (ip, true), ids (ids2), pixel (pixel2)
00506 {
00507   ref = _ref;
00508   anchor = _anchor;
00509   insert (b, 0, 0);
00510   position ();
00511   left_justify ();
00512   finalize ();
00513 }
00514 
00515 
00516 void
00517 locus_box_rep::loci (SI x, SI y, SI delta, list<string>& l, rectangles& rs) {
00518   bs[0]->loci (x, y, delta, l, rs);
00519   l = l * ids;
00520   rs= rs * outline (rectangles (rectangle (x1, y1, x2, y2)), pixel);
00521 }
00522 
00523 void
00524 locus_box_rep::post_display (renderer &ren) {
00525   if (ref!="") ren->href(ref, x1, y1, x2, y2);
00526   if (anchor!="") ren->anchor(anchor, x1, y1);
00527 }
00528 
00529 /******************************************************************************
00530 * tag boxes
00531 ******************************************************************************/
00532 
00533 struct tag_box_rep: public change_box_rep {
00534   tree keys;
00535   tag_box_rep (path ip, box b, tree keys);
00536   operator tree () { return tree (TUPLE, "tag", bs[0]); }
00537   tree tag (tree t, SI x, SI y, SI delta);
00538   void collect_page_numbers (hashmap<string,tree>& h, tree page);
00539   path find_tag (string name);
00540 };
00541 
00542 tag_box_rep::tag_box_rep (path ip, box b, tree keys2):
00543   change_box_rep (ip, false), keys (keys2)
00544 {
00545   insert (b, 0, 0);
00546   position ();
00547   left_justify ();
00548   finalize ();
00549 }
00550 
00551 void
00552 tag_box_rep::collect_page_numbers (hashmap<string,tree>& h, tree page) {
00553   for (int i=0; i<N(keys); i++)
00554     h (keys[i]->label)= page;
00555   bs[0]->collect_page_numbers (h, page);
00556 }
00557 
00558 path
00559 tag_box_rep::find_tag (string search) {
00560   for (int i=0; i<N(keys); i++)
00561     if (keys[i]->label == search)
00562       return reverse (descend_decode (ip, 1));
00563   return path ();
00564 }
00565 
00566 /******************************************************************************
00567 * text_at boxes
00568 ******************************************************************************/
00569 
00570 struct text_at_box_rep: public move_box_rep {
00571   SI axis;
00572   SI pad;
00573   text_at_box_rep (path ip, box b, SI x, SI y, SI axis, SI pad);
00574   gr_selections graphical_select (SI x, SI y, SI dist);
00575   operator tree () { return tree (TUPLE, "text-at", (tree) bs[0]); }
00576   /*
00577   void pre_display (renderer &ren) {
00578     array<SI> xs, ys;
00579     xs << x1 - pad << x2 + pad << x2 + pad << x1 - pad << x1 - pad;
00580     ys << y1 - pad << y1 - pad << y2 + pad << y2 + pad << y1 - pad;
00581     ren->set_color (rgb_color (255, 255, 224));
00582     ren->polygon (xs, ys);
00583   }
00584   */
00585 };
00586 
00587 text_at_box_rep::text_at_box_rep (path ip, box b, SI x, SI y, SI a2, SI p2):
00588   move_box_rep (ip, b, x, y, false, false), axis (a2), pad (p2) {}
00589 
00590 gr_selections
00591 text_at_box_rep::graphical_select (SI x, SI y, SI dist) {
00592   array<point> special;
00593   special << point (x1 - pad, y1 - pad)
00594          << point (x1 - pad, y2 + pad)
00595          << point (x2 + pad, y2 + pad)
00596          << point (x2 + pad, y1 - pad)
00597          << point ((x1 + x2) >> 1, y1 - pad)
00598          << point ((x1 + x2) >> 1, y2 + pad)
00599          << point (x1 - pad, y1 + axis)
00600          << point (x2 + pad, y1 + axis);
00601   array<point> ps;
00602   ps << point (x1 - pad, y1 - pad) << point (x2 + pad, y1 - pad)
00603      << point (x2 + pad, y2 + pad) << point (x1 - pad, y2 + pad)
00604      << point (x1 - pad, y1 - pad);
00605   array<curve> cs;
00606   for (int i=0; i<N(ps)-1; i++)
00607     cs << segment (ps[i], ps[i+1]);
00608 
00609   gr_selections res;
00610   point p= point (x, y);
00611   if (norm (p - point (sx(0), sy(0))) <= dist) {
00612     gr_selection gs;
00613     gs->type= "text-handle";
00614     gs->dist= norm (p - point (sx(0), sy(0)));
00615     gs->p= point (sx(0), sy(0));
00616     gs->cp << reverse (path (0, path (1, ip)));
00617     gs->pts << gs->p;
00618     gs->c= curve ();
00619     res << gs;
00620   }
00621   else if (graphical_distance (x, y) == 0) {
00622     gr_selection gs;
00623     gs->type= "text";
00624     gs->dist= graphical_distance (x, y);
00625     gs->p= p;
00626     gs->cp << box_rep::find_tree_path (x, y, dist);
00627     gs->pts << gs->p;
00628     gs->c= curve ();
00629     res << gs;
00630   }
00631 
00632   for (int i=0; i<N(special); i++)
00633     if (norm (special[i] - p) <= dist) {
00634       gr_selection gs;
00635       gs->type= "text-border-point";
00636       gs->p= special[i];
00637       gs->dist= norm (gs->p - p);
00638       gs->cp << box_rep::find_tree_path (x, y, dist);
00639       gs->pts << gs->p;
00640       gs->c= curve ();
00641       res << gs;
00642     }
00643   for (int i=0; i<N(cs); i++) {
00644     if (N(res) == 0 && norm (closest (cs[i], p) - p) <= dist) {
00645       gr_selection gs;
00646       gs->type= "text-border";
00647       gs->p= closest (cs[i], p);
00648       gs->dist= norm (gs->p - p);
00649       gs->cp << box_rep::find_tree_path (x, y, dist);
00650       gs->pts << gs->p;
00651       gs->c= cs[i];
00652       res << gs;    
00653     }
00654   }
00655   return res;
00656 }
00657 
00658 /******************************************************************************
00659 * box construction routines
00660 ******************************************************************************/
00661 
00662 box
00663 move_box (path ip, box b, SI x, SI y, bool child_flag, bool big_flag) {
00664   return tm_new<move_box_rep> (ip, b, x, y, child_flag, big_flag);
00665 }
00666 
00667 box
00668 shift_box (path ip, box b, SI x, SI y, bool child_flag, bool big_flag) {
00669   return tm_new<shift_box_rep> (ip, b, x, y, child_flag, big_flag);
00670 }
00671 
00672 box
00673 resize_box (path ip, box b, SI x1, SI y1, SI x2, SI y2,
00674            bool child_flag, bool adjust) {
00675   return tm_new<resize_box_rep> (ip, b, x1, y1, x2, y2, child_flag, adjust);
00676 }
00677 
00678 box
00679 clip_box (path ip, box b, SI x1, SI y1, SI x2, SI y2) {
00680   return tm_new<clip_box_rep> (ip, b, x1, y1, x2, y2, UNINIT, UNINIT, 0, 0);
00681 }
00682 
00683 box
00684 clip_box (path ip, box b, SI x1, SI y1, SI x2, SI y2,
00685          tree xt, tree yt, SI scx, SI scy) {
00686   return tm_new<clip_box_rep> (ip, b, x1, y1, x2, y2, xt, yt, scx, scy);
00687 }
00688 
00689 box
00690 vcorrect_box (path ip, box b, SI top_cor, SI bot_cor) {
00691   return tm_new<vcorrect_box_rep> (ip, b, top_cor, bot_cor);
00692 }
00693 
00694 box
00695 repeat_box (path ip, box ref, box repeat, SI xoff) {
00696   return tm_new<repeat_box_rep> (ip, ref, repeat, xoff);
00697 }
00698 
00699 box
00700 cell_box (path ip, box b, SI x0, SI y0, SI x1, SI y1, SI x2, SI y2,
00701          SI bl, SI br, SI bb, SI bt, color fg, tree bg, int a)
00702 {
00703   box cb= tm_new<cell_box_rep> (ip, b, x0, y0, x1, y1, x2, y2,
00704                                 bl, br, bb, bt, fg, bg, a);
00705   return cb;
00706 }
00707 
00708 box
00709 remember_box (path ip, box b) {
00710   return tm_new<remember_box_rep> (ip, b);
00711 }
00712 
00713 box
00714 highlight_box (path ip, box b, SI w, SI xpad, SI ypad,
00715               tree bg, int a, color sun, color shad) {
00716   return tm_new<highlight_box_rep> (ip, b, w, xpad, ypad, bg, a, sun, shad);
00717 }
00718 
00719 box
00720 action_box (path ip, box b, tree filter, command cmd, bool ch, path vip) {
00721   return tm_new<action_box_rep> (ip, b, filter, cmd, ch, vip);
00722 }
00723 
00724 box
00725 action_box (path ip, box b, tree filter, command cmd, bool ch) {
00726   return tm_new<action_box_rep> (ip, b, filter, cmd, ch, decorate ());
00727 }
00728 
00729 box
00730 locus_box (path ip, box b, list<string> ids, SI pixel) {
00731   return tm_new<locus_box_rep> (ip, b, ids, pixel);
00732 }
00733 
00734 box
00735 locus_box (path ip, box b, list<string> ids, SI pixel, string ref, string anchor) {
00736   return tm_new<locus_box_rep> (ip, b, ids, pixel, ref, anchor);
00737 }
00738 
00739 box
00740 tag_box (path ip, box b, tree keys) {
00741   return tm_new<tag_box_rep> (ip, b, keys);
00742 }
00743 
00744 box
00745 text_at_box (path ip, box b, SI x, SI y, SI axis, SI pad) {
00746   return tm_new<text_at_box_rep> (ip, b, x, y, axis, pad);
00747 }