From 6f8c291e3e8153acc2f3f92f3f8a76b8300e9b7a Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Tue, 28 Dec 2004 20:37:19 +0000
Subject: [PATCH] - cleaned up + generalized font selection - generalized
 Plugin(Annotate) to allow font style selection for   each text fragment -
 fixed bug in per-view color selection

---
 Common/DefaultOptions.h |  2 ++
 Common/Options.cpp      | 60 ++++++++++++++++++++------------------
 Common/Options.h        |  2 ++
 Common/Views.cpp        |  4 ++-
 Common/Views.h          |  1 +
 Fltk/Callbacks.cpp      | 36 ++++++++++++++++-------
 Fltk/Callbacks.h        |  1 +
 Fltk/GUI.cpp            | 64 ++++++++++++++++++++++++++++++++++++-----
 Fltk/GUI.h              |  6 ++++
 Fltk/Opengl.cpp         | 43 ++++++++++++++++++++++-----
 Graphics/Graph2D.cpp    |  6 ++--
 Graphics/Post.cpp       |  4 +--
 Plugin/Annotate.cpp     | 38 ++++++++++++++++++------
 Plugin/Makefile         |  4 +--
 doc/VERSIONS            |  6 ++--
 doc/texinfo/gmsh.texi   | 47 +++++++++++++++++++++++-------
 16 files changed, 242 insertions(+), 82 deletions(-)

diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index f26d3abeef..75fda08c5f 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1418,6 +1418,8 @@ StringXColor ViewOptions_Color[] = {
     PACK_COLOR(255, 0, 0, 255),
     PACK_COLOR(0,   0, 0, 255),
     "Normal vector color" },
+  { F|O, "Text2D" , opt_view_color_text2d , ELECOL, "2D text color" },
+  { F|O, "Text3D" , opt_view_color_text3d , ELECOL, "3D text color" },
   { 0, NULL , NULL , 0, 0, 0 , NULL }
 } ;
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 940ebc5cc4..6deb7e3a8f 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.218 2004-12-27 00:46:59 geuzaine Exp $
+// $Id: Options.cpp,v 1.219 2004-12-28 20:37:18 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -886,39 +886,15 @@ char *opt_general_scheme(OPT_ARGS_STR)
   return CTX.scheme;
 }
 
