]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextdisplay.c
Adapt to uscore-ification of gtktextiterprivate
[~andy/gtk] / gtk / gtktextdisplay.c
index 10fd95c5624d01fa277551b3f0480474494c8f3d..3782cb82505e83d682fb8d132ec9fa67cf17d55c 100644 (file)
@@ -75,7 +75,9 @@
  */
 
 #include "gtktextdisplay.h"
-#include "gtktextiterprivate.h"
+/* DO NOT go putting private headers in here. This file should only
+ * use the semi-public headers, as with gtktextview.c.
+ */
 
 #include <pango/pango.h>
 
@@ -86,6 +88,7 @@ struct _GtkTextRenderState
   GtkWidget *widget;
 
   GtkTextAppearance *last_appearance;
+  GtkTextAppearance *last_bg_appearance;
   GdkGC *fg_gc;
   GdkGC *bg_gc;
   GdkRectangle clip_rect;
@@ -159,12 +162,12 @@ gtk_text_render_state_update (GtkTextRenderState *state,
 
   if (new_appearance->draw_bg)
     {
-      if (!state->last_appearance ||
-          !gdk_color_equal (&new_appearance->bg_color, &state->last_appearance->bg_color))
+      if (!state->last_bg_appearance ||
+          !gdk_color_equal (&new_appearance->bg_color, &state->last_bg_appearance->bg_color))
         gtk_text_render_state_set_color (state, state->bg_gc, &new_appearance->bg_color);
 
-      if (!state->last_appearance ||
-          new_appearance->bg_stipple != state->last_appearance->bg_stipple)
+      if (!state->last_bg_appearance ||
+          new_appearance->bg_stipple != state->last_bg_appearance->bg_stipple)
         {
           if (new_appearance->bg_stipple)
             {
@@ -176,11 +179,41 @@ gtk_text_render_state_update (GtkTextRenderState *state,
               gdk_gc_set_fill (state->bg_gc, GDK_SOLID);
             }
         }
+
+      state->last_bg_appearance = new_appearance;
     }
 
   state->last_appearance = new_appearance;
 }
 
+static void
+get_shape_extents (PangoLayoutRun *run,
+                   PangoRectangle *ink_rect,
+                   PangoRectangle *logical_rect)
+{
+  GSList *tmp_list = run->item->extra_attrs;
+    
+  while (tmp_list)
+    {
+      PangoAttribute *attr = tmp_list->data;
+
+      if (attr->klass->type == PANGO_ATTR_SHAPE)
+       {          
+         if (logical_rect)
+           *logical_rect = ((PangoAttrShape *)attr)->logical_rect;
+
+         if (ink_rect)
+           *ink_rect = ((PangoAttrShape *)attr)->ink_rect;
+
+          return;
+        }
+
+      tmp_list = tmp_list->next;
+    }
+
+  g_assert_not_reached ();
+}
+
 static void
 render_layout_line (GdkDrawable        *drawable,
                     GtkTextRenderState *render_state,
@@ -194,85 +227,72 @@ render_layout_line (GdkDrawable        *drawable,
   PangoRectangle overall_rect;
   PangoRectangle logical_rect;
   PangoRectangle ink_rect;
-
   gint x_off = 0;
-
+  GdkGC *fg_gc;
+  
   pango_layout_line_get_extents (line, NULL, &overall_rect);
 
   while (tmp_list)
     {
       PangoLayoutRun *run = tmp_list->data;
       GtkTextAppearance *appearance;
-
+      gint risen_y;
+      gint shaped_width_pixels = 0;
+      gboolean need_ink = FALSE;
+      
       tmp_list = tmp_list->next;
 
       get_item_properties (run->item, &appearance);
 
-      if (appearance)           /* A text segment */
+      g_assert (appearance != NULL);
+      
+      risen_y = y - PANGO_PIXELS (appearance->rise);
+      
+      if (selected)
         {
-          GdkGC *fg_gc;
-
-          if (selected)
-            {
-              fg_gc = render_state->widget->style->fg_gc[GTK_STATE_SELECTED];
-            }
+          fg_gc = render_state->widget->style->fg_gc[GTK_STATE_SELECTED];
+        }
+      else
+        {
+          gtk_text_render_state_update (render_state, appearance);
+          
+          fg_gc = render_state->fg_gc;
+        }
+      
+      if (appearance->underline != PANGO_UNDERLINE_NONE ||
+          appearance->strikethrough)
+        need_ink = TRUE;
+      
+      if (appearance->is_text)
+        {
+          if (need_ink)
+            pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
+                                        &ink_rect, &logical_rect);
           else
-            {
-              gtk_text_render_state_update (render_state, appearance);
-
-              fg_gc = render_state->fg_gc;
-            }
-
-          if (appearance->underline == PANGO_UNDERLINE_NONE && !appearance->strikethrough)
             pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
                                         NULL, &logical_rect);
+        }
+      else
+        {
+          if (need_ink)
+            get_shape_extents (run, &ink_rect, &logical_rect);
           else
-            pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
-                                        &ink_rect, &logical_rect);
-
-          if (appearance->draw_bg && !selected)
-            gdk_draw_rectangle (drawable, render_state->bg_gc, TRUE,
-                                x + (x_off + logical_rect.x) / PANGO_SCALE,
-                                y + logical_rect.y / PANGO_SCALE,
-                                logical_rect.width / PANGO_SCALE,
-                                logical_rect.height / PANGO_SCALE);
-
-          gdk_draw_glyphs (drawable, fg_gc,
-                           run->item->analysis.font,
-                           x + x_off / PANGO_SCALE, y, run->glyphs);
-
-          switch (appearance->underline)
-            {
-            case PANGO_UNDERLINE_NONE:
-              break;
-            case PANGO_UNDERLINE_DOUBLE:
-              gdk_draw_line (drawable, fg_gc,
-                             x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 4,
-                             x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 4);
-              /* Fall through */
-            case PANGO_UNDERLINE_SINGLE:
-              gdk_draw_line (drawable, fg_gc,
-                             x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 2,
-                             x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 2);
-              break;
-            case PANGO_UNDERLINE_LOW:
-              gdk_draw_line (drawable, fg_gc,
-                             x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2,
-                             x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2);
-              break;
-            }
-
-          if (appearance->strikethrough)
-            {
-              gint strikethrough_y = y + (0.3 * logical_rect.y) / PANGO_SCALE;
-              gdk_draw_line (drawable, fg_gc,
-                             x + (x_off + ink_rect.x) / PANGO_SCALE - 1, strikethrough_y,
-                             x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, strikethrough_y);
-            }
-
-          x_off += logical_rect.width;
+            get_shape_extents (run, NULL, &logical_rect);
         }
-      else                      /* Pixbuf or widget segment */
+      
+      if (appearance->draw_bg && !selected)
+        gdk_draw_rectangle (drawable, render_state->bg_gc, TRUE,
+                            x + PANGO_PIXELS (x_off) + PANGO_PIXELS (logical_rect.x),
+                            risen_y + PANGO_PIXELS (logical_rect.y),
+                            PANGO_PIXELS (logical_rect.width),
+                            PANGO_PIXELS (logical_rect.height));
+
+      if (appearance->is_text)
+        gdk_draw_glyphs (drawable, fg_gc,
+                         run->item->analysis.font,
+                         x + PANGO_PIXELS (x_off),
+                         risen_y, run->glyphs);
+      else
         {
           GObject *shaped = (*shaped_pointer)->data;
 
@@ -290,7 +310,7 @@ render_layout_line (GdkDrawable        *drawable,
               height = gdk_pixbuf_get_height (pixbuf);
 
               pixbuf_rect.x = x + x_off / PANGO_SCALE;
-              pixbuf_rect.y = y - height;
+              pixbuf_rect.y = risen_y - height;
               pixbuf_rect.width = width;
               pixbuf_rect.height = height;
 
@@ -340,32 +360,91 @@ render_layout_line (GdkDrawable        *drawable,
                     }
                 }
 
-              x_off += width * PANGO_SCALE;
+              shaped_width_pixels = width;
             }
           else if (GTK_IS_WIDGET (shaped))
             {
               gint width, height;
               GdkRectangle draw_rect;
               GtkWidget *widget;
-
+              
               widget = GTK_WIDGET (shaped);
               
               width = widget->allocation.width;
               height = widget->allocation.height;
 
+              g_print ("widget allocation at %d,%d %d x %d\n",
+                      widget->allocation.x,
+                      widget->allocation.y,
+                      widget->allocation.width,
+                      widget->allocation.height);
+              
               if (GTK_WIDGET_DRAWABLE (widget) &&
-                  gtk_widget_intersect (widget,
-                                        &render_state->clip_rect,
-                                        &draw_rect))
+                  gdk_rectangle_intersect (&widget->allocation,
+                                           &render_state->clip_rect,
+                                           &draw_rect))
+
                 {
+                  g_print ("drawing widget area %d,%d %d x %d\n",
+                          draw_rect.x,
+                          draw_rect.y,
+                          draw_rect.width,
+                          draw_rect.height);
+
                   gtk_widget_draw (widget, &draw_rect);
                 }
 
-              x_off += width * PANGO_SCALE;
+              shaped_width_pixels = width;
             }
           else
             g_assert_not_reached (); /* not a pixbuf or widget */
         }
