[Swfdec-commits] 9 commits - swfdec/swfdec_actor.c swfdec/swfdec_net_stream.c swfdec/swfdec_text_field.c swfdec/swfdec_text_field_movie_as.c swfdec/swfdec_text_field_movie.c swfdec/swfdec_text_field_movie.h swfdec/swfdec_text_layout.c swfdec/swfdec_text_layout.h test/image

Benjamin Otte company at kemper.freedesktop.org
Wed May 14 07:04:56 PDT 2008


 swfdec/swfdec_actor.c                    |    5 
 swfdec/swfdec_net_stream.c               |    2 
 swfdec/swfdec_text_field.c               |    2 
 swfdec/swfdec_text_field_movie.c         |  231 ++++++++++++++++---------------
 swfdec/swfdec_text_field_movie.h         |    2 
 swfdec/swfdec_text_field_movie_as.c      |   27 +--
 swfdec/swfdec_text_layout.c              |   72 +++++++--
 swfdec/swfdec_text_layout.h              |   10 -
 test/image/Makefile.am                   |   18 ++
 test/image/text-field-align-5.swf        |binary
 test/image/text-field-align-5.swf.png    |binary
 test/image/text-field-align-6.swf        |binary
 test/image/text-field-align-6.swf.png    |binary
 test/image/text-field-align-7.swf        |binary
 test/image/text-field-align-7.swf.png    |binary
 test/image/text-field-align-8.swf        |binary
 test/image/text-field-align-8.swf.png    |binary
 test/image/text-field-align.as           |   30 ++++
 test/image/text-field-autoSize-5.swf     |binary
 test/image/text-field-autoSize-5.swf.png |binary
 test/image/text-field-autoSize-6.swf     |binary
 test/image/text-field-autoSize-6.swf.png |binary
 test/image/text-field-autoSize-7.swf     |binary
 test/image/text-field-autoSize-7.swf.png |binary
 test/image/text-field-autoSize-8.swf     |binary
 test/image/text-field-autoSize-8.swf.png |binary
 test/image/text-field-autoSize.as        |   23 +++
 27 files changed, 271 insertions(+), 151 deletions(-)

New commits:
commit f38ea83584d269f085b229bd2de103e08591b8cf
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed May 14 15:53:43 2008 +0200

    actually emit onChanged and not onScroller when text changes

diff --git a/swfdec/swfdec_actor.c b/swfdec/swfdec_actor.c
index e173f3f..767c862 100644
--- a/swfdec/swfdec_actor.c
+++ b/swfdec/swfdec_actor.c
@@ -223,7 +223,10 @@ swfdec_actor_execute (SwfdecActor *actor, SwfdecEventType condition,
   } else if (condition == SWFDEC_EVENT_SCROLL || condition == SWFDEC_EVENT_CHANGED) {
     SwfdecAsValue argv[2];
 
-    SWFDEC_AS_VALUE_SET_STRING (&argv[0], SWFDEC_AS_STR_onScroller);
+    if (condition == SWFDEC_EVENT_SCROLL)
+      SWFDEC_AS_VALUE_SET_STRING (&argv[0], SWFDEC_AS_STR_onScroller);
+    else
+      SWFDEC_AS_VALUE_SET_STRING (&argv[0], SWFDEC_AS_STR_onChanged);
     SWFDEC_AS_VALUE_SET_OBJECT (&argv[1], SWFDEC_AS_OBJECT (actor));
     swfdec_sandbox_use (SWFDEC_MOVIE (actor)->resource->sandbox);
     swfdec_as_object_call (SWFDEC_AS_OBJECT (actor),
commit 9c04f732fd329636c57ef07afd90d7aa3b6e9349
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed May 14 15:42:21 2008 +0200

    Check for a valid decoder before doing stuff with it

diff --git a/swfdec/swfdec_net_stream.c b/swfdec/swfdec_net_stream.c
index 9336f09..7260ee9 100644
--- a/swfdec/swfdec_net_stream.c
+++ b/swfdec/swfdec_net_stream.c
@@ -79,7 +79,7 @@ swfdec_net_stream_video_goto (SwfdecNetStream *stream, guint timestamp)
     cairo_surface_destroy (stream->surface);
     stream->surface = NULL;
   }
-  if (stream->flvdecoder->video) {
+  if (stream->flvdecoder && stream->flvdecoder->video) {
     buffer = swfdec_flv_decoder_get_video (stream->flvdecoder, timestamp,
 	FALSE, &format, &stream->current_time, &stream->next_time);
   } else {
commit 04552468e38f7d88381751617781b8ee603f22a6
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed May 14 15:30:13 2008 +0200

    make autoSize work properly for matrix-transformed textfields

diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index 87522d6..a738a3a 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -97,38 +97,46 @@ swfdec_text_field_movie_auto_size (SwfdecTextFieldMovie *text)
 {
   SwfdecMovie *movie = SWFDEC_MOVIE (text);
   SwfdecRectangle area;
-  double xdiff, ydiff;
+  double x0, z0, x1, z1; /* y0 and y1 are taken by math.h */
 
   if (text->auto_size == SWFDEC_AUTO_SIZE_NONE)
     return;
 
   swfdec_text_field_movie_get_visible_area (text, &area);
-  xdiff = (double) text->layout_width - area.width;
-  ydiff = (double) text->layout_height - area.height;
+  x1 = (double) text->layout_width - area.width;
+  z1 = (double) text->layout_height - area.height;
 
-  if (xdiff == 0 && ydiff == 0)
+  if (x1 == 0 && z1 == 0)
     return;
 
   /* FIXME: rounding */
-  xdiff *= SWFDEC_TWIPS_SCALE_FACTOR / text->xscale;
-  ydiff *= SWFDEC_TWIPS_SCALE_FACTOR / text->yscale;
+  x1 *= SWFDEC_TWIPS_SCALE_FACTOR / text->xscale;
+  z1 *= SWFDEC_TWIPS_SCALE_FACTOR / text->yscale;
 
-  text->extents.x1 += xdiff;
   switch (text->auto_size) {
     case SWFDEC_AUTO_SIZE_LEFT:
+      x0 = 0;
       break;
     case SWFDEC_AUTO_SIZE_RIGHT:
-      movie->matrix.x0 -= xdiff;
+      x0 = x1;
+      x1 = 0;
       break;
     case SWFDEC_AUTO_SIZE_CENTER:
-      movie->matrix.x0 -= xdiff / 2;
+      x0 = x1 = x1 / 2;
       break;
     case SWFDEC_AUTO_SIZE_NONE:
     default:
       g_assert_not_reached ();
   }
+  z0 = 0;
 
-  text->extents.y1 += ydiff;
+  cairo_matrix_transform_distance (&movie->inverse_matrix, &x0, &z0);
+  text->extents.x0 += x0;
+  text->extents.y0 += z0;
+
+  cairo_matrix_transform_distance (&movie->inverse_matrix, &x1, &z1);
+  text->extents.x1 += x1;
+  text->extents.y1 += z1;
 
   swfdec_text_field_movie_update_area (text);
 }
commit 414d78ac45e23188e5290016371eeeaf3e12a5c8
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed May 14 11:02:13 2008 +0200

    no, textWidth and textHeight don't cause autoSize

diff --git a/swfdec/swfdec_text_field_movie_as.c b/swfdec/swfdec_text_field_movie_as.c
index 7e88819..3bab7e7 100644
--- a/swfdec/swfdec_text_field_movie_as.c
+++ b/swfdec/swfdec_text_field_movie_as.c
@@ -427,7 +427,6 @@ swfdec_text_field_movie_get_textHeight (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
-  swfdec_movie_update (SWFDEC_MOVIE (text));
   SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_height / text->yscale));
 }
 
@@ -440,7 +439,6 @@ swfdec_text_field_movie_get_textWidth (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
-  swfdec_movie_update (SWFDEC_MOVIE (text));
   SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_width / text->yscale));
 }
 