-#if defined(HAVE_FLTK)
-extern Fl_Menu_Item menu_font_names[];
-#endif
-
 char *opt_general_graphics_font(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
     CTX.gl_font = val;
 #if defined(HAVE_FLTK)
-  int index = -1, i = 0;
-  if(CTX.gl_font){
-    while(menu_font_names[i].label()){
-      if(!strcmp(menu_font_names[i].label(), CTX.gl_font)){
-	index = i;
-	break;
-      }
-      i++;
-    }
-  }
+  int index = GetFontIndex(CTX.gl_font);
   if(action & GMSH_SET){
-    if(index < 0){
-      Msg(GERROR, "Unknown font \"%s\" (using \"Helvetica\" instead)", CTX.gl_font);
-      Msg(INFO, "Available fonts:");
-      i = 0;
-      while(menu_font_names[i].label()){
-	Msg(INFO, "  \"%s\"", menu_font_names[i].label());
-	i++;
-      }
-      CTX.gl_font = "Helvetica";
-      CTX.gl_font_enum = FL_HELVETICA;
-    }
-    else
-      CTX.gl_font_enum = (long)menu_font_names[index].user_data();
+    CTX.gl_font = GetFontName(index);
+    CTX.gl_font_enum = GetFontEnum(index);
   }
   if(WID && (action & GMSH_GUI)){
     WID->gen_choice[1]->value(index);
@@ -6358,3 +6334,31 @@ unsigned int opt_view_color_normals(OPT_ARGS_COL)
   return v->color.normals;
 }
 
+unsigned int opt_view_color_text2d(OPT_ARGS_COL)
+{
+  GET_VIEW(0);
+  if(action & GMSH_SET) {
+    v->color.text2d = val;
+  }
+#if defined(HAVE_FLTK)
+  if(_gui_action_valid(action, num)){
+    CCC(v->color.text2d, WID->view_col[10]);
+  }
+#endif
+  return v->color.text2d;
+}
+
+unsigned int opt_view_color_text3d(OPT_ARGS_COL)
+{
+  GET_VIEW(0);
+  if(action & GMSH_SET) {
+    v->color.text3d = val;
+  }
+#if defined(HAVE_FLTK)
+  if(_gui_action_valid(action, num)){
+    CCC(v->color.text3d, WID->view_col[11]);
+  }
+#endif
+  return v->color.text3d;
+}
+
diff --git a/Common/Options.h b/Common/Options.h
index ad6c62c24c..7a7cb900fa 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -607,6 +607,8 @@ unsigned int opt_view_color_prisms(OPT_ARGS_COL);
 unsigned int opt_view_color_pyramids(OPT_ARGS_COL);
 unsigned int opt_view_color_tangents(OPT_ARGS_COL);
 unsigned int opt_view_color_normals(OPT_ARGS_COL);
+unsigned int opt_view_color_text2d(OPT_ARGS_COL);
+unsigned int opt_view_color_text3d(OPT_ARGS_COL);
 
 // Data structures and global functions
 
diff --git a/Common/Views.cpp b/Common/Views.cpp
index 3ce10f2be3..7d5853e105 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.155 2004-12-28 06:03:48 geuzaine Exp $
+// $Id: Views.cpp,v 1.156 2004-12-28 20:37:18 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -664,6 +664,8 @@ void CopyViewOptions(Post_View * src, Post_View * dest)
   dest->color.pyramid = src->color.pyramid;
   dest->color.tangents = src->color.tangents;
   dest->color.normals = src->color.normals;
+  dest->color.text2d = src->color.text2d;
+  dest->color.text3d = src->color.text3d;
   ColorTable_Copy(&src->CT);
   ColorTable_Paste(&dest->CT);
 }
diff --git a/Common/Views.h b/Common/Views.h
index a3b8904026..c516449bb3 100644
--- a/Common/Views.h
+++ b/Common/Views.h
@@ -106,6 +106,7 @@ class Post_View{
     unsigned int point, line, triangle, quadrangle;
     unsigned int tetrahedron, hexahedron, prism, pyramid;
     unsigned int tangents, normals;
+    unsigned int text2d, text3d;
   } color;
 
   // dynamic
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index df2d56d1e6..d79fb2aa27 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.311 2004-12-27 16:13:45 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.312 2004-12-28 20:37:18 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -236,6 +236,18 @@ void color_cb(CALLBACK_ARGS)
   Draw();
 }
 
+void view_color_cb(CALLBACK_ARGS)
+{
+  unsigned int (*fct) (int, int, unsigned int);
+  fct = (unsigned int (*)(int, int, unsigned int))data;
+  uchar r = UNPACK_RED(fct(WID->view_number, GMSH_GET, 0));
+  uchar g = UNPACK_GREEN(fct(WID->view_number, GMSH_GET, 0));
+  uchar b = UNPACK_BLUE(fct(WID->view_number, GMSH_GET, 0));
+  if(fl_color_chooser("Color Chooser", r, g, b))
+    fct(WID->view_number, GMSH_SET | GMSH_GUI, PACK_COLOR(r, g, b, 255));
+  Draw();
+}
+
 void redraw_cb(CALLBACK_ARGS)
 {
   Draw();
@@ -3409,7 +3421,7 @@ void view_options_timestep_cb(CALLBACK_ARGS)
   for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
     if((links == 2 || links == 4) ||
        ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
-       (links == 0 && i == (long int)data)) {
+       (links == 0 && i == WID->view_number)) {
       opt_view_timestep(i, GMSH_SET, (long)((Fl_Value_Input *) w)->value());
     }
   }
