1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     font_PackedFont.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 25674 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FONT_FONT_PACKED_FONT_H_
17 #define NN_FONT_FONT_PACKED_FONT_H_
18 
19 #include <nn/types.h>
20 #include <nn/font/font_ArchiveFontBase.h>
21 
22 namespace nn {
23 namespace font {
24 
25 
26 //---------------------------------------------------------------------------
27 //
28 //
29 //---------------------------------------------------------------------------
30 class PackedFont : public ArchiveFontBase
31 {
32 public:
33     /* ------------------------------------------------------------------------
34             Functions
35        ------------------------------------------------------------------------ */
36     //
37     //
38 
39     //
40                         PackedFont();
41 
42     //
43     virtual             ~PackedFont();
44 
45     //
46 
47     //
48     //
49 
50     //
51     //
52     //
53     //
54     //
55     //
56     //
57     //
58     //
59     //
60     //
GetRequireBufferSize(const void * bfnt,int numSheetCache)61     static u32      GetRequireBufferSize(
62                         const void* bfnt,
63                         int         numSheetCache
64     )
65     {
66         return GetRequireBufferSize(bfnt, LOAD_GLYPH_ALL, numSheetCache);
67     }
68 
69     //
70     //
71     //
72     //
73     //
74     //
75     //
76     //
77     //
78     //
79     //
80     //
81     //
82     //
83     static u32      GetRequireBufferSize(
84                         const void* bfnt,
85                         const char* glyphGroups,
86                         int         numSheetCache);
87 
88     //
89     //
90     //
91     //
92     //
93     //
94     //
95     //
96     //
97     //
98     //
99     //
GetRequireBufferSize(const void * bfnt,f32 rateSheetCache)100     static u32      GetRequireBufferSize(
101                         const void* bfnt,
102                         f32         rateSheetCache
103     )
104     {
105         return GetRequireBufferSize(bfnt, LOAD_GLYPH_ALL, rateSheetCache);
106     }
107 
108     //
109     //
110     //
111     //
112     //
113     //
114     //
115     //
116     //
117     //
118     //
119     //
120     //
121     static u32      GetRequireBufferSize(
122                         const void* bfnt,
123                         const char* glyphGroups,
124                         f32         rateSheetCache
125                     );
126 
127     //
128     //
129     //
130     //
131     //
132     //
133     //
134     //
135     //
136     //
137     //
138     //
139     bool            Construct(
140                         void*               pBuffer,
141                         u32                 bufferSize,
142                         const void*         bfnt,
143                         const char*         glyphGroups = LOAD_GLYPH_ALL
144                     );
145 
146     //
147     //
148     //
149     //
150     //
151     //
152     //
153     //
154     //
155     void            InitStreamingConstruct(
156                         ConstructContext*   pContext,
157                         void*               pBuffer,
158                         u32                 bufferSize,
159                         const char*         glyphGroups = LOAD_GLYPH_ALL
160                     );
161 
162     //
163     //
164     //
165     //
166     //
167     //
168     //
169     //
170     //
171     ConstructResult StreamingConstruct(
172                         ConstructContext*   pContext,
173                         const void*         stream,
174                         u32                 streamSize);
175 
176     //
177     //
178     //
179     //
180     //
181     void*           Destroy();
182 
183     //
184 
185 
186     //
187     //
188 
189     //
190     //
191     //
192     //
GetNumCache()193     int             GetNumCache() const { return m_NumSheetCache; }
194 
195     //
196     //
197     //
198     //
199     //
200 	//
201     //
202     bool            PreloadSheet(CharCode c);
203 
204     //
205     //
206     //
207     //
208     //
209     //
210     //
211     //
212     bool            LockSheet(CharCode c);
213 
214     //
215     //
216     //
217     //
218     //
219     //
220     //
221     bool            UnlockSheet(
222                         CharCode    c,
223                         bool        bUnload = true
224                     );
225 
226     //
227     //
228     void            UnlockSheetAll();
229 
230     //
231 
232 
233     //
234     //
235 
236     //
237     //
238     //
239     //
240     //
241     virtual void    GetGlyph(
242                         Glyph*      glyph,
243                         CharCode    c
244                     ) const;
245 
246     //
247 
248 
249 protected:
250 
251     //
252     //
253 
254     virtual int             GetActiveSheetNum() const;
255 
256     //
257 
258 
259 private:
260     /* ------------------------------------------------------------------------
261             Types
262        ------------------------------------------------------------------------ */
263     // Class for managing Least Recently Used
264     class LRUManager
265     {
266     public:
267         struct OrderNode
268         {
269             u16 prevIndex;
270             u16 nextIndex;
271         };
272 
GetRequireBufferSize(int numNode)273         static u32          GetRequireBufferSize(int numNode)
274         {
275             return sizeof(OrderNode) * (numNode + 1);
276         }
277 
278         //
279         //
280         //
281         //
282         //
283         void                Init(
284                                 void*   buffer,
285                                 int     numOrderNode);
286 
287         //
288         //
289         //
290         //
291         void                Use(int index);
292 
293         //
294         //
295         //
296         //
297         void                Unuse(int index);
298 
299         //
300         //
301         //
302         //
303         void                Lock(int index);
304 
305         //
306         //
307         //
308         //
309         void                Unlock(int index);
310 
GetLastIndex()311         int                 GetLastIndex() const    { return GetRootNode().prevIndex; }
312 
IsLocked(int index)313         bool                IsLocked(int index) const
314         {
315             const OrderNode& node = GetNode(index);
316             return IsLockedNode(node);
317         }
318 
GetNumLocked()319         int                 GetNumLocked() const    { return mNumLockedNode; }
320 
321     private:
IsLockedNode(const OrderNode & node)322         bool                IsLockedNode(const OrderNode& node) const
323         {
324             NN_ASSERT( ! (node.prevIndex == LOCKED_INDEX) ^ (node.nextIndex == LOCKED_INDEX) );
325             return (node.prevIndex == LOCKED_INDEX);
326         }
327 
MarkLocked(OrderNode & node)328         void                MarkLocked(OrderNode& node) const
329         {
330             node.prevIndex = LOCKED_INDEX;
331             node.nextIndex = LOCKED_INDEX;
332         }
333 
Unlink(OrderNode & node)334         void                Unlink(OrderNode& node)
335         {
336             OrderNode& prev = GetNode(node.prevIndex);
337             OrderNode& next = GetNode(node.nextIndex);
338             prev.nextIndex = node.nextIndex;
339             next.prevIndex = node.prevIndex;
340         }
341 
GetRootNode()342         OrderNode&          GetRootNode()           { return GetNode(mNumOrderNode); }
343 
GetRootNode()344         const OrderNode&    GetRootNode() const     { return GetNode(mNumOrderNode); }
345 
GetNode(int index)346         OrderNode& GetNode(int index)               { return mpOrderNodeArray[index]; }
347 
GetNode(int index)348         const OrderNode& GetNode(int index) const   { return mpOrderNodeArray[index]; }
349 
350     private:
351         static const u16    LOCKED_INDEX  = 0xFFFF;
352 
353         OrderNode*          mpOrderNodeArray;
354         u16                 mNumOrderNode;
355         u16                 mNumLockedNode;
356     };
357 
358 
359     /* ------------------------------------------------------------------------
360             Constants
361        ------------------------------------------------------------------------ */
362     static const u16 SHEET_INDEX_NOT_LOADED = 0xFFFF;
363 
364 
365     /* ------------------------------------------------------------------------
366             Functions
367        ------------------------------------------------------------------------ */
368     //---- Gets glyphs
369 
370     //
371     //
372     //
373     //
374     //
375     //
376     //
377     void                MakeGlyph(
378                             Glyph*      glyph,
379                             GlyphIndex  gindex,
380                             int         cacheIndex
381                         ) const;
382 
383     //---- Decompresses sheet
384 
385     //
386     //
387     //
388     //
389     //
390     //
391     int                 LoadSheet(int compIndex) const;
392 
393     //
394     //
395     //
396     //
397     void                UnloadSheet(int compIndex) const;
398 
399     //---- Manages sheet state
400 
401     //
402     //
403     //
404     //
405     //
406     //
407     //
408     int                 GetSheetIndex(CharCode c) const;
409 
410     //
411     //
412     //
413     //
414     //
415     //
416     //
417     int                 CalcSheetIndex(GlyphIndex index) const;
418 
419     //
420     //
421     //
422     //
423     //
424     //
425     //
426     //
427     //
428     int                 GetCacheIndex(int compIndex) const;
429 
430     //
431     //
432     //
433     //
434     //
435     //
436     //
437     //
438     //
439     //
440     int                 GetCacheUser(int cacheIndex) const;
441 
442     //
443     //
444     //
445     //
446     //
447     //
448     //
449     void                SetCacheUser(
450                             int compIndex,
451                             int cacheIndex
452                         ) const;
453 
454     //
455     //
456     //
457     //
458     //
459     //
460     void                ResetCacheUser(
461                             int compIndex,
462                             int cacheIndex
463                         ) const;
464 
465     //---- Gets sheet
466 
467     //
468     //
469     //
470     //
471     //
472     //
473     u8*                 GetLoadedSheet(int cacheIndex) const;
474 
475     //
476     //
477     //
478     //
479     //
480     //
481     const u8*           GetCompSheet(int compIndex) const;
482 
483     //---- Memory allocation
484 
485     //
486     //
487     //
488     //
489     //
490     //
491     //
492     //
493     //
494     //
495     //
496     //
497     u16*                AssignMemory(
498                             u8* buffer,
499                             u32 bufferSize,
500                             u32 numResSheet,
501                             u32 numLoadSheet,
502                             u32 sheetSize);
503 
504 
505     //---- Necessary memory size calculation
506 
507     //
508     //
509     //
510     //
511     //
512     //
513     //
514     //
515     //
516     static u32          CalcCopySize(
517                             const FontGlyphGroupsAcs&   gg,
518                             const char*                 glyphGroups,
519                             int*                        pNumLoadSheet);
520 
521     //
522     //
523     //
524     //
525     //
526     //
527     //
528     static u32          CalcCacheSize(
529                             const FontGlyphGroupsAcs&   gg,
530                             int                         numSheetCache);
531 
532     //---- Streaming process
533 
534     //
535     //
536     //
537     //
538     //
539     //
540     //
541     ConstructResult     ConstructOpAnalyzeGLGRPacked(
542                             ConstructContext*   pContext,
543                             CachedStreamReader* pStream);
544 
545     //
546     //
547     //
548     //
549     //
550     //
551     //
552     static ConstructResult
553                         ConstructOpPrepairCopyPackedSheet(
554                             ConstructContext*   pContext,
555                             CachedStreamReader* pStream);
556 
557     /* ------------------------------------------------------------------------
558             Variables
559        ------------------------------------------------------------------------ */
560     //
561     mutable LRUManager  m_LRUMan;
562 
563     u16                 m_NumCompSheet;         //
564     u16                 m_NumSheetCache;        //
565 
566     //
567     u16*                m_pCacheIndexArray;     // mNumLoadedSheet
568 
569     //
570     u16*                m_pCacheUserArray;      // m_NumSheetCache
571 
572     //
573     const u8**          m_pCompSheetArray;      // mNumLoadedSheet
574 
575     //
576     u8*                 m_pSheetCache;          // sheetSize * m_NumSheetCache
577 };
578 
579 }   // namespace font
580 }   // namespace nn
581 
582 #endif //  NN_FONT_FONT_PACKED_FONT_H_
583