Optimized shader hash to not allocate memory or perform multiple passes of string...
[platform/core/uifw/dali-core.git] / dali / internal / event / text / font-factory.cpp
1 /*
2  * Copyright (c) 2014 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/internal/event/text/font-factory.h>
20
21 // INTERNAL HEADERS
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/internal/event/resources/resource-client.h>
25 #include <dali/internal/event/text/atlas/glyph-atlas-manager.h>
26 #include <dali/internal/common/dali-hash.h>
27
28
29 using namespace Dali::Integration;
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 FontFactory::FontFactory(ResourceClient& resourceClient)
38 : mResourceClient(resourceClient),
39   mFontCount( 0 ),
40   mHorizontalDpi( 0.f ),
41   mVerticalDpi( 0.f )
42 {
43   mAtlasManager = new GlyphAtlasManager( *this );
44
45   mResourceClient.SetGlyphLoadObserver( &mAtlasManager->GetLoadObserver() );
46 }
47
48 FontFactory::~FontFactory()
49 {
50   mResourceClient.SetGlyphLoadObserver( NULL );
51
52   delete mAtlasManager;
53 }
54
55 FontMetricsIntrusivePtr FontFactory::GetFontMetrics( const std::string& fontFamily, const std::string& fontStyle )
56 {
57
58   std::size_t hashValue = CalculateHash(fontFamily,fontStyle);
59   FontMetricsIntrusivePtr metrics;
60
61   FontMetricsIter iter = mMetricsCache.find( hashValue );
62   if ( iter == mMetricsCache.end() )
63   {
64     metrics = FontMetrics::New( Vector2(mHorizontalDpi, mVerticalDpi), hashValue, mFontCount, fontFamily, fontStyle );
65     mFontCount++;
66
67     // load the global metrics
68     metrics->LoadGlobalMetrics();
69
70     // insert into a lookup table.
71     mMetricsCache.insert( FontMetricsPair( hashValue, metrics ) );
72
73   }
74   else
75   {
76     metrics = iter->second;
77   }
78   // increase the number of fonts using this metrics
79   metrics->IncreaseFontCount();
80
81   return metrics;
82 }
83
84 void FontFactory::RemoveFontMetrics(const std::string& fontFamily,
85                                     const std::string& fontStyle)
86 {
87   std::size_t hashValue = CalculateHash(fontFamily, fontStyle);
88   FontMetricsIntrusivePtr metrics;
89
90   FontMetricsIter iter = mMetricsCache.find( hashValue );
91   if ( iter != mMetricsCache.end() )
92   {
93     (*iter).second->DecreaseFontCount();
94   }
95   // for now we keep metrics in memory even if ref count = 0
96   // @todo implement a scheme to delete metrics that haven't been used for
97   // a certain amount of time
98 }
99
100
101 void FontFactory::GetFontInformation( FontId fontId,
102                                       std::string& family,
103                                       std::string& style,
104                                       float& maxGlyphWidth,
105                                       float& maxGlyphHeight) const
106 {
107   // typically we only have around 4 fonts in the cache,
108   // and GetFontInformation is only called a couple of times on startup
109   // so just iterate over the map, manually searching for the font id
110   FontMetricsMap::const_iterator endIter = mMetricsCache.end();
111
112   for( FontMetricsMap::const_iterator iter =  mMetricsCache.begin(); iter != endIter; ++iter)
113   {
114     const FontMetrics* metric( (*iter).second.Get() );
115
116     if( metric->GetFontId() == fontId)
117     {
118       family = metric->GetFontFamilyName();
119       style = metric->GetFontStyleName();
120       metric->GetMaximumGylphSize( maxGlyphWidth, maxGlyphHeight );
121       return;
122     }
123   }
124   DALI_ASSERT_ALWAYS( 0 && "Font id not found");
125 }
126
127 void FontFactory::SendTextRequests()
128 {
129   mAtlasManager->SendTextRequests();
130 }
131
132 GlyphAtlasManagerInterface& FontFactory::GetAtlasManagerInterface()
133 {
134   return *mAtlasManager;
135 }
136
137 void FontFactory::SetDpi( float horizontalDpi, float verticalDpi )
138 {
139   mHorizontalDpi = horizontalDpi;
140   mVerticalDpi = verticalDpi;
141 }
142
143 } // namespace Internal
144
145 } // namespace Dali