Merge "Button Resizing in SB" into tizen_2.1
[framework/osp/uifw.git] / src / graphics / FGrp_FontCache.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /*
19  * @file        FGrp_FontCache.cpp
20  * @brief       This is the cpp file for _FontCache class.
21  *
22  */
23
24 #include <new>
25 #include <list>
26
27 #include <FBaseErrors.h>
28
29 #include <FBaseSysLog.h>
30
31 #include "FGrp_FontCache.h"
32 #include "FGrp_FontRsrcManager.h"
33 #include "util/FGrp_UtilType.h"
34
35 #define __pBspCache ((_BspTree<unsigned long, void*>*)__pCache)
36
37
38 namespace // unnamed
39 {
40
41 inline bool
42 _MakeId(unsigned long character, Tizen::Graphics::_Util::FixedPoint26_6 size, int style, unsigned long& out)
43 {
44         int fixedSize = size >> 5;
45
46         if (((character >> 22) > 0) || ((fixedSize >> 8) > 0) || ((style >> 2) > 0))
47         {
48                 return false;
49         }
50
51         out = (character << 10) | ((fixedSize & 0xFF) << 2) | (style & 0x3);
52
53         return true;
54 }
55
56 template <typename Type>
57 inline unsigned long _MakeIndex(Type id, int level);
58
59 template <>
60 inline unsigned long
61 _MakeIndex<unsigned long>(unsigned long id, int level)
62 {
63         typedef unsigned long TBase;
64
65         TBase index = (id & (0x80808080 >> level)) >> ((sizeof(TBase) * 2 - 1) - level);
66
67         index |= (index >> 7);
68         index |= (index >> 14);
69         index |= (index >> 21);
70
71         return (index & 0x0000000F);
72 }
73
74 template <typename TId, typename TData>
75 class _BspTree
76 {
77         enum
78         {
79                 MAX_CHILD = 16,
80                 MAX_LEVEL = sizeof(TId) * 2
81         };
82
83 public:
84         _BspTree(int level = 0)
85                 : __level(level)
86                 , __data(null)
87         {
88                 for (int i = 0; i < MAX_CHILD; i++)
89                 {
90                         __child[i] = null;
91                 }
92         }
93
94         ~_BspTree(void)
95         {
96                 __Destroy();
97         }
98
99         bool Add(TId id, TData data)
100         {
101                 if (__IsEdge())
102                 {
103                         // shkim, TODO.
104                         // collision should not be occured.
105                         __data = data;
106                         return true;
107                 }
108
109                 unsigned long index = __GetIndex(id);
110
111                 if (__child[index] == null)
112                 {
113                         __child[index] = new (std::nothrow) _BspTree<TId, TData>(__level + 1);
114                         if (__child[index] == null)
115                         {
116                                 return false;
117                         }
118                 }
119
120                 return __child[index]->Add(id, data);
121         }
122
123         TData Find(TId id) const
124         {
125                 if (__data != null)
126                 {
127                         return __data;
128                 }
129
130                 unsigned long index = __GetIndex(id);
131
132                 if (__child[index])
133                 {
134                         return __child[index]->Find(id);
135                 }
136
137                 return 0;
138         }
139
140         TData Remove(TId id)
141         {
142                 TData found = 0;
143                 __Remove(id, found);
144                 return found;
145         }
146
147 private:
148         void __Destroy(void)
149         {
150                 for (int i = 0; i < MAX_CHILD; i++)
151                 {
152                         delete __child[i];
153                         __child[i] = null;
154                 }
155
156                 Tizen::Graphics::_FontRsrcManager::GetInstance().GetMemoryManager().Free(__data);
157
158                 __data = null;
159         }
160
161         bool __IsEdge(void) const
162         {
163                 return (__level >= MAX_LEVEL);
164         }
165
166         inline unsigned long __GetIndex(TId id) const
167         {
168                 return _MakeIndex(id, __level);
169         }
170
171         bool __Remove(TId id, TData& found)
172         {
173                 if (__data != null)
174                 {
175                         found = __data;
176                         return true;
177                 }
178
179                 unsigned long index = __GetIndex(id);
180
181                 if (__child[index])
182                 {
183                         if (__child[index]->__Remove(id, found))
184                         {
185                                 delete __child[index];
186                                 __child[index] = null;
187
188                                 unsigned long check = 0;
189
190                                 for (int i = 0; i < MAX_CHILD; i++)
191                                 {
192                                         check |= (unsigned long)__child[i];
193                                 }
194
195                                 return (check == 0);
196                         }
197                 }
198
199                 return false;
200         }
201
202         int __level;
203         TData __data;
204         _BspTree<TId, TData>* __child[MAX_CHILD];
205 };
206
207 }
208
209 namespace Tizen { namespace Graphics
210 {
211
212 class _FontCacheImpl
213 {
214 public:
215         _FontCacheImpl(void)
216         {
217         }
218
219         virtual ~_FontCacheImpl(void)
220         {
221         }
222
223         void Add(unsigned long id)
224         {
225                 __leastRecentlyUsedKeyList.push_back(id);
226         }
227
228         void Remove(unsigned long id)
229         {
230                 __leastRecentlyUsedKeyList.remove(id);
231         }
232
233         void RemoveFirst(void)
234         {
235                 __leastRecentlyUsedKeyList.pop_front();
236         }
237
238         void RemoveAll(void)
239         {
240                 __leastRecentlyUsedKeyList.clear();
241         }
242
243         unsigned long GetFirst(void)
244         {
245                 return __leastRecentlyUsedKeyList.front();
246         }
247
248         bool IsEmpty(void)
249         {
250                 return __leastRecentlyUsedKeyList.empty();
251         }
252
253 private:
254         //_BspTree<unsigned long, void*> bspTree;
255         std::list<unsigned long> __leastRecentlyUsedKeyList;
256 };
257
258 _FontCache::_FontCache(void)
259         : __pCache((void*) new (std::nothrow) _BspTree<unsigned long, void*>())
260 {
261         __pFontCacheImpl = new (std::nothrow) _FontCacheImpl;
262 }
263
264 _FontCache::~_FontCache(void)
265 {
266         delete reinterpret_cast<_BspTree<unsigned long, void*>*>(__pCache);
267         __pCache = null;
268
269         delete __pFontCacheImpl;
270         __pFontCacheImpl = null;
271 }
272
273 bool
274 _FontCache::IsValid(void) const
275 {
276         return (this->__pCache && this->__pFontCacheImpl);
277 }
278
279 bool
280 _FontCache::Find(unsigned long character, _Util::FixedPoint26_6 size, int style, _IFont::Glyph** pOut)
281 {
282         unsigned long id = 0;
283         bool rtn = _MakeId(character, size, style, id);
284
285         if (!rtn)
286         {
287                 return false;
288         }
289
290         _IFont::Glyph* p = (_IFont::Glyph*)__pBspCache->Find(id);
291
292         if (p != null)
293         {
294                 *pOut = p;
295                 return true;
296         }
297         else
298         {
299                 return false;
300         }
301 }
302
303 bool
304 _FontCache::Add(unsigned long character, _Util::FixedPoint26_6 size, int style, _IFont::Glyph* pGlyph)
305 {
306         unsigned long bufferSize = 0;
307         unsigned long id = 0;
308         bool rtn = _MakeId(character, size, style, id);
309         if (!rtn)
310         {
311                 // Requested glyph is not cachable
312                 return false;
313         }
314
315         bufferSize = sizeof(_IFont::Glyph) + (pGlyph->image.bytesPerLine * pGlyph->image.height);
316         _IFont::Glyph* pGlyphCache = (_IFont::Glyph*) _FontRsrcManager::GetInstance().GetMemoryManager().Alloc(bufferSize);
317         if (pGlyphCache == null)
318         {
319                 // secure memory
320                 bool rtn = _FontRsrcManager::GetInstance().RemoveMemory(bufferSize);
321
322                 if (!rtn)
323                 {
324                         return false;
325                 }
326
327                 pGlyphCache = (_IFont::Glyph*) _FontRsrcManager::GetInstance().GetMemoryManager().Alloc(bufferSize);
328
329                 if (pGlyphCache == null)
330                 {
331                         return false;
332                 }
333         }
334
335         memcpy(pGlyphCache, pGlyph, sizeof(_IFont::Glyph));
336         pGlyphCache->image.pBitmap = (unsigned char*)((pGlyphCache) + 1);
337         memcpy(pGlyphCache->image.pBitmap, pGlyph->image.pBitmap, pGlyph->image.bytesPerLine * pGlyph->image.height);
338
339         if (__pBspCache->Add(id, pGlyphCache))
340         {
341                 __pFontCacheImpl->Add(id);
342                 return true;
343         }
344         else
345         {
346                 return false;
347         }
348 }
349
350 void
351 _FontCache::Remove(unsigned long character, _Util::FixedPoint26_6 size, int style)
352 {
353         unsigned long id = 0;
354         bool rtn = _MakeId(character, size, style, id);
355         if (!rtn)
356         {
357                 return;
358         }
359
360         __pBspCache->Remove(id);
361         __pFontCacheImpl->Remove(id);
362 }
363
364 void
365 _FontCache::RemoveFirst(void)
366 {
367         unsigned long id = 0;
368
369         id = __pFontCacheImpl->GetFirst();
370
371         __pBspCache->Remove(id);
372         __pFontCacheImpl->RemoveFirst();
373 }
374
375 bool
376 _FontCache::IsEmpty(void)
377 {
378         return __pFontCacheImpl->IsEmpty();
379 }
380
381 bool
382 _FontCache::Cleanup(void)
383 {
384         _BspTree<unsigned long, void*>* p = reinterpret_cast<_BspTree<unsigned long, void*>*>(__pCache);
385
386         p->~_BspTree();
387         new (p) _BspTree<unsigned long, void*>();
388
389         __pFontCacheImpl->RemoveAll();
390
391         return true;
392 }
393
394 bool
395 _FontCache::__DiscardVictim(unsigned long requestedSize)
396 {
397         return true;
398 }
399
400 bool
401 _FontCache::__RemoveId(unsigned long id)
402 {
403         _IFont::Glyph* pCachedGlyph = null;
404
405         pCachedGlyph = (_IFont::Glyph*)__pBspCache->Find(id);
406
407         if (pCachedGlyph != null)
408         {
409                 __pBspCache->Remove(id);
410
411                 return true;
412         }
413         else
414         {
415                 return false;
416         }
417 }
418
419 }} // Tizen::Graphics