commit c0a961bc7b75ee62cd0b2955357f7effa6081cd1
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 13 19:16:31 2008 +0200

    add alignment test

diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index b2b1d76..b5b42af 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -379,6 +379,15 @@ EXTRA_DIST = \
 	replace-shape-shape-7.swf \
 	replace-shape-shape-7.swf.png \
 	swfdec.jpg \
+	text-field-align-5.swf \
+	text-field-align-5.swf.png \
+	text-field-align-6.swf \
+	text-field-align-6.swf.png \
+	text-field-align-7.swf \
+	text-field-align-7.swf.png \
+	text-field-align-8.swf \
+	text-field-align-8.swf.png \
+	text-field-align.as \
 	text-field-autoSize-5.swf \
 	text-field-autoSize-5.swf.png \
 	text-field-autoSize-6.swf \
diff --git a/test/image/text-field-align-5.swf b/test/image/text-field-align-5.swf
new file mode 100644
index 0000000..7172c34
Binary files /dev/null and b/test/image/text-field-align-5.swf differ
diff --git a/test/image/text-field-align-5.swf.png b/test/image/text-field-align-5.swf.png
new file mode 100644
index 0000000..ee0852d
Binary files /dev/null and b/test/image/text-field-align-5.swf.png differ
diff --git a/test/image/text-field-align-6.swf b/test/image/text-field-align-6.swf
new file mode 100644
index 0000000..b0d44b4
Binary files /dev/null and b/test/image/text-field-align-6.swf differ
diff --git a/test/image/text-field-align-6.swf.png b/test/image/text-field-align-6.swf.png
new file mode 100644
index 0000000..903cbae
Binary files /dev/null and b/test/image/text-field-align-6.swf.png differ
diff --git a/test/image/text-field-align-7.swf b/test/image/text-field-align-7.swf
new file mode 100644
index 0000000..746da70
Binary files /dev/null and b/test/image/text-field-align-7.swf differ
diff --git a/test/image/text-field-align-7.swf.png b/test/image/text-field-align-7.swf.png
new file mode 100644
index 0000000..b958c4d
Binary files /dev/null and b/test/image/text-field-align-7.swf.png differ
diff --git a/test/image/text-field-align-8.swf b/test/image/text-field-align-8.swf
new file mode 100644
index 0000000..716b6d1
Binary files /dev/null and b/test/image/text-field-align-8.swf differ
diff --git a/test/image/text-field-align-8.swf.png b/test/image/text-field-align-8.swf.png
new file mode 100644
index 0000000..83b7e8b
Binary files /dev/null and b/test/image/text-field-align-8.swf.png differ
diff --git a/test/image/text-field-align.as b/test/image/text-field-align.as
new file mode 100644
index 0000000..72f2d19
--- /dev/null
+++ b/test/image/text-field-align.as
@@ -0,0 +1,30 @@
+// makeswf -v 7 -s 200x150 -r 1 -o text-field-align.swf text-field-align.as
+
+function create (depth, align) {
+  var x = int (depth / 4);
+  var y = depth % 4;
+  createTextField ("t" + depth, depth, 100 * x, y * 30, 90, 25);
+  var t = this["t" + depth];
+  var tf = new TextFormat ();
+  tf.font = "Bitstream Vera Sans";
+  tf.align = align;
+  t.setNewTextFormat (tf);
+  t.border = true;
+  t.text = "Hello World";
+
+  return t;
+};
+
+create (0, "left");
+create (1, "right");
+create (2, "center");
+create (3, "justify");
+
+t = create (4, "left");
+t.wordWrap = true;
+t = create (5, "right");
+t.wordWrap = true;
+t = create (6, "center");
+t.wordWrap = true;
+t = create (7, "justify");
+t.wordWrap = true;
commit b55d8331c412e52c1611b697085beea1183b82c0
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 13 15:16:23 2008 +0200

    add test for autosize

diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index 7d3901e..b2b1d76 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -379,6 +379,15 @@ EXTRA_DIST = \
 	replace-shape-shape-7.swf \
 	replace-shape-shape-7.swf.png \
 	swfdec.jpg \
+	text-field-autoSize-5.swf \
+	text-field-autoSize-5.swf.png \
+	text-field-autoSize-6.swf \
+	text-field-autoSize-6.swf.png \
+	text-field-autoSize-7.swf \
+	text-field-autoSize-7.swf.png \
+	text-field-autoSize-8.swf \
+	text-field-autoSize-8.swf.png \
+	text-field-autoSize.as \
 	text-field-autosize.as \
 	text-field-autosize-6.swf \
 	text-field-autosize-6.swf.png \
diff --git a/test/image/text-field-autoSize-5.swf b/test/image/text-field-autoSize-5.swf
new file mode 100644
index 0000000..8cd3357
Binary files /dev/null and b/test/image/text-field-autoSize-5.swf differ
diff --git a/test/image/text-field-autoSize-5.swf.png b/test/image/text-field-autoSize-5.swf.png
new file mode 100644
index 0000000..d529068
Binary files /dev/null and b/test/image/text-field-autoSize-5.swf.png differ
diff --git a/test/image/text-field-autoSize-6.swf b/test/image/text-field-autoSize-6.swf
new file mode 100644
index 0000000..05be6df
Binary files /dev/null and b/test/image/text-field-autoSize-6.swf differ
diff --git a/test/image/text-field-autoSize-6.swf.png b/test/image/text-field-autoSize-6.swf.png
new file mode 100644
index 0000000..db321e5
Binary files /dev/null and b/test/image/text-field-autoSize-6.swf.png differ
diff --git a/test/image/text-field-autoSize-7.swf b/test/image/text-field-autoSize-7.swf
new file mode 100644
index 0000000..58eb44e
Binary files /dev/null and b/test/image/text-field-autoSize-7.swf differ
diff --git a/test/image/text-field-autoSize-7.swf.png b/test/image/text-field-autoSize-7.swf.png
new file mode 100644
index 0000000..6b3585e
Binary files /dev/null and b/test/image/text-field-autoSize-7.swf.png differ
diff --git a/test/image/text-field-autoSize-8.swf b/test/image/text-field-autoSize-8.swf
new file mode 100644
index 0000000..02f726b
Binary files /dev/null and b/test/image/text-field-autoSize-8.swf differ
diff --git a/test/image/text-field-autoSize-8.swf.png b/test/image/text-field-autoSize-8.swf.png
new file mode 100644
index 0000000..ea5bf0f
Binary files /dev/null and b/test/image/text-field-autoSize-8.swf.png differ
diff --git a/test/image/text-field-autoSize.as b/test/image/text-field-autoSize.as
new file mode 100644
index 0000000..607a319
--- /dev/null
+++ b/test/image/text-field-autoSize.as
@@ -0,0 +1,23 @@
+// makeswf -v 7 -s 200x150 -r 1 -o text-field-autoSize.swf text-field-autoSize.as
+
+function create (depth) {
+  createTextField ("t" + depth, depth, 50, depth * 30, 100, 25);
+  var t = this["t" + depth];
+  var tf = new TextFormat ();
+  tf.font = "Bitstream Vera Sans";
+  t.setNewTextFormat (tf);
+  t.border = true;
+  t.text = "Hello World";
+
+  return t;
+};
+
+t = create (0);
+t.autoSize = "none";
+t = create (1);
+t.autoSize = "left";
+t = create (2);
+t.autoSize = "center";
+t = create (3);
+t.autoSize = "right";
+
commit dd24e089d0b7f29e3337a4218dd4635ec96fcecc
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 13 15:14:49 2008 +0200

    implement proper layouting for right/center aligned non-wrapped text

diff --git a/swfdec/swfdec_text_layout.c b/swfdec/swfdec_text_layout.c
index cbeeae2..775cb5b 100644
--- a/swfdec/swfdec_text_layout.c
+++ b/swfdec/swfdec_text_layout.c
@@ -772,6 +772,28 @@ out:
   return MAX (count, 1);
 }
 
