[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 (
¶graphs[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