1 /*
2  *   Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program 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
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16  *
17  *
18  */
19 
20 /*
21  * Test DefineEditText tag.
22  * Uses both "embedded" font and device fonts.
23  * The text written is 'Hello world' in both cases.
24  * Text at the bottom is the one with embedded fonts.
25  *
26  * TODO: add a testrunner for pixel checking.
27  * TODO: test autoSize and wordWrap interaction (what takes precedence?)
28  *
29  * run as ./DefineEditTextTest
30  */
31 
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <ming.h>
35 
36 #include "ming_utils.h"
37 
38 #define OUTPUT_VERSION 7
39 #define OUTPUT_FILENAME "DefineEditTextTest.swf"
40 
41 SWFDisplayItem add_text_field(SWFMovie mo, SWFBlock font, const char* text,
42 	float indent, float leftMargin, float rightMargin, SWFTextFieldAlignment align,
43 	float lineSpacing,
44 	unsigned int textR, unsigned int textG, unsigned int textB, unsigned int textA);
45 
46 SWFDisplayItem
add_text_field(SWFMovie mo,SWFBlock font,const char * text,float indent,float leftMargin,float rightMargin,SWFTextFieldAlignment align,float lineSpacing,unsigned int textR,unsigned int textG,unsigned int textB,unsigned int textA)47 add_text_field(SWFMovie mo, SWFBlock font, const char* text, float indent,
48 		float leftMargin, float rightMargin,
49 		SWFTextFieldAlignment align, float lineSpacing,
50 		unsigned int textR, unsigned int textG,
51 		unsigned int textB, unsigned int textA)
52 {
53   SWFTextField tf;
54 
55   tf = newSWFTextField();
56 
57   SWFTextField_setFont(tf, font);
58   SWFTextField_setIndentation(tf, indent);
59   SWFTextField_setLeftMargin(tf, leftMargin);
60   SWFTextField_setRightMargin(tf, rightMargin);
61   SWFTextField_setAlignment(tf, align);
62   SWFTextField_setLineSpacing(tf, lineSpacing);
63   SWFTextField_setColor(tf, textR, textG, textB, textA);
64 
65   /* setting flags seem unneeded */
66   /*SWFTextField_setFlags(tf, SWFTEXTFIELD_USEFONT|SWFTEXTFIELD_NOEDIT);*/
67   SWFTextField_addChars(tf, text);
68 
69   SWFTextField_addString(tf, text);
70 
71   /*
72    * Bounds computed by Ming (if we omit the setBounds call)
73    * are 2640, 240. This means that we're shrinking the available
74    * space with this explicit setting. Gnash chokes in this case.
75    *
76    * Ref: https://savannah.gnu.org/bugs/?func=detailitem&item_id=16637.
77    */
78   SWFTextField_setBounds(tf, 100, 100);
79   //SWFTextField_setBounds(tf, 60000, 338);
80 
81   /*
82    * The following settings (found in the reported SWF)
83    * are not needed to exploit the bug.
84    */
85 
86   /*SWFTextField_setHeight(tf, 240);*/
87   /*SWFTextField_setColor(tf, 0x00, 0x00, 0x00, 0xff);*/
88   /*SWFTextField_setAlignment(tf, SWFTEXTFIELD_ALIGN_LEFT);*/
89   /*SWFTextField_setLeftMargin(tf, 0);*/
90   /*SWFTextField_setRightMargin(tf, 0);*/
91   /*SWFTextField_setIndentation(tf, 0);*/
92   /*SWFTextField_setLineSpacing(tf, 40);*/
93   /*SWFTextField_setLineSpacing(tf, 40);*/
94 
95   return SWFMovie_add(mo, (SWFBlock)tf);
96 }
97 
98 int
main(int argc,char ** argv)99 main(int argc, char** argv)
100 {
101   SWFMovie mo;
102   const char *srcdir=".";
103   char fdbfont[256];
104   SWFMovieClip  dejagnuclip;
105 
106   /*********************************************
107    *
108    * Initialization
109    *
110    *********************************************/
111 
112   if ( argc>1 ) srcdir=argv[1];
113   else
114   {
115     fprintf(stderr, "Usage: %s <mediadir>\n", argv[0]);
116     return 1;
117   }
118 
119   sprintf(fdbfont, "%s/Bitstream-Vera-Sans.fdb", srcdir);
120 
121   puts("Setting things up");
122 
123   Ming_init();
124   Ming_useSWFVersion (OUTPUT_VERSION);
125   //Ming_setScale(20.0); /* so we talk twips */
126 
127   mo = newSWFMovie();
128   SWFMovie_setRate(mo, 1.0);
129   SWFMovie_setDimension(mo, 800, 600);
130 
131   dejagnuclip = get_dejagnu_clip((SWFBlock)get_default_font(srcdir), 10, 0, 0, 800, 600);
132   SWFMovie_add(mo, (SWFBlock)dejagnuclip);
133   SWFMovie_nextFrame(mo); // 1st frame
134 
135   // Check that the dejagnu clip is really a TextField.
136   check_equals(mo, "_root.getInstanceAtDepth(-16383)",
137           "_level0.instance1");
138   check(mo, "_level0.instance1._xtrace_win "
139           "instanceof TextField");
140 
141   // Note: the dejagnuclip already placed some texts, so the following
142   // should be true.
143   check(mo, "TextField.prototype.hasOwnProperty('background')");
144   check(mo, "TextField.prototype.hasOwnProperty('backgroundColor')");
145   check(mo, "TextField.prototype.hasOwnProperty('text')");
146   check(mo, "TextField.prototype.hasOwnProperty('textColor')");
147 
148   /*********************************************
149    *
150    * Add some textfields
151    *
152    *********************************************/
153   {
154     SWFDisplayItem it;
155     FILE *font_file = fopen(fdbfont, "r");
156     if ( font_file == NULL )
157     {
158       perror(fdbfont);
159       exit(1);
160     }
161     SWFBrowserFont bfont = newSWFBrowserFont("_sans");
162     SWFFont efont = loadSWFFontFromFile(font_file);
163 
164     it = add_text_field(mo, (SWFBlock)bfont, "Hello", 1, 2, 3, SWFTEXTFIELD_ALIGN_LEFT, 10, 100, 101, 102, 50);
165     SWFDisplayItem_setName(it, "dtext1");
166     SWFDisplayItem_moveTo(it, 0, 200);
167     it = add_text_field(mo, (SWFBlock)efont, "Hello", 4, 5, 6, SWFTEXTFIELD_ALIGN_CENTER, 11, 110, 111, 112, 51);
168     SWFDisplayItem_setName(it, "etext1");
169     SWFDisplayItem_moveTo(it, 0, 300);
170 
171     SWFBrowserFont bfont2 = newSWFBrowserFont("times");
172     it = add_text_field(mo, (SWFBlock)bfont2, "Hello", 7, 8, 9, SWFTEXTFIELD_ALIGN_RIGHT, 12, 120, 121, 122, 52);
173     SWFDisplayItem_setName(it, "dtext2");
174     SWFDisplayItem_moveTo(it, 0, 400);
175   }
176   SWFMovie_nextFrame(mo);
177 
178   check_equals(mo, "dtext1.embedFonts", "false");
179   check_equals(mo, "etext1.embedFonts", "true");
180   check_equals(mo, "etext1.hasOwnProperty('embedFonts')", "false");
181 
182   add_actions(mo, "ret = Selection.setFocus(dtext1);"
183                   "check_equals(ret, false);"
184                   "check_equals(Selection.getFocus(), '_level0.dtext1');");
185   add_actions(mo, "ret = Selection.setFocus(etext1);"
186                   "check_equals(ret, false);"
187                   "check_equals(Selection.getFocus(), '_level0.etext1');");
188 
189   add_actions(mo, "createTextField('dynamictext1', 99, 10, 10, 10, 10);");
190 
191   add_actions(mo, "ret = Selection.setFocus(dynamictext1);"
192                "check_equals(ret, false);"
193                "check_equals(Selection.getFocus(), '_level0.dynamictext1');");
194 
195   check_equals(mo, "dtext1.__proto__", "TextField.prototype");
196   check_equals(mo, "etext1.__proto__", "TextField.prototype");
197   check_equals(mo, "etext1.__proto__", "dynamictext1.__proto__");
198 
199   // checks after placing some swf defined TextField
200   check(mo, "TextField.prototype.hasOwnProperty('background')");
201   check(mo, "TextField.prototype.hasOwnProperty('backgroundColor')");
202   check(mo, "TextField.prototype.hasOwnProperty('text')");
203   check(mo, "TextField.prototype.hasOwnProperty('textColor')");
204   check(mo, "!TextField.prototype.hasOwnProperty('_parent')");
205   check(mo, "!TextField.prototype.hasOwnProperty('_xmouse')");
206   check(mo, "!TextField.prototype.hasOwnProperty('_ymouse')");
207   check(mo, "!TextField.prototype.hasOwnProperty('_xscale')");
208   check(mo, "!TextField.prototype.hasOwnProperty('_yscale')");
209 
210   check_equals(mo, "typeof(dtext1)", "'object'");
211   check_equals(mo, "typeof(dtext1.text)", "'string'");
212   check_equals(mo, "typeof(dtext1.background)", "'boolean'");
213   check_equals(mo, "typeof(dtext1.backgroundColor)", "'number'");
214   check_equals(mo, "typeof(dtext1.textColor)", "'number'");
215   check_equals(mo, "typeof(dtext1._alpha)", "'number'");
216   check_equals(mo, "typeof(dtext1.type)", "'string'");
217   check_equals(mo, "dtext1.type", "'input'");
218 
219   check_equals(mo, "typeof(dtext1.__proto__.text)", "'undefined'");
220   check_equals(mo, "typeof(dtext1.__proto__.background)", "'undefined'");
221   check_equals(mo, "typeof(dtext1.__proto__.backgroundColor)", "'undefined'");
222   check_equals(mo, "typeof(dtext1.__proto__.textColor)", "'undefined'");
223   check_equals(mo, "typeof(dtext1.__proto__._alpha)", "'undefined'");
224 
225   check_equals(mo, "dtext1.hasOwnProperty('text')", "false");
226   check_equals(mo, "dtext1.hasOwnProperty('background')", "false");
227   check_equals(mo, "dtext1.hasOwnProperty('backgroundColor')", "false");
228   check_equals(mo, "dtext1.hasOwnProperty('textColor')", "false");
229   check_equals(mo, "dtext1.hasOwnProperty('_alpha')", "false");
230   check(mo, "!dtext1.hasOwnProperty('_parent')");
231   check(mo, "!dtext1.hasOwnProperty('_xmouse')");
232   check(mo, "!dtext1.hasOwnProperty('_ymouse')");
233   check(mo, "!dtext1.hasOwnProperty('_xscale')");
234   check(mo, "!dtext1.hasOwnProperty('_yscale')");
235   check(mo, "!etext1.hasOwnProperty('_parent')");
236   check(mo, "!etext1.hasOwnProperty('_xmouse')");
237   check(mo, "!etext1.hasOwnProperty('_ymouse')");
238   check(mo, "!etext1.hasOwnProperty('_xscale')");
239   check(mo, "!etext1.hasOwnProperty('_yscale')");
240 
241   check(mo, "dtext1.__proto__.hasOwnProperty('text')");
242   check_equals(mo, "dtext1.__proto__.hasOwnProperty('background')", "true");
243   check_equals(mo, "dtext1.__proto__.hasOwnProperty('backgroundColor')", "true");
244   check_equals(mo, "dtext1.__proto__.hasOwnProperty('textColor')", "true");
245   // Why _alpha is special???
246   check_equals(mo, "dtext1.__proto__.hasOwnProperty('_alpha')", "false");
247 
248   check_equals(mo, "dtext1.text", "'Hello'");
249   check_equals(mo, "etext1.text", "'Hello'");
250   check_equals(mo, "dtext2.text", "'Hello'");
251   check_equals(mo, "dtext1.background", "false");
252   check_equals(mo, "etext1.background", "false");
253   check_equals(mo, "dtext2.background", "false");
254   check_equals(mo, "dtext1.backgroundColor", "0xffffff");
255   check_equals(mo, "etext1.backgroundColor", "0xffffff");
256   check_equals(mo, "dtext2.backgroundColor", "0xffffff");
257   check_equals(mo, "dtext1.textColor", "6579558");
258   check_equals(mo, "etext1.textColor", "7237488");
259   check_equals(mo, "dtext2.textColor", "7895418");
260   check_equals(mo, "dtext1._alpha", "100");
261   check_equals(mo, "etext1._alpha", "100");
262   check_equals(mo, "dtext2._alpha", "100");
263   check_equals(mo, "etext1._parent", "_root");
264   check_equals(mo, "dtext2._parent", "_root");
265   check_equals(mo, "etext1._xscale", "100");
266   check_equals(mo, "dtext2._xscale", "100");
267   check_equals(mo, "etext1._yscale", "100");
268   check_equals(mo, "dtext2._yscale", "100");
269   check_equals(mo, "typeof(etext1._xmouse)", "'number'");
270   check_equals(mo, "typeof(dtext2._xmouse)", "'number'");
271   check_equals(mo, "typeof(etext1._ymouse)", "'number'");
272   check_equals(mo, "typeof(dtext2._ymouse)", "'number'");
273 
274   // TextFormat objects are created on the fly
275   add_actions(mo,
276 	"etext1.tf = etext1.getTextFormat();"
277 	"dtext2.tf = dtext2.getTextFormat();"
278 	);
279   check_equals(mo, "typeof(etext1.tf)", "'object'");
280   check_equals(mo, "typeof(dtext2.tf)", "'object'");
281   check_equals(mo, "etext1.tf.size", "12");
282   check_equals(mo, "dtext2.tf.size", "12");
283   check_equals(mo, "etext1.tf.font", "'Bitstream Vera Sans'");
284   check_equals(mo, "dtext2.tf.font", "'times'");
285   check_equals(mo, "typeof(etext1.tf.bold)", "'boolean'");
286   check_equals(mo, "typeof(dtext2.tf.bold)", "'boolean'");
287   check_equals(mo, "etext1.tf.bold", "false");
288   check_equals(mo, "dtext2.tf.bold", "false");
289   check_equals(mo, "typeof(etext1.tf.italic)", "'boolean'");
290   check_equals(mo, "typeof(dtext2.tf.italic)", "'boolean'");
291   check_equals(mo, "etext1.tf.italic", "false");
292   check_equals(mo, "dtext2.tf.italic", "false");
293   check_equals(mo, "typeof(etext1.tf.indent)", "'number'");
294   check_equals(mo, "typeof(dtext2.tf.indent)", "'number'");
295   check_equals(mo, "etext1.tf.indent", "4");
296   check_equals(mo, "dtext2.tf.indent", "7");
297   check_equals(mo, "typeof(etext1.tf.leftMargin)", "'number'");
298   check_equals(mo, "typeof(dtext2.tf.leftMargin)", "'number'");
299   check_equals(mo, "etext1.tf.leftMargin", "5");
300   check_equals(mo, "dtext2.tf.leftMargin", "8");
301   check_equals(mo, "typeof(etext1.tf.rightMargin)", "'number'");
302   check_equals(mo, "typeof(dtext2.tf.rightMargin)", "'number'");
303   check_equals(mo, "etext1.tf.rightMargin", "6");
304   check_equals(mo, "dtext2.tf.rightMargin", "9");
305   check_equals(mo, "typeof(etext1.tf.align)", "'string'");
306   check_equals(mo, "typeof(dtext2.tf.align)", "'string'");
307   check_equals(mo, "etext1.tf.align", "'center'");
308   check_equals(mo, "dtext2.tf.align", "'right'");
309   check_equals(mo, "typeof(etext1.tf.leading)", "'number'");
310   check_equals(mo, "typeof(dtext2.tf.leading)", "'number'");
311   check_equals(mo, "etext1.tf.leading", "11");
312   check_equals(mo, "dtext2.tf.leading", "12");
313   check_equals(mo, "typeof(etext1.tf.color)", "'number'");
314   check_equals(mo, "typeof(dtext2.tf.color)", "'number'");
315   check_equals(mo, "etext1.tf.color", "7237488");
316   check_equals(mo, "dtext2.tf.color", "7895418");
317   check_equals(mo, "typeof(etext1.tf.blockIndent)", "'number'");
318   check_equals(mo, "typeof(dtext2.tf.blockIndent)", "'number'");
319   check_equals(mo, "etext1.tf.blockIndent", "0");
320   check_equals(mo, "dtext2.tf.blockIndent", "0");
321   check_equals(mo, "typeof(etext1.tf.underline)", "'boolean'");
322   check_equals(mo, "typeof(dtext2.tf.underline)", "'boolean'");
323   check_equals(mo, "etext1.tf.underline", "false");
324   check_equals(mo, "dtext2.tf.underline", "false");
325 
326   add_actions(mo, "dtext1.background = true;"
327                   "etext1.background = true;"
328                   "dtext2.background = true;"
329                   "dtext1.backgroundColor = 0xff0000;"
330                   "etext1.backgroundColor = 0x00ff00;"
331                   "dtext2.backgroundColor = 0x0000ff;"
332                   "dtext1.textColor = 0x00ffff;"
333                   "etext1.textColor = 0xff00ff;"
334                   "dtext2.textColor = 0xffff00;"
335                   "dtext1.text += ' world';"
336                   "etext1.text += ' world';"
337                   "dtext2.text += ' world';" );
338 
339   check_equals(mo, "etext1.getTextFormat().color", "0xff00ff");
340   check_equals(mo, "dtext2.getTextFormat().color", "0xffff00");
341 
342   check_equals(mo, "dtext1.text", "'Hello world'");
343   check_equals(mo, "etext1.text", "'Hello world'");
344   check_equals(mo, "dtext2.text", "'Hello world'");
345   check_equals(mo, "dtext1.background", "true");
346   check_equals(mo, "etext1.background", "true");
347   check_equals(mo, "dtext2.background", "true");
348   check_equals(mo, "dtext1.backgroundColor", "0xff0000");
349   check_equals(mo, "etext1.backgroundColor", "0x00ff00");
350   check_equals(mo, "dtext2.backgroundColor", "0x0000ff");
351   check_equals(mo, "dtext1.textColor", "0x00ffff");
352   check_equals(mo, "etext1.textColor", "0xff00ff");
353   check_equals(mo, "dtext2.textColor", "0xffff00");
354   SWFMovie_nextFrame(mo);
355 
356   add_actions(mo, "dtext1._alpha = 0;"
357                   "etext1._alpha = 0;"
358                   "dtext2._alpha = 0;" );
359   check_equals(mo, "dtext1._alpha", "0");
360   check_equals(mo, "etext1._alpha", "0");
361   check_equals(mo, "dtext2._alpha", "0");
362   SWFMovie_nextFrame(mo);
363 
364   add_actions(mo, "dtext1._alpha = 100; dtext1.embedFonts=true; dtext1.text = 'embedFonts';"
365                   "etext1._alpha = 100; etext1.embedFonts=false; etext1.text = '!embedFonts';"
366                   "dtext2._alpha = 100;" );
367 
368   check_equals(mo, "dtext1.embedFonts", "true");
369   check_equals(mo, "etext1.embedFonts", "false");
370 
371   add_actions(mo, "totals(); stop();");
372   SWFMovie_nextFrame(mo);
373 
374   /*****************************************************
375    *
376    * Output movie
377    *
378    *****************************************************/
379   puts("Saving " OUTPUT_FILENAME );
380 
381   SWFMovie_save(mo, OUTPUT_FILENAME);
382 
383   return 0;
384 }
385