fix linespacing calculation in TextLabel
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / layouts / layout-engine-helper-functions.cpp
1 /*
2  * Copyright (c) 2022 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 // FILE HEADER
19 #include <dali-toolkit/internal/text/layouts/layout-engine-helper-functions.h>
20
21 // INTERNAL INCLUDE
22 #include <dali-toolkit/internal/text/glyph-metrics-helper.h>
23
24 namespace Dali
25 {
26 namespace Toolkit
27 {
28 namespace Text
29 {
30 namespace Layout
31 {
32 void CalculateGlyphPositionsLTR(const VisualModelPtr&  visualModel,
33                                 const LogicalModelPtr& logicalModel,
34                                 const float            interGlyphExtraAdvance,
35                                 const Length           numberOfGlyphs,
36                                 const GlyphIndex       startIndexForGlyph,
37                                 const GlyphIndex       startIndexForGlyphPositions,
38                                 Vector2*               glyphPositionsBuffer,
39                                 float&                 penX)
40 {
41   const GlyphInfo* const glyphsBuffer     = visualModel->mGlyphs.Begin();
42   const float            characterSpacing = visualModel->GetCharacterSpacing();
43   const Character* const textBuffer       = logicalModel->mText.Begin();
44
45   Vector<CharacterIndex>& glyphToCharacterMap       = visualModel->mGlyphsToCharacters;
46   const CharacterIndex*   glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
47
48   float calculatedAdvance = 0.f;
49
50   for(GlyphIndex i = 0u; i < numberOfGlyphs; ++i)
51   {
52     const GlyphInfo& glyph    = *(glyphsBuffer + startIndexForGlyph + i);
53     Vector2&         position = *(glyphPositionsBuffer + startIndexForGlyphPositions + i);
54
55     position.x = penX + glyph.xBearing;
56     position.y = -glyph.yBearing;
57
58     calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + (startIndexForGlyph + i)))), characterSpacing, glyph.advance);
59     penX += (calculatedAdvance + interGlyphExtraAdvance);
60   }
61 }
62
63 void CalculateGlyphPositionsRTL(const VisualModelPtr&            visualModel,
64                                 const LogicalModelPtr&           logicalModel,
65                                 const BidirectionalLineRunIndex& bidiLineIndex,
66                                 const GlyphIndex&                startGlyphIndex,
67                                 Vector2*                         glyphPositionsBuffer,
68                                 CharacterIndex&                  characterVisualIndex,
69                                 CharacterIndex&                  characterLogicalIndex,
70                                 float&                           penX)
71 {
72   const Character* const          textBuffer               = logicalModel->mText.Begin();
73   const BidirectionalLineInfoRun& bidiLine                 = logicalModel->mBidirectionalLineInfo[bidiLineIndex];
74   const GlyphInfo* const          glyphsBuffer             = visualModel->mGlyphs.Begin();
75   const GlyphIndex* const         charactersToGlyphsBuffer = visualModel->mCharactersToGlyph.Begin();
76   const float                     characterSpacing         = visualModel->GetCharacterSpacing();
77
78   float calculatedAdvance = 0.f;
79
80   while(TextAbstraction::IsWhiteSpace(*(textBuffer + characterVisualIndex)))
81   {
82     const GlyphIndex glyphIndex = *(charactersToGlyphsBuffer + characterVisualIndex);
83     const GlyphInfo& glyph      = *(glyphsBuffer + glyphIndex);
84
85     Vector2& position = *(glyphPositionsBuffer + glyphIndex - startGlyphIndex);
86     position.x        = penX;
87     position.y        = -glyph.yBearing;
88
89     calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyph.advance);
90     penX += calculatedAdvance;
91
92     ++characterLogicalIndex;
93     characterVisualIndex = bidiLine.characterRun.characterIndex + *(bidiLine.visualToLogicalMap + characterLogicalIndex);
94   }
95 }
96
97 void TraversesCharactersForGlyphPositionsRTL(const VisualModelPtr&  visualModel,
98                                              const Character* const textBuffer,
99                                              const GlyphIndex&      startGlyphIndex,
100                                              const float            interGlyphExtraAdvance,
101                                              const CharacterRun&    bidiLineCharacterRun,
102                                              CharacterIndex*        bidiLineVisualToLogicalMap,
103                                              Vector2*               glyphPositionsBuffer,
104                                              CharacterIndex&        characterLogicalIndex,
105                                              float&                 penX)
106 {
107   const GlyphInfo* const  glyphsBuffer             = visualModel->mGlyphs.Begin();
108   const GlyphIndex* const charactersToGlyphsBuffer = visualModel->mCharactersToGlyph.Begin();
109   const float             characterSpacing         = visualModel->GetCharacterSpacing();
110   const Length* const     glyphsPerCharacterBuffer = visualModel->mGlyphsPerCharacter.Begin();
111
112   float calculatedAdvance = 0.f;
113
114   for(; characterLogicalIndex < bidiLineCharacterRun.numberOfCharacters;
115       ++characterLogicalIndex)
116   {
117     // Convert the character in the logical order into the character in the visual order.
118     const CharacterIndex characterVisualIndex = bidiLineCharacterRun.characterIndex + *(bidiLineVisualToLogicalMap + characterLogicalIndex);
119
120     // Get the number of glyphs of the character.
121     const Length numberOfGlyphs = *(glyphsPerCharacterBuffer + characterVisualIndex);
122
123     for(GlyphIndex index = 0u; index < numberOfGlyphs; ++index)
124     {
125       // Convert the character in the visual order into the glyph in the visual order.
126       const GlyphIndex glyphIndex = *(charactersToGlyphsBuffer + characterVisualIndex) + index;
127
128       DALI_ASSERT_DEBUG(glyphIndex < visualModel->mGlyphs.Count());
129
130       const GlyphInfo& glyph    = *(glyphsBuffer + glyphIndex);
131       Vector2&         position = *(glyphPositionsBuffer + glyphIndex - startGlyphIndex);
132
133       position.x = penX + glyph.xBearing;
134       position.y = -glyph.yBearing;
135
136       calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyph.advance);
137       penX += (calculatedAdvance + interGlyphExtraAdvance);
138     }
139   }
140 }
141
142 } // namespace Layout
143
144 } // namespace Text
145
146 } // namespace Toolkit
147
148 } // namespace Dali