Pekka Lampila
2007-Nov-04 14:14 UTC
[Swfdec] 7 commits - libswfdec/swfdec_text_field_movie.c libswfdec/swfdec_text_field_movie.h libswfdec/swfdec_text_field_movie_html.c
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;
Seemingly Similar Threads
- libswfdec/swfdec_text_field.c libswfdec/swfdec_text_field.h libswfdec/swfdec_text_field_movie.c
- 10 commits - libswfdec/swfdec_as_strings.c libswfdec/swfdec_text_field.c libswfdec/swfdec_text_field_movie_as.c libswfdec/swfdec_text_field_movie.c
- 20 commits - libswfdec/Makefile.am libswfdec/swfdec_as_interpret.c libswfdec/swfdec_html_parser.c libswfdec/swfdec_initialize.as libswfdec/swfdec_initialize.h libswfdec/swfdec_text_field.c libswfdec/swfdec_text_field.h
- [Mesa-dev] [RFC] tegra: Initial support
- [RFC] tegra: Initial support