2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/dali-toolkit.h>
24 #include <toolkit-text-utils.h>
25 #include <dali-toolkit/internal/text/font-description-run.h>
26 #include <dali-toolkit/internal/text/rendering/text-typesetter.h>
27 #include <dali-toolkit/internal/text/rendering/view-model.h>
28 #include <dali-toolkit/internal/text/text-controller.h>
31 using namespace Toolkit;
37 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
39 const Size CONTROL_SIZE( 200.f, 400.f );
40 const Size CONTROL_SMALL_SIZE( 50.f, 100.f );
41 const char* LOREM_IPSUM = "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
42 "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
43 "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
44 "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
45 "Quidam corpora at duo. An eos possim scripserit?\n\n"
46 "Aťqui dicant sěnťenťíae aň vel!\n"
47 "Vis viris médiocrem elaboraret ét, verear civibus moderatius ex duo!\n"
48 "Án veri laborě iňtěgré quó, mei aď poššit lobortis, mei prompťa čonsťitůťó eů.\n"
49 "Aliquip sanctůs delicáta quí ěá, et natum aliquam est?\n"
50 "Asšúm sapěret usu ůť.\n"
51 "Síť ut apeirián laboramúš percipitur, sůas hařum ín éos?\n";
52 const Vector2 LOREM_SCROLL_POSITION( 0.f, -208.f );
53 const Length LOREM_NUMBER_OF_LINES = 32u;
54 const Length LOREM_NUMBER_OF_LINES_ELIDED = 21u;
55 const Length LOREM_NUMBER_OF_GLYPHS = 632;
56 const Length LOREM_NUMBER_OF_GLYPHS_ELIDED = 397u;
58 // The expected layout size for UtcDaliTextViewModelGetLayoutSize
59 const Size LAYOUT_SIZE( 190.f, 48.f );
61 // The expected color indices for UtcDaliTextViewModelGetColors
62 const ColorIndex COLOR_INDICES[] = { 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 1u, 1u, 1u, 1u, 1u, 3u, 1u, 1u, 1u, 0u, 0u, 0u, 0u };
63 const Length NUMBER_OF_COLORS = 3u;
64 const Vector4 COLORS[] = { Color::RED, Color::BLUE, Color::GREEN };
68 std::string description;
71 unsigned int numberOfLines;
72 unsigned int numberOfGlyphs;
76 bool ElideTest( const ElideData& data )
78 std::cout << " testing : " << data.description << std::endl;
81 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
82 fontClient.SetDpi( 93u, 93u );
84 char* pathNamePtr = get_current_dir_name();
85 const std::string pathName( pathNamePtr );
88 fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
89 fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf" );
90 fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansArabicRegular.ttf" );
92 // Creates a text controller.
93 ControllerPtr controller = Controller::New();
95 // Tests the rendering controller has been created.
96 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
97 DALI_TEST_CHECK( typesetter );
99 // Tests the view model has been created.
100 ViewModel* model = typesetter->GetViewModel();
101 DALI_TEST_CHECK( NULL != model );
103 // Configures the text controller similarly to the text-label.
104 ConfigureTextLabel( controller );
106 // Sets a text and relais-out.
107 controller->SetMarkupProcessorEnabled( true );
109 controller->SetText( data.text );
110 controller->Relayout( data.size );
113 model->ElideGlyphs();
115 if( data.numberOfLines != model->GetNumberOfLines() )
117 std::cout << " different number of lines : " << model->GetNumberOfLines() << ", expected : " << data.numberOfLines << std::endl;
121 if( data.numberOfGlyphs != model->GetNumberOfGlyphs() )
123 std::cout << " different number of glyphs : " << model->GetNumberOfGlyphs() << ", expected : " << data.numberOfGlyphs << std::endl;
127 const Vector2* const layoutBuffer = model->GetLayout();
128 const Length numberOfLines = model->GetNumberOfLines();
130 if( numberOfLines != 0u )
132 const LineRun& lastLine = *( model->GetLines() + numberOfLines - 1u );
133 const Length numberOfLastLineGlyphs = data.numberOfGlyphs - lastLine.glyphRun.glyphIndex;
135 std::cout << " last line alignment offset : " << lastLine.alignmentOffset << std::endl;
137 for( unsigned int index = 0u; index < numberOfLastLineGlyphs; ++index )
139 if( *( data.positions + index ) != ( lastLine.alignmentOffset + ( *( layoutBuffer + lastLine.glyphRun.glyphIndex + index ) ).x ) )
141 std::cout << " different layout :";
142 for( unsigned int i = 0; i < numberOfLastLineGlyphs; ++i )
144 std::cout << " " << ( lastLine.alignmentOffset + ( *( layoutBuffer + lastLine.glyphRun.glyphIndex + i ) ).x );
146 std::cout << std::endl;
147 std::cout << " expected :";
148 for( unsigned int i = 0; i < numberOfLastLineGlyphs; ++i )
150 std::cout << " " << *( data.positions + i );
152 std::cout << std::endl;
163 int UtcDaliTextViewModel(void)
165 tet_infoline(" UtcDaliTextViewModel");
166 ToolkitTestApplication application;
168 // Creates a text controller.
169 ControllerPtr controller = Controller::New();
171 // Tests the rendering controller has been created.
172 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
173 DALI_TEST_CHECK( typesetter );
175 // Tests the view model has been created.
176 ViewModel* model = typesetter->GetViewModel();
177 DALI_TEST_CHECK( NULL != model );
179 tet_result(TET_PASS);
183 int UtcDaliTextViewModelGetControlSize(void)
185 tet_infoline(" UtcDaliTextViewModelGetControlSize");
186 ToolkitTestApplication application;
188 // Creates a text controller.
189 ControllerPtr controller = Controller::New();
191 // Tests the rendering controller has been created.
192 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
193 DALI_TEST_CHECK( typesetter );
195 // Tests the view model has been created.
196 ViewModel* model = typesetter->GetViewModel();
197 DALI_TEST_CHECK( NULL != model );
199 // Configures the text controller similarly to the text-editor.
200 ConfigureTextEditor( controller );
202 // The text has not been laid-out. The stored control's size should be zero.
203 DALI_TEST_EQUALS( Size::ZERO, model->GetControlSize(), TEST_LOCATION );
205 // Sets a text and relais-out.
206 controller->SetText( "Hello world" );
207 controller->Relayout( CONTROL_SIZE );
209 // The control's size should be stored now.
210 DALI_TEST_EQUALS( CONTROL_SIZE, model->GetControlSize(), TEST_LOCATION );
212 tet_result(TET_PASS);
216 int UtcDaliTextViewModelGetLayoutSize(void)
218 tet_infoline(" UtcDaliTextViewModelGetLayoutSize");
219 ToolkitTestApplication application;
222 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
223 fontClient.SetDpi( 93u, 93u );
225 char* pathNamePtr = get_current_dir_name();
226 const std::string pathName( pathNamePtr );
229 fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
231 // Creates a text controller.
232 ControllerPtr controller = Controller::New();
234 // Tests the rendering controller has been created.
235 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
236 DALI_TEST_CHECK( typesetter );
238 // Tests the view model has been created.
239 ViewModel* model = typesetter->GetViewModel();
240 DALI_TEST_CHECK( NULL != model );
242 // Configures the text controller similarly to the text-editor.
243 ConfigureTextEditor( controller );
245 // The text has not been laid-out. The stored control's size should be zero.
246 DALI_TEST_EQUALS( Size::ZERO, model->GetLayoutSize(), TEST_LOCATION );
248 // Sets a text and relais-out.
249 controller->SetMarkupProcessorEnabled( true );
250 controller->SetText( "<font family='TizenSansRegular' size='10'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>" );
251 controller->Relayout( CONTROL_SIZE );
253 // The control's size should be stored now.
254 DALI_TEST_EQUALS( LAYOUT_SIZE, model->GetLayoutSize(), TEST_LOCATION );
256 tet_result(TET_PASS);
260 int UtcDaliTextViewModelGetScrollPosition(void)
262 tet_infoline(" UtcDaliTextViewModelGetScrollPosition");
263 ToolkitTestApplication application;
265 // Creates a text controller.
266 ControllerPtr controller = Controller::New();
268 // Tests the rendering controller has been created.
269 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
270 DALI_TEST_CHECK( typesetter );
272 // Tests the view model has been created.
273 ViewModel* model = typesetter->GetViewModel();
274 DALI_TEST_CHECK( NULL != model );
276 // Configures the text controller similarly to the text-editor.
277 ConfigureTextEditor( controller );
279 // No text has been set. The scroll position should be zero.
280 DALI_TEST_EQUALS( Vector2::ZERO, model->GetScrollPosition(), TEST_LOCATION );
282 // Gains the keyboard focus, sets a big text and relais-out.
283 controller->KeyboardFocusGainEvent();
284 controller->SetText( LOREM_IPSUM );
285 controller->Relayout( CONTROL_SIZE );
287 // The text should be scrolled to the end.
288 DALI_TEST_EQUALS( LOREM_SCROLL_POSITION, model->GetScrollPosition(), TEST_LOCATION );
290 tet_result(TET_PASS);
294 int UtcDaliTextViewModelGetAlignment(void)
296 tet_infoline(" UtcDaliTextViewModelGetAlignment");
297 ToolkitTestApplication application;
299 // Creates a text controller.
300 ControllerPtr controller = Controller::New();
302 // Tests the rendering controller has been created.
303 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
304 DALI_TEST_CHECK( typesetter );
306 // Tests the view model has been created.
307 ViewModel* model = typesetter->GetViewModel();
308 DALI_TEST_CHECK( NULL != model );
310 DALI_TEST_EQUALS( Text::HorizontalAlignment::BEGIN, model->GetHorizontalAlignment(), TEST_LOCATION );
311 DALI_TEST_EQUALS( Text::VerticalAlignment::TOP, model->GetVerticalAlignment(), TEST_LOCATION );
313 controller->SetHorizontalAlignment( Text::HorizontalAlignment::CENTER );
314 controller->SetVerticalAlignment( Text::VerticalAlignment::CENTER );
316 DALI_TEST_EQUALS( Text::HorizontalAlignment::CENTER, model->GetHorizontalAlignment(), TEST_LOCATION );
317 DALI_TEST_EQUALS( Text::VerticalAlignment::CENTER, model->GetVerticalAlignment(), TEST_LOCATION );
319 tet_result(TET_PASS);
323 int UtcDaliTextViewModelIsTextElideEnabled(void)
325 tet_infoline(" UtcDaliTextViewModelIsTextElideEnabled");
326 ToolkitTestApplication application;
328 // Creates a text controller.
329 ControllerPtr controller = Controller::New();
331 // Tests the rendering controller has been created.
332 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
333 DALI_TEST_CHECK( typesetter );
335 // Tests the view model has been created.
336 ViewModel* model = typesetter->GetViewModel();
337 DALI_TEST_CHECK( NULL != model );
339 // Configures the text controller similarly to the text-editor.
340 ConfigureTextEditor( controller );
342 // Elide text should be disabled.
343 DALI_TEST_CHECK( !model->IsTextElideEnabled() );
345 // Configures the text controller similarly to the text-label.
346 ConfigureTextLabel( controller );
348 // Elide text should be enabled.
349 DALI_TEST_CHECK( model->IsTextElideEnabled() );
351 tet_result(TET_PASS);
355 int UtcDaliTextViewModelGetLines(void)
357 tet_infoline(" UtcDaliTextViewModelGetLines");
358 ToolkitTestApplication application;
360 // Creates a text controller.
361 ControllerPtr controller = Controller::New();
363 // Tests the rendering controller has been created.
364 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
365 DALI_TEST_CHECK( typesetter );
367 // Tests the view model has been created.
368 ViewModel* model = typesetter->GetViewModel();
369 DALI_TEST_CHECK( NULL != model );
371 // Configures the text controller similarly to the text-editor.
372 ConfigureTextEditor( controller );
374 // The number of lines should be zero.
375 DALI_TEST_EQUALS( 0u, model->GetNumberOfLines(), TEST_LOCATION );
376 DALI_TEST_CHECK( NULL == model->GetLines() );
378 // Sets a text and relais-out.
379 controller->SetText( LOREM_IPSUM );
380 controller->Relayout( CONTROL_SIZE );
382 DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES, model->GetNumberOfLines(), TEST_LOCATION );
383 DALI_TEST_CHECK( NULL != model->GetLines() );
385 // Configures the text controller similarly to the text-label.
386 ConfigureTextLabel( controller );
388 // Relais-out for the text-label configuration.
389 controller->Relayout( Size( 100.f, 100.f) ); // Change the size to force a relayout.
390 controller->Relayout( CONTROL_SIZE );
392 DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES_ELIDED, model->GetNumberOfLines(), TEST_LOCATION );
393 DALI_TEST_CHECK( NULL != model->GetLines() );
395 tet_result(TET_PASS);
399 int UtcDaliTextViewModelGetGlyphsLayout(void)
401 tet_infoline(" UtcDaliTextViewModelGetGlyphsLayout");
402 ToolkitTestApplication application;
404 // Creates a text controller.
405 ControllerPtr controller = Controller::New();
407 // Tests the rendering controller has been created.
408 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
409 DALI_TEST_CHECK( typesetter );
411 // Tests the view model has been created.
412 ViewModel* model = typesetter->GetViewModel();
413 DALI_TEST_CHECK( NULL != model );
415 // Configures the text controller similarly to the text-editor.
416 ConfigureTextEditor( controller );
418 // The number of glyphs should be zero.
419 DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
420 DALI_TEST_CHECK( NULL == model->GetGlyphs() );
421 DALI_TEST_CHECK( NULL == model->GetLayout() );
423 // Sets a text and relais-out.
424 controller->SetText( LOREM_IPSUM );
425 controller->Relayout( CONTROL_SIZE );
427 DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS, model->GetNumberOfGlyphs(), TEST_LOCATION );
428 DALI_TEST_CHECK( NULL != model->GetGlyphs() );
429 DALI_TEST_CHECK( NULL != model->GetLayout() );
431 // Configures the text controller similarly to the text-label.
432 ConfigureTextLabel( controller );
434 // Relais-out for the text-label configuration.
435 controller->Relayout( Size( 100.f, 100.f) ); // Change the size to force a relayout.
436 controller->Relayout( CONTROL_SIZE );
439 model->ElideGlyphs();
441 DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS_ELIDED, model->GetNumberOfGlyphs(), TEST_LOCATION );
442 DALI_TEST_CHECK( NULL != model->GetGlyphs() );
443 DALI_TEST_CHECK( NULL != model->GetLayout() );
445 tet_result(TET_PASS);
449 int UtcDaliTextViewModelGetColors(void)
451 tet_infoline(" UtcDaliTextViewModelGetColors");
452 ToolkitTestApplication application;
454 // Creates a text controller.
455 ControllerPtr controller = Controller::New();
457 // Tests the rendering controller has been created.
458 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
459 DALI_TEST_CHECK( typesetter );
461 // Tests the view model has been created.
462 ViewModel* model = typesetter->GetViewModel();
463 DALI_TEST_CHECK( NULL != model );
465 // Configures the text controller similarly to the text-label.
466 ConfigureTextLabel( controller );
468 // Sets a text and relais-out.
469 controller->SetMarkupProcessorEnabled( true );
470 controller->SetText( "Lorem <color value='red'>ips<color value='blue'>um do</color>lor s<color value='green'>i</color>t a</color>met." );
471 controller->Relayout( CONTROL_SIZE );
473 DALI_TEST_EQUALS( Color::BLACK, model->GetDefaultColor(), TEST_LOCATION );
475 const ColorIndex* const colorIndicesBuffer = model->GetColorIndices();
477 const Length numberOfGlyphs = model->GetNumberOfGlyphs();
478 for( ColorIndex index = 0u; index < numberOfGlyphs; ++index )
480 DALI_TEST_EQUALS( COLOR_INDICES[index], *( colorIndicesBuffer + index ), TEST_LOCATION );
483 const Vector4* const colors = model->GetColors();
484 for( unsigned int index = 0u; index < NUMBER_OF_COLORS; ++index )
486 DALI_TEST_EQUALS( COLORS[index], *( colors + index ), TEST_LOCATION );
489 tet_result(TET_PASS);
493 int UtcDaliTextViewModelElideText01(void)
495 tet_infoline(" UtcDaliTextViewModelElideText01");
496 ToolkitTestApplication application;
498 // Creates a text controller.
499 ControllerPtr controller = Controller::New();
501 // Tests the rendering controller has been created.
502 TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
503 DALI_TEST_CHECK( typesetter );
505 // Tests the view model has been created.
506 ViewModel* model = typesetter->GetViewModel();
507 DALI_TEST_CHECK( NULL != model );
509 // Configures the text controller similarly to the text-editor.
510 ConfigureTextEditor( controller );
512 // The number of glyphs should be zero.
513 DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
514 DALI_TEST_EQUALS( 0u, model->GetNumberOfLines(), TEST_LOCATION );
515 DALI_TEST_CHECK( NULL == model->GetGlyphs() );
516 DALI_TEST_CHECK( NULL == model->GetLayout() );
518 // Sets a text and relais-out.
519 controller->SetText( LOREM_IPSUM );
520 controller->Relayout( CONTROL_SIZE );
522 // Keep the pointers to the glyphs and layout.
523 // As the text is not elided with this configuration, the pointers shoud be the same after calling the ElideGlyphs() method.
524 const GlyphInfo* const glyphsModel = model->GetGlyphs();
525 const Vector2* layoutsModel = model->GetLayout();
527 // Elide the glyphs. Text shouldn't be elided with this configuration.
528 model->ElideGlyphs();
530 DALI_TEST_CHECK( glyphsModel == model->GetGlyphs() );
531 DALI_TEST_CHECK( layoutsModel == model->GetLayout() );
533 DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS, model->GetNumberOfGlyphs(), TEST_LOCATION );
534 DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES, model->GetNumberOfLines(), TEST_LOCATION );
536 // Configures the text controller similarly to the text-label.
537 ConfigureTextLabel( controller );
539 // Clear the text and relais-out.
540 controller->SetText( "" );
541 controller->Relayout( CONTROL_SIZE );
543 DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
544 DALI_TEST_EQUALS( 0u, model->GetNumberOfLines(), TEST_LOCATION );
546 // Elide the glyphs. Should not add the ellipsis glyph.
547 model->ElideGlyphs();
549 DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
551 // Sets a text that doesn't need to be elided.
552 controller->SetText( "Hello\n" );
553 controller->Relayout( CONTROL_SIZE );
556 model->ElideGlyphs();
558 DALI_TEST_EQUALS( 6u, model->GetNumberOfGlyphs(), TEST_LOCATION );
559 DALI_TEST_EQUALS( 2u, model->GetNumberOfLines(), TEST_LOCATION );
561 // Sets a text and relais-out.
562 controller->SetText( LOREM_IPSUM );
563 controller->Relayout( CONTROL_SIZE );
566 model->ElideGlyphs();
568 DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS_ELIDED, model->GetNumberOfGlyphs(), TEST_LOCATION );
569 DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES_ELIDED, model->GetNumberOfLines(), TEST_LOCATION );
570 const GlyphInfo* const glyphs = model->GetGlyphs();
571 const Vector2* layouts = model->GetLayout();
572 DALI_TEST_CHECK( NULL != glyphs );
573 DALI_TEST_CHECK( NULL != layouts );
575 tet_result(TET_PASS);
579 int UtcDaliTextViewModelElideText02(void)
581 tet_infoline(" UtcDaliTextViewModelElideText02");
583 Size textSize00( 100.f, 100.f );
585 Size textSize01( 80.f, 100.f );
586 float positions01[] = { 0.f, 9.f, 17.f, 27.f, 35.f, 37.f, 46.f, 56.f };
588 Size textSize02( 80.f, 100.f );
589 float positions02[] = { 72.f, 63.f, 54.f, 50.f, 43.f, 38.f, 30.f, 11.f };
591 Size textSize03( 80.f, 100.f );
592 float positions03[] = { 77.f, 76.f, 71.f, 62.f, 59.f, 52.f, 47.f, 42.f, 39.f, 35.f, 32.f, 13.f };
594 Size textSize04( 80.f, 10.f );
595 float positions04[] = { 2.f };
597 struct ElideData data[] =
609 "<font family='TizenSans'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>",
617 "<font family='TizenSansHebrew'>צעד על לשון המלצת לאחרונה, אם לכאן שנורו סרבול מדע, קרן דת שפות להפוך.</font>",
625 "<font family='TizenSansArabic'>عل النفط ديسمبر الإمداد بال, بين وترك شعار هو. لمّ من المبرمة النفط بالسيطرة, أم يتم تحرّك وبغطاء, عدم في لإعادة وإقامة رجوعهم.</font>",
632 "Small control size, no line fits.",
633 "<font family='TizenSans'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>",
640 const unsigned int numberOfTests = 5u;
642 for( unsigned int index = 0u; index < numberOfTests; ++index )
644 ToolkitTestApplication application;
645 if( !ElideTest( data[index] ) )
647 tet_result(TET_FAIL);
651 tet_result(TET_PASS);