1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     font_ArchiveFontBase.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: 33587 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FONT_FONT_ARCHIVE_FONT_BASE_H_
17 #define NN_FONT_FONT_ARCHIVE_FONT_BASE_H_
18 
19 #include <nn/types.h>
20 #include <nn/os.h>
21 #include <nn/math.h>
22 #include <nn/cx.h>
23 #include <nn/font/font_ResFontBase.h>
24 
25 
26 #define NN_FONT_FLOAT_ASSERT(exp)       ((void)0)
27 
28 #define NN_FONT_BUFFERSIZE_ASSERT(size) ((void)0)
29 
30 namespace nn {
31 namespace font {
32 
33 //---------------------------------------------------------------------------
34 //
35 //---------------------------------------------------------------------------
36 class ArchiveFontBase : public ResFontBase
37 {
38 public:
39     struct ConstructContext;
40 
41 protected:
42     struct CachedStreamReader
43     {
44         friend struct ConstructContext;
45 
46     public:
47         //
48         //
49         //
50         //
51         u32                 GetRemain() const;
52 
53         //
54         //
55         //
56         //
57         void                Advance(u32 dx);
58 
59         //
60         //
61         //
62         //
63         //
64         void                CopyTo(
65                                 ConstructContext*   pContext,
66                                 u32                 size);
67 
68         //
69         //
70         //
71         //
72         //
73         void                CopyTo(
74                                 void*   buf,
75                                 u32     size);
76 
77         //
78         //
79         //
80         //
81         //
82         //
83         //
84         void                MoveTo(
85                                 void*   buf,
86                                 u32     size);
87 
88         //
89         //
90         //
91         //
92         //
93         //
94         u32                 ManagedCopy(ConstructContext* pContext);
95 
96         //
97         //
98         //
99         //
HasBufDataCachedStreamReader100         bool                HasBufData() const  { return mpTempStrmBufPos < mpTempStrmBufEnd; }
101 
102         //
103         //
104         //
105         //
106         //
107         //
108         //
109         //
110         const void*         Get(u32 size);
111 
112         //
113         //
114         //
115         //
116         //
117         void                Attach(
118                                 const void* stream,
119                                 u32         streamSize);
120 
121         //
122         //
123         //
124         //
125         //
126         //
127         //
128         bool                RequestData(
129                                 ConstructContext*   pContext,
130                                 u32                 size);
131 
132         //
133         //
134         //
135         //
136         u32                 GetOffset() const;
137 
138     private:
139         //
140         void                Init();
141 
142     private:
143         const u8*           mStreamBegin;
144         const u8*           mStreamPos;
145         const u8*           mStreamEnd;
146         u8*                 mpTempStrmBuf;
147         u8*                 mpTempStrmBufPos;
148         u8*                 mpTempStrmBufEnd;
149 
150         u32                 mRequireSize;
151     };
152 
153 public:
154     /* ------------------------------------------------------------------------
155             Types
156        ------------------------------------------------------------------------ */
157     // Return value of the construction process
158     enum ConstructResult
159     {
160         CONSTRUCT_MORE_DATA,
161         CONSTRUCT_FINISH,
162         CONSTRUCT_ERROR,
163         CONSTRUCT_CONTINUE,
164         NUM_OF_CONSTRUCT_RESULT
165     };
166 
167     struct ConstructContext
168     {
169     public:
170         enum Operation
171         {
172             DISPATCH,               // 0
173             ANALYZE_FILE_HEADER,    // 1
174             ANALYZE_GLGR,           // 2
175             ANALYZE_FINF,           // 3
176             ANALYZE_CMAP,           // 4
177             ANALYZE_CWDH,           // 5
178             ANALYZE_TGLP,           // 6
179             PREPAIR_COPY_SHEET,     // 7
180             PREPAIR_EXPAND_SHEET,   // 8
181             COPY,                   // 9
182             SKIP,                   // 10
183             EXPAND,                 // 11
184             FATAL_ERROR,            // 12
185             NUM_OF_OPERATION,       //
186             INVALID_OPERATION
187         };
188 
189     public:
InitConstructContext190         void                Init(
191                                 void*   outBuffer,
192                                 u32     outBufferSize,
193                                 u16*    pAdjustTable,
194                                 u16     nSheets,
195                                 u16     nPerSheet,
196                                 u32     numBlock
197                             )
198         {
199             Init(outBuffer, outBufferSize, NULL);
200             SetGLGR(pAdjustTable, nSheets, nPerSheet, numBlock);
201         }
202 
203         void                Init(
204                                 void*       outBuffer,
205                                 u32         outBufferSize,
206                                 const char* glyphGroups);
207 
208         void                SetGLGR(
209                                 u16*        pAdjustTable,
210                                 u16         nSheets,
211                                 u16         nPerSheet,
212                                 u32         numBlock);
213 
214         // Output buffer location scan
215         template <typename PtrT>
GetCurrentPtrConstructContext216         PtrT                GetCurrentPtr()
217         {
218             return reinterpret_cast<PtrT>(targetBufferCur);
219         }
220 
GetRemainConstructContext221         u32                 GetRemain() const
222         {
223             return static_cast<u32>(targetBufferEnd - targetBufferCur);
224         }
225 
AlignConstructContext226         void                Align(u32 align)
227         {
228             targetBufferCur = reinterpret_cast<u8*>(nn::math::RoundUp(reinterpret_cast<uptr>(targetBufferCur), align));
229         }
230 
AdvanceConstructContext231         void                Advance(u32 dx) { targetBufferCur += dx; }
232 
233 #ifdef NN_DEBUG
offsetConstructContext234         u32                 offset() const
235         {
236             return static_cast<u32>(targetBufferCur - targetBuffer);
237         }
238 
sIndexConstructContext239         u32                 sIndex() const  { return sheetIndex; }
240 #endif
241 
242         // Expansion completion
243         void                Finish(
244                                 void**              ppData,
245                                 FontInformation**   ppFontInfo,
246                                 u16**               ppAdjustTable);
247 
248         // Get members
GetNumSheetsConstructContext249         u16                 GetNumSheets() const            { return numSheets; }
250 
GetNumGlyphsPerSheetConstructContext251         u16                 GetNumGlyphsPerSheet() const    { return glyphsPerSheet; }
252 
GetStreamReaderConstructContext253         CachedStreamReader& GetStreamReader()               { return streamReader; }
254 
255         cx::UncompContextHuffman*
GetUncompContextConstructContext256                             GetUncompContext()              { return extendContext; }
257 
GetGlyphGroupsConstructContext258         const char*         GetGlyphGroups() const          { return pGlyphGroups; }
259 
260         // Member increment
NextBlockConstructContext261         void                NextBlock()                     { currentBlock++; }
262 
NextSheetConstructContext263         void                NextSheet()                     { sheetIndex++; }
264 
265         // Condition tests
IsRequireSheetConstructContext266         bool                IsRequireSheet(int sheetNo) const
267         {
268             NN_ASSERT( sheetNo < numSheets );
269             return pGlyphIndexAdjustTable[sheetNo] != ADJUST_OFFSET_SHEET_NOT_LOADED;
270         }
271 
IsRequireSheetConstructContext272         bool                IsRequireSheet() const  { return IsRequireSheet(sheetIndex); }
273 
HasMoreSheetConstructContext274         bool                HasMoreSheet()   const  { return sheetIndex < numSheets; }
275 
HasMoreBlockConstructContext276         bool                HasMoreBlock()   const  { return currentBlock < resNumBlock; }
277 
278         // Common tasks
279         void                SetupCopyTask(
280                                 u32         copySize,
281                                 Operation   nextOp      = DISPATCH
282                             )
283         {
284             NN_FONT_BUFFERSIZE_ASSERT( copySize );
285             opSize = copySize;
286             op     = ConstructContext::COPY;
287             op2    = nextOp;
288         }
289 
290         void                SetupSkipTask(
291                                 u32         skipSize,
292                                 Operation   nextOp      = DISPATCH
293                             )
294         {
295             NN_FONT_BUFFERSIZE_ASSERT( skipSize );
296             opSize = skipSize;
297             op     = ConstructContext::SKIP;
298             op2    = nextOp;
299         }
300 
301         void                SetupExtendTask(
302                                 u32         extendSize,
303                                 Operation   nextOp      = DISPATCH
304                             )
305         {
306             NN_FONT_BUFFERSIZE_ASSERT( extendSize );
307             opSize = extendSize;
308             op     = ConstructContext::EXPAND;
309             op2    = nextOp;
310         }
311 
EndTaskConstructContext312         void                EndTask()               { op = op2; }
313 
TaskRemainConstructContext314         u32                 TaskRemain() const      { return opSize; }
315 
TaskProceedConstructContext316         void                TaskProceed(u32 size)   { opSize -= nn::math::Min(size, opSize); }
317 
318 
319     public:
320         FontInformation*    pFINF;
321         FontWidth*          pPrevCWDH;
322         FontCodeMap*        pPrevCMAP;
323 
324         Operation           op;
325         NN_PADDING3;
326         detail::BinaryBlockHeader
327                             header;
328 
329         u32                 streamOffset;
330 
331     private:
332         CachedStreamReader streamReader;
333         cx::UncompContextHuffman*
334                             extendContext;
335 
336         const char*         pGlyphGroups;
337         u16*                pGlyphIndexAdjustTable;
338         u8*                 targetBuffer;
339         u8*                 targetBufferEnd;
340         u8*                 targetBufferCur;
341 
342         Operation           op2;
343         NN_PADDING3;
344         u32                 opSize;
345         u32                 resNumBlock;
346         u32                 currentBlock;
347 
348         u16                 sheetIndex;
349         u16                 numSheets;
350         u16                 glyphsPerSheet;
351         u16                 padding[1];
352     };
353 
354 
355     /* ------------------------------------------------------------------------
356             Constants
357        ------------------------------------------------------------------------ */
358     static const char       LOAD_GLYPH_ALL[1];
359     static const int        HEADER_SIZE = 16 * 1024;
360 
361 
362 
363 
364     /* ------------------------------------------------------------------------
365             Functions
366        ------------------------------------------------------------------------ */
367 
368     //
369     //
370 
371     //
372                             ArchiveFontBase();
373 
374     //
375     virtual                 ~ArchiveFontBase();
376 
377     //
378 
379 
380     //
381     //
382 
383     //---- ResFontBase override
384     virtual const CharWidths
385                             GetCharWidths(CharCode c) const;
386 
387     virtual bool            HasGlyph(CharCode c) const;
388 
389     //
390 
391 
392 protected:
393     /* ------------------------------------------------------------------------
394             Types
395        ------------------------------------------------------------------------ */
396     class FontGlyphGroupsAcs
397     {
398     public:
399         explicit            FontGlyphGroupsAcs(const void* brfnt);
400 
GetNumBlock()401         u16                 GetNumBlock() const     { return mpHeader->dataBlocks; }
402 
GetFileSize()403         u32                 GetFileSize() const     { return mpHeader->fileSize; }
404 
GetGLGRSize()405         u32                 GetGLGRSize() const     { return mpData->header.size; }
406 
GetSetName(int setNo)407         const char*         GetSetName(int setNo) const
408         {
409             return reinterpret_cast<const char*>(
410                 reinterpret_cast<uptr>(mpHeader) + mpData->body.nameOffsets[setNo]
411             );
412         }
413 
GetSizeCompSheet(int sheetNo)414         u32                 GetSizeCompSheet(int sheetNo) const
415                                 { return mpSizeSheetsArray[sheetNo]; }
416 
GetSizeCWDH(int cwdhNo)417         u32                 GetSizeCWDH(int cwdhNo) const   { return mpSizeCWDHArray[cwdhNo]; }
418 
GetSizeCMAP(int cmapNo)419         u32                 GetSizeCMAP(int cmapNo) const   { return mpSizeCMAPArray[cmapNo]; }
420 
IsUseSheet(int setNo,int sheetNo)421         bool                IsUseSheet(
422                                 int setNo,
423                                 int sheetNo
424                             ) const
425         {
426             return GetBit(mpUseSheetArray, setNo * mSizeSheetFlags * 8 + sheetNo);
427         }
428 
IsUseCWDH(int setNo,int cwdhNo)429         bool                IsUseCWDH(
430                                 int setNo,
431                                 int cwdhNo
432                             ) const
433         {
434             return GetBit(mpUseCWDHArray,  setNo * mSizeCWDHFlags  * 8 + cwdhNo);
435         }
436 
IsUseCMAP(int setNo,int cmapNo)437         bool                IsUseCMAP(
438                                 int setNo,
439                                 int cmapNo
440                             ) const
441         {
442             return GetBit(mpUseCMAPArray,  setNo * mSizeCMAPFlags  * 8 + cmapNo);
443         }
444 
GetUseSheetFlags(int setNo,int flagSetNo)445         u32                 GetUseSheetFlags(
446                                 int setNo,
447                                 int flagSetNo
448                             ) const
449         {
450             return mpUseSheetArray[setNo * mSizeSheetFlags / 4 + flagSetNo];
451         }
452 
GetUseCWDHFlags(int setNo,int flagSetNo)453         u32                 GetUseCWDHFlags(
454                                 int setNo,
455                                 int flagSetNo
456                             ) const
457         {
458             return mpUseCWDHArray [setNo * mSizeCWDHFlags  / 4 + flagSetNo];
459         }
460 
GetUseCMAPFlags(int setNo,int flagSetNo)461         u32                 GetUseCMAPFlags(
462                                 int setNo,
463                                 int flagSetNo
464                             ) const
465         {
466             return mpUseCMAPArray [setNo * mSizeCMAPFlags  / 4 + flagSetNo];
467         }
468 
GetSheetSize()469         u32                 GetSheetSize() const        { return mpData->body.sheetSize; }
470 
GetNumGlyphsPerSheet()471         u16                 GetNumGlyphsPerSheet() const { return mpData->body.glyphsPerSheet; }
472 
GetNumSheet()473         u16                 GetNumSheet() const         { return mpData->body.numSheet; }
474 
GetNumSet()475         u16                 GetNumSet() const           { return mpData->body.numSet; }
476 
GetNumCWDH()477         u16                 GetNumCWDH() const          { return mpData->body.numCWDH; }
478 
GetNumCMAP()479         u16                 GetNumCMAP() const          { return mpData->body.numCMAP; }
480 
481         const detail::BinaryBlockHeader*
GetNextBlock()482                             GetNextBlock() const
483         {
484             return reinterpret_cast<const detail::BinaryBlockHeader*>(
485                 reinterpret_cast<uptr>(mpData) + mpData->header.size);
486         }
487 
488     private:
GetBit(const u32 * bits,u32 index)489         static bool         GetBit(const u32* bits, u32 index)
490         {
491             u32 wordIndex = index / 32;
492             u32 bitIndex  = index % 32;
493             return ((bits[wordIndex] << bitIndex) & (1u << 31)) != 0;
494         }
495 
496         const detail::BinaryFileHeader*
497                             mpHeader;
498         const FontGlyphGroupsBlock*
499                             mpData;
500         const u16*          mpNameOffsetArray;
501         const u32*          mpSizeSheetsArray;
502         const u32*          mpSizeCWDHArray;
503         const u32*          mpSizeCMAPArray;
504         const u32*          mpUseSheetArray;
505         const u32*          mpUseCWDHArray;
506         const u32*          mpUseCMAPArray;
507         u32                 mSizeSheetFlags;
508         u32                 mSizeCWDHFlags;
509         u32                 mSizeCMAPFlags;
510     };
511 
512 
513     /* ------------------------------------------------------------------------
514             Constants
515        ------------------------------------------------------------------------ */
516     static const u16        ADJUST_OFFSET_SHEET_NOT_LOADED = 0xFFFF;
517 
518 
519     /* ------------------------------------------------------------------------
520             Functions
521        ------------------------------------------------------------------------ */
522     //---- Construct/Destruct
523 
524     //
525     //
526     //
527     //
528     //
529     //
530     //
531     void                    SetResourceBuffer(
532                                 void*               pUserBuffer,
533                                 FontInformation*    pFontInfo,
534                                 u16*                pAdjustTable);
535 
536     //
537     //
538     //
539     //
540     //
541     void*                   RemoveResourceBuffer();
542 
543     //---- glyph index
544 
545     //
546     //
547     //
548     //
549     //
550     //
551     //
552     //
553     //
554     //
555     //
556     //
557     u16                     AdjustIndex(u16 index) const;
558 
559     //---- For searching GLGR block
560 
IsNullString(const char * str)561     static bool             IsNullString(const char* str)   { return *str == '\0'; }
562 
563     //
564     //
565     //
566     //
567     //
568     //
569     //
570     static bool             IncludeName(
571                                 const char* nameList,
572                                 const char* name);
573 
574     //
575     //
576     //
577     //
578     //
579 
580     //
581     //
582     //
583     static bool             IsValidResource(
584                                 const void* brfnt,
585                                 u32         dataSize);
586 
587     //---- Construction
588 
589     //
590     //
591     //
592     //
593     //
594     //
595     //
596     //
597     static ConstructResult  RequestData(
598                                 ConstructContext*   pContext,
599                                 CachedStreamReader* pStream,
600                                 u32                 size);
601 
602     //
603     //
604     //
605     //
606     //
607     //
608     //
609     static ConstructResult  ConstructOpDispatch(
610                                 ConstructContext*   pContext,
611                                 CachedStreamReader* pStream);
612 
613     //
614     //
615     //
616     //
617     //
618     //
619     //
620     static ConstructResult  ConstructOpAnalyzeFileHeader(
621                                 ConstructContext*   pContext,
622                                 CachedStreamReader* pStream);
623 
624     //
625     //
626     //
627     //
628     //
629     //
630     //
631     static ConstructResult  ConstructOpAnalyzeGLGR(
632                                 ConstructContext*   pContext,
633                                 CachedStreamReader* pStream);
634 
635     //
636     //
637     //
638     //
639     //
640     //
641     //
642     static ConstructResult ConstructOpAnalyzeFINF(
643                                 ConstructContext*   pContext,
644                                 CachedStreamReader* pStream);
645 
646     //
647     //
648     //
649     //
650     //
651     //
652     //
653     static ConstructResult ConstructOpAnalyzeCMAP(
654                                 ConstructContext*   pContext,
655                                 CachedStreamReader* pStream);
656 
657     //
658     //
659     //
660     //
661     //
662     //
663     //
664     static ConstructResult  ConstructOpAnalyzeCWDH(
665                                 ConstructContext*   pContext,
666                                 CachedStreamReader* pStream);
667 
668     //
669     //
670     //
671     //
672     //
673     //
674     //
675     static ConstructResult  ConstructOpAnalyzeTGLP(
676                                 ConstructContext*   pContext,
677                                 CachedStreamReader* pStream);
678 
679     //
680     //
681     //
682     //
683     //
684     //
685     //
686     static ConstructResult  ConstructOpPrepairCopySheet(
687                                 ConstructContext*   pContext,
688                                 CachedStreamReader* pStream);
689 
690     //
691     //
692     //
693     //
694     //
695     //
696     //
697     static ConstructResult  ConstructOpPrepairExpandSheet(
698                                 ConstructContext*   pContext,
699                                 CachedStreamReader* pStream);
700 
701     //
702     //
703     //
704     //
705     //
706     //
707     //
708     //
709     static ConstructResult  ConstructOpCopy(
710                                 ConstructContext*   pContext,
711                                 CachedStreamReader* pStream);
712 
713     //
714     //
715     //
716     //
717     //
718     //
719     //
720     static ConstructResult  ConstructOpSkip(
721                                 ConstructContext*   pContext,
722                                 CachedStreamReader* pStream);
723 
724     //
725     //
726     //
727     //
728     //
729     //
730     //
731     //
732     static ConstructResult ConstructOpExpand(
733                                 ConstructContext*   pContext,
734                                 CachedStreamReader* pStream);
735 
736     //
737     //
738     //
739     //
740     //
741     //
742     //
743     //
744     static ConstructResult  ConstructOpFatalError(
745                                 ConstructContext*   pContext,
746                                 CachedStreamReader* pStream);
747 
748 private:
749     /* ------------------------------------------------------------------------
750             Variables
751        ------------------------------------------------------------------------ */
752     u16*                    m_pGlyphIndexAdjustArray;
753 };
754 
755 }   // namespace font
756 }   // namespace nn
757 
758 #endif //  NN_FONT_FONT_ARCHIVE_FONT_BASE_H_
759