1
// textformat.cpp: ActionScript text formatting decorators, for Gnash.
3
// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#include "Object.h" // for getObjectInterface
22
#include "TextFormat.h"
24
#include "builtin_function.h" // for getter/setter properties
25
#include "namedStrings.h"
27
#include "types.h" // for PIXELS_TO_TWIPS
28
#include "StringPredicates.h" // for parseAlignString
29
#include "smart_ptr.h" // intrusive_ptr
33
// Forward declarations
34
static as_value textformat_new(const fn_call& fn);
35
static as_object* getTextFormatInterface();
36
static void attachTextFormatInterface(as_object& o);
40
registerTextFormatNative(as_object& o)
44
//vm.registerNative(110, 0) // [_global] TextFormat
45
vm.registerNative(&TextFormat::font_getset, 110, 1);
46
vm.registerNative(&TextFormat::font_getset, 110, 2);
47
vm.registerNative(&TextFormat::size_getset, 110, 3);
48
vm.registerNative(&TextFormat::size_getset, 110, 4);
49
vm.registerNative(&TextFormat::color_getset, 110, 5);
50
vm.registerNative(&TextFormat::color_getset, 110, 6);
51
vm.registerNative(&TextFormat::url_getset, 110, 7);
52
vm.registerNative(&TextFormat::url_getset, 110, 8);
53
vm.registerNative(&TextFormat::target_getset, 110, 9);
54
vm.registerNative(&TextFormat::target_getset, 110, 10);
55
vm.registerNative(&TextFormat::bold_getset, 110, 11);
56
vm.registerNative(&TextFormat::bold_getset, 110, 12);
57
vm.registerNative(&TextFormat::italic_getset, 110, 13);
58
vm.registerNative(&TextFormat::italic_getset, 110, 14);
59
vm.registerNative(&TextFormat::underline_getset, 110, 15);
60
vm.registerNative(&TextFormat::underline_getset, 110, 16);
61
vm.registerNative(&TextFormat::align_getset, 110, 17);
62
vm.registerNative(&TextFormat::align_getset, 110, 18);
63
vm.registerNative(&TextFormat::leftMargin_getset, 110, 19);
64
vm.registerNative(&TextFormat::leftMargin_getset, 110, 20);
65
vm.registerNative(&TextFormat::rightMargin_getset, 110, 21);
66
vm.registerNative(&TextFormat::rightMargin_getset, 110, 22);
67
vm.registerNative(&TextFormat::indent_getset, 110, 23);
68
vm.registerNative(&TextFormat::indent_getset, 110, 24);
69
vm.registerNative(&TextFormat::leading_getset, 110, 25);
70
vm.registerNative(&TextFormat::leading_getset, 110, 26);
71
vm.registerNative(&TextFormat::blockIndent_getset, 110, 27);
72
vm.registerNative(&TextFormat::blockIndent_getset, 110, 28);
73
vm.registerNative(&TextFormat::tabStops_getset, 110, 29);
74
vm.registerNative(&TextFormat::tabStops_getset, 110, 30);
75
vm.registerNative(&TextFormat::bullet_getset, 110, 31);
76
vm.registerNative(&TextFormat::bullet_getset, 110, 32);
77
vm.registerNative(&TextFormat::getTextExtent_method, 110, 33);
81
TextFormat::TextFormat()
83
as_object(getTextFormatInterface()),
89
_align(edit_text_character_def::ALIGN_LEFT),
100
//log_debug("%s:", __FUNCTION__);
101
init_member("getTextExtent", new builtin_function(TextFormat::getTextExtent_method));
104
/// new TextFormat([font, [size, [color, [bold, [italic, [underline, [url, [target, [align,[leftMargin, [rightMargin, [indent, [leading]]]]]]]]]]]]])
106
textformat_new(const fn_call& fn)
108
//GNASH_REPORT_FUNCTION;
110
boost::intrusive_ptr<TextFormat> tf = new TextFormat;
112
const unsigned int args = fn.nargs;
117
log_error(_("Too many args (%d) passed to TextFormat"), args);
119
tf->leadingSet(PIXELS_TO_TWIPS(fn.arg(12).to_int()));
121
tf->indentSet(PIXELS_TO_TWIPS(fn.arg(11).to_int()));
123
tf->rightMarginSet(PIXELS_TO_TWIPS(fn.arg(10).to_int()));
125
tf->leftMarginSet(PIXELS_TO_TWIPS(fn.arg(9).to_int()));
127
tf->alignSet(fn.arg(8).to_string());
129
tf->targetSet(fn.arg(7).to_string());
131
tf->urlSet(fn.arg(6).to_string());
133
tf->underlinedSet(fn.arg(5).to_bool());
135
tf->italicedSet(fn.arg(4).to_bool());
137
tf->boldSet(fn.arg(3).to_bool());
141
col.parseRGB(fn.arg(2).to_int());
145
tf->sizeSet(PIXELS_TO_TWIPS(fn.arg(1).to_int()));
147
tf->fontSet(fn.arg(0).to_string());
150
// What happens here?
154
return as_value(tf.get());
158
TextFormat::display_getset(const fn_call& /*fn*/)
160
LOG_ONCE( log_unimpl("TextField.display") );
165
TextFormat::bullet_getset(const fn_call& fn)
167
// Has the right return values, but not properly implemented
168
LOG_ONCE( log_unimpl("TextFormat.bullet") );
170
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
174
if ( fn.nargs == 0 ) // getter
176
if ( ptr->bulletDefined() ) ret.set_bool(ptr->bullet());
182
ptr->bulletSet(fn.arg(0).to_bool());
189
TextFormat::tabStops_getset(const fn_call& /*fn*/)
191
LOG_ONCE( log_unimpl("TextField.tabStops") );
196
TextFormat::blockIndent_getset(const fn_call& fn)
198
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
202
if ( fn.nargs == 0 ) // getter
204
if ( ptr->blockIndentDefined() ) ret.set_double(TWIPS_TO_PIXELS(ptr->blockIndent()));
209
ptr->blockIndentSet(PIXELS_TO_TWIPS(fn.arg(0).to_int()));
216
TextFormat::leading_getset(const fn_call& fn)
218
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
222
if ( fn.nargs == 0 ) // getter
224
if ( ptr->leadingDefined() ) ret.set_double(TWIPS_TO_PIXELS(ptr->leading()));
229
ptr->leadingSet(PIXELS_TO_TWIPS(fn.arg(0).to_int()));
236
TextFormat::indent_getset(const fn_call& fn)
238
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
242
if ( fn.nargs == 0 ) // getter
244
if ( ptr->indentDefined() ) ret.set_double(TWIPS_TO_PIXELS(ptr->indent()));
249
ptr->indentSet(PIXELS_TO_TWIPS(fn.arg(0).to_int()));
256
TextFormat::rightMargin_getset(const fn_call& fn)
258
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
262
if ( fn.nargs == 0 ) // getter
264
if ( ptr->rightMarginDefined() ) ret.set_double(TWIPS_TO_PIXELS(ptr->rightMargin()));
269
ptr->rightMarginSet(PIXELS_TO_TWIPS(fn.arg(0).to_int()));
276
TextFormat::leftMargin_getset(const fn_call& fn)
278
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
282
if ( fn.nargs == 0 ) // getter
284
if ( ptr->leftMarginDefined() ) ret.set_double(TWIPS_TO_PIXELS(ptr->leftMargin()));
289
ptr->leftMarginSet(PIXELS_TO_TWIPS(fn.arg(0).to_int()));
296
TextFormat::align_getset(const fn_call& fn)
298
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
302
if ( fn.nargs == 0 ) // getter
304
if ( ptr->alignDefined() ) ret.set_string(ptr->getAlignString(ptr->align()));
309
ptr->alignSet(fn.arg(0).to_string());
316
TextFormat::underline_getset(const fn_call& fn)
318
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
322
if ( fn.nargs == 0 ) // getter
324
if ( ptr->underlinedDefined() ) ret.set_bool(ptr->underlined());
329
ptr->underlinedSet(fn.arg(0).to_bool());
336
TextFormat::italic_getset(const fn_call& fn)
338
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
342
if ( fn.nargs == 0 ) // getter
344
if ( ptr->italicedDefined() ) ret.set_bool(ptr->italiced());
349
ptr->italicedSet(fn.arg(0).to_bool());
356
TextFormat::bold_getset(const fn_call& fn)
358
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
362
if ( fn.nargs == 0 ) // getter
364
if ( ptr->boldDefined() ) ret.set_bool(ptr->bold());
369
ptr->boldSet(fn.arg(0).to_bool());
376
TextFormat::target_getset(const fn_call& /*fn*/)
378
LOG_ONCE( log_unimpl("TextField.target") );
383
TextFormat::url_getset(const fn_call& /*fn*/)
385
LOG_ONCE( log_unimpl("TextField.url") );
390
TextFormat::color_getset(const fn_call& fn)
392
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
396
if ( fn.nargs == 0 ) // getter
398
if ( ptr->colorDefined() ) ret.set_double(ptr->color().toRGB());
404
newcolor.parseRGB(fn.arg(0).to_int());
405
ptr->colorSet(newcolor);
412
TextFormat::size_getset(const fn_call& fn)
414
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
418
if ( fn.nargs == 0 ) // getter
420
if ( ptr->sizeDefined() ) ret.set_double(TWIPS_TO_PIXELS(ptr->size()));
425
ptr->sizeSet(PIXELS_TO_TWIPS(fn.arg(0).to_int()));
432
TextFormat::font_getset(const fn_call& fn)
434
boost::intrusive_ptr<TextFormat> ptr = ensureType<TextFormat>(fn.this_ptr);
438
if ( fn.nargs == 0 ) // getter
440
if ( ptr->fontDefined() ) ret.set_string(ptr->font());
445
ptr->fontSet(fn.arg(0).to_string());
452
TextFormat::getTextExtent_method(const fn_call& /*fn*/)
454
LOG_ONCE( log_unimpl("TextField.getTextExtent") );
459
attachTextFormatInterface(as_object& o)
461
int flags = 0; // for sure we want to enum, dunno about deleting yet
463
o.init_property("display", &TextFormat::display_getset, &TextFormat::display_getset, flags);
464
o.init_property("bullet", &TextFormat::bullet_getset, &TextFormat::bullet_getset, flags);
465
o.init_property("tabStops", &TextFormat::tabStops_getset, &TextFormat::tabStops_getset, flags);
466
o.init_property("blockIndent", &TextFormat::blockIndent_getset, &TextFormat::blockIndent_getset, flags);
467
o.init_property("leading", &TextFormat::leading_getset, &TextFormat::leading_getset, flags);
468
o.init_property("indent", &TextFormat::indent_getset, &TextFormat::indent_getset, flags);
469
o.init_property("rightMargin", &TextFormat::rightMargin_getset, &TextFormat::rightMargin_getset, flags);
470
o.init_property("leftMargin", &TextFormat::leftMargin_getset, &TextFormat::leftMargin_getset, flags);
471
o.init_property("align", &TextFormat::align_getset, &TextFormat::align_getset, flags);
472
o.init_property("underline", &TextFormat::underline_getset, &TextFormat::underline_getset, flags);
473
o.init_property("italic", &TextFormat::italic_getset, &TextFormat::italic_getset, flags);
474
o.init_property("bold", &TextFormat::bold_getset, &TextFormat::bold_getset, flags);
475
o.init_property("target", &TextFormat::target_getset, &TextFormat::target_getset, flags);
476
o.init_property("url", &TextFormat::url_getset, &TextFormat::url_getset, flags);
477
o.init_property("color", &TextFormat::color_getset, &TextFormat::color_getset, flags);
478
o.init_property("size", &TextFormat::size_getset, &TextFormat::size_getset, flags);
479
o.init_property("font", &TextFormat::font_getset, &TextFormat::font_getset, flags);
483
getTextFormatInterface()
485
static boost::intrusive_ptr<as_object> o;
488
o = new as_object(getObjectInterface());
489
attachTextFormatInterface(*o);
494
// extern (used by Global.cpp)
495
void textformat_class_init(as_object& global)
497
// This is going to be the global Color "class"/"function"
498
static boost::intrusive_ptr<builtin_function> cl;
502
cl=new builtin_function(&textformat_new, getTextFormatInterface());
505
// Register _global.Color
506
global.init_member("TextFormat", cl.get());
510
edit_text_character_def::alignment
511
TextFormat::parseAlignString(const std::string& align)
513
StringNoCaseEqual cmp;
514
if ( cmp(align, "left") ) return edit_text_character_def::ALIGN_LEFT;
515
else if ( cmp(align, "center") ) return edit_text_character_def::ALIGN_CENTER;
516
else if ( cmp(align, "right") ) return edit_text_character_def::ALIGN_RIGHT;
517
else if ( cmp(align, "justify") ) return edit_text_character_def::ALIGN_JUSTIFY;
520
log_debug("Invalid align string %s, take as left", align);
521
return edit_text_character_def::ALIGN_LEFT;
526
TextFormat::getAlignString(edit_text_character_def::alignment a)
530
case edit_text_character_def::ALIGN_LEFT:
532
case edit_text_character_def::ALIGN_CENTER:
534
case edit_text_character_def::ALIGN_RIGHT:
536
case edit_text_character_def::ALIGN_JUSTIFY:
539
log_error("Uknown alignment value: %d, take as left", a);
545
} // end of gnash namespace