+static int
+swfdec_text_layout_get_line_offset (SwfdecTextLayout *layout, 
+    SwfdecTextBlock *block, PangoLayoutLine *line)
+{
+  PangoAlignment align;
+  int width, diff;
+
+  align = pango_layout_get_alignment (block->layout);
+  if (align == PANGO_ALIGN_LEFT)
+    return 0;
+
+  /* FIXME: realign lines that are too long */
+  pango_layout_get_pixel_size (block->layout, &width, NULL);
+  diff = layout->width - width;
+  if (align == PANGO_ALIGN_CENTER)
+    diff /= 2;
+  else
+    diff -= 1;
+
+  return diff;
+}
+
 /**
  * swfdec_text_layout_render:
  * @layout: the layout to render
@@ -811,15 +833,16 @@ swfdec_text_layout_render (SwfdecTextLayout *layout, cairo_t *cr,
     }
     for (;row < (guint) pango_layout_get_line_count (block->layout); row++) {
       PangoLayoutLine *line = pango_layout_get_line_readonly (block->layout, row);
+      int xoffset = swfdec_text_layout_get_line_offset (layout, block, line);
       
       pango_layout_line_get_pixel_extents (line, NULL, &extents);
       if (extents.height > (int) height && !first_line)
 	return;
       first_line = FALSE;
-      cairo_translate (cr, 0, - extents.y);
+      cairo_translate (cr, xoffset, - extents.y);
       pango_cairo_show_layout_line (cr, line);
       height -= extents.height;
-      cairo_translate (cr, 0, extents.height + extents.y);
+      cairo_translate (cr, - xoffset, extents.height + extents.y);
     }
     if ((int) height <= pango_layout_get_spacing (block->layout) / PANGO_SCALE)
       return;
commit 57ca8f9a698067ed277e553f0232b9bacca31712
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 13 14:50:22 2008 +0200

    change TextLayout API for wrap handling changes
    
    This is necessary as we are going to do alignment ourselves

diff --git a/swfdec/swfdec_text_field.c b/swfdec/swfdec_text_field.c
index ddffb8d..0711b8b 100644
--- a/swfdec/swfdec_text_field.c
+++ b/swfdec/swfdec_text_field.c
@@ -54,7 +54,7 @@ swfdec_text_field_create_movie (SwfdecGraphic *graphic, gsize *size)
   ret->max_chars = text->max_chars;
   ret->selectable = text->selectable;
   ret->embed_fonts = text->embed_fonts;
-  ret->word_wrap = text->word_wrap;
+  swfdec_text_layout_set_word_wrap (ret->layout, text->word_wrap);
   ret->multiline = text->multiline;
   ret->auto_size = text->auto_size;
   ret->border = text->border;
diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index 837e69c..87522d6 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -88,10 +88,8 @@ swfdec_text_field_movie_update_area (SwfdecTextFieldMovie *text)
   text->xscale = matrix.xx * SWFDEC_TWIPS_SCALE_FACTOR;
   text->yscale = matrix.yy * SWFDEC_TWIPS_SCALE_FACTOR;
   swfdec_text_layout_set_scale (text->layout, text->yscale);
-  if (text->word_wrap && text->stage_rect.width >= BORDER_LEFT + BORDER_RIGHT) {
-    swfdec_text_layout_set_wrap_width (text->layout, text->stage_rect.width - 
-	BORDER_LEFT - BORDER_RIGHT);
-  }
+  swfdec_text_layout_set_wrap_width (text->layout, text->stage_rect.width - 
+      BORDER_LEFT - BORDER_RIGHT);
 }
 
 static void
diff --git a/swfdec/swfdec_text_field_movie.h b/swfdec/swfdec_text_field_movie.h
index 1c9ad8b..5cdae42 100644
--- a/swfdec/swfdec_text_field_movie.h
+++ b/swfdec/swfdec_text_field_movie.h
@@ -54,7 +54,6 @@ struct _SwfdecTextFieldMovie {
   int			max_chars;
   gboolean		selectable;
   gboolean		embed_fonts;
-  gboolean		word_wrap;
   gboolean		multiline;
   SwfdecAutoSize	auto_size;
   gboolean		border;
diff --git a/swfdec/swfdec_text_field_movie_as.c b/swfdec/swfdec_text_field_movie_as.c
index 2188447..7e88819 100644
--- a/swfdec/swfdec_text_field_movie_as.c
+++ b/swfdec/swfdec_text_field_movie_as.c
@@ -427,6 +427,7 @@ swfdec_text_field_movie_get_textHeight (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
+  swfdec_movie_update (SWFDEC_MOVIE (text));
   SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_height / text->yscale));
 }
 
@@ -439,6 +440,7 @@ swfdec_text_field_movie_get_textWidth (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
+  swfdec_movie_update (SWFDEC_MOVIE (text));
   SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_width / text->yscale));
 }
 
@@ -808,7 +810,8 @@ swfdec_text_field_movie_get_wordWrap (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
-  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, text->word_wrap);
+  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, 
+      swfdec_text_layout_get_word_wrap (text->layout));
 }
 
 static void
@@ -823,16 +826,7 @@ swfdec_text_field_movie_set_wordWrap (SwfdecAsContext *cx,
 
   swfdec_as_value_to_number (cx, &argv[0]);
 
-  if (text->word_wrap != value) {
-    text->word_wrap = value;
-    if (text->word_wrap) {
-      /* FIXME: find a proper way to use BORDER_LEFT and BORDER_RIGHT here */
-      swfdec_text_layout_set_wrap_width (text->layout, text->stage_rect.width - 4);
-    } else {
-      swfdec_text_layout_set_wrap_width (text->layout, -1);
-    }
-    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
-  }
+  swfdec_text_layout_set_word_wrap (text->layout, value);
 }
 
 /*
diff --git a/swfdec/swfdec_text_layout.c b/swfdec/swfdec_text_layout.c
index 632941d..cbeeae2 100644
--- a/swfdec/swfdec_text_layout.c
+++ b/swfdec/swfdec_text_layout.c
@@ -323,11 +323,7 @@ swfdec_text_layout_create_paragraph (SwfdecTextLayout *layout, PangoContext *con
       block->rect.y = 0;
       block->row = 0;
     }
-    if (layout->wrap_width == -1) {
-      block->rect.width = G_MAXINT;
-    } else {
-      block->rect.width = layout->wrap_width;
-    }
+    block->rect.width = layout->width;
     desc = pango_font_description_new ();
     swfdec_text_layout_apply_attributes_to_description (layout, attr, desc);
     pango_layout_set_font_description (block->layout, desc);
@@ -347,7 +343,7 @@ swfdec_text_layout_create_paragraph (SwfdecTextLayout *layout, PangoContext *con
       first = FALSE;
     }
     swfdec_text_layout_apply_line_attributes (block, attr);
-    if (layout->wrap_width != -1)
+    if (layout->word_wrap)
       pango_layout_set_width (block->layout, block->rect.width * PANGO_SCALE);
 
     iter = swfdec_text_buffer_get_iter (layout->text, start);
@@ -488,7 +484,7 @@ swfdec_text_layout_class_init (SwfdecTextLayoutClass *klass)
 static void
 swfdec_text_layout_init (SwfdecTextLayout *layout)
 {
-  layout->wrap_width = -1;
+  layout->width = G_MAXINT; /* G_MAXUINT causes overflow */
   layout->scale = 1.0;
   layout->blocks = g_sequence_new (swfdec_text_block_free);
 }
