[Swfdec] 7 commits - libswfdec/swfdec_text_field_movie.c libswfdec/swfdec_text_field_movie.h libswfdec/swfdec_text_field_movie_html.c

Pekka Lampila medar at kemper.freedesktop.org
Sun Nov 4 06:14:21 PST 2007


 libswfdec/swfdec_text_field_movie.c      |  135 +++++++++++++++++++++++++++----
 libswfdec/swfdec_text_field_movie.h      |    2 
 libswfdec/swfdec_text_field_movie_html.c |    1 
 3 files changed, 123 insertions(+), 15 deletions(-)

New commits:
commit 9ca546dd0eaab842f879ed3373ccceb7183688ac
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun Nov 4 16:13:30 2007 +0200

    More fixes to handling paragraph ending newline

diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index 36b3596..08afd73 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -136,6 +136,7 @@ swfdec_text_field_movie_generate_paragraph (SwfdecTextFieldMovie *text,
 
   paragraph->index_ = start_index;
   paragraph->length = length;
+  paragraph->newline = (text->input->str[start_index + length - 1] == '\n');
 
   paragraph->blocks = NULL;
   paragraph->attrs = NULL;
@@ -519,6 +520,7 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
       SwfdecBlock *block;
       int width;
       guint length;
+      gboolean end_of_paragraph;
 
       block = (SwfdecBlock *)iter->data;
       if (iter->next != NULL) {
@@ -526,6 +528,8 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
 	  ((SwfdecBlock *)(iter->next->data))->index_ - block->index_;
       } else {
 	length = paragraphs[i].length - block->index_;
+	if (paragraphs[i].newline)
+	  length -= 1;
       }
 
       if (skip > length) {
@@ -577,14 +581,16 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
       pango_layout_set_attributes (playout, attr_list);
 
       if (text->text->password) {
-	pango_layout_set_text (playout, text->asterisks,
-	    paragraphs[i].length - block->index_ - skip);
+	pango_layout_set_text (playout, text->asterisks, paragraphs[i].length -
+	    block->index_ - skip - (paragraphs[i].newline ? 1 : 0));
       } else {
 	pango_layout_set_text (playout,
 	    text->input->str + paragraphs[i].index_ + block->index_ + skip,
-	    paragraphs[i].length - block->index_ - skip);
+	    paragraphs[i].length - block->index_ - skip -
+	    (paragraphs[i].newline ? 1 : 0));
       }
 
+      end_of_paragraph = TRUE;
       if (iter->next != NULL && text->text->word_wrap)
       {
 	PangoLayoutLine *line;
@@ -593,12 +599,15 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
 
 	pango_layout_index_to_line_x (playout, length - skip, FALSE, &line_num,
 	    NULL);
-	line = pango_layout_get_line_readonly (playout, line_num);
-	skip_new = line->start_index + line->length - (length - skip);
-	pango_layout_set_text (playout,
-	    text->input->str + paragraphs[i].index_ + block->index_ + skip,
-	    length - skip + skip_new);
-	skip = skip_new;
+	if (line_num < pango_layout_get_line_count (playout) - 1) {
+	  end_of_paragraph = FALSE;
+	  line = pango_layout_get_line_readonly (playout, line_num);
+	  skip_new = line->start_index + line->length - (length - skip);
+	  pango_layout_set_text (playout,
+	      text->input->str + paragraphs[i].index_ + block->index_ + skip,
+	      length - skip + skip_new);
+	  skip = skip_new;
+	}
       }
       else
       {
@@ -625,12 +634,12 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
 
       // figure out if we need to add extra height because of the size of the
       // line break character
-      if (pango_layout_get_text (playout)[strlen (pango_layout_get_text (playout)) - 1] == '\n')
+      if (end_of_paragraph && paragraphs[i].newline)
       {
 	int ascent, descent;
 
 	swfdec_text_field_movie_attr_list_get_ascent_descent (attr_list,
-	    strlen (pango_layout_get_text (playout)), &ascent, &descent);
+	    paragraphs[i].length - block->index_ - skip, &ascent, &descent);
 
 	if (ascent + descent > layout.height) {
 	  int baseline =
diff --git a/libswfdec/swfdec_text_field_movie.h b/libswfdec/swfdec_text_field_movie.h
index 98a91e9..c574279 100644
--- a/libswfdec/swfdec_text_field_movie.h
+++ b/libswfdec/swfdec_text_field_movie.h
@@ -61,6 +61,7 @@ typedef struct {
 typedef struct {
   guint			index_;
   guint			length;
+  gboolean		newline;	// ends in newline
 
   gboolean		bullet;
   int			indent;
commit 2591272bf2c6ebee6efe94e13bfd9f5c712ad94d
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Nov 3 19:21:19 2007 +0200

    Fix a memory leak in TextField's HTML parsing code

diff --git a/libswfdec/swfdec_text_field_movie_html.c b/libswfdec/swfdec_text_field_movie_html.c
index 0a2d950..1a007a9 100644
--- a/libswfdec/swfdec_text_field_movie_html.c
+++ b/libswfdec/swfdec_text_field_movie_html.c
@@ -494,6 +494,7 @@ swfdec_text_field_movie_html_parse (SwfdecTextFieldMovie *text, const char *str)
 	  tag->end_index);
     }
 
+    g_free (tag);
     data.tags_closed = g_slist_remove (data.tags_closed, tag);
   }
 }
commit 9ddbc49a70935eeac9fe5e2d22f53a9b2f6c5a7b
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Nov 3 19:11:02 2007 +0200

    Fix a memory leak in TextField code (PangoLayoutIter not freed)

diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index b130da2..36b3596 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -789,6 +789,8 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
       y += layout->height - skipped;
       skipped = 0;
     }
