2 * Copyright (c) 2015 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.
19 #include <dali-toolkit/public-api/text/layouts/layout-engine.h>
22 #include <dali/public-api/math/vector2.h>
23 #include <dali/public-api/text-abstraction/font-client.h>
26 #include <dali-toolkit/public-api/text/logical-model.h>
27 #include <dali-toolkit/public-api/text/visual-model.h>
38 struct LayoutEngine::Impl
41 : mLayout( LayoutEngine::SINGLE_LINE_BOX )
43 mFontClient = TextAbstraction::FontClient::Get();
46 void UpdateVisualModel( const Vector2& boundingBox,
47 const Vector<GlyphInfo>& glyphs,
48 const Vector<CharacterIndex>& characterIndices,
49 const Vector<Length>& charactersPerGlyph,
50 VisualModel& visualModel )
52 // TODO Switch between different layouts
54 visualModel.SetGlyphs( &glyphs[0],
56 &charactersPerGlyph[0],
59 UpdateGlyphPositions( boundingBox, visualModel );
62 void UpdateGlyphPositions( const Vector2& boundingBox, VisualModel& visualModel )
64 if( LayoutEngine::SINGLE_LINE_BOX == mLayout )
66 SingleLineLayout( boundingBox, visualModel );
70 MultiLineLayout( boundingBox, visualModel );
74 // TODO - Rewrite this to handle bidi
75 void SingleLineLayout( const Vector2& boundingBox, VisualModel& visualModel )
77 Length glyphCount = visualModel.GetNumberOfGlyphs();
79 std::vector<Vector2> glyphPositions;
80 glyphPositions.reserve( glyphCount );
84 // FIXME Single font assumption
85 Text::FontMetrics fontMetrics;
87 visualModel.GetGlyphs( 0, &firstGlyph, 1 );
88 mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
91 float penY( fontMetrics.ascender ); // Move to baseline
93 for( unsigned int i=0; i<glyphCount; ++i )
96 visualModel.GetGlyphs( i, &glyph, 1 );
98 glyphPositions.push_back( Vector2( penX + glyph.xBearing,
99 penY - glyph.yBearing ) );
101 penX += glyph.advance;
104 visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
108 // TODO - Rewrite this to handle bidi
109 void MultiLineLayout( const Vector2& boundingBox, VisualModel& visualModel )
111 Length glyphCount = visualModel.GetNumberOfGlyphs();
113 std::vector<Vector2> glyphPositions;
114 glyphPositions.reserve( glyphCount );
118 // FIXME Single font assumption
119 Text::FontMetrics fontMetrics;
120 GlyphInfo firstGlyph;
121 visualModel.GetGlyphs( 0, &firstGlyph, 1 );
122 mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
125 float penY( fontMetrics.ascender ); // Move to baseline
128 while( i < glyphCount )
130 // Skip initial whitespace
131 for( ; i<glyphCount; ++i )
134 visualModel.GetGlyphs( i, &glyph, 1 );
136 if( glyph.width > 0 &&
143 glyphPositions.push_back( Vector2( penX + glyph.xBearing,
144 penY - glyph.yBearing ) );
148 // Find last glyph for the next line
149 unsigned int endIndex = i;
150 float endPenX = penX;
152 for( ; j<glyphCount; ++j )
155 visualModel.GetGlyphs( j, &glyph, 1 );
157 endPenX += glyph.advance;
159 if( glyph.width <= 0 ||
162 // Potential line end found
165 else if( endPenX > boundingBox.width )
171 // If end of text or no whitespace found
172 if( glyphCount == j ||
178 for( ; i<endIndex; ++i )
181 visualModel.GetGlyphs( i, &glyph, 1 );
183 glyphPositions.push_back( Vector2( penX + glyph.xBearing,
184 penY - glyph.yBearing ) );
186 penX += glyph.advance;
191 penY += fontMetrics.height;
194 visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
198 unsigned int mLayout;
200 TextAbstraction::FontClient mFontClient;
203 LayoutEngine::LayoutEngine()
206 mImpl = new LayoutEngine::Impl();
209 LayoutEngine::~LayoutEngine()
214 void LayoutEngine::SetLayout( Layout layout )
216 mImpl->mLayout = layout;
219 void LayoutEngine::UpdateVisualModel( const Vector2& boundingBox,
220 const Vector<GlyphInfo>& glyphs,
221 const Vector<CharacterIndex>& characterIndices,
222 const Vector<Length>& charactersPerGlyph,
223 VisualModel& visualModel )
225 mImpl->UpdateVisualModel( boundingBox,
234 } // namespace Toolkit