@@ -509,24 +505,43 @@ swfdec_text_layout_new (SwfdecTextBuffer *buffer)
 }
 
 void
-swfdec_text_layout_set_wrap_width (SwfdecTextLayout *layout, int wrap_width)
+swfdec_text_layout_set_wrap_width (SwfdecTextLayout *layout, guint width)
 {
   g_return_if_fail (SWFDEC_IS_TEXT_LAYOUT (layout));
-  g_return_if_fail (wrap_width >= -1);
 
-  if (layout->wrap_width == wrap_width)
+  if (layout->width == width)
     return;
 
-  layout->wrap_width = wrap_width;
+  layout->width = width;
   swfdec_text_layout_invalidate (layout);
 }
 
-int
+guint
 swfdec_text_layout_get_wrap_width (SwfdecTextLayout *layout)
 {
   g_return_val_if_fail (SWFDEC_IS_TEXT_LAYOUT (layout), -1);
 
-  return layout->wrap_width;
+  return layout->width;
+}
+
+void
+swfdec_text_layout_set_word_wrap (SwfdecTextLayout *layout, gboolean word_wrap)
+{
+  g_return_if_fail (SWFDEC_IS_TEXT_LAYOUT (layout));
+
+  if (layout->word_wrap == word_wrap)
+    return;
+
+  layout->word_wrap = word_wrap;
+  swfdec_text_layout_invalidate (layout);
+}
+
+gboolean
+swfdec_text_layout_get_word_wrap (SwfdecTextLayout *layout)
+{
+  g_return_val_if_fail (SWFDEC_IS_TEXT_LAYOUT (layout), -1);
+
+  return layout->word_wrap;
 }
 
 gboolean
@@ -575,7 +590,7 @@ swfdec_text_layout_set_scale (SwfdecTextLayout *layout, double scale)
  * @layout: the layout
  *
  * Computes the width of the layout in pixels. Note that the width can still
- * exceed the width set with swfdec_text_layout_set_wrap_width() if some
+ * exceed the width set with swfdec_text_layout_set_width() if some
  * words are too long. Computing the width takes a long time, so it might be
  * useful to cache the value.
  *
@@ -620,6 +635,8 @@ swfdec_text_layout_get_height (SwfdecTextLayout *layout)
 
   swfdec_text_layout_ensure (layout);
 
+  if (swfdec_text_buffer_get_length (layout->text) == 0)
+    return 0;
   iter = g_sequence_iter_prev (g_sequence_get_end_iter (layout->blocks));
   block = g_sequence_get (iter);
   return block->rect.y + block->rect.height;
diff --git a/swfdec/swfdec_text_layout.h b/swfdec/swfdec_text_layout.h
index dfb521f..34fc3a3 100644
--- a/swfdec/swfdec_text_layout.h
+++ b/swfdec/swfdec_text_layout.h
@@ -43,7 +43,8 @@ struct _SwfdecTextLayout
 
   SwfdecTextBuffer *	text;		/* the text we render */
   /* properties */
-  int			wrap_width;	/* maximum width to use */
+  gboolean		word_wrap;	/* TRUE if we do word wrapping */
+  guint			width;		/* width we use for alignment */
   gboolean		password;	/* TRUE if the text should be displayed as asterisks */
   double		scale;		/* scale factor in use */
 