+
+    pango_layout_iter_free (iter_line);
   }
 
   swfdec_text_field_movie_free_layouts (layouts);
commit 5f3abe827c99cca6b067b90c0ee88eddfb8c9242
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Nov 3 19:09:54 2007 +0200

    More work to make paragraph's ending newline character size matter

diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index 94388f6..b130da2 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -420,6 +420,68 @@ swfdec_text_field_movie_paragraph_get_attr_list (
   return attr_list;
 }
 
+static int
+swfdec_text_field_movie_layout_get_last_line_baseline (PangoLayout *playout)
+{
+  int baseline;
+  PangoLayoutIter *iter;
+
+  g_return_val_if_fail (playout != NULL, 0);
+
+  iter = pango_layout_get_iter (playout);
+  while (!pango_layout_iter_at_last_line (iter))
+    pango_layout_iter_next_line (iter);
+
+  baseline = pango_layout_iter_get_baseline (iter) / PANGO_SCALE;
+
+  pango_layout_iter_free (iter);
+
+  return baseline;
+}
+
+static void
+swfdec_text_field_movie_attr_list_get_ascent_descent (PangoAttrList *attr_list,
+    guint pos, int *ascent, int *descent)
+{
+  PangoAttrIterator *attr_iter;
+  PangoFontDescription *desc;
+  PangoFontMap *fontmap;
+  PangoFont *font;
+  PangoFontMetrics *metrics;
+  PangoContext *pcontext;
+  int end;
+
+  if (ascent != NULL)
+    *ascent = 0;
+  if (descent != NULL)
+    *descent = 0;
+
+  g_return_if_fail (attr_list != NULL);
+
+  attr_iter = pango_attr_list_get_iterator (attr_list);
+  pango_attr_iterator_range (attr_iter, NULL, &end);
+  while ((guint)end < pos && pango_attr_iterator_next (attr_iter)) {
+    pango_attr_iterator_range (attr_iter, NULL, &end);
+  }
+  desc = pango_font_description_new ();
+  pango_attr_iterator_get_font (attr_iter, desc, NULL, NULL);
+  fontmap = pango_cairo_font_map_get_default ();
+  pcontext =
+    pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+  font = pango_font_map_load_font (fontmap, pcontext, desc);
+  metrics = pango_font_get_metrics (font, NULL);
+
+  if (ascent != NULL)
+    *ascent = pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
+  if (descent != NULL)
+    *descent = pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
+
+  g_object_unref (pcontext);
+  pango_font_metrics_unref (metrics);
+  pango_font_description_free (desc);
+  pango_attr_iterator_destroy (attr_iter);
+}
+
 static SwfdecLayout *
 swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
     cairo_t *cr, const SwfdecParagraph *paragraphs,
@@ -559,43 +621,21 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
 
       pango_layout_get_pixel_size (playout, &layout.width, &layout.height);
       layout.width += layout.offset_x + block->right_margin;