@@ -3422,7 +3434,7 @@ void view_options_timestep_decr_cb(CALLBACK_ARGS)
   for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
     if((links == 2 || links == 4) ||
        ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
-       (links == 0 && i == (long int)data)) {
+       (links == 0 && i == WID->view_number)) {
       opt_view_timestep(i, GMSH_SET | GMSH_GUI,
                         opt_view_timestep(i, GMSH_GET, 0) - 1);
     }
@@ -3436,7 +3448,7 @@ void view_options_timestep_incr_cb(CALLBACK_ARGS)
   for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
     if((links == 2 || links == 4) ||
        ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
-       (links == 0 && i == (long int)data)) {
+       (links == 0 && i == WID->view_number)) {
       opt_view_timestep(i, GMSH_SET | GMSH_GUI,
                         opt_view_timestep(i, GMSH_GET, 0) + 1);
     }
@@ -3908,8 +3920,10 @@ void view_options_ok_cb(CALLBACK_ARGS)
         opt_view_color_hexahedra(i, GMSH_SET, opt_view_color_hexahedra(current, GMSH_GET, 0));
         opt_view_color_prisms(i, GMSH_SET, opt_view_color_prisms(current, GMSH_GET, 0));
         opt_view_color_pyramids(i, GMSH_SET, opt_view_color_pyramids(current, GMSH_GET, 0));
-        opt_view_color_normals(i, GMSH_SET, opt_view_color_normals(current, GMSH_GET, 0));
         opt_view_color_tangents(i, GMSH_SET, opt_view_color_tangents(current, GMSH_GET, 0));
+        opt_view_color_normals(i, GMSH_SET, opt_view_color_normals(current, GMSH_GET, 0));
+        opt_view_color_text2d(i, GMSH_SET, opt_view_color_text2d(current, GMSH_GET, 0));
+        opt_view_color_text3d(i, GMSH_SET, opt_view_color_text3d(current, GMSH_GET, 0));
       }
 
       // colorbar window
@@ -3930,13 +3944,13 @@ void view_options_ok_cb(CALLBACK_ARGS)
 
 void view_arrow_param_cb(CALLBACK_ARGS)
 {
-  double a = opt_view_arrow_head_radius((long int)data, GMSH_GET, 0);
-  double b = opt_view_arrow_stem_length((long int)data, GMSH_GET, 0);
-  double c = opt_view_arrow_stem_radius((long int)data, GMSH_GET, 0);
+  double a = opt_view_arrow_head_radius(WID->view_number, GMSH_GET, 0);
+  double b = opt_view_arrow_stem_length(WID->view_number, GMSH_GET, 0);
+  double c = opt_view_arrow_stem_radius(WID->view_number, GMSH_GET, 0);
   while(arrow_editor("Arrow editor", a, b, c)){
-    opt_view_arrow_head_radius((long int)data, GMSH_SET, a);
-    opt_view_arrow_stem_length((long int)data, GMSH_SET, b);
-    opt_view_arrow_stem_radius((long int)data, GMSH_SET, c);
+    opt_view_arrow_head_radius(WID->view_number, GMSH_SET, a);
+    opt_view_arrow_stem_length(WID->view_number, GMSH_SET, b);
+    opt_view_arrow_stem_radius(WID->view_number, GMSH_SET, c);
     Draw();
   }
 }
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index cc7bae7496..e29bd5d27f 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -31,6 +31,7 @@ void ManualPlay(int time, int step);
 
 void cancel_cb(CALLBACK_ARGS) ;
 void color_cb(CALLBACK_ARGS) ;
+void view_color_cb(CALLBACK_ARGS) ;
 void redraw_cb(CALLBACK_ARGS);
 
 // Graphical window
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 20ea8e85d1..bdc210961c 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.393 2004-12-27 16:13:45 geuzaine Exp $
+// $Id: GUI.cpp,v 1.394 2004-12-28 20:37:18 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -360,6 +360,8 @@ static Fl_Menu_Item menu_line_display_with_plugin[] = {
   {0}
 };
 
