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( &firstGlyph, 0, 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( &glyph, i, 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 );
120 // FIXME Single font assumption
121 Text::FontMetrics fontMetrics;
122 GlyphInfo firstGlyph;
123 visualModel.GetGlyphs( &firstGlyph, 0, 1 );
124 mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
127 float penY( fontMetrics.ascender ); // Move to baseline
130 while( i < glyphCount )
132 // Skip initial whitespace
133 for( ; i<glyphCount; ++i )
136 visualModel.GetGlyphs( &glyph, i, 1 );
138 if( glyph.width > 0 &&
145 glyphPositions.push_back( Vector2( penX + glyph.xBearing,
146 penY - glyph.yBearing ) );
150 // Find last glyph for the next line
151 unsigned int endIndex = i;
152 float endPenX = penX;
154 for( ; j<glyphCount; ++j )
157 visualModel.GetGlyphs( &glyph, j, 1 );
159 endPenX += glyph.advance;
161 if( glyph.width <= 0 ||
164 // Potential line end found
167 else if( endPenX > boundingBox.width )
169 actualSize.width = ( actualSize.width < endPenX - glyph.advance ) ? endPenX - glyph.advance : actualSize.width;
174 // If end of text or no whitespace found
175 if( glyphCount == j ||
181 for( ; i<endIndex; ++i )
184 visualModel.GetGlyphs( &glyph, i, 1 );
186 glyphPositions.push_back( Vector2( penX + glyph.xBearing,
187 penY - glyph.yBearing ) );
189 penX += glyph.advance;
194 penY += fontMetrics.height;
196 actualSize.height += fontMetrics.height;
199 visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
201 visualModel.SetActualSize( actualSize );
205 unsigned int mLayout;
207 TextAbstraction::FontClient mFontClient;
210 LayoutEngine::LayoutEngine()
213 mImpl = new LayoutEngine::Impl();
216 LayoutEngine::~LayoutEngine()
221 void LayoutEngine::SetLayout( Layout layout )
223 mImpl->mLayout = layout;
226 void LayoutEngine::UpdateVisualModel( const Vector2& boundingBox,
227 const Vector<GlyphInfo>& glyphs,
228 const Vector<CharacterIndex>& characterIndices,
229 const Vector<Length>& charactersPerGlyph,
230 VisualModel& visualModel )
232 mImpl->UpdateVisualModel( boundingBox,
241 } // namespace Toolkit