+      layout.last_line_offset_y = 0;
 
       // figure out if we need to add extra height because of the size of the
       // line break character
       if (pango_layout_get_text (playout)[strlen (pango_layout_get_text (playout)) - 1] == '\n')
       {
-	PangoAttrIterator *attr_iter;
-	PangoFontDescription *desc;
-	PangoFontMap *fontmap;
-	PangoFont *font;
-	PangoFontMetrics *metrics;
-	PangoContext *pcontext;
-	int end, ascent, descent;
-
-	attr_iter = pango_attr_list_get_iterator (attr_list);
-	pango_attr_iterator_range (attr_iter, NULL, &end);
-	while ((guint)end < paragraphs[i].length - block->index_ - skip &&
-	    pango_attr_iterator_next (attr_iter)) {
-	  pango_attr_iterator_range (attr_iter, NULL, &end);
-	}
-	desc = pango_font_description_new ();
-	pango_attr_iterator_get_font (attr_iter, desc, NULL, NULL);
-	fontmap = pango_cairo_font_map_get_default ();
-	pcontext =
-	  pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
-	font = pango_font_map_load_font (fontmap, pcontext, desc);
-	metrics = pango_font_get_metrics (font, NULL);
-
-	ascent = pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
-	descent = pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
-
-	g_object_unref (pcontext);
-	pango_font_metrics_unref (metrics);
-	pango_font_description_free (desc);
-	pango_attr_iterator_destroy (attr_iter);
+	int ascent, descent;
+
+	swfdec_text_field_movie_attr_list_get_ascent_descent (attr_list,
+	    strlen (pango_layout_get_text (playout)), &ascent, &descent);
 
 	if (ascent + descent > layout.height) {
-	  g_print (":: %i -> %i\n", layout.height, ascent + descent);
+	  int baseline =
+	    swfdec_text_field_movie_layout_get_last_line_baseline (playout);
+	  layout.last_line_offset_y = ascent - baseline;
 	  layout.height = ascent + descent;
 	}
       }
@@ -719,8 +759,7 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
       if (linenum == text_movie->scroll)
 	skipped = rect.y;
 
-      if (!first &&
-	  y + rect.y + rect.height > movie->original_extents.y1)
+      if (!first && y + rect.y + rect.height > movie->original_extents.y1)
 	break;
 
       first = FALSE;
@@ -733,12 +772,16 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
 	  x + layout->offset_x + rect.x + rect.width < limit.x0)
 	continue;
 
+      if (pango_layout_iter_at_last_line (iter_line))
+	cairo_rel_move_to (cr, 0, layout->last_line_offset_y);
       cairo_rel_move_to (cr, layout->offset_x + rect.x,
 	  pango_layout_iter_get_baseline (iter_line) / PANGO_SCALE - skipped);
       line = pango_layout_iter_get_line_readonly (iter_line);
       pango_cairo_show_layout_line (cr, line);
       cairo_rel_move_to (cr, -(layout->offset_x + rect.x),
 	  -(pango_layout_iter_get_baseline (iter_line) / PANGO_SCALE - skipped));