+#define NUM_FONTS 14
+
 Fl_Menu_Item menu_font_names[] = {
   {"Times-Roman",           0, 0, (void*)FL_TIMES},
   {"Times-Bold",            0, 0, (void*)FL_TIMES_BOLD},
@@ -378,6 +380,52 @@ Fl_Menu_Item menu_font_names[] = {
   {0}
 };
 
+int GetFontIndex(char *fontname)
+{
+  if(fontname){
+    for(int i = 0; i < NUM_FONTS; i++)
+      if(!strcmp(menu_font_names[i].label(), fontname))
+	return i;
+  }
+  Msg(GERROR, "Unknown font \"%s\" (using \"Helvetica\" instead)", fontname);
+  Msg(INFO, "Available fonts:");
+  for(int i = 0; i < NUM_FONTS; i++)
+    Msg(INFO, "  \"%s\"", menu_font_names[i].label());
+  return 4;
+}
+
+int GetFontEnum(int index)
+{
+  if(index >= 0 && index < NUM_FONTS)
+    return (long)menu_font_names[index].user_data();
+  return FL_HELVETICA;
+}
+
+char *GetFontName(int index)
+{
+  if(index >= 0 && index < NUM_FONTS)
+    return (char*)menu_font_names[index].label();
+  return "Helvetica";
+}
+
+int GetFontAlign(char *alignstr)
+{
+  if(alignstr){
+    if(!strcmp(alignstr, "left") || !strcmp(alignstr, "Left"))
+      return 0;
+    else if(!strcmp(alignstr, "center") || !strcmp(alignstr, "Center"))
+      return 1;
+    else if(!strcmp(alignstr, "right") || !strcmp(alignstr, "Right"))
+      return 2;
+  }
+  Msg(GERROR, "Unknown font alignment \"%s\" (using \"Left\" instead)", alignstr);
+  Msg(INFO, "Available font alignments:");
+  Msg(INFO, "  \"Left\"");
+  Msg(INFO, "  \"Center\"");
+  Msg(INFO, "  \"Right\"");
+  return 0;
+}
+
 // Definition of global shortcuts
 
 int GUI::global_shortcuts(int event)
@@ -2374,8 +2422,11 @@ void GUI::create_option_window()
 
       int sw = (int)(1.5 * fontsize);
       view_butt_rep[0] = new Fl_Repeat_Button(L + 2 * WB, 2 * WB + 4 * BH, sw, BH, "-");
+      view_butt_rep[0]->callback(view_options_timestep_decr_cb);
       view_butt_rep[1] = new Fl_Repeat_Button(L + 2 * WB + IW - sw, 2 * WB + 4 * BH, sw, BH, "+");
+      view_butt_rep[1]->callback(view_options_timestep_incr_cb);
       view_value[50] = new Fl_Value_Input(L + 2 * WB + sw, 2 * WB + 4 * BH, IW - 2 * sw, BH);
+      view_value[50]->callback(view_options_timestep_cb);
       view_value[50]->align(FL_ALIGN_RIGHT);
       view_value[50]->minimum(0);
       view_value[50]->maximum(0);
@@ -2713,7 +2764,8 @@ void GUI::create_option_window()
         view_choice[2]->align(FL_ALIGN_RIGHT);
 
 	view_push_butt[0] = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 6 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
-      
+        view_push_butt[0]->callback(view_arrow_param_cb);
+
         view_value[60] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Arrow size");
         view_value[60]->minimum(0);
         view_value[60]->maximum(500);
@@ -2799,7 +2851,7 @@ void GUI::create_option_window()
       int i = 0;
       while(ViewOptions_Color[i].str) {
         view_col[i] = new Fl_Button(L + 2 * WB, 3 * WB + (2 + i) * BH, IW, BH, ViewOptions_Color[i].str);
-        view_col[i]->callback(color_cb, (void *)ViewOptions_Color[i].function);
+        view_col[i]->callback(view_color_cb, (void *)ViewOptions_Color[i].function);
         i++;
       }
       s->end();
@@ -2961,10 +3013,7 @@ void GUI::update_view_window(int num)
     view_butt_rep[1]->activate();
     view_butt[8]->activate();
   }
