2 * Copyright (C) 2007 Pekka Lampila <pekka.lampila@iki.fi>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
27 #include "swfdec_text_field_movie.h"
28 #include "swfdec_as_strings.h"
29 #include "swfdec_style_sheet.h"
30 #include "swfdec_xml.h"
31 #include "swfdec_debug.h"
41 SwfdecTextFormat
*format
;
47 gboolean condense_white
;
48 SwfdecStyleSheet
*style_sheet
;
55 swfdec_text_field_movie_html_parse_close_tag (ParserData
*data
, ParserTag
*tag
)
57 g_return_if_fail (data
!= NULL
);
58 g_return_if_fail (tag
!= NULL
);
60 if (data
->multiline
&&
61 ((tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "p", 1)) ||
62 (tag
->name_length
== 2 && !g_strncasecmp (tag
->name
, "li", 2))))
66 for (iter
= data
->tags_closed
; iter
!= NULL
; iter
= iter
->next
) {
67 ParserTag
*f
= iter
->data
;
68 if (f
->end_index
< tag
->index
)
70 if (f
->name_length
== 4 && !g_strncasecmp (f
->name
, "font", 4)) {
71 ParserTag
*n
= g_new0 (ParserTag
, 1);
73 n
->name_length
= f
->name_length
;
74 n
->index
= data
->text
->len
;
75 n
->end_index
= n
->index
+ 1;
76 if (f
->format
!= NULL
) {
77 n
->format
= swfdec_text_format_copy (f
->format
);
81 data
->tags_closed
= g_slist_prepend (data
->tags_closed
, n
);
85 data
->text
= g_string_append_c (data
->text
, '\n');
88 tag
->end_index
= data
->text
->len
;
90 data
->tags_open
= g_slist_remove (data
->tags_open
, tag
);
91 data
->tags_closed
= g_slist_prepend (data
->tags_closed
, tag
);
95 swfdec_text_field_movie_html_parse_comment (ParserData
*data
, const char *p
)
99 g_return_val_if_fail (data
!= NULL
, NULL
);
100 g_return_val_if_fail (p
!= NULL
, NULL
);
101 g_return_val_if_fail (strncmp (p
, "<!--", strlen ("<!--")) == 0, NULL
);
103 end
= strstr (p
+ strlen ("<!--"), "-->");
105 end
+= strlen("-->");
107 // return NULL if no end found
112 swfdec_text_field_movie_html_tag_set_attribute (ParserData
*data
,
113 ParserTag
*tag
, const char *name
, int name_length
, const char *value
,
117 SwfdecAsObject
*object
;
119 g_return_if_fail (data
!= NULL
);
120 g_return_if_fail (tag
!= NULL
);
121 g_return_if_fail (name
!= NULL
);
122 g_return_if_fail (name_length
>= 0);
123 g_return_if_fail (value
!= NULL
);
124 g_return_if_fail (value_length
>= 0);
129 object
= SWFDEC_AS_OBJECT (tag
->format
);
130 SWFDEC_AS_VALUE_SET_STRING (&val
, swfdec_as_context_give_string (
131 object
->context
, g_strndup (value
, value_length
)));
133 if (tag
->name_length
== 10 && !g_strncasecmp (tag
->name
, "textformat", 10))
135 if (name_length
== 10 && !g_strncasecmp (name
, "leftmargin", 10))
137 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_leftMargin
, &val
);
139 else if (name_length
== 11 && !g_strncasecmp (name
, "rightmargin", 11))
141 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_rightMargin
, &val
);
143 else if (name_length
== 6 && !g_strncasecmp (name
, "indent", 6))
145 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_indent
, &val
);
147 else if (name_length
== 11 && !g_strncasecmp (name
, "blockindent", 11))
149 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_blockIndent
, &val
);
151 else if (name_length
== 8 && !g_strncasecmp (name
, "tabstops", 8))
154 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_tabStops
, &val
);
157 else if (tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "p", 1))
159 if (name_length
== 5 && !g_strncasecmp (name
, "align", 5))
161 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_align
, &val
);
164 else if (tag
->name_length
== 4 && !g_strncasecmp (tag
->name
, "font", 4))
166 if (name_length
== 4 && !g_strncasecmp (name
, "face", 4))
168 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_font
, &val
);
170 else if (name_length
== 4 && !g_strncasecmp (name
, "size", 4))
172 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_size
, &val
);
174 else if (name_length
== 5 && !g_strncasecmp (name
, "color", 5))
176 SwfdecAsValue val_number
;
178 if (value_length
!= 7 || *value
!= '#') {
179 SWFDEC_AS_VALUE_SET_NUMBER (&val_number
, 0);
184 number
= g_ascii_strtoll (value
+ 1, &tail
, 16);
185 if (tail
!= value
+ 7)
187 SWFDEC_AS_VALUE_SET_NUMBER (&val_number
, number
);
190 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_color
, &val_number
);
192 else if (name_length
== 13 && !g_strncasecmp (name
, "letterspacing", 13))
194 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_letterSpacing
,
197 // special case: Don't parse kerning
199 else if (tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "a", 1))
201 if (name_length
== 4 && !g_strncasecmp (name
, "href", 4))
203 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_url
, &val
);
205 else if (name_length
== 6 && !g_strncasecmp (name
, "target", 6))
207 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_target
, &val
);
211 if (data
->style_sheet
&&
212 ((tag
->name_length
== 2 && !g_strncasecmp (tag
->name
, "li", 2)) ||
213 (tag
->name_length
== 4 && !g_strncasecmp (tag
->name
, "span", 4)) ||
214 (tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "p", 1))))
216 if (name_length
== 5 && !g_strncasecmp (name
, "class", 5)) {
217 SwfdecTextFormat
*format
= swfdec_style_sheet_get_class_format (
218 data
->style_sheet
, swfdec_as_context_give_string (data
->cx
,
219 g_strndup (value
, value_length
)));
221 swfdec_text_format_add (tag
->format
, format
);
227 swfdec_text_field_movie_html_parse_attribute (ParserData
*data
, ParserTag
*tag
,
230 const char *end
, *name
, *value
;
231 int name_length
, value_length
;
233 g_return_val_if_fail (data
!= NULL
, NULL
);
234 g_return_val_if_fail (tag
!= NULL
, NULL
);
235 g_return_val_if_fail ((*p
!= '>' && *p
!= '\0'), NULL
);
237 end
= p
+ strcspn (p
, "=> \r\n\t");
239 return NULL
; // Correct?
242 name_length
= end
- p
;
244 p
= end
+ strspn (end
, " \r\n\t");
246 return NULL
; // FIXME: Correct?
248 p
= p
+ strspn (p
, " \r\n\t");
250 if (*p
!= '"' && *p
!= '\'')
251 return NULL
; // FIXME: Correct?
255 end
= strchr (end
, *p
);
256 } while (end
!= NULL
&& *(end
- 1) == '\\');
259 return NULL
; // FIXME: Correct?
262 value_length
= end
- (p
+ 1);
265 swfdec_text_field_movie_html_tag_set_attribute (data
, tag
, name
,
266 name_length
, value
, value_length
);
269 g_return_val_if_fail (end
+ 1 > p
, NULL
);
275 swfdec_text_field_movie_html_parse_tag (ParserData
*data
, const char *p
)
278 const char *name
, *end
;
282 g_return_val_if_fail (data
!= NULL
, NULL
);
283 g_return_val_if_fail (p
!= NULL
, NULL
);
284 g_return_val_if_fail (*p
== '<', NULL
);
288 // closing tag or opening tag?
296 // find the end of the name
297 end
= p
+ strcspn (p
, "> \r\n\t");
302 // don't count trailing / as part of the name if it's followed by >
303 // we still act like it's a normal opening tag even if it has /
304 if (*end
== '>' && *(end
- 1) == '/')
307 if (end
== p
) // empty name
311 name_length
= end
- p
;
315 if (data
->tags_open
!= NULL
) {
316 tag
= data
->tags_open
->data
;
317 if (name_length
== tag
->name_length
&&
318 !g_strncasecmp (name
, tag
->name
, name_length
))
319 swfdec_text_field_movie_html_parse_close_tag (data
, tag
);
322 end
= strchr (end
, '>');
328 SwfdecAsObject
*object
;
331 if (data
->multiline
) {
332 if (name_length
== 2 && !g_strncasecmp (name
, "br", 2))
334 data
->text
= g_string_append_c (data
->text
, '\n');
336 else if ((name_length
== 1 && !g_strncasecmp (name
, "p", 1)) ||
337 (name_length
== 2 && !g_strncasecmp (name
, "li", 2)) ||
338 (name_length
== 2 && !g_strncasecmp (name
, "br", 2)))
342 for (iter
= data
->tags_open
; iter
!= NULL
; iter
= iter
->next
) {
343 ParserTag
*f
= iter
->data
;
344 if ((f
->name_length
== 1 && !g_strncasecmp (f
->name
, "p", 1)) ||
345 (f
->name_length
== 2 && !g_strncasecmp (f
->name
, "li", 2))) {
346 data
->text
= g_string_append_c (data
->text
, '\n');
353 tag
= g_new0 (ParserTag
, 1);
355 tag
->name_length
= name_length
;
356 tag
->format
= SWFDEC_TEXT_FORMAT (swfdec_text_format_new (data
->cx
));
357 tag
->index
= data
->text
->len
;
359 data
->tags_open
= g_slist_prepend (data
->tags_open
, tag
);
361 // set format based on tag
362 if (tag
->format
!= NULL
) {
363 object
= SWFDEC_AS_OBJECT (tag
->format
);
364 SWFDEC_AS_VALUE_SET_BOOLEAN (&val
, TRUE
);
366 if (tag
->name_length
== 2 && !g_strncasecmp (tag
->name
, "li", 2)) {
367 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_bullet
, &val
);
368 } else if (tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "b", 1)) {
369 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_bold
, &val
);
370 } else if (tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "i", 1)) {
371 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_italic
, &val
);
372 } else if (tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "u", 1)) {
373 swfdec_as_object_set_variable (object
, SWFDEC_AS_STR_underline
, &val
);
375 else if (tag
->name_length
== 3 && !g_strncasecmp (tag
->name
, "img", 3))
377 SWFDEC_FIXME ("IMG tag support for TextField's HTML input missing");
381 if (data
->style_sheet
&&
382 ((tag
->name_length
== 2 && !g_strncasecmp (tag
->name
, "li", 2)) ||
383 (tag
->name_length
== 1 && !g_strncasecmp (tag
->name
, "p", 1)))) {
384 SwfdecTextFormat
*format
= swfdec_style_sheet_get_tag_format (
385 data
->style_sheet
, swfdec_as_context_give_string (data
->cx
,
386 g_strndup (tag
->name
, tag
->name_length
)));
388 swfdec_text_format_add (tag
->format
, format
);
392 end
= end
+ strspn (end
, " \r\n\t");
393 while (*end
!= '\0' && *end
!= '>' && (*end
!= '/' || *(end
+ 1) != '>')) {
394 end
= swfdec_text_field_movie_html_parse_attribute (data
, tag
, end
);
397 end
= end
+ strspn (end
, " \r\n\t");
411 swfdec_text_field_movie_html_parse_text (ParserData
*data
, const char *p
)
416 g_return_val_if_fail (data
!= NULL
, NULL
);
417 g_return_val_if_fail (p
!= NULL
, NULL
);
418 g_return_val_if_fail (*p
!= '\0' && *p
!= '<', NULL
);
421 // if condense_white: all whitespace blocks are converted to a single space
422 while (*p
!= '\0' && *p
!= '<') {
423 if (data
->condense_white
) {
424 end
= p
+ strcspn (p
, "< \n\r\t");
426 end
= strchr (p
, '<');
428 end
= strchr (p
, '\0');
431 unescaped
= swfdec_xml_unescape_len (data
->cx
, p
, end
- p
);
432 data
->text
= g_string_append (data
->text
, unescaped
);
435 if (data
->condense_white
&& g_ascii_isspace (*end
)) {
436 data
->text
= g_string_append_c (data
->text
, ' ');
437 p
= end
+ strspn (end
, " \n\r\t");
447 swfdec_text_field_movie_html_parse (SwfdecTextFieldMovie
*text
, const char *str
)
452 g_return_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text
));
453 g_return_if_fail (str
!= NULL
);
455 text
->input
= g_string_assign (text
->input
, "");
457 data
.cx
= SWFDEC_AS_OBJECT (text
)->context
;
458 data
.multiline
= (data
.cx
->version
< 7 || text
->text
->multiline
);
459 data
.condense_white
= text
->condense_white
;
460 if (text
->style_sheet
!= NULL
&& SWFDEC_IS_STYLESHEET (text
->style_sheet
)) {
461 data
.style_sheet
= SWFDEC_STYLESHEET (text
->style_sheet
);
463 data
.style_sheet
= NULL
;
465 data
.text
= text
->input
;
466 data
.tags_open
= NULL
;
467 data
.tags_closed
= NULL
;
470 while (p
!= NULL
&& *p
!= '\0') {
472 if (strncmp (p
+ 1, "!--", strlen ("!--")) == 0) {
473 p
= swfdec_text_field_movie_html_parse_comment (&data
, p
);
475 p
= swfdec_text_field_movie_html_parse_tag (&data
, p
);
478 p
= swfdec_text_field_movie_html_parse_text (&data
, p
);
482 // close remaining tags
483 while (data
.tags_open
!= NULL
) {
484 swfdec_text_field_movie_html_parse_close_tag (&data
,
485 (ParserTag
*)data
.tags_open
->data
);
489 while (data
.tags_closed
!= NULL
) {
490 ParserTag
*tag
= (ParserTag
*)data
.tags_closed
->data
;
492 if (tag
->index
!= tag
->end_index
&& tag
->format
!= NULL
) {
493 swfdec_text_field_movie_set_text_format (text
, tag
->format
, tag
->index
,
498 data
.tags_closed
= g_slist_remove (data
.tags_closed
, tag
);
506 swfdec_text_field_movie_html_text_align_to_string (SwfdecTextAlign align
)
509 case SWFDEC_TEXT_ALIGN_LEFT
:
511 case SWFDEC_TEXT_ALIGN_RIGHT
:
513 case SWFDEC_TEXT_ALIGN_CENTER
:
515 case SWFDEC_TEXT_ALIGN_JUSTIFY
:
518 g_assert_not_reached ();
524 * TEXTFORMAT / P or LI / FONT / A / B / I / U
526 * Order of attributes:
528 * LEFTMARGIN / RIGHTMARGIN / INDENT / LEADING / BLOCKINDENT / TABSTOPS
531 * FONT: FACE / SIZE / COLOR / LETTERSPACING / KERNING
538 swfdec_text_field_movie_html_text_append_paragraph (SwfdecTextFieldMovie
*text
,
539 GString
*string
, guint start_index
, guint end_index
)
541 SwfdecTextFormat
*format
, *format_prev
, *format_font
;
542 GSList
*iter
, *fonts
, *iter_font
;
543 guint index_
, index_prev
;
544 gboolean textformat
, bullet
, font
;
547 g_return_val_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text
), string
);
548 g_return_val_if_fail (string
!= NULL
, string
);
549 g_return_val_if_fail (start_index
<= end_index
, string
);
551 g_return_val_if_fail (text
->formats
!= NULL
, string
);
552 for (iter
= text
->formats
; iter
->next
!= NULL
&&
553 ((SwfdecFormatIndex
*)(iter
->next
->data
))->index_
<= start_index
;
556 index_
= start_index
;
557 format
= ((SwfdecFormatIndex
*)(iter
->data
))->format
;
559 if (format
->left_margin
!= 0 || format
->right_margin
!= 0 ||
560 format
->indent
!= 0 || format
->leading
!= 0 ||
561 format
->block_indent
!= 0 ||
562 swfdec_as_array_get_length (format
->tab_stops
) > 0)
564 string
= g_string_append (string
, "<TEXTFORMAT");
565 if (format
->left_margin
) {
566 g_string_append_printf (string
, " LEFTMARGIN=\"%i\"",
567 format
->left_margin
);
569 if (format
->right_margin
) {
570 g_string_append_printf (string
, " RIGHTMARGIN=\"%i\"",
571 format
->right_margin
);
574 g_string_append_printf (string
, " INDENT=\"%i\"", format
->indent
);
576 g_string_append_printf (string
, " LEADING=\"%i\"", format
->leading
);
577 if (format
->block_indent
) {
578 g_string_append_printf (string
, " BLOCKINDENT=\"%i\"",
579 format
->block_indent
);
581 if (swfdec_as_array_get_length (format
->tab_stops
) > 0) {
583 SWFDEC_AS_VALUE_SET_OBJECT (&val
, SWFDEC_AS_OBJECT (format
->tab_stops
));
584 g_string_append_printf (string
, " TABSTOPS=\"%s\"",
585 swfdec_as_value_to_string (SWFDEC_AS_OBJECT
586 (format
->tab_stops
)->context
, &val
));
588 string
= g_string_append (string
, ">");
597 if (format
->bullet
) {
598 string
= g_string_append (string
, "<LI>");
601 g_string_append_printf (string
, "<P ALIGN=\"%s\">",
602 swfdec_text_field_movie_html_text_align_to_string (format
->align
));
606 // note we don't escape format->font, even thought it can have evil chars
607 g_string_append_printf (string
, "<FONT FACE=\"%s\" SIZE=\"%i\" COLOR=\"#%06X\" LETTERSPACING=\"%i\" KERNING=\"%i\">",
608 format
->font
, format
->size
, format
->color
, (int)format
->letter_spacing
,
609 (format
->kerning
? 1 : 0));
610 fonts
= g_slist_prepend (NULL
, format
);
612 if (format
->url
!= SWFDEC_AS_STR_EMPTY
)
613 g_string_append_printf (string
, "<A HREF=\"%s\" TARGET=\"%s\">",
614 format
->url
, format
->target
);
616 string
= g_string_append (string
, "<B>");
618 string
= g_string_append (string
, "<I>");
619 if (format
->underline
)
620 string
= g_string_append (string
, "<U>");
622 // special case: use <= instead of < to add some extra markup
623 for (iter
= iter
->next
;
624 iter
!= NULL
&& ((SwfdecFormatIndex
*)(iter
->data
))->index_
<= end_index
;
628 format_prev
= format
;
629 index_
= ((SwfdecFormatIndex
*)(iter
->data
))->index_
;
630 format
= ((SwfdecFormatIndex
*)(iter
->data
))->format
;
632 escaped
= swfdec_xml_escape_len (text
->input
->str
+ index_prev
,
633 index_
- index_prev
);
634 string
= g_string_append (string
, escaped
);
638 // Figure out what tags need to be rewritten
639 if (format
->font
!= format_prev
->font
||
640 format
->size
!= format_prev
->size
||
641 format
->color
!= format_prev
->color
||
642 (int)format
->letter_spacing
!= (int)format_prev
->letter_spacing
||
643 format
->kerning
!= format_prev
->kerning
) {
645 } else if (format
->url
== format_prev
->url
&&
646 format
->target
== format_prev
->target
&&
647 format
->bold
== format_prev
->bold
&&
648 format
->italic
== format_prev
->italic
&&
649 format
->underline
== format_prev
->underline
) {
654 for (iter_font
= fonts
; iter_font
!= NULL
; iter_font
= iter_font
->next
)
656 format_font
= (SwfdecTextFormat
*)iter_font
->data
;
657 if (format
->font
== format_font
->font
&&
658 format
->size
== format_font
->size
&&
659 format
->color
== format_font
->color
&&
660 (int)format
->letter_spacing
== (int)format_font
->letter_spacing
&&
661 format
->kerning
== format_font
->kerning
) {
665 if (format_prev
->underline
)
666 string
= g_string_append (string
, "</U>");
667 if (format_prev
->italic
)
668 string
= g_string_append (string
, "</I>");
669 if (format_prev
->bold
)
670 string
= g_string_append (string
, "</B>");
671 if (format_prev
->url
!= SWFDEC_AS_STR_EMPTY
)
672 string
= g_string_append (string
, "</A>");
673 if (iter_font
!= NULL
) {
674 while (fonts
!= iter_font
) {
675 string
= g_string_append (string
, "</FONT>");
676 fonts
= g_slist_remove (fonts
, fonts
->data
);
681 format_font
= (SwfdecTextFormat
*)fonts
->data
;
682 if (font
&& (format
->font
!= format_font
->font
||
683 format
->size
!= format_font
->size
||
684 format
->color
!= format_font
->color
||
685 (int)format
->letter_spacing
!= (int)format_font
->letter_spacing
||
686 format
->kerning
!= format_font
->kerning
))
688 fonts
= g_slist_prepend (fonts
, format
);
690 string
= g_string_append (string
, "<FONT");
691 // note we don't escape format->font, even thought it can have evil chars
692 if (format
->font
!= format_font
->font
)
693 g_string_append_printf (string
, " FACE=\"%s\"", format
->font
);
694 if (format
->size
!= format_font
->size
)
695 g_string_append_printf (string
, " SIZE=\"%i\"", format
->size
);
696 if (format
->color
!= format_font
->color
)
697 g_string_append_printf (string
, " COLOR=\"#%06X\"", format
->color
);
698 if ((int)format
->letter_spacing
!= (int)format_font
->letter_spacing
) {
699 g_string_append_printf (string
, " LETTERSPACING=\"%i\"",
700 (int)format
->letter_spacing
);
702 if (format
->kerning
!= format_font
->kerning
) {
703 g_string_append_printf (string
, " KERNING=\"%i\"",
704 (format
->kerning
? 1 : 0));
706 string
= g_string_append (string
, ">");
708 if (format
->url
!= SWFDEC_AS_STR_EMPTY
) {
709 g_string_append_printf (string
, "<A HREF=\"%s\" TARGET=\"%s\">",
710 format
->url
, format
->target
);
713 string
= g_string_append (string
, "<B>");
715 string
= g_string_append (string
, "<I>");
716 if (format
->underline
)
717 string
= g_string_append (string
, "<U>");
720 escaped
= swfdec_xml_escape_len (text
->input
->str
+ index_
,
722 string
= g_string_append (string
, escaped
);
725 if (format
->underline
)
726 string
= g_string_append (string
, "</U>");
728 string
= g_string_append (string
, "</I>");
730 string
= g_string_append (string
, "</B>");
731 if (format
->url
!= SWFDEC_AS_STR_EMPTY
)
732 string
= g_string_append (string
, "</A>");
733 for (iter
= fonts
; iter
!= NULL
; iter
= iter
->next
)
734 string
= g_string_append (string
, "</FONT>");
735 g_slist_free (fonts
);
737 string
= g_string_append (string
, "</LI>");
739 string
= g_string_append (string
, "</P>");
742 string
= g_string_append (string
, "</TEXTFORMAT>");
748 swfdec_text_field_movie_get_html_text (SwfdecTextFieldMovie
*text
)
753 g_return_val_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text
),
754 SWFDEC_AS_STR_EMPTY
);
756 if (text
->input
== NULL
)
757 return SWFDEC_AS_STR_EMPTY
;
759 string
= g_string_new ("");
761 p
= text
->input
->str
;
763 end
= strpbrk (p
, "\r\n");
765 end
= strchr (p
, '\0');
767 string
= swfdec_text_field_movie_html_text_append_paragraph (text
, string
,
768 p
- text
->input
->str
, end
- text
->input
->str
);
774 return swfdec_as_context_give_string (SWFDEC_AS_OBJECT (text
)->context
,
775 g_string_free (string
, FALSE
));