+
+      switch (appearance->underline)
+        {
+        case PANGO_UNDERLINE_NONE:
+          break;
+        case PANGO_UNDERLINE_DOUBLE:
+          g_assert (need_ink);
+          gdk_draw_line (drawable, fg_gc,
+                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
+                         risen_y + 3,
+                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
+                         risen_y + 3);
+          /* Fall through */
+        case PANGO_UNDERLINE_SINGLE:
+          g_assert (need_ink);
+          gdk_draw_line (drawable, fg_gc,
+                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
+                         risen_y + 1,
+                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
+                         risen_y + 1);
+          break;
+        case PANGO_UNDERLINE_LOW:
+          g_assert (need_ink);
+          gdk_draw_line (drawable, fg_gc,
+                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
+                         risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1,
+                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
+                         risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1);
+          break;
+        }
+
+      if (appearance->strikethrough)
+        {          
+          gint strikethrough_y = risen_y + (0.3 * logical_rect.y) / PANGO_SCALE;
+
+          g_assert (need_ink);
+          
+          gdk_draw_line (drawable, fg_gc,
+                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1, strikethrough_y,
+                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, strikethrough_y);
+        }
+
+      if (appearance->is_text)
+        x_off += logical_rect.width;
+      else
+        x_off += shaped_width_pixels * PANGO_SCALE;
     }
 }
 