@@ -61,8 +62,11 @@ GType			swfdec_text_layout_get_type		(void);
 SwfdecTextLayout *	swfdec_text_layout_new			(SwfdecTextBuffer *	buffer);
 
 void			swfdec_text_layout_set_wrap_width	(SwfdecTextLayout *	layout,
-								 int			wrap_width);
-int			swfdec_text_layout_get_wrap_width	(SwfdecTextLayout *	layout);
+								 guint			width);
+guint			swfdec_text_layout_get_wrap_width	(SwfdecTextLayout *	layout);
+void			swfdec_text_layout_set_word_wrap	(SwfdecTextLayout *	layout,
+								 gboolean		wrap);
+gboolean		swfdec_text_layout_get_word_wrap	(SwfdecTextLayout *	layout);
 void			swfdec_text_layout_set_password		(SwfdecTextLayout *	layout,
 								 gboolean		password);
 gboolean		swfdec_text_layout_get_password		(SwfdecTextLayout *	layout);
commit 0e97c51fda157d0771459ac600bcf810482b778f
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 13 11:54:44 2008 +0200

    implement auto size
    
    Ugh, this is hacky...

diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index a7ee238..837e69c 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -46,12 +46,114 @@ G_DEFINE_TYPE (SwfdecTextFieldMovie, swfdec_text_field_movie, SWFDEC_TYPE_ACTOR)
 
 /*** VFUNCS ***/
 
+/* NB: This signal can happen without a locked player */
+static void
+swfdec_text_field_movie_update_area (SwfdecTextFieldMovie *text)
+{
+  SwfdecMovie *movie = SWFDEC_MOVIE (text);
+  cairo_matrix_t matrix, translate;
+  double x, y;
+
+  if (swfdec_player_is_locked (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (text)->context)))
+    swfdec_movie_invalidate_next (movie);
+
+  /* check if we indeed want to render */
+  swfdec_movie_local_to_global_matrix (movie, &matrix);
+  cairo_matrix_multiply (&matrix, &matrix,
+      &SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context)->priv->global_to_stage);
+  if (matrix.xy != 0.0 || matrix.yx != 0.0 ||
+      matrix.xx <= 0.0 || matrix.yy <= 0.0) {
+    swfdec_rectangle_init_empty (&text->stage_rect);
+    return;
+  }
+
+  translate = matrix;
+  x = text->extents.x0;
+  y = text->extents.y0;
+  cairo_matrix_transform_point (&matrix, &x, &y);
+  cairo_matrix_init_translate (&translate, round (x) - x, round (y) - y);
+  cairo_matrix_multiply (&matrix, &matrix, &translate);
+  
+  x = text->extents.x0;
+  y = text->extents.y0;
+  cairo_matrix_transform_point (&matrix, &x, &y);
+  text->stage_rect.x = x;
+  text->stage_rect.y = y;
+  x = text->extents.x1;
+  y = text->extents.y1;
+  cairo_matrix_transform_point (&matrix, &x, &y);
+  /* FIXME: floor, ceil or round? */
+  text->stage_rect.width = round (x) - text->stage_rect.x;
+  text->stage_rect.height = round (y) - text->stage_rect.y;
+  text->xscale = matrix.xx * SWFDEC_TWIPS_SCALE_FACTOR;
+  text->yscale = matrix.yy * SWFDEC_TWIPS_SCALE_FACTOR;
+  swfdec_text_layout_set_scale (text->layout, text->yscale);
+  if (text->word_wrap && text->stage_rect.width >= BORDER_LEFT + BORDER_RIGHT) {
+    swfdec_text_layout_set_wrap_width (text->layout, text->stage_rect.width - 
+	BORDER_LEFT - BORDER_RIGHT);
+  }
+}
+
+static void
+swfdec_text_field_movie_auto_size (SwfdecTextFieldMovie *text)
+{
+  SwfdecMovie *movie = SWFDEC_MOVIE (text);
+  SwfdecRectangle area;
+  double xdiff, ydiff;
+
+  if (text->auto_size == SWFDEC_AUTO_SIZE_NONE)
+    return;
+
+  swfdec_text_field_movie_get_visible_area (text, &area);
+  xdiff = (double) text->layout_width - area.width;
+  ydiff = (double) text->layout_height - area.height;
+
+  if (xdiff == 0 && ydiff == 0)
+    return;
+
+  /* FIXME: rounding */
+  xdiff *= SWFDEC_TWIPS_SCALE_FACTOR / text->xscale;
+  ydiff *= SWFDEC_TWIPS_SCALE_FACTOR / text->yscale;
+
+  text->extents.x1 += xdiff;
+  switch (text->auto_size) {
+    case SWFDEC_AUTO_SIZE_LEFT:
+      break;
+    case SWFDEC_AUTO_SIZE_RIGHT:
+      movie->matrix.x0 -= xdiff;
+      break;
+    case SWFDEC_AUTO_SIZE_CENTER:
+      movie->matrix.x0 -= xdiff / 2;
+      break;
+    case SWFDEC_AUTO_SIZE_NONE:
+    default:
+      g_assert_not_reached ();
+  }
+
+  text->extents.y1 += ydiff;
+
+  swfdec_text_field_movie_update_area (text);
+}
+
 static void
 swfdec_text_field_movie_update_extents (SwfdecMovie *movie,
     SwfdecRect *extents)
 {
   SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (movie);
 
+  /* Doing auto-size when invalidating extents is a nasty trick that is 
+   * supposed to help in calculating the correct size with the same caching
+   * algorithm as the official player. Consider the following code:
+   * text.autoSize = "left";
+   * if (foo)
+   *   y = text._width;
+   * text.autoSize = "right";
+   * If foo is set, querying width will cause the autosize to happen, which
+   * will cause text to be left-aligned. If foo is not set, autosize doesn't
+   * happen until after it's set to right-aligned.
+   */
+  swfdec_text_field_movie_auto_size (text);
+
   swfdec_rect_union (extents, extents, &text->extents);
 }
 
