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/internal/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/internal/text/logical-model.h>
27 #include <dali-toolkit/internal/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 );
106 visualModel.SetActualSize( Vector2(penX, fontMetrics.height) );
110 // TODO - Rewrite this to handle bidi
111 void MultiLineLayout( const Vector2& boundingBox, VisualModel& visualModel )
113 Length glyphCount = visualModel.GetNumberOfGlyphs();
115 std::vector<Vector2> glyphPositions;
116 glyphPositions.reserve( glyphCount );
122 // FIXME Single font assumption
123 Text::FontMetrics fontMetrics;
124 GlyphInfo firstGlyph;
125 visualModel.GetGlyphs( &firstGlyph, 0, 1 );
126 mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
129 float penY( fontMetrics.ascender ); // Move to baseline
132 while( i < glyphCount )
134 // Skip initial whitespace
135 for( ; i<glyphCount; ++i )
138 visualModel.GetGlyphs( &glyph, i, 1 );
140 if( glyph.width > 0 &&
147 glyphPositions.push_back( Vector2( penX + glyph.xBearing,
148 penY - glyph.yBearing ) );
152 // Find last glyph for the next line
153 unsigned int endIndex = i;
154 float endPenX = penX;
156 for( ; j<glyphCount; ++j )
159 visualModel.GetGlyphs( &glyph, j, 1 );
161 endPenX += glyph.advance;
163 if( glyph.width <= 0 ||
166 // Potential line end found
169 else if( endPenX > boundingBox.width )
175 actualSize.width = ( actualSize.width < endPenX ) ? endPenX : actualSize.width;
177 // If end of text or no whitespace found
178 if( glyphCount == j ||
184 for( ; i<endIndex; ++i )
187 visualModel.GetGlyphs( &glyph, i, 1 );
189 glyphPositions.push_back( Vector2( penX + glyph.xBearing,
190 penY - glyph.yBearing ) );
192 penX += glyph.advance;
197 penY += fontMetrics.height;
199 actualSize.height += fontMetrics.height;
202 visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
204 visualModel.SetActualSize( actualSize );
208 unsigned int mLayout;
210 TextAbstraction::FontClient mFontClient;
213 LayoutEngine::LayoutEngine()
216 mImpl = new LayoutEngine::Impl();
219 LayoutEngine::~LayoutEngine()
224 void LayoutEngine::SetLayout( Layout layout )
226 mImpl->mLayout = layout;
229 unsigned int LayoutEngine::GetLayout() const
231 return mImpl->mLayout;
234 void LayoutEngine::UpdateVisualModel( const Vector2& boundingBox,
235 const Vector<GlyphInfo>& glyphs,
236 const Vector<CharacterIndex>& characterIndices,
237 const Vector<Length>& charactersPerGlyph,
238 VisualModel& visualModel )
240 mImpl->UpdateVisualModel( boundingBox,
249 } // namespace Toolkit