-  view_value[50]->callback(view_options_timestep_cb, (void *)num);
   view_value[50]->maximum(v->NbTimeStep - 1);
-  view_butt_rep[0]->callback(view_options_timestep_decr_cb, (void *)num);
-  view_butt_rep[1]->callback(view_options_timestep_incr_cb, (void *)num);
   opt_view_timestep(num, GMSH_GUI, 0);
   opt_view_show_time(num, GMSH_GUI, 0);
 
@@ -2988,7 +3037,6 @@ void GUI::update_view_window(int num)
   opt_view_external_view(num, GMSH_GUI, 0);
   opt_view_arrow_location(num, GMSH_GUI, 0);
   //opt_view_tensor_type(num, GMSH_GUI, 0);
-  view_push_butt[0]->callback(view_arrow_param_cb, (void*)num);
 
   opt_view_fake_transparency(num, GMSH_GUI, 0);
   opt_view_color_points(num, GMSH_GUI, 0);
@@ -3001,6 +3049,8 @@ void GUI::update_view_window(int num)
   opt_view_color_pyramids(num, GMSH_GUI, 0);
   opt_view_color_tangents(num, GMSH_GUI, 0);
   opt_view_color_normals(num, GMSH_GUI, 0);
+  opt_view_color_text2d(num, GMSH_GUI, 0);
+  opt_view_color_text3d(num, GMSH_GUI, 0);
 
   view_colorbar_window->update(v->Name, v->Min, v->Max, &v->CT, &v->Changed);
 }
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index 76bf96c297..07491413e2 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -305,5 +305,11 @@ public:
 
 };
 
+// some utility font functions
+int GetFontIndex(char *fontname);
+int GetFontEnum(int index);
+char *GetFontName(int index);
+int GetFontAlign(char *alignstr);
+
 #endif
 
diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp
index 987382da87..7ca866cd15 100644
--- a/Fltk/Opengl.cpp
+++ b/Fltk/Opengl.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl.cpp,v 1.44 2004-12-27 03:57:23 geuzaine Exp $
+// $Id: Opengl.cpp,v 1.45 2004-12-28 20:37:19 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -82,13 +82,42 @@ void Draw_String(char *s)
 
 void Draw_String(char *s, double style)
 {
-  int size = (int)style, oldsize = CTX.gl_fontsize;
-  // extract the 8 lower bits of style to get the font size (and
-  // ignore if size==0):
-  size &= 0xff;
-  if(size) CTX.gl_fontsize = size;
+  unsigned int bits = (unsigned int)style;
+
+  if(!bits){ // use defaults
+    Draw_String(s);
+    return;
+  }
+
+  int size = (bits & 0xff);
+  int font = (bits>>8 & 0xff);
+  int align = (bits>>16 & 0xff);
+  
+  int oldsize = CTX.gl_fontsize;
+  int oldfont_enum = CTX.gl_font_enum;
+  char * oldfont = CTX.gl_font;
+  
+  CTX.gl_font_enum = GetFontEnum(font);
+  CTX.gl_font = GetFontName(font);
+  if(size)
+    CTX.gl_fontsize = size;
+  if(align > 0){
+    GLfloat pos[4];
+    glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
+    gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+    float width = gl_width(s);
+    if(align == 1) // center
+      glRasterPos2d(pos[0]-width/2., pos[1]);
+    else if(align == 2) // right
+      glRasterPos2d(pos[0]-width, pos[1]);
+  }
+
   Draw_String(s);
-  if(size) CTX.gl_fontsize = oldsize;
+  
+  CTX.gl_font_enum = oldfont_enum;
+  CTX.gl_font = oldfont;
+  if(size)
+    CTX.gl_fontsize = oldsize;
 }
 
 void Draw_OnScreenMessages()
