GtkText + underline (partial patch)



So the new GtkText replacement is taking a bit too long to come to life, so
I decided to add underlining to the existing text widget (even if it is
going away in the future, this functionality is needed by many people, in
the present).

So I started the patch, but I'm a little confused on how to continue. This
is against 1.2.6 tarball from the ftp sites.

Basically, I've added a gboolean to the TextProperty structure which lets
you know if the chunk of text is to be underlined or not, and I've fixed up
all the code (I think) that messes with TextProperty's and that inserts new
text. I have the underlining code done too (at very end of patch). The only
part I'm missing is how you decide in draw_line() if the text you are
drawing with gdk_draw_text() is to be underlined or not. I can find no
TextProperty that function has access, and I'm a little confused by the
LineParams stuff. Could someone give me a hint on how to connect the final
underlining to the Textproperty the text belongs to?


--- gtk+-1.2.6/gtk/gtktext.c	Fri Sep  3 18:20:39 1999
+++ gtk+-1.2.6.me/gtk/gtktext.c	Tue Feb  1 10:05:53 2000
@@ -154,6 +154,9 @@
 
   /* Length of this property. */
   guint length;
+
+  /* text property is underlined */
+  gboolean underlined;
 };
 
 struct _TabStopMark
@@ -262,9 +265,10 @@
 static void         text_font_unref (GtkTextFont *text_font);
 
 static void insert_text_property (GtkText* text, GdkFont* font,
-				  GdkColor *fore, GdkColor* back, guint len);
+				  GdkColor *fore, GdkColor* back, guint len, gboolean uline);
 static TextProperty* new_text_property (GtkText *text, GdkFont* font, 
-					GdkColor* fore, GdkColor* back, guint length);
+					GdkColor* fore, GdkColor* back,
+					guint length, gboolean uline);
 static void destroy_text_property (TextProperty *prop);
 static void init_properties      (GtkText *text);
 static void realize_property     (GtkText *text, TextProperty *prop);
@@ -925,7 +929,8 @@
 		 GdkColor   *fore,
 		 GdkColor   *back,
 		 const char *chars,
-		 gint        nchars)
+		 gint        nchars,
+		 gboolean    uline)
 {
   GtkEditable *editable = GTK_EDITABLE (text);
   gboolean frozen = FALSE;
@@ -1021,7 +1026,7 @@
  
   if (numwcs > 0)
     {
-      insert_text_property (text, font, fore, back, numwcs);
+      insert_text_property (text, font, fore, back, numwcs, uline);
    
       text->gap_size -= numwcs;
       text->gap_position += numwcs;
@@ -1952,7 +1957,8 @@
   fore = property->flags & PROPERTY_FOREGROUND ? &property->fore_color : NULL; 
   back = property->flags & PROPERTY_BACKGROUND ? &property->back_color : NULL; 
   
-  gtk_text_insert (text, font, fore, back, new_text, new_text_length);
+  gtk_text_insert (text, font, fore, back, new_text, new_text_length,
+		   property->underlined);
 
   *position = text->point.index;
 }
@@ -2950,7 +2956,8 @@
 }
 
 static gint
-text_properties_equal (TextProperty* prop, GdkFont* font, GdkColor *fore, GdkColor *back)
+text_properties_equal (TextProperty* prop, GdkFont* font, GdkColor *fore,
+		       GdkColor *back, gboolean uline)
 {
   if (prop->flags & PROPERTY_FONT)
     {
@@ -2989,6 +2996,9 @@
   else
     if (back != NULL)
       return FALSE;
+
+  if (prop->underlined != uline)
+    return FALSE;
   
   return TRUE;
 }
@@ -3045,7 +3055,7 @@
 
 static TextProperty*
 new_text_property (GtkText *text, GdkFont *font, GdkColor* fore, 
-		   GdkColor* back, guint length)
+		   GdkColor* back, guint length, gboolean uline)
 {
   TextProperty *prop;
   
@@ -3082,6 +3092,8 @@
 
   prop->length = length;
 
+  prop->underlined = uline;
+
   if (GTK_WIDGET_REALIZED (text))
     realize_property (text, prop);
 
@@ -3178,7 +3190,7 @@
  * point. */
 static void
 insert_text_property (GtkText* text, GdkFont* font,
-		      GdkColor *fore, GdkColor* back, guint len)
+		      GdkColor *fore, GdkColor* back, guint len, gboolean uline)
 {
   GtkPropertyMark *mark = &text->point;
   TextProperty* forward_prop = MARK_CURRENT_PROPERTY(mark);
@@ -3190,14 +3202,14 @@
        * If it is the same as either, grow, else insert
        * a new one. */
       
-      if (text_properties_equal(forward_prop, font, fore, back))
+      if (text_properties_equal(forward_prop, font, fore, back, uline))
 	{
 	  /* Grow the property in front of us. */
 	  
 	  MARK_PROPERTY_LENGTH(mark) += len;
 	}
       else if (backward_prop &&
-	       text_properties_equal(backward_prop, font, fore, back))
+	       text_properties_equal(backward_prop, font, fore, back, uline))
 	{
 	  /* Grow property behind us, point property and offset
 	   * change. */
@@ -3253,7 +3265,7 @@
 	  if (new_prop->prev)
 	    new_prop->prev->next = new_prop;
 
-	  new_prop->data = new_text_property (text, font, fore, back, len);
+	  new_prop->data = new_text_property (text, font, fore, back, len, uline);
 
 	  SET_PROPERTY_MARK (mark, new_prop, 0);
 	}
