Change FontMetrics format to match GlyphMetrics
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / public-api / text / text-controller.cpp
1 /*
2  * Copyright (c) 2015 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 // CLASS HEADER
19 #include <dali-toolkit/public-api/text/text-controller.h>
20
21 // INTERNAL INCLUDES
22 #include <dali-toolkit/public-api/text/character-set-conversion.h>
23 #include <dali-toolkit/public-api/text/logical-model.h>
24 #include <dali-toolkit/public-api/text/text-view.h>
25 #include <dali-toolkit/public-api/text/visual-model.h>
26
27 namespace Dali
28 {
29
30 namespace Toolkit
31 {
32
33 namespace Text
34 {
35
36 struct Controller::Impl
37 {
38   Impl()
39   {
40     mLogicalModel = LogicalModel::New();
41     mVisualModel  = VisualModel::New();
42
43     mView.SetVisualModel( mVisualModel );
44
45     mFontClient = TextAbstraction::FontClient::Get();
46   }
47
48   LogicalModelPtr mLogicalModel;
49   VisualModelPtr  mVisualModel;
50
51   View mView;
52
53   TextAbstraction::FontClient mFontClient;
54 };
55
56 ControllerPtr Controller::New()
57 {
58   return ControllerPtr( new Controller() );
59 }
60
61 void Controller::SetText( const std::string& text )
62 {
63   //  Convert text into UTF-32
64   Vector<Character> utf32Characters;
65   utf32Characters.Resize( text.size() );
66
67   // This is a bit horrible but std::string returns a (signed) char*
68   const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
69
70   Length characterCount = Utf8ToUtf32( utf8, text.size(), &utf32Characters[0] );
71
72   // Manipulate the logical model
73   mImpl->mLogicalModel->SetText( &utf32Characters[0], characterCount );
74
75   UpdateVisualModel();
76 }
77
78 View& Controller::GetView()
79 {
80   return mImpl->mView;
81 }
82
83 Controller::~Controller()
84 {
85   delete mImpl;
86 }
87
88 Controller::Controller()
89 : mImpl( NULL )
90 {
91   mImpl = new Controller::Impl();
92 }
93
94 // TODO - Move this with LayoutEngine
95 void Controller::UpdateVisualModel()
96 {
97   if( mImpl->mLogicalModel &&
98       mImpl->mVisualModel )
99   {
100     const LogicalModel& logicalModel = *(mImpl->mLogicalModel);
101     VisualModel& visualModel = *(mImpl->mVisualModel);
102
103     TextAbstraction::FontId fontId = mImpl->mFontClient.GetFontId( "/usr/share/fonts/truetype/ubuntu-font-family/UbuntuMono-R.ttf", 13*64 );
104
105     const Length characterCount = logicalModel.GetNumberOfCharacters();
106
107     Vector<GlyphInfo> glyphs;
108     glyphs.Reserve( characterCount );
109
110     Vector<CharacterIndex> characterIndices;
111     characterIndices.Reserve( characterCount );
112
113     std::vector<Length> charactersPerGlyph;
114     charactersPerGlyph.assign( characterCount, 1 );
115
116     for( unsigned int i=0; i<characterCount; ++i )
117     {
118       Character charcode;
119       logicalModel.GetText( i, &charcode, 1 );
120
121       // TODO - Perform shaping to get correct glyph indices
122       GlyphIndex glyphIndex = mImpl->mFontClient.GetGlyphIndex( fontId, charcode );
123
124       glyphs.PushBack( GlyphInfo(fontId, glyphIndex) );
125       characterIndices.PushBack( 1 );
126     }
127
128     if( mImpl->mFontClient.GetGlyphMetrics( &glyphs[0], glyphs.Size() ) )
129     {
130       visualModel.SetGlyphs( &glyphs[0],
131                              &characterIndices[0],
132                              &charactersPerGlyph[0],
133                              characterCount );
134
135       UpdateVisualPositions();
136     }
137   }
138 }
139
140 // TODO - Move this with LayoutEngine
141 void Controller::UpdateVisualPositions()
142 {
143   if( mImpl->mVisualModel )
144   {
145     VisualModel& visualModel = *(mImpl->mVisualModel);
146
147     Length glyphCount = visualModel.GetNumberOfGlyphs();
148
149     std::vector<Vector2> glyphPositions;
150     glyphPositions.reserve( glyphCount );
151
152     if( glyphCount > 0 )
153     {
154       // FIXME Single font assumption
155       Text::FontMetrics fontMetrics;
156       GlyphInfo firstGlyph;
157       visualModel.GetGlyphs( 0, &firstGlyph, 1 );
158       mImpl->mFontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics );
159
160       float penX( 0 );
161       float penY( fontMetrics.ascender ); // Move to baseline
162
163       for( unsigned int i=0; i<glyphCount; ++i )
164       {
165         GlyphInfo glyph;
166         visualModel.GetGlyphs( i, &glyph, 1 );
167
168         glyphPositions.push_back( Vector2( penX + glyph.xBearing,
169                                            penY - glyph.yBearing ) );
170
171         penX += glyph.advance;
172       }
173
174       visualModel.SetGlyphPositions( &glyphPositions[0], glyphCount );
175     }
176   }
177 }
178
179 } // namespace Text
180
181 } // namespace Toolkit
182
183 } // namespace Dali