diff --git a/Graphics/Graph2D.cpp b/Graphics/Graph2D.cpp
index 667eae6dcf..ffdd249ecb 100644
--- a/Graphics/Graph2D.cpp
+++ b/Graphics/Graph2D.cpp
@@ -1,4 +1,4 @@
-// $Id: Graph2D.cpp,v 1.39 2004-12-27 03:57:23 geuzaine Exp $
+// $Id: Graph2D.cpp,v 1.40 2004-12-28 20:37:19 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -509,8 +509,10 @@ void Draw_Text2D(void)
 
   for(i = 0; i < List_Nbr(CTX.post.list); i++) {
     v = *(Post_View **) List_Pointer(CTX.post.list, i);
-    if(v->Visible && !v->Dirty && v->DrawStrings)
+    if(v->Visible && !v->Dirty && v->DrawStrings){
+      glColor4ubv((GLubyte *) & v->color.text2d);
       Draw_Text2D3D(2, v->TimeStep, v->NbT2, v->T2D, v->T2C);
+    }
   }
 
 }
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index a69ed3451a..8d7594652e 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.87 2004-12-24 23:10:27 geuzaine Exp $
+// $Id: Post.cpp,v 1.88 2004-12-28 20:37:19 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -728,7 +728,7 @@ void Draw_Post(void)
       }
 
       if(v->DrawStrings) {
-	glColor4ubv((GLubyte *) & CTX.color.text);
+	glColor4ubv((GLubyte *) & v->color.text3d);
 	Draw_Text2D3D(3, v->TimeStep, v->NbT3, v->T3D, v->T3C);
       }
 
diff --git a/Plugin/Annotate.cpp b/Plugin/Annotate.cpp
index 53482192d2..a4eca47f74 100644
--- a/Plugin/Annotate.cpp
+++ b/Plugin/Annotate.cpp
@@ -1,4 +1,4 @@
-// $Id: Annotate.cpp,v 1.1 2004-12-27 03:57:23 geuzaine Exp $
+// $Id: Annotate.cpp,v 1.2 2004-12-28 20:37:19 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -26,11 +26,16 @@
 #include "Context.h"
 #include "Numeric.h"
 
+#if defined(HAVE_FLTK)
+#include "GmshUI.h"
+#include "GUI.h"
+#endif
+
 extern Context_T CTX;
 
 StringXNumber AnnotateOptions_Number[] = {
-  {GMSH_FULLRC, "X", NULL, 20.},
-  {GMSH_FULLRC, "Y", NULL, 20.},
+  {GMSH_FULLRC, "X", NULL, 50.},
+  {GMSH_FULLRC, "Y", NULL, 30.},
   {GMSH_FULLRC, "Z", NULL, 0.},
   {GMSH_FULLRC, "3D", NULL, 0.},
   {GMSH_FULLRC, "FontSize", NULL, 14.},
@@ -38,7 +43,9 @@ StringXNumber AnnotateOptions_Number[] = {
 };
 
 StringXString AnnotateOptions_String[] = {
-  {GMSH_FULLRC, "Text", NULL, "My Text"}
+  {GMSH_FULLRC, "Text", NULL, "My Text"},
+  {GMSH_FULLRC, "Font", NULL, "Helvetica"},
+  {GMSH_FULLRC, "Align", NULL, "Left"}
 };
 
 extern "C"
@@ -71,8 +78,9 @@ void GMSH_AnnotatePlugin::getInfos(char *author, char *copyright,
 	 "in model coordinates at the position (`X',`Y',`Z').\n"
 	 "If `3D' is equal to 0, the plugin inserts the\n"
 	 "string in screen coordinates at the position\n"
-	 "(`X',`Y'). If `iView' < 0, the plugin is run on\n"
-	 "the current view.\n"
+	 "(`X',`Y'), and aligns it according to `Align'.\n"
+	 "If `iView' < 0, the plugin is run on the current\n"
+	 "view.\n"
 	 "\n"
 	 "Plugin(Annotate) is executed in-place.\n");
 }