+      if (pango_layout_iter_at_last_line (iter_line))
+	cairo_rel_move_to (cr, 0, -layout->last_line_offset_y);
     } while (pango_layout_iter_next_line (iter_line));
 
     if (linenum >= text_movie->scroll) {
diff --git a/libswfdec/swfdec_text_field_movie.h b/libswfdec/swfdec_text_field_movie.h
index 4c4af82..98a91e9 100644
--- a/libswfdec/swfdec_text_field_movie.h
+++ b/libswfdec/swfdec_text_field_movie.h
@@ -41,6 +41,7 @@ typedef struct _SwfdecTextFieldMovieClass SwfdecTextFieldMovieClass;
 typedef struct {
   PangoLayout *		layout;
   int			offset_x;
+  int			last_line_offset_y;
   int			height;
   int			width;
 } SwfdecLayout;
commit e23fba794362b9590f73ee6b7a1ddd572c6e457f
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Nov 3 17:37:38 2007 +0200

    Take the size of paragraph's closing newline into account for line height

diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index d1da999..94388f6 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -323,8 +323,11 @@ swfdec_text_field_movie_get_paragraphs (SwfdecTextFieldMovie *text, int *num)
   while (*p != '\0')
   {
     end = strpbrk (p, "\r\n");
-    if (end == NULL)
+    if (end == NULL) {
       end = strchr (p, '\0');
+    } else {
+      end++;
+    }
 
     if (end - p > max_length)
       max_length = end - p;
@@ -334,7 +337,6 @@ swfdec_text_field_movie_get_paragraphs (SwfdecTextFieldMovie *text, int *num)
     paragraphs = g_array_append_val (paragraphs, paragraph);
 
     p = end;
-    if (*p != '\0') p++;
   }
 
   if (num != NULL)
@@ -511,7 +513,6 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
       attr_list = swfdec_text_field_movie_paragraph_get_attr_list (
 	  &paragraphs[i], block->index_ + skip, trans);
       pango_layout_set_attributes (playout, attr_list);
-      pango_attr_list_unref (attr_list);
 
       if (text->text->password) {
 	pango_layout_set_text (playout, text->asterisks,
@@ -558,6 +559,50 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
 
       pango_layout_get_pixel_size (playout, &layout.width, &layout.height);
       layout.width += layout.offset_x + block->right_margin;
+
+      // figure out if we need to add extra height because of the size of the
+      // line break character
+      if (pango_layout_get_text (playout)[strlen (pango_layout_get_text (playout)) - 1] == '\n')
+      {
+	PangoAttrIterator *attr_iter;
+	PangoFontDescription *desc;
+	PangoFontMap *fontmap;
+	PangoFont *font;
+	PangoFontMetrics *metrics;
+	PangoContext *pcontext;
+	int end, ascent, descent;
+
+	attr_iter = pango_attr_list_get_iterator (attr_list);
+	pango_attr_iterator_range (attr_iter, NULL, &end);
+	while ((guint)end < paragraphs[i].length - block->index_ - skip &&
+	    pango_attr_iterator_next (attr_iter)) {
+	  pango_attr_iterator_range (attr_iter, NULL, &end);
+	}
+	desc = pango_font_description_new ();
+	pango_attr_iterator_get_font (attr_iter, desc, NULL, NULL);
+	fontmap = pango_cairo_font_map_get_default ();
+	pcontext =
+	  pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+	font = pango_font_map_load_font (fontmap, pcontext, desc);
+	metrics = pango_font_get_metrics (font, NULL);
+
+	ascent = pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
+	descent = pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
+
+	g_object_unref (pcontext);
+	pango_font_metrics_unref (metrics);
+	pango_font_description_free (desc);
+	pango_attr_iterator_destroy (attr_iter);
+
+	if (ascent + descent > layout.height) {
+	  g_print (":: %i -> %i\n", layout.height, ascent + descent);
+	  layout.height = ascent + descent;
+	}
+      }
+
+      pango_attr_list_unref (attr_list);
+
+      // add leading to last line too
       layout.height += block->leading / PANGO_SCALE;
 
       layouts = g_array_append_val (layouts, layout);
commit 4086a627354975d95531f637d6d7bc7446620717
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Nov 3 16:10:41 2007 +0200

    Free asterisks when disposing TextField

diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index 90c2990..d1da999 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -891,6 +891,12 @@ swfdec_text_field_movie_dispose (GObject *object)
 
   text = SWFDEC_TEXT_FIELD_MOVIE (object);
 
+  if (text->asterisks != NULL) {
+    g_free (text->asterisks);
+    text->asterisks = NULL;
+    text->asterisks_length = 0;
+  }
+
   if (text->style_sheet) {
     if (SWFDEC_IS_STYLESHEET (text->style_sheet)) {
       swfdec_style_sheet_remove_listener (
commit 225b62e13bc7fdc40177448c9e2f5f74adfd8ae4
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Nov 3 15:39:45 2007 +0200

    Stop iterating in TextField's render method when we have passed vertical limit

diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index 16e58db..90c2990 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -653,7 +653,7 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
   y = movie->original_extents.y0 + EXTRA_MARGIN;
   cairo_move_to (cr, x, y);
 
-  for (i = 0; layouts[i].layout != NULL/* && y < limit.y1*/; i++)
+  for (i = 0; layouts[i].layout != NULL && y < limit.y1; i++)
   {
     SwfdecLayout *layout = &layouts[i];
     PangoLayoutIter *iter_line;


More information about the Swfdec mailing list