@@ -61,15 +163,18 @@ swfdec_text_field_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *ma
   SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (movie);
   SwfdecRect rect;
 
-  rect = text->extents;
+  rect.x0 = text->stage_rect.x;
+  rect.y0 = text->stage_rect.y;
+  rect.x1 = text->stage_rect.x + text->stage_rect.width;
+  rect.y1 = text->stage_rect.y + text->stage_rect.height;
 
-  // border is drawn partly outside the extents
   if (text->border) {
-    rect.x1 += SWFDEC_TWIPS_TO_DOUBLE (1);
-    rect.y1 += SWFDEC_TWIPS_TO_DOUBLE (1);
+    rect.x1++;
+    rect.y1++;
   }
 
-  swfdec_rect_transform (&rect, &rect, matrix);
+  swfdec_rect_transform (&rect, &rect,
+      &SWFDEC_PLAYER (SWFDEC_AS_OBJECT (text)->context)->priv->stage_to_global);
   swfdec_player_invalidate (
       SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context), &rect);
 }
@@ -128,53 +233,6 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
       text->scroll, area.height);
 }
 
-gboolean
-swfdec_text_field_movie_auto_size (SwfdecTextFieldMovie *text)
-{
-  int height, width, diff;
-
-  g_return_val_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text), FALSE);
-
-  if (text->auto_size == SWFDEC_AUTO_SIZE_NONE)
-    return FALSE;
-
-  width = SWFDEC_DOUBLE_TO_TWIPS (text->layout_width + BORDER_LEFT + BORDER_RIGHT);
-  height = SWFDEC_DOUBLE_TO_TWIPS (text->layout_height + BORDER_TOP + BORDER_BOTTOM);
-
-  swfdec_movie_invalidate_next (SWFDEC_MOVIE (text));
-
-  if (!text->word_wrap && text->extents.x1 -
-      text->extents.x0 != width)
-  {
-    switch (text->auto_size) {
-      case SWFDEC_AUTO_SIZE_LEFT:
-	text->extents.x1 = text->extents.x0 + width;
-	break;
-      case SWFDEC_AUTO_SIZE_RIGHT:
-	text->extents.x0 = text->extents.x1 - width;
-	break;
-      case SWFDEC_AUTO_SIZE_CENTER:
-	diff = (text->extents.x1 - text->extents.x0) - width;
-	text->extents.x0 += floor (diff / 2.0);
-	text->extents.x1 = text->extents.x0 + width;
-	break;
-      case SWFDEC_AUTO_SIZE_NONE:
-      default:
-	g_return_val_if_reached (FALSE);
-    }
-  }
-
-  if (text->extents.y1 - text->extents.y0 != height)
-  {
-    text->extents.y1 = text->extents.y0 + height;
-  }
-
-  swfdec_movie_queue_update (SWFDEC_MOVIE (text),
-      SWFDEC_MOVIE_INVALID_EXTENTS);
-
-  return TRUE;
-}
-
 static void
 swfdec_text_field_movie_dispose (GObject *object)
 {
@@ -229,51 +287,6 @@ swfdec_text_field_movie_mark (SwfdecAsObject *object)
   SWFDEC_AS_OBJECT_CLASS (swfdec_text_field_movie_parent_class)->mark (object);
 }
 
-/* NB: This signal can happen without a locked player */
-static void
-swfdec_text_field_movie_update_area (SwfdecTextFieldMovie *text)
-{
-  SwfdecMovie *movie = SWFDEC_MOVIE (text);
-  cairo_matrix_t matrix, translate;
-  double x, y;
-
-  /* check if we indeed want to render */
-  swfdec_movie_local_to_global_matrix (movie, &matrix);
-  cairo_matrix_multiply (&matrix, &matrix,
-      &SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context)->priv->global_to_stage);
-  if (matrix.xy != 0.0 || matrix.yx != 0.0 ||
-      matrix.xx <= 0.0 || matrix.yy <= 0.0) {
-    swfdec_rectangle_init_empty (&text->stage_rect);
-    return;
-  }
-
-  translate = matrix;
-  x = text->extents.x0;
-  y = text->extents.y0;
-  cairo_matrix_transform_point (&matrix, &x, &y);
-  cairo_matrix_init_translate (&translate, round (x) - x, round (y) - y);
-  cairo_matrix_multiply (&matrix, &matrix, &translate);
-  
-  x = text->extents.x0;
-  y = text->extents.y0;
-  cairo_matrix_transform_point (&matrix, &x, &y);
-  text->stage_rect.x = x;
-  text->stage_rect.y = y;
-  x = text->extents.x1;
-  y = text->extents.y1;
-  cairo_matrix_transform_point (&matrix, &x, &y);
-  /* FIXME: floor, ceil or round? */
-  text->stage_rect.width = round (x) - text->stage_rect.x;
-  text->stage_rect.height = round (y) - text->stage_rect.y;
-  text->xscale = matrix.xx * SWFDEC_TWIPS_SCALE_FACTOR;
-  text->yscale = matrix.yy * SWFDEC_TWIPS_SCALE_FACTOR;
-  swfdec_text_layout_set_scale (text->layout, text->yscale);
-  if (text->word_wrap && text->stage_rect.width >= BORDER_LEFT + BORDER_RIGHT) {
-    swfdec_text_layout_set_wrap_width (text->layout, text->stage_rect.width - 
-	BORDER_LEFT - BORDER_RIGHT);
-  }
-}
-
 /* NB: can be run with unlocked player */
 void
 swfdec_text_field_movie_update_scroll (SwfdecTextFieldMovie *text)