@@ -373,85 +452,65 @@ static void
 render_para (GdkDrawable        *drawable,
              GtkTextRenderState *render_state,
              GtkTextLineDisplay *line_display,
+             /* Top-left corner of paragraph including all margins */
              int                 x,
              int                 y,
              int                 selection_start_index,
              int                 selection_end_index)
 {
-  PangoRectangle logical_rect;
   GSList *shaped_pointer = line_display->shaped_objects;
-  GSList *tmp_list;
-  PangoAlignment align;
   PangoLayout *layout = line_display->layout;
-  int indent;
-  int total_width;
-  int y_offset = 0;
   int byte_offset = 0;
-
+  PangoLayoutIter *iter;
+  PangoRectangle layout_logical;
+  int screen_width;
+  
   gboolean first = TRUE;
 
-  indent = pango_layout_get_indent (layout);
-  total_width = pango_layout_get_width (layout);
-  align = pango_layout_get_alignment (layout);
+  iter = pango_layout_get_iter (layout);
 
-  if (total_width < 0)
-    total_width = line_display->total_width * PANGO_SCALE;
+  pango_layout_iter_get_layout_extents (iter, NULL, &layout_logical);
 
-  tmp_list = pango_layout_get_lines (layout);
-  while (tmp_list)
+  /* Adjust for margins */
+  
+  layout_logical.x += line_display->x_offset * PANGO_SCALE;
+  layout_logical.y += line_display->top_margin * PANGO_SCALE;
+
+  screen_width = line_display->total_width;
+  
+  do
     {
-      PangoLayoutLine *line = tmp_list->data;
-      int x_offset;
+      PangoLayoutLine *line = pango_layout_iter_get_line (iter);
       int selection_y, selection_height;
-
-      pango_layout_line_get_extents (line, NULL, &logical_rect);
-
-      x_offset = line_display->left_margin * PANGO_SCALE;
-
-      switch (align)
-        {
-        case PANGO_ALIGN_RIGHT:
-          x_offset += total_width - logical_rect.width;
-          break;
-        case PANGO_ALIGN_CENTER:
-          x_offset += (total_width - logical_rect.width) / 2;
-          break;
-        default:
-          break;
-        }
-
-      if (first)
-        {
-          if (indent > 0)
-            {
-              if (align == PANGO_ALIGN_LEFT)
-                x_offset += indent;
-              else
-                x_offset -= indent;
-            }
-        }
-      else
-        {
-          if (indent < 0)
-            {
-              if (align == PANGO_ALIGN_LEFT)
-                x_offset -= indent;
-              else
-                x_offset += indent;
-            }
-        }
-
-      selection_y = y + y_offset / PANGO_SCALE;
-      selection_height = logical_rect.height / PANGO_SCALE;
+      int first_y, last_y;
+      PangoRectangle line_rect;
+      int baseline;
+      
+      pango_layout_iter_get_line_extents (iter, NULL, &line_rect);
+      baseline = pango_layout_iter_get_baseline (iter);
+      pango_layout_iter_get_line_yrange (iter, &first_y, &last_y);
+      
+      /* Adjust for margins */
+
+      line_rect.x += line_display->x_offset * PANGO_SCALE;
+      line_rect.y += line_display->top_margin * PANGO_SCALE;
+      baseline += line_display->top_margin * PANGO_SCALE;
+
+      /* Selection is the height of the line, plus top/bottom
+       * margin if we're the first/last line
+       */
+      selection_y = y + PANGO_PIXELS (first_y) + line_display->top_margin;
+      selection_height = PANGO_PIXELS (last_y) - PANGO_PIXELS (first_y);
 
       if (first)
         {
           selection_y -= line_display->top_margin;
           selection_height += line_display->top_margin;
         }
-      if (!tmp_list->next)
+      
+      if (pango_layout_iter_at_last_line (iter))
         selection_height += line_display->bottom_margin;
-
+      
       first = FALSE;
 
       if (selection_start_index < byte_offset &&
@@ -460,18 +519,24 @@ render_para (GdkDrawable        *drawable,
           gdk_draw_rectangle (drawable,
                               render_state->widget->style->bg_gc[GTK_STATE_SELECTED],
                               TRUE,
-                              x + line_display->left_margin, selection_y,
-                              total_width / PANGO_SCALE, selection_height);
+                              x + line_display->left_margin,
+                              selection_y,
+                              screen_width,
+                              selection_height);
+
           render_layout_line (drawable, render_state, line, &shaped_pointer,
-                              x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE,
+                              x + PANGO_PIXELS (line_rect.x),
+                              y + PANGO_PIXELS (baseline),
                               TRUE);
         }
       else
         {
           GSList *shaped_pointer_tmp = shaped_pointer;
 
-          render_layout_line (drawable, render_state, line, &shaped_pointer,
-                              x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE,
+          render_layout_line (drawable, render_state,
+                              line, &shaped_pointer,
+                              x + PANGO_PIXELS (line_rect.x),
+                              y + PANGO_PIXELS (baseline),
                               FALSE);
 
           if (selection_start_index < byte_offset + line->length &&
@@ -479,7 +544,8 @@ render_para (GdkDrawable        *drawable,
             {
               GdkRegion *clip_region = get_selected_clip (render_state, layout, line,
                                                           x + line_display->x_offset,
-                                                          selection_y, selection_height,
+                                                          selection_y,
+                                                          selection_height,
                                                           selection_start_index, selection_end_index);
 
               gdk_gc_set_clip_region (render_state->widget->style->fg_gc [GTK_STATE_SELECTED], clip_region);
@@ -488,12 +554,14 @@ render_para (GdkDrawable        *drawable,
               gdk_draw_rectangle (drawable,
                                   render_state->widget->style->bg_gc[GTK_STATE_SELECTED],
                                   TRUE,
-                                  x + x_offset / PANGO_SCALE, selection_y,
-                                  logical_rect.width / PANGO_SCALE,
+                                  x + PANGO_PIXELS (line_rect.x),
+                                  selection_y,
+                                  PANGO_PIXELS (line_rect.width),
                                   selection_height);
 
               render_layout_line (drawable, render_state, line, &shaped_pointer_tmp,
-                                  x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE,
+                                  x + PANGO_PIXELS (line_rect.x),
+                                  y + PANGO_PIXELS (baseline),
                                   TRUE);
 
               gdk_gc_set_clip_region (render_state->widget->style->fg_gc [GTK_STATE_SELECTED], NULL);
@@ -502,39 +570,46 @@ render_para (GdkDrawable        *drawable,
               gdk_region_destroy (clip_region);
 
               /* Paint in the ends of the line */
-              if (x_offset > line_display->left_margin * PANGO_SCALE &&
+              if (line_rect.x > line_display->left_margin * PANGO_SCALE &&
                   ((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) ||
                    (line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset + line->length)))
                 {
                   gdk_draw_rectangle (drawable,
                                       render_state->widget->style->bg_gc[GTK_STATE_SELECTED],
                                       TRUE,
-                                      x + line_display->left_margin, selection_y,
-                                      x + x_offset / PANGO_SCALE - line_display->left_margin,
+                                      x + line_display->left_margin,
+                                      selection_y,
+                                      PANGO_PIXELS (line_rect.x) - line_display->left_margin,
                                       selection_height);
                 }
 
-              if (x_offset + logical_rect.width < line_display->left_margin * PANGO_SCALE + total_width &&
+              if (line_rect.x + line_rect.width <
+                  (screen_width + line_display->left_margin) * PANGO_SCALE &&
                   ((line_display->direction == GTK_TEXT_DIR_LTR && selection_end_index > byte_offset + line->length) ||
                    (line_display->direction == GTK_TEXT_DIR_RTL && selection_start_index < byte_offset)))
                 {
+                  int nonlayout_width;
 
+                  nonlayout_width =
+                    line_display->left_margin + screen_width -
+                    PANGO_PIXELS (line_rect.x) - PANGO_PIXELS (line_rect.width);
 
                   gdk_draw_rectangle (drawable,
                                       render_state->widget->style->bg_gc[GTK_STATE_SELECTED],
                                       TRUE,
-                                      x + (x_offset + logical_rect.width) / PANGO_SCALE,
+                                      x + PANGO_PIXELS (line_rect.x) + PANGO_PIXELS (line_rect.width),
                                       selection_y,
-                                      x + (line_display->left_margin * PANGO_SCALE + total_width - x_offset - logical_rect.width) / PANGO_SCALE,
+                                      nonlayout_width,
                                       selection_height);
                 }
             }
         }
 
       byte_offset += line->length;
-      y_offset += logical_rect.height;
-      tmp_list = tmp_list->next;
     }
+  while (pango_layout_iter_next_line (iter));
+
+  pango_layout_iter_free (iter);
 }
 
 static GdkRegion *
@@ -551,20 +626,18 @@ get_selected_clip (GtkTextRenderState *render_state,
   gint n_ranges, i;
   GdkRegion *clip_region = gdk_region_new ();
   GdkRegion *tmp_region;
-  PangoRectangle logical_rect;
 
-  pango_layout_line_get_extents (line, NULL, &logical_rect);
   pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
 
   for (i=0; i < n_ranges; i++)
     {
       GdkRectangle rect;
 
-      rect.x = x + ranges[2*i] / PANGO_SCALE;
+      rect.x = x + PANGO_PIXELS (ranges[2*i]);
       rect.y = y;
-      rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE;
+      rect.width = PANGO_PIXELS (ranges[2*i + 1]) - PANGO_PIXELS (ranges[2*i]);
       rect.height = height;
-
+      
       gdk_region_union_with_rect (clip_region, &rect);
     }
 
@@ -601,8 +674,8 @@ void
 gtk_text_layout_draw (GtkTextLayout *layout,
                       GtkWidget *widget,
                       GdkDrawable *drawable,
-                      /* Location of the layout
-                         in buffer coordinates */
+                      /* Location of the drawable
+                         in layout coordinates */
                       gint x_offset,
                       gint y_offset,
                       /* Region of the layout to
@@ -614,13 +687,13 @@ gtk_text_layout_draw (GtkTextLayout *layout,
 {
   GdkRectangle clip;
   gint current_y;
-  GSList *line_list;
-  GSList *tmp_list;
   GSList *cursor_list;
   GtkTextRenderState *render_state;
   GtkTextIter selection_start, selection_end;
   gboolean have_selection = FALSE;
-
+  GSList *line_list;
+  GSList *tmp_list;
+  
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   g_return_if_fail (layout->default_style != NULL);
   g_return_if_fail (layout->buffer != NULL);
@@ -666,18 +739,21 @@ gtk_text_layout_draw (GtkTextLayout *layout,
       GtkTextLine *line = tmp_list->data;
 
       line_display = gtk_text_layout_get_line_display (layout, line, FALSE);
-
+      
       if (have_selection)
         {
           GtkTextIter line_start, line_end;
-          gint byte_count = gtk_text_line_byte_count (line);
+          gint byte_count;
 
-          gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                           &line_start,
-                                           line, 0);
-          gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                           &line_end,
-                                           line, byte_count - 1);
+          gtk_text_layout_get_iter_at_line (layout,
+                                            &line_start,
+                                            line, 0);
+          byte_count = gtk_text_iter_get_bytes_in_line (&line_start);
+          
+          /* FIXME the -1 assumes a newline I think */
+          gtk_text_layout_get_iter_at_line (layout,
+                                            &line_end,
+                                            line, byte_count - 1);
 
           if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
               gtk_text_iter_compare (&selection_end, &line_start) > 0)
@@ -696,7 +772,7 @@ gtk_text_layout_draw (GtkTextLayout *layout,
 
       render_para (drawable, render_state, line_display,
                    - x_offset,
-                   current_y + line_display->top_margin,
+                   current_y,
                    selection_start_index, selection_end_index);
 
 
@@ -715,17 +791,19 @@ gtk_text_layout_draw (GtkTextLayout *layout,
             gc = widget->style->fg_gc[GTK_STATE_NORMAL];
 
           gdk_draw_line (drawable, gc,
-                         line_display->x_offset + cursor->x,
+                         line_display->x_offset + cursor->x - x_offset,
                          current_y + line_display->top_margin + cursor->y,
-                         line_display->x_offset + cursor->x,
-                         current_y + line_display->top_margin + cursor->y + cursor->height);
+                         line_display->x_offset + cursor->x - x_offset,
+                         current_y + line_display->top_margin + cursor->y + cursor->height - 1);
 
           cursor_list = cursor_list->next;
         }
 
       current_y += line_display->height;
       gtk_text_layout_free_line_display (layout, line_display);
-
+      render_state->last_appearance = NULL;
+      render_state->last_bg_appearance = NULL;
+      
       tmp_list = g_slist_next (tmp_list);
     }