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