@@ -3267,7 +3279,7 @@
       /* In the middle of forward_prop, if properties are equal,
        * just add to its length, else split it into two and splice
        * in a new one. */
-      if (text_properties_equal (forward_prop, font, fore, back))
+      if (text_properties_equal (forward_prop, font, fore, back, uline))
 	{
 	  forward_prop->length += len;
 	}
@@ -3280,7 +3292,7 @@
 	  forward_prop->length -= 1;
 	  
 	  new_prop = g_list_alloc();
-	  new_prop->data = new_text_property (text, font, fore, back, len+1);
+	  new_prop->data = new_text_property (text, font, fore, back, len+1, uline);
 	  new_prop->prev = MARK_LIST_PTR(mark);
 	  new_prop->next = NULL;
 	  MARK_NEXT_LIST_PTR(mark) = new_prop;
@@ -3306,9 +3318,10 @@
   			             &forward_prop->fore_color : NULL,
 			      forward_prop->flags & PROPERTY_BACKGROUND ? 
   			             &forward_prop->back_color : NULL,
-			      old_length - forward_prop->length);
+			      old_length - forward_prop->length,
+			      forward_prop->underlined);
 
-	  new_prop->data = new_text_property(text, font, fore, back, len);
+	  new_prop->data = new_text_property(text, font, fore, back, len, uline);
 
 	  /* Now splice things in. */
 	  MARK_NEXT_LIST_PTR(mark) = new_prop;
@@ -3426,7 +3439,7 @@
       text->text_properties = g_list_alloc();
       text->text_properties->next = NULL;
       text->text_properties->prev = NULL;
-      text->text_properties->data = new_text_property (text, NULL, NULL, NULL, 1);
+      text->text_properties->data = new_text_property (text, NULL, NULL, NULL, 1, 0);
       text->text_properties_end = text->text_properties;
       
       SET_PROPERTY_MARK (&text->point, text->text_properties, 0);
@@ -4973,6 +4986,7 @@
 	  union { GdkWChar *wc; guchar *ch; } next_tab;
 	  gint pixel_width;
 	  GdkFont *font;
+	  int textwidth;
 
 	  next_tab.wc = NULL;
 	  if (text->use_wchar)
@@ -5042,20 +5056,37 @@
 	      fg_gc = text->gc;
 	    }
 
-	  if (text->use_wchar)
+
+	  if (text->use_wchar) {
+	    gdk_text_extents_wc (MARK_CURRENT_FONT (text, &mark), buffer.wc, len,
+			      NULL, NULL, &textwidth, NULL, NULL);
+
 	    gdk_draw_text_wc (text->text_area, MARK_CURRENT_FONT (text, &mark),
 			      fg_gc,
 			      running_offset,
 			      pixel_height,
 			      buffer.wc,
 			      len);
-	  else
+
+	  } else {
+	    gdk_text_extents (MARK_CURRENT_FONT (text, &mark), buffer.ch, len,
+			      NULL, NULL, &textwidth, NULL, NULL);
+
 	    gdk_draw_text (text->text_area, MARK_CURRENT_FONT (text, &mark),
 			   fg_gc,
 			   running_offset,
 			   pixel_height,
 			   buffer.ch,
 			   len);
+
+	  }
+	  if (THIS TEXT SHOULD BE UNDERLINED)
+	    gdk_draw_line (text->text_area,
+			   fg_gc,
+			   running_offset,
+			   pixel_height,
+			   running_offset + textwidth,
+			   pixel_height);
 	  
 	  running_offset += pixel_width;
 	  


-- 
___________________________________________________________________________
Danny Dulai                                           Feet. Pumice. Lotion.
http://www.ishiboo.com/~nirva/                            nirva@ishiboo.com



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]