@@ -102,6 +110,10 @@ void GMSH_AnnotatePlugin::catchErrorMessage(char *errorMessage) const
   strcpy(errorMessage, "Annotate failed...");
 }
 
+#if defined(HAVE_FLTK)
+extern Fl_Menu_Item menu_font_names[];
+#endif
+
 Post_View *GMSH_AnnotatePlugin::execute(Post_View * v)
 {
   double X = AnnotateOptions_Number[0].def;
@@ -111,6 +123,8 @@ Post_View *GMSH_AnnotatePlugin::execute(Post_View * v)
   int fontsize = (int)AnnotateOptions_Number[4].def;
   int iView = (int)AnnotateOptions_Number[5].def;
   char *text = AnnotateOptions_String[0].def;
+  char *fontname = AnnotateOptions_String[1].def;
+  char *alignstr =  AnnotateOptions_String[2].def;
 
   if(iView < 0)
     iView = v ? v->Index : 0;
@@ -120,9 +134,17 @@ Post_View *GMSH_AnnotatePlugin::execute(Post_View * v)
     return v;
   }
 
+  int font = 0, align = 0;
+#if defined(HAVE_FLTK)
+  font = GetFontIndex(fontname);
+  // align only makes sense in screen coordinates at the moment:
+  if(!dim3)
+    align = GetFontAlign(alignstr);
+#endif
+
   Post_View *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView);
