Back to index

texmacs  1.0.7.15
edit_repaint.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : edit_repaint.cpp
00004 * DESCRIPTION: repaint invalid rectangles
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 "Interface/edit_interface.hpp"
00013 #include "message.hpp"
00014 
00015 extern int nr_painted;
00016 extern void clear_pattern_rectangles (renderer ren, rectangles l);
00017 
00018 /******************************************************************************
00019 * repainting the window
00020 ******************************************************************************/
00021 
00022 void
00023 edit_interface_rep::draw_text (renderer ren, rectangles& l) {
00024   nr_painted=0;
00025   bool tp_found= false;
00026   tree bg= get_init_value (BG_COLOR);
00027   ren->set_background_pattern (bg);
00028   refresh_needed= do_animate;
00029   refresh_next  = next_animate;
00030   eb->redraw (ren, eb->find_box_path (tp, tp_found), l);
00031   do_animate  = refresh_needed;
00032   next_animate= refresh_next;
00033 }
00034 
00035 void
00036 edit_interface_rep::draw_env (renderer ren) {
00037   if (!full_screen) {
00038     if (!is_nil (env_rects)) {
00039       ren->set_color (rgb_color (0, 85, 85, 24));
00040       ren->draw_rectangles (env_rects);
00041     }
00042     if (!is_nil (foc_rects)) {
00043       ren->set_color (rgb_color (0, 255, 255));
00044       ren->draw_rectangles (foc_rects);
00045     }
00046     if (!is_nil (sem_rects)) {
00047       if (sem_correct) ren->set_color (rgb_color (112, 208, 112));
00048       else ren->set_color (rgb_color (208, 144, 80));
00049       ren->draw_rectangles (sem_rects);
00050     }
00051   }
00052 }
00053 
00054 void
00055 edit_interface_rep::draw_cursor (renderer ren) {
00056   if (!temp_invalid_cursor && (got_focus || full_screen)) {
00057     cursor cu= get_cursor();
00058     if (!inside_active_graphics ()) {
00059       cu->y1 -= 2*pixel; cu->y2 += 2*pixel;
00060       SI x1= cu->ox + ((SI) (cu->y1 * cu->slope)), y1= cu->oy + cu->y1;
00061       SI x2= cu->ox + ((SI) (cu->y2 * cu->slope)), y2= cu->oy + cu->y2;
00062       ren->set_line_style (pixel);
00063       string mode= get_env_string (MODE);
00064       string family, series;
00065       if ((mode == "text") || (mode == "src")) {
00066        family= get_env_string (FONT_FAMILY);
00067        series= get_env_string (FONT_SERIES);
00068       }
00069       else if (mode == "math") {
00070        family= get_env_string (MATH_FONT_FAMILY);
00071        series= get_env_string (MATH_FONT_SERIES);
00072       }
00073       else if (mode == "prog") {
00074        family= get_env_string (PROG_FONT_FAMILY);
00075        series= get_env_string (PROG_FONT_SERIES);
00076       }
00077       if (cu->valid) {
00078        if (mode == "math")
00079          ren->set_color (rgb_color (192, 0, 255));
00080        else ren->set_color (red);
00081       }
00082       else ren->set_color (green);
00083       SI lserif= (series=="bold"? 2*pixel: pixel), rserif= pixel;
00084       if (family == "ss") lserif= rserif= 0;
00085       ren->line (x1-lserif, y1, x1+rserif, y1);
00086       if (y1<=y2-pixel) {
00087        ren->line (x1, y1, x2, y2-pixel);
00088        if (series == "bold") ren->line (x1-pixel, y1, x2-pixel, y2-pixel);
00089        ren->line (x2-lserif, y2-pixel, x2+rserif, y2-pixel);
00090       }
00091     }
00092   }
00093 }
00094 
00095 void
00096 edit_interface_rep::draw_surround (renderer ren, rectangle r) {
00097   ren->set_background (light_grey);
00098   string medium= get_init_string (PAGE_MEDIUM);
00099   if ((medium == "papyrus") || (medium == "paper"))
00100     ren->clear (max (eb->x2, r->x1), r->y1,
00101                 r->x2, min (eb->y2+ 2*pixel, r->y2));
00102   else if (medium == "paper")
00103     ren->clear (r->x1, r->y1, r->x2, min (eb->y1, r->y2));
00104 }
00105 
00106 void
00107 edit_interface_rep::draw_context (renderer ren, rectangle r) {
00108   int i;
00109   ren->set_color (light_grey);
00110   ren->set_line_style (pixel);
00111   for (i=1; i<N(eb[0]); i++) {
00112     SI y= eb->sy(0)+ eb[0]->sy2(i);
00113     if ((y >= r->y1) && (y < r->y2))
00114       ren->line (r->x1, y, r->x2, y);
00115   }
00116   draw_surround (ren, r);
00117 }
00118 
00119 void
00120 edit_interface_rep::draw_selection (renderer ren) {
00121   if (!is_nil (locus_rects)) {
00122     ren->set_color (rgb_color (32, 160, 96));
00123     ren->draw_rectangles (locus_rects);
00124   }
00125   if (made_selection && !is_nil (selection_rects)) {
00126     ren->set_color (table_selection? rgb_color (192, 0, 255): red);
00127 #ifdef QTTEXMACS
00128     ren->draw_selection (selection_rects);
00129 #else
00130     ren->draw_rectangles (selection_rects);
00131 #endif
00132   }
00133 }
00134 
00135 void
00136 edit_interface_rep::draw_graphics (renderer ren) {
00137   if (got_focus || full_screen) {
00138     cursor cu= get_cursor();
00139     if (over_graphics(cu->ox, cu->oy) && inside_active_graphics ()) {
00140       eval ("(graphics-reset-context 'graphics-cursor)");
00141       draw_graphical_object (ren);
00142       string tm_curs= as_string (eval ("graphics-texmacs-pointer"));
00143       if (tm_curs != "none") {
00144        if (tm_curs == "graphics-cross") {
00145          ren->set_line_style (pixel);
00146          ren->set_color (red);
00147          ren->line (cu->ox, cu->oy-5*pixel, cu->ox, cu->oy+5*pixel);
00148          ren->line (cu->ox-5*pixel, cu->oy, cu->ox+5*pixel, cu->oy);
00149         }
00150        else if (tm_curs == "graphics-cross-arrows") {
00151          static int s= 6*pixel, a= 2*pixel;
00152          ren->set_line_style (pixel);
00153          ren->set_color (red);
00154          ren->line (cu->ox, cu->oy-s, cu->ox, cu->oy+s);
00155          ren->line (cu->ox-s, cu->oy, cu->ox+s, cu->oy);
00156          ren->line (cu->ox, cu->oy-s,cu->ox-a, cu->oy-s+a);
00157          ren->line (cu->ox, cu->oy-s, cu->ox+a, cu->oy-s+a);
00158          ren->line (cu->ox, cu->oy+s, cu->ox-a, cu->oy+s-a);
00159          ren->line (cu->ox, cu->oy+s, cu->ox+a, cu->oy+s-a);
00160          ren->line (cu->ox-s, cu->oy, cu->ox-s+a, cu->oy+a);
00161          ren->line (cu->ox-s, cu->oy, cu->ox-s+a, cu->oy-a);
00162          ren->line (cu->ox+s, cu->oy, cu->ox+s-a, cu->oy+a);
00163          ren->line (cu->ox+s, cu->oy, cu->ox+s-a, cu->oy-a);
00164         }
00165       }
00166     }
00167     else eval ("(graphics-reset-context 'text-cursor)");
00168   }
00169 }
00170 
00171 void
00172 edit_interface_rep::draw_pre (renderer ren, rectangle r) {
00173   // draw surroundings
00174   tree bg= get_init_value (BG_COLOR);
00175   ren->set_background_pattern (bg);
00176   clear_pattern_rectangles (ren, rectangles (translate (r, ren->ox, ren->oy)));
00177   draw_surround (ren, r);
00178 
00179   // predraw cursor
00180   renderer win= get_renderer (this);
00181   draw_cursor (ren);
00182   rectangles l= copy_always;
00183   while (!is_nil (l)) {
00184     rectangle lr (l->item);
00185     win->put_shadow (ren, lr->x1, lr->y1, lr->x2, lr->y2);
00186     l= l->next;
00187   }
00188 }
00189 
00190 void
00191 edit_interface_rep::draw_post (renderer ren, rectangle r) {
00192   renderer win= get_renderer (this);
00193   win->set_shrinking_factor (sfactor);
00194   ren->set_shrinking_factor (sfactor);
00195   draw_context (ren, r);
00196   draw_env (ren);
00197   draw_selection (ren);
00198   draw_graphics (ren);
00199   draw_cursor (ren); // the text cursor must be drawn over the graphical object
00200   ren->set_shrinking_factor (1);
00201   win->set_shrinking_factor (1);
00202 }
00203 
00204 void
00205 edit_interface_rep::draw_with_shadow (rectangle r) {
00206   renderer win= get_renderer (this);
00207   rectangle sr= r / sfactor;
00208   win->new_shadow (shadow);
00209   win->get_shadow (shadow, sr->x1, sr->y1, sr->x2, sr->y2);
00210   renderer ren= shadow;
00211 
00212   rectangles l;
00213   win->set_shrinking_factor (sfactor);
00214   ren->set_shrinking_factor (sfactor);
00215   draw_pre (ren, r);
00216   draw_text (ren, l);
00217   ren->set_shrinking_factor (1);
00218   win->set_shrinking_factor (1);
00219 
00220   if (ren->interrupted ()) {
00221     ren->set_shrinking_factor (sfactor);
00222     l= l & rectangles (translate (r, ren->ox, ren->oy));
00223     simplify (l);
00224     copy_always= translate (copy_always, ren->ox, ren->oy);
00225     while (!is_nil (copy_always)) {
00226       l= rectangles (copy_always->item, l);
00227       copy_always= copy_always->next;
00228     }
00229     ren->set_shrinking_factor (1);
00230 
00231     draw_post (ren, r);
00232     while (!is_nil(l)) {
00233       SI x1= (l->item->x1)/sfactor - ren->ox - PIXEL;
00234       SI y1= (l->item->y1)/sfactor - ren->oy - PIXEL;
00235       SI x2= (l->item->x2)/sfactor - ren->ox + PIXEL;
00236       SI y2= (l->item->y2)/sfactor - ren->oy + PIXEL;
00237       ren->outer_round (x1, y1, x2, y2);
00238       win->put_shadow (ren, x1, y1, x2, y2);
00239       l= l->next;
00240     }
00241   }
00242 }
00243 
00244 void
00245 edit_interface_rep::draw_with_stored (rectangle r) {
00246   renderer win= get_renderer (this);
00247   //cout << "Redraw " << (r/(sfactor*PIXEL)) << "\n";
00248 
00249   /* Verify whether the backing store is still valid */
00250   if (!is_nil (stored_rects)) {
00251     SI w1, h1, w2, h2;
00252     win   -> get_extents (w1, h1);
00253     stored -> get_extents (w2, h2);
00254     if (stored->ox != win->ox || stored->oy != win->oy ||
00255        w1 != w2 || h1 != h2) {
00256       // cout << "x"; cout.flush ();
00257       stored_rects= rectangles ();
00258     }
00259   }
00260 
00261   /* Either draw with backing store or regenerate */
00262   rectangle sr= r / sfactor;
00263   if (is_nil (rectangles (r) - stored_rects) && !is_nil (stored_rects)) {
00264     // cout << "*"; cout.flush ();
00265     win->new_shadow (shadow);
00266     win->get_shadow (shadow, sr->x1, sr->y1, sr->x2, sr->y2);
00267     shadow->put_shadow (stored, sr->x1, sr->y1, sr->x2, sr->y2);
00268     draw_post (shadow, r);
00269     win->put_shadow (shadow, sr->x1, sr->y1, sr->x2, sr->y2);
00270   }
00271   else {
00272     // cout << "."; cout.flush ();
00273     draw_with_shadow (r);
00274     if (!win->interrupted ()) {
00275       if (inside_active_graphics ()) {
00276        shadow->new_shadow (stored);
00277        shadow->get_shadow (stored, sr->x1, sr->y1, sr->x2, sr->y2);
00278        //stored_rects= /*stored_rects |*/ rectangles (r);
00279        stored_rects= simplify (rectangles (r, stored_rects));
00280        //cout << "Stored: " << stored_rects << "\n";
00281        //cout << "M"; cout.flush ();
00282       }
00283       draw_post (shadow, r);
00284       win->put_shadow (shadow, sr->x1, sr->y1, sr->x2, sr->y2);
00285     }
00286     else draw_post (win, r);
00287   }
00288 }
00289 
00290 /******************************************************************************
00291 * event handlers
00292 ******************************************************************************/
00293 
00294 void
00295 edit_interface_rep::handle_clear (SI x1, SI y1, SI x2, SI y2) {
00296   renderer win= get_renderer (this);
00297   x1 *= sfactor; y1 *= sfactor; x2 *= sfactor; y2 *= sfactor;
00298   win->set_shrinking_factor (sfactor);
00299   tree bg= get_init_value (BG_COLOR);
00300   win->set_background_pattern (bg);
00301   win->clear_pattern (max (eb->x1, x1), max (eb->y1, y1),
00302                     min (eb->x2, x2), min (eb->y2, y2));
00303   draw_surround (win, rectangle (x1, y1, x2, y2));
00304   win->set_shrinking_factor (1);
00305 }
00306 
00307 void
00308 edit_interface_rep::handle_repaint (SI x1, SI y1, SI x2, SI y2) {
00309   if (is_nil (eb)) apply_changes ();
00310   if (env_change != 0) {
00311     system_warning ("Invalid situation (" * as_string (env_change) * ")",
00312                   "(edit_interface_rep::handle_repaint)");
00313     return;
00314   }
00315 
00316   /*
00317   // In the past, we used the code below in order to hide the trace of
00318   // a moving cursor. This code is now incorrect, because the rectangle
00319   // (x1, y1)--(x2, y2) does not correspond to the repaint region clipping.
00320   // Nevertheless, the code seems no longer necessary. In case it would be,
00321   // it should be moved somewhere inside the internal repaint routines.
00322   SI extra= 3 * get_init_int (FONT_BASE_SIZE) * PIXEL / (2*sfactor);
00323   SI X1= (x1-extra) * sfactor, Y1= (y1-extra) * sfactor;
00324   SI X2= (x2+extra) * sfactor, Y2= (y2+extra) * sfactor;
00325   draw_with_stored (rectangle (X1, Y1, X2, Y2));
00326   */
00327 
00328   // cout << "Repainting\n";
00329   draw_with_stored (rectangle (x1, y1, x2, y2) * sfactor);
00330   if (last_change-last_update > 0)
00331     last_change = texmacs_time ();
00332   // cout << "Repainted\n";
00333 }