@@ -304,19 +317,19 @@ static void
 swfdec_text_field_movie_layout_changed (SwfdecTextLayout *layout,
     SwfdecTextFieldMovie *text)
 {
-  double scale;
   guint w, h, max;
 
-  swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
+  if (swfdec_player_is_locked (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (text)->context)))
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
 
-  scale = swfdec_text_layout_get_scale (layout);
-  w = swfdec_text_layout_get_width (layout) / scale;
-  h = swfdec_text_layout_get_height (layout) / scale;
+  w = swfdec_text_layout_get_width (layout);
+  h = swfdec_text_layout_get_height (layout);
 
   if (w != text->layout_width || h != text->layout_height) {
     text->layout_width = w;
     text->layout_height = h;
-    //swfdec_text_field_movie_auto_size (text);
+    if (text->auto_size != SWFDEC_AUTO_SIZE_NONE)
+      swfdec_movie_queue_update (SWFDEC_MOVIE (text), SWFDEC_MOVIE_INVALID_EXTENTS);
   }
 
   swfdec_text_field_movie_update_scroll (text);
@@ -923,8 +936,6 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text,
   } else {
     swfdec_text_buffer_insert_text (text->text, start_index, str);
   }
-
-  swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
 }
 
 void
@@ -966,8 +977,6 @@ swfdec_text_field_movie_set_text (SwfdecTextFieldMovie *text, const char *str,
       g_free (s);
     }
   }
-
-  swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
 }
 
 gboolean
@@ -1006,7 +1015,7 @@ swfdec_text_field_movie_get_hscroll_max (SwfdecTextFieldMovie *text)
   g_return_val_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text), 0);
 
   swfdec_text_field_movie_get_visible_area (text, &area);
-  width = swfdec_text_layout_get_width (text->layout);
+  width = text->layout_width;
   if ((guint) area.width >= width)
     return 0;
   else
diff --git a/swfdec/swfdec_text_field_movie.h b/swfdec/swfdec_text_field_movie.h
index a533ff6..1c9ad8b 100644
--- a/swfdec/swfdec_text_field_movie.h
+++ b/swfdec/swfdec_text_field_movie.h
@@ -103,7 +103,6 @@ void		swfdec_text_field_movie_set_text	(SwfdecTextFieldMovie *	movie,
 							 const char *		str,
 							 gboolean		html);
 void		swfdec_text_field_movie_update_scroll	(SwfdecTextFieldMovie * text);
-gboolean	swfdec_text_field_movie_auto_size	(SwfdecTextFieldMovie *	text);
 const char *	swfdec_text_field_movie_get_text	(SwfdecTextFieldMovie *		text);
 void		swfdec_text_field_movie_set_listen_variable (SwfdecTextFieldMovie *	text,
 							 const char *			value);
diff --git a/swfdec/swfdec_text_field_movie_as.c b/swfdec/swfdec_text_field_movie_as.c
index c4ac58d..2188447 100644
--- a/swfdec/swfdec_text_field_movie_as.c
+++ b/swfdec/swfdec_text_field_movie_as.c
@@ -1,5 +1,5 @@
 /* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2007-2008 Benjamin Otte <otte at gnome.org>
  *               2007 Pekka Lampila <pekka.lampila at iki.fi>
  *
  * This library is free software; you can redistribute it and/or
@@ -22,6 +22,7 @@
 #include "config.h"
 #endif
 
+#include <math.h>
 #include <string.h>
 #include <pango/pangocairo.h>
 
@@ -426,7 +427,7 @@ swfdec_text_field_movie_get_textHeight (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
-  SWFDEC_AS_VALUE_SET_NUMBER (ret, text->layout_height);
+  SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_height / text->yscale));
 }
 
 static void
@@ -438,7 +439,7 @@ swfdec_text_field_movie_get_textWidth (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
-  SWFDEC_AS_VALUE_SET_NUMBER (ret, text->layout_width);
+  SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_width / text->yscale));
 }
 
 /*
@@ -766,8 +767,7 @@ swfdec_text_field_movie_set_autoSize (SwfdecAsContext *cx,
   }
 
   if (text->auto_size != old) {
-    swfdec_text_field_movie_auto_size (text);
-    // FIXME: fix scrolling
+    swfdec_movie_queue_update (SWFDEC_MOVIE (text), SWFDEC_MOVIE_INVALID_EXTENTS);
   }
 }
 
@@ -832,8 +832,6 @@ swfdec_text_field_movie_set_wordWrap (SwfdecAsContext *cx,
       swfdec_text_layout_set_wrap_width (text->layout, -1);
     }
     swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
-    swfdec_text_field_movie_auto_size (text);
-    // special case: don't set scrolling
   }
 }
 
@@ -1157,7 +1155,6 @@ swfdec_text_field_movie_setTextFormat (SwfdecAsContext *cx,
       &format->attr, format->values_set);
 
   swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
-  swfdec_text_field_movie_auto_size (text);
   // special case: update the max values, not the current values
   // swfdec_text_field_movie_update_scroll (text, FALSE);
 }


More information about the Swfdec-commits mailing list