Add the paragraph's direction to all lines.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / layouts / layout-engine.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/math/vector2.h>
23 #include <dali/public-api/text-abstraction/font-client.h>
24
25 // INTERNAL INCLUDES
26 #include <dali-toolkit/internal/text/layouts/layout-parameters.h>
27 #include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Text
36 {
37
38 /**
39  * @brief Stores temporary layout info of the line.
40  */
41 struct LineLayout
42 {
43   GlyphIndex     glyphIndex;         ///< Index of the first glyph to be laid-out.
44   CharacterIndex characterIndex;     ///< Index of the first character to be laid-out.
45   Length         numberOfCharacters; ///< The number of characters which fit in one line.
46   Length         numberOfGlyphs;     ///< The number of glyph which fit in one line.
47   float          length;             ///< The length of the glyphs which fit in one line.
48   float          widthAdvanceDiff;   ///< The difference between the width and the advance of the last glyph.
49   float          wsLengthEndOfLine;  ///< The length of the white spaces at the end of the line.
50   float          ascender;           ///< The maximum ascender of all fonts in the line.
51   float          descender;          ///< The maximum descender of all fonts in the line.
52 };
53
54 struct LayoutEngine::Impl
55 {
56   Impl()
57   : mLayout( LayoutEngine::SINGLE_LINE_BOX ),
58     mHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ),
59     mVerticalAlignment( LayoutEngine::VERTICAL_ALIGN_TOP )
60   {
61     mFontClient = TextAbstraction::FontClient::Get();
62   }
63
64   /**
65    * Retrieves the line layout for a given box width.
66    */
67   void GetLineLayoutForBox( const LayoutParameters& parameters,
68                             LineLayout& lineLayout )
69   {
70     // Initializes the line layout.
71     lineLayout.numberOfCharacters = 0u;
72     lineLayout.numberOfGlyphs = 0u;
73     lineLayout.length = 0.f;
74     lineLayout.wsLengthEndOfLine = 0.f;
75     lineLayout.ascender = 0.f;
76     lineLayout.descender = 0.f;
77
78     // Get the last glyph index.
79     const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u;
80
81     FontId lastFontId = 0u;
82     for( GlyphIndex glyphIndex = lineLayout.glyphIndex;
83          glyphIndex < parameters.totalNumberOfGlyphs;
84          ++glyphIndex )
85     {
86       // Get the glyph info.
87       const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex );
88
89       // Check whether is a white space.
90       const Character character = *( parameters.textBuffer + lineLayout.numberOfCharacters );
91       const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character );
92
93       // Get the character indices for the current glyph. The last character index is needed
94       // because there are glyphs formed by more than one character but their break info is
95       // given only for the last character.
96       const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex );
97
98       // Increase the number of characters.
99       lineLayout.numberOfCharacters += charactersPerGlyph;
100
101       // Increase the number of glyphs.
102       lineLayout.numberOfGlyphs++;
103
104       // Increase the accumulated length.
105       const float glyphLength = ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance;
106
107       if( isWhiteSpace )
108       {
109         // Add the length to the length of white spaces at the end of the line.
110         lineLayout.wsLengthEndOfLine += glyphLength;
111       }
112       else
113       {
114         // Add as well any previous white space length.
115         lineLayout.length += lineLayout.wsLengthEndOfLine + glyphLength;
116
117         // Clear the white space length at the end of the line.
118         lineLayout.wsLengthEndOfLine = 0.f;
119       }
120
121       if( lastFontId != glyphInfo.fontId )
122       {
123         Text::FontMetrics fontMetrics;
124         mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics );
125
126         // Sets the maximum ascender.
127         if( fontMetrics.ascender > lineLayout.ascender )
128         {
129           lineLayout.ascender = fontMetrics.ascender;
130         }
131
132         // Sets the maximum descender.
133         if( fontMetrics.descender > lineLayout.descender )
134         {
135           lineLayout.descender = fontMetrics.descender;
136         }
137
138         lastFontId = glyphInfo.fontId;
139       }
140     }
141   }
142
143   /**
144    * Retrieves the line layout for a given box width.
145    */
146   void GetMultiLineLayoutForBox( const LayoutParameters& parameters,
147                                  LineLayout& lineLayout )
148   {
149     // Initializes the line layout.
150     lineLayout.numberOfCharacters = 0u;
151     lineLayout.numberOfGlyphs = 0u;
152     lineLayout.length = 0.f;
153     lineLayout.widthAdvanceDiff = 0.f;
154     lineLayout.wsLengthEndOfLine = 0.f;
155     lineLayout.ascender = 0.f;
156     lineLayout.descender = 0.f;
157
158     // Stores temporary line layout which has not been added to the final line layout.
159     LineLayout tmpLineLayout;
160     tmpLineLayout.numberOfCharacters = 0u;
161     tmpLineLayout.numberOfGlyphs = 0u;
162     tmpLineLayout.length = 0.f;
163     tmpLineLayout.widthAdvanceDiff = 0.f;
164     tmpLineLayout.wsLengthEndOfLine = 0.f;
165     tmpLineLayout.ascender = 0.f;
166     tmpLineLayout.descender = 0.f;
167
168     FontId lastFontId = 0u;
169     for( GlyphIndex glyphIndex = lineLayout.glyphIndex;
170          glyphIndex < parameters.totalNumberOfGlyphs;
171          ++glyphIndex )
172     {
173       // Get the glyph info.
174       const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex );
175
176       // Get the character indices for the current glyph. The last character index is needed
177       // because there are glyphs formed by more than one character but their break info is
178       // given only for the last character.
179       const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex );
180       const CharacterIndex characterFirstIndex = *( parameters.glyphsToCharactersBuffer + glyphIndex );
181       const CharacterIndex characterLastIndex = characterFirstIndex + ( ( 1u > charactersPerGlyph ) ? 0u : charactersPerGlyph - 1u );
182
183       // Get the line break info for the current character.
184       const LineBreakInfo lineBreakInfo = *( parameters.lineBreakInfoBuffer + characterLastIndex );
185
186       // Get the word break info for the current character.
187       const WordBreakInfo wordBreakInfo = *( parameters.wordBreakInfoBuffer + characterLastIndex );
188
189       // Increase the number of characters.
190       tmpLineLayout.numberOfCharacters += charactersPerGlyph;
191
192       // Increase the number of glyphs.
193       tmpLineLayout.numberOfGlyphs++;
194
195       // Check whether is a white space.
196       const Character character = *( parameters.textBuffer + characterFirstIndex );
197       const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character );
198
199       // Increase the accumulated length.
200       if( isWhiteSpace )
201       {
202         // Add the length to the length of white spaces at the end of the line.
203         tmpLineLayout.wsLengthEndOfLine += glyphInfo.advance; // I use the advance as the width is always zero for the white spaces.
204         tmpLineLayout.widthAdvanceDiff = 0.f;
205       }
206       else
207       {
208         // Add as well any previous white space length.
209         tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphInfo.advance;
210         tmpLineLayout.widthAdvanceDiff = glyphInfo.width - glyphInfo.advance;
211
212         // Clear the white space length at the end of the line.
213         tmpLineLayout.wsLengthEndOfLine = 0.f;
214       }
215
216       // Check if the accumulated length fits in the width of the box.
217       if( lineLayout.length + tmpLineLayout.length + tmpLineLayout.widthAdvanceDiff + ( ( 0.f < tmpLineLayout.length ) ? lineLayout.wsLengthEndOfLine : 0.f ) > parameters.boundingBox.width )
218       {
219         // Current word does not fit in the box's width.
220         return;
221       }
222
223       if( TextAbstraction::LINE_MUST_BREAK == lineBreakInfo )
224       {
225         // Must break the line. Update the line layout and return.
226         lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters;
227         lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs;
228         lineLayout.length += tmpLineLayout.length;
229         lineLayout.widthAdvanceDiff = tmpLineLayout.widthAdvanceDiff;
230
231         if( 0.f < tmpLineLayout.length )
232         {
233           lineLayout.length += lineLayout.wsLengthEndOfLine;
234
235           lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine;
236         }
237         else
238         {
239           lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine;
240         }
241
242         if( tmpLineLayout.ascender > lineLayout.ascender )
243         {
244           lineLayout.ascender = tmpLineLayout.ascender;
245         }
246
247         if( tmpLineLayout.descender > lineLayout.descender )
248         {
249           lineLayout.descender = tmpLineLayout.descender;
250         }
251
252         tmpLineLayout.numberOfCharacters = 0u;
253         tmpLineLayout.numberOfGlyphs = 0u;
254         tmpLineLayout.length = 0u;
255         tmpLineLayout.widthAdvanceDiff = 0u;
256         tmpLineLayout.wsLengthEndOfLine = 0u;
257         tmpLineLayout.ascender = 0.f;
258         tmpLineLayout.descender = 0.f;
259         return;
260       }
261
262       if( TextAbstraction::WORD_BREAK == wordBreakInfo )
263       {
264         // Current glyph is the last one of the current word.
265         // Add the temporal layout to the current one.
266         lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters;
267         lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs;
268         lineLayout.length += tmpLineLayout.length;
269         lineLayout.widthAdvanceDiff = tmpLineLayout.widthAdvanceDiff;
270
271         if( 0.f < tmpLineLayout.length )
272         {
273           lineLayout.length += lineLayout.wsLengthEndOfLine;
274
275           lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine;
276         }
277         else
278         {
279           lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine;
280         }
281
282         if( tmpLineLayout.ascender > lineLayout.ascender )
283         {
284           lineLayout.ascender = tmpLineLayout.ascender;
285         }
286
287         if( tmpLineLayout.descender > lineLayout.descender )
288         {
289           lineLayout.descender = tmpLineLayout.descender;
290         }
291
292         tmpLineLayout.numberOfCharacters = 0u;
293         tmpLineLayout.numberOfGlyphs = 0u;
294         tmpLineLayout.length = 0u;
295         tmpLineLayout.widthAdvanceDiff = 0u;
296         tmpLineLayout.wsLengthEndOfLine = 0u;
297         tmpLineLayout.ascender = 0.f;
298         tmpLineLayout.descender = 0.f;
299       }
300
301       if( lastFontId != glyphInfo.fontId )
302       {
303         Text::FontMetrics fontMetrics;
304         mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics );
305
306         // Sets the maximum ascender.
307         if( fontMetrics.ascender > tmpLineLayout.ascender )
308         {
309           tmpLineLayout.ascender = fontMetrics.ascender;
310         }
311
312         // Sets the maximum descender.
313         if( -fontMetrics.descender > tmpLineLayout.descender )
314         {
315           tmpLineLayout.descender = -fontMetrics.descender;
316         }
317
318         lastFontId = glyphInfo.fontId;
319       }
320     }
321   }
322
323   bool LayoutText( const LayoutParameters& layoutParameters,
324                    Vector<Vector2>& glyphPositions,
325                    Vector<LineRun>& lines,
326                    Size& actualSize )
327   {
328     // TODO Switch between different layouts
329     bool update = false;
330
331     switch( mLayout )
332     {
333       case LayoutEngine::SINGLE_LINE_BOX:
334       {
335         update = SingleLineLayout( layoutParameters,
336                                    glyphPositions,
337                                    lines,
338                                    actualSize );
339         break;
340       }
341       case LayoutEngine::MULTI_LINE_BOX:
342       {
343         update = MultiLineLayout( layoutParameters,
344                                   glyphPositions,
345                                   lines,
346                                   actualSize );
347         break;
348       }
349       default:
350         break;
351     }
352
353     return update;
354   }
355
356   void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
357                                  Vector<Vector2>& glyphPositions )
358   {
359     // Traverses the paragraphs with right to left characters.
360     for( LineIndex lineIndex = 0u; lineIndex < layoutParameters.numberOfBidirectionalInfoRuns; ++lineIndex )
361     {
362       const BidirectionalLineInfoRun& bidiLine = *( layoutParameters.lineBidirectionalInfoRunsBuffer + lineIndex );
363
364       float penX = 0.f;
365
366       Vector2* glyphPositionsBuffer = glyphPositions.Begin();
367
368       // Traverses the characters of the right to left paragraph.
369       for( CharacterIndex characterLogicalIndex = 0u;
370            characterLogicalIndex < bidiLine.characterRun.numberOfCharacters;
371            ++characterLogicalIndex )
372       {
373         // Convert the character in the logical order into the character in the visual order.
374         const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *( bidiLine.visualToLogicalMap + characterLogicalIndex );
375
376         // Get the number of glyphs of the character.
377         const Length numberOfGlyphs = *( layoutParameters.glyphsPerCharacterBuffer + characterVisualIndex );
378
379         for( GlyphIndex index = 0u; index < numberOfGlyphs; ++index )
380         {
381           // Convert the character in the visual order into the glyph in the visual order.
382           const GlyphIndex glyphIndex = *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) + index;
383
384           DALI_ASSERT_DEBUG( 0u <= glyphIndex && glyphIndex < layoutParameters.totalNumberOfGlyphs );
385
386           const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + glyphIndex );
387           Vector2& position = *( glyphPositionsBuffer + glyphIndex );
388
389           position.x = penX + glyph.xBearing;
390           penX += glyph.advance;
391         }
392       }
393     }
394   }
395
396   void Align( const LayoutParameters& layoutParameters,
397               const Size& layoutSize,
398               const Vector<LineRun>& lines,
399               Vector<Vector2>& glyphPositions )
400   {
401     Vector2* glyphPositionsBuffer = glyphPositions.Begin();
402
403     // Traverse all lines and align the glyphs.
404     // LayoutParameters contains bidirectional info for those lines with
405     // right to left text, this info includes the paragraph's direction.
406
407     LineIndex bidiLineIndex = 0u;
408     for( Vector<LineRun>::ConstIterator it = lines.Begin(), endIt = lines.End();
409          it != endIt;
410          ++it )
411     {
412       const LineRun& line = *it;
413
414       // 1) Get the paragrap's direction.
415       bool paragraphDirection = false;
416
417       // Check if there is any right to left line.
418       if( ( NULL != layoutParameters.lineBidirectionalInfoRunsBuffer ) &&
419           ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
420       {
421         const BidirectionalLineInfoRun* bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
422
423         // Get the right to left line that match with current line.
424         while( ( line.characterRun.characterIndex > bidiLine->characterRun.characterIndex ) &&
425                ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
426         {
427           ++bidiLineIndex;
428           bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
429         }
430
431         if( line.characterRun.characterIndex == bidiLine->characterRun.characterIndex )
432         {
433           paragraphDirection = bidiLine->direction;
434         }
435       }
436
437       // 2) Calculate the alignment offset accordingly with the align option,
438       //    the box width, line length, and the paragraphs direction.
439       float alignOffset = CalculateHorizontalAlignment( layoutSize.width,
440                                                         line.lineSize.width,
441                                                         line.extraLength,
442                                                         paragraphDirection );
443
444       // 3) Traverse all glyphs and update the 'x' position.
445       for( GlyphIndex index = line.glyphIndex,
446              endIndex = line.glyphIndex + line.numberOfGlyphs;
447            index < endIndex;
448            ++index )
449       {
450         Vector2& position = *( glyphPositionsBuffer + index );
451
452         position.x += alignOffset;
453       }
454     }
455   }
456
457   bool SingleLineLayout( const LayoutParameters& layoutParameters,
458                          Vector<Vector2>& glyphPositions,
459                          Vector<LineRun>& lines,
460                          Size& actualSize )
461   {
462     LineLayout layout;
463     layout.glyphIndex = 0u;
464     GetLineLayoutForBox( layoutParameters,
465                          layout );
466
467     // Create a line run and add it to the lines.
468     const GlyphIndex lastGlyphIndex = layoutParameters.totalNumberOfGlyphs - 1u;
469
470     LineRun lineRun;
471     lineRun.glyphIndex = 0u;
472     lineRun.numberOfGlyphs = layoutParameters.totalNumberOfGlyphs;
473     lineRun.characterRun.characterIndex = 0u;
474     lineRun.characterRun.numberOfCharacters = *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex );
475     lineRun.lineSize.width = layout.length;
476     lineRun.lineSize.height = layout.ascender + layout.descender;
477     lineRun.extraLength = layout.wsLengthEndOfLine;
478     lineRun.direction = false;
479
480     lines.PushBack( lineRun );
481
482     // Update the actual size.
483     actualSize.width = layout.length;
484     actualSize.height = lineRun.lineSize.height;
485
486     float penX = 0.f;
487     float penY = layout.ascender;
488
489     Vector2* glyphPositionsBuffer = glyphPositions.Begin();
490     for( GlyphIndex glyphIndex = 0u; glyphIndex < layout.numberOfGlyphs; ++glyphIndex )
491     {
492       const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + glyphIndex );
493       Vector2& position = *( glyphPositionsBuffer + glyphIndex );
494
495       position.x = penX + glyph.xBearing;
496       position.y = penY - glyph.yBearing;
497
498       penX += glyph.advance;
499     }
500
501     return true;
502   }
503
504   bool MultiLineLayout( const LayoutParameters& layoutParameters,
505                         Vector<Vector2>& glyphPositions,
506                         Vector<LineRun>& lines,
507                         Size& actualSize )
508   {
509     float penY = 0.f;
510     for( GlyphIndex index = 0u; index < layoutParameters.totalNumberOfGlyphs; )
511     {
512       float penX = 0.f;
513
514       // Get the layout for the line.
515       LineLayout layout;
516       layout.glyphIndex = index;
517       GetMultiLineLayoutForBox( layoutParameters,
518                                 layout );
519
520       if( 0u == layout.numberOfGlyphs )
521       {
522         // The width is too small and no characters are laid-out.
523         return false;
524       }
525
526       // Create a line run and add it to the lines.
527       const GlyphIndex lastGlyphIndex = index + layout.numberOfGlyphs - 1u;
528
529       LineRun lineRun;
530       lineRun.glyphIndex = index;
531       lineRun.numberOfGlyphs = layout.numberOfGlyphs;
532       lineRun.characterRun.characterIndex = *( layoutParameters.glyphsToCharactersBuffer + index );
533       lineRun.characterRun.numberOfCharacters = ( *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex ) ) - lineRun.characterRun.characterIndex;
534       lineRun.lineSize.width = layout.length + ( ( layout.widthAdvanceDiff > 0.f ) ? layout.widthAdvanceDiff : 0.f );
535       lineRun.lineSize.height = layout.ascender + layout.descender;
536       lineRun.extraLength = layout.wsLengthEndOfLine;
537       lineRun.direction = false;
538
539       lines.PushBack( lineRun );
540
541       // Update the actual size.
542       if( layout.length + layout.widthAdvanceDiff > actualSize.width )
543       {
544         actualSize.width = layout.length;
545       }
546
547       actualSize.height += lineRun.lineSize.height;
548
549       // Traverse the glyphs and set the positions.
550
551       penY += layout.ascender;
552
553       Vector2* glyphPositionsBuffer = glyphPositions.Begin();
554       for( GlyphIndex i = index; i < index + layout.numberOfGlyphs; ++i )
555       {
556         const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + i );
557         Vector2& position = *( glyphPositionsBuffer + i );
558
559         position.x = penX + glyph.xBearing;
560         position.y = penY - glyph.yBearing;
561
562         penX += glyph.advance;
563       }
564
565       penY += layout.descender;
566
567       // Increase the glyph index.
568       index += layout.numberOfGlyphs;
569     }
570
571     return true;
572   }
573
574   float CalculateHorizontalAlignment( float boxWidth,
575                                       float lineLength,
576                                       float extraLength,
577                                       bool paragraphDirection )
578   {
579     float offset = 0.f;
580
581     HorizontalAlignment alignment = mHorizontalAlignment;
582     if( paragraphDirection &&
583         ( HORIZONTAL_ALIGN_CENTER != alignment ) )
584     {
585       if( HORIZONTAL_ALIGN_BEGIN == alignment )
586       {
587         alignment = HORIZONTAL_ALIGN_END;
588       }
589       else
590       {
591         alignment = HORIZONTAL_ALIGN_BEGIN;
592       }
593     }
594
595     switch( alignment )
596     {
597       case HORIZONTAL_ALIGN_BEGIN:
598       {
599         offset = 0.f;
600         break;
601       }
602       case HORIZONTAL_ALIGN_CENTER:
603       {
604         offset = 0.5f * ( boxWidth - lineLength );
605         const int intOffset = static_cast<int>( offset ); // try to avoid pixel alignment.
606         offset = static_cast<float>( intOffset );
607         break;
608       }
609       case HORIZONTAL_ALIGN_END:
610       {
611         offset = boxWidth - lineLength;
612         break;
613       }
614     }
615
616     if( paragraphDirection )
617     {
618       offset -= extraLength;
619     }
620
621     return offset;
622   }
623
624   LayoutEngine::Layout mLayout;
625   LayoutEngine::HorizontalAlignment mHorizontalAlignment;
626   LayoutEngine::VerticalAlignment mVerticalAlignment;
627
628   TextAbstraction::FontClient mFontClient;
629 };
630
631 LayoutEngine::LayoutEngine()
632 : mImpl( NULL )
633 {
634   mImpl = new LayoutEngine::Impl();
635 }
636
637 LayoutEngine::~LayoutEngine()
638 {
639   delete mImpl;
640 }
641
642 void LayoutEngine::SetLayout( Layout layout )
643 {
644   mImpl->mLayout = layout;
645 }
646
647 unsigned int LayoutEngine::GetLayout() const
648 {
649   return mImpl->mLayout;
650 }
651
652 void LayoutEngine::SetHorizontalAlignment( HorizontalAlignment alignment )
653 {
654   mImpl->mHorizontalAlignment = alignment;
655 }
656
657 LayoutEngine::HorizontalAlignment LayoutEngine::GetHorizontalAlignment() const
658 {
659   return mImpl->mHorizontalAlignment;
660 }
661
662 void LayoutEngine::SetVerticalAlignment( VerticalAlignment alignment )
663 {
664   mImpl->mVerticalAlignment = alignment;
665 }
666
667 LayoutEngine::VerticalAlignment LayoutEngine::GetVerticalAlignment() const
668 {
669   return mImpl->mVerticalAlignment;
670 }
671
672 bool LayoutEngine::LayoutText( const LayoutParameters& layoutParameters,
673                                Vector<Vector2>& glyphPositions,
674                                Vector<LineRun>& lines,
675                                Size& actualSize )
676 {
677   return mImpl->LayoutText( layoutParameters,
678                             glyphPositions,
679                             lines,
680                             actualSize );
681 }
682
683 void LayoutEngine::ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
684                                              Vector<Vector2>& glyphPositions )
685 {
686   mImpl->ReLayoutRightToLeftLines( layoutParameters,
687                                    glyphPositions );
688 }
689
690 void LayoutEngine::Align( const LayoutParameters& layoutParameters,
691                           const Size& layoutSize,
692                           const Vector<LineRun>& lines,
693                           Vector<Vector2>& glyphPositions )
694 {
695   mImpl->Align( layoutParameters,
696                 layoutSize,
697                 lines,
698                 glyphPositions );
699 }
700
701 } // namespace Text
702
703 } // namespace Toolkit
704
705 } // namespace Dali