-  
-  double style = (double)fontsize; // for now...
+
+  double style = (double)((align<<16)|(font<<8)|(fontsize));
 
   if(dim3){
     List_Add(v1->T3D, &X);
diff --git a/Plugin/Makefile b/Plugin/Makefile
index 204a348613..c1bb886657 100644
--- a/Plugin/Makefile
+++ b/Plugin/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.70 2004-12-27 19:18:12 geuzaine Exp $
+# $Id: Makefile,v 1.71 2004-12-28 20:37:19 geuzaine Exp $
 #
 # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 #
@@ -22,7 +22,7 @@
 include ../variables
 
 LIB     = ../lib/libGmshPlugin.a
-INCLUDE = -I../Common -I../Graphics -I../DataStr -I../Geo\
+INCLUDE = -I../Common -I../Graphics -I../DataStr -I../Geo -I../Fltk\
             -I../Mesh -I../Numeric -I../Triangle -I../MathEval
 CFLAGS  = -DMPICH_SKIP_MPICXX ${OPTIM} ${FLAGS} ${INCLUDE}
 
diff --git a/doc/VERSIONS b/doc/VERSIONS
index fec19d39f2..39b89f121a 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,10 +1,10 @@
-$Id: VERSIONS,v 1.286 2004-12-27 17:08:26 geuzaine Exp $
+$Id: VERSIONS,v 1.287 2004-12-28 20:37:19 geuzaine Exp $
 
 New since 1.57: new File->Rename menu; new colormaps+improved colormap
 handling; new color+min/max options in views; new GetValue() function
 to ask for values interactively in scripts; generalized For/EndFor
-loops in parser; new plugins (Annotate, Remove, Probe); various other
-small enhancements and bug fixes.
+loops in parser; new plugins (Annotate, Remove, Probe); new text
+attributes in views; various other small enhancements and bug fixes.
 
 New in 1.57: generalized displacement maps to display arbitrary view
 types; the arrows representing a vector field can now also be colored
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 29557168b5..e47c18c5d1 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -1,5 +1,5 @@
 \input texinfo.tex @c -*-texinfo-*-
-@c $Id: gmsh.texi,v 1.153 2004-12-27 17:51:55 geuzaine Exp $
+@c $Id: gmsh.texi,v 1.154 2004-12-28 20:37:19 geuzaine Exp $
 @c
 @c Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 @c
@@ -3072,8 +3072,8 @@ tensor prism        TI    18           54 * @var{nb-time-steps}
 scalar pyramid      SY    15           5  * @var{nb-time-steps}
 vector pyramid      VY    15           15 * @var{nb-time-steps}
 tensor pyramid      TY    15           45 * @var{nb-time-steps}
-text 2d             T2    4            arbitrary
-text 3d             T3    5            arbitrary
+text 2d             T2    3            arbitrary
+text 3d             T3    4            arbitrary
 @end example
 
 The coordinates are given `by node'@footnote{Beware that this is different
@@ -3105,6 +3105,26 @@ The values are given by time step, by node and by component, i.e.:
 @dots{}
 @end example
 
+For the 2D text objects, the two first @var{expression}s in
+@var{list-of-coords} give the position of the string in screen coordinates.
+If the third @var{expression} is equal to zero, the text is left-aligned and
+displayed using the default font and size. Otherwise, the third
+@var{expression} is converted into an integer whose eight lower bits give
+the font size, whose eight next bits select the font (the index corresponds
+to the position in the font menu in the GUI), and whose eight next bits
+define the text alignment (0=left, 1=center, 2=right).
+
+For the 3D text objects, the three first @var{expression}s in
+@var{list-of-coords} give the position of the leftmost element of the string
+in model (real world) coordinates.  If the fourth @var{expression} is equal
+to zero, the text is displayed using the default font and size. Otherwise,
+the fourth @var{expression} is converted into an integer whose eight lower
+bits give the font size and whose eight next bits select the font (the index
+corresponds to the position in the font menu in the GUI).
+
+For both 2D and 3D text objects, the @var{list-of-values} can contain an
+arbitrary number of @var{char-expression}s.
+
 The optional @code{TIME} list can contain a list of expressions giving the
 value of the time (or any other variable) for which an evolution was saved.
 
@@ -3230,11 +3250,14 @@ is a list of 4 double precision numbers:
 @example
 @var{coord1} @var{coord2} @var{style} @var{index}
 @end example
-where @var{coord1} and @var{coord2} give the coordinates of the leftmost
-element of the 2D string in screen coordinates, @var{index} gives the
-starting index of the string in @var{text2d-chars} and, if nonzero, the
-eight lower bits in @var{style} give the font size (the rest of @var{style}
-is reserved for future use).
+where @var{coord1} and @var{coord2} give the position of the 2D string in
+screen coordinates and @var{index} gives the starting index of the string in
+@var{text2d-chars}. If @var{style} is equal to zero, the text is
+left-aligned and displayed using the default font and size. Otherwise,
+@var{style} is converted into an integer whose eight lower bits give the
+font size, whose eight next bits select the font (the index corresponds to
+the position in the font menu in the GUI), and whose eight next bits define
+the text alignment (0=left, 1=center, 2=right).
 
 @item @var{text2d-chars}
 is a list of @var{nb-text2d-chars} characters. Substrings are separated with
@@ -3247,9 +3270,11 @@ is a list of 5 double precision numbers
 @end example
 where @var{coord1}, @var{coord2} and @var{coord3} give the coordinates of
 the leftmost element of the 3D string in model (real world) coordinates,
-@var{index} gives the starting index of the string in @var{text3d-chars}
-and, if nonzero, the eight lower bits in @var{style} give the font size (the
-rest of @var{style} is reserved for future use).
+@var{index} gives the starting index of the string in @var{text3d-chars}.
+If @var{style} is equal to zero, the text is displayed using the default
+font and size. Otherwise, @var{style} is converted into an integer whose
+eight lower bits give the font size and whose eight next bits select the font
+(the index corresponds to the position in the font menu in the GUI).
 
 @item @var{text3d-chars}
 is a list of @var{nb-text3d-chars} chars. Substrings are separated with the
-- 
GitLab