1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     font_TextWriterBase.h
4 
5   Copyright (C)2009-2012 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: 46347 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FONT_CTR_FONT_TEXT_WRITER_BASE_H_
17 #define NN_FONT_CTR_FONT_TEXT_WRITER_BASE_H_
18 
19 #include <cstddef>
20 #include <cwchar>
21 #include <cstdio>
22 #include <cstring>
23 #include <cfloat>
24 #include <nn/types.h>
25 #include <nn/font/font_Font.h>
26 #include <nn/font/CTR/font_TagProcessorBase.h>
27 #include <nn/font/CTR/font_CharWriter.h>
28 #include <nn/util/util_Rect.h>
29 
30 
31 namespace nn {
32 namespace font {
33 namespace CTR {
34 
35 
36 //---------------------------------------------------------------------------
37 //
38 //
39 //
40 //---------------------------------------------------------------------------
41 template <typename CharType>
42 class TextWriterBase: public CharWriter
43 {
44 public:
45     /* ------------------------------------------------------------------------
46             Types
47        ------------------------------------------------------------------------ */
48 
49     //
50     enum PositionFlag
51     {
52         //Horizontal positioning
53         HORIZONTAL_ALIGN_LEFT       = 0x0,      //
54         HORIZONTAL_ALIGN_CENTER     = 0x1,      //
55         HORIZONTAL_ALIGN_RIGHT      = 0x2,      //
56         HORIZONTAL_ALIGN_MASK       = 0x3,
57 
58         // Horizontal position of the origin
59         HORIZONTAL_ORIGIN_LEFT      = 0x00,     //
60         HORIZONTAL_ORIGIN_CENTER    = 0x10,     //
61         HORIZONTAL_ORIGIN_RIGHT     = 0x20,     //
62         HORIZONTAL_ORIGIN_MASK      = 0x30,
63 
64         // Vertical position of the origin
65         VERTICAL_ORIGIN_TOP         = 0x000,    //
66         VERTICAL_ORIGIN_MIDDLE      = 0x100,    //
67         VERTICAL_ORIGIN_BOTTOM      = 0x200,    //
68         VERTICAL_ORIGIN_BASELINE    = 0x300,    //
69         VERTICAL_ORIGIN_MASK        = 0x300
70     };
71 
72     enum ContextFlag
73     {
74         //
75         CONTEXT_NO_CHAR_SPACE       = 0x1
76     };
77 
78     /* ------------------------------------------------------------------------
79             Variables
80        ------------------------------------------------------------------------ */
81     //
82     static const u32 DEFAULT_DRAWFLAG =
83         HORIZONTAL_ALIGN_LEFT | HORIZONTAL_ORIGIN_LEFT | VERTICAL_ORIGIN_TOP;
84 
85 
86     /* ------------------------------------------------------------------------
87             Functions
88        ------------------------------------------------------------------------ */
89 
90     //
91     //
92 
93     //
94                         TextWriterBase();
95 
96     //
97                         ~TextWriterBase();
98 
99     //
100 
101     //
102     //
103 
104     //
105     //
106     //
107     //
SetLineSpace(f32 space)108     void                SetLineSpace(f32 space)     { m_LineSpace = space; }
109 
110     //
111     //
112     //
113     //
GetLineSpace()114     f32                 GetLineSpace() const        { return m_LineSpace; }
115 
116     //
117     //
118     //
119     //
120     void                SetLineHeight(f32 height);
121 
122     //
123     //
124     //
125     //
126     f32                 GetLineHeight() const;
127 
128     //
129     //
130     //
131     //
SetCharSpace(f32 space)132     void                SetCharSpace(f32 space)     { m_CharSpace = space; }
133 
134     //
135     //
136 	//
137     //
GetCharSpace()138     f32                 GetCharSpace() const        { return m_CharSpace; }
139 
140     //
141     //
142     //
143     //
SetTabWidth(int tabWidth)144     void                SetTabWidth(int tabWidth)   { m_TabWidth = tabWidth; }
145 
146     //
147     //
148     //
149     //
GetTabWidth()150     int                 GetTabWidth() const         { return m_TabWidth; }
151 
152     //
153 
154     //
155     //
156 
157     //
158     //
159     //
160     //
SetWidthLimit(f32 limit)161     void                SetWidthLimit(f32 limit)    { m_WidthLimit  = limit; }
162 
163     //
164     //
165     //
166     //
167     //
GetWidthLimit()168     f32                 GetWidthLimit() const       { return m_WidthLimit; }
169 
170     //
ResetWidthLimit()171     void                ResetWidthLimit()           { SetWidthLimit(FLT_MAX); }
172 
173     //
174 
175 
176     //
177     //
178 
179 	//
180     //
181     //
182     //
SetDrawFlag(u32 flags)183     void                SetDrawFlag(u32 flags)      { m_DrawFlag = flags; }
184 
185     //
186     //
187     //
188     //
GetDrawFlag()189     u32                 GetDrawFlag() const         { return m_DrawFlag; }
190 
191     //
192 
193 
194     //
195     //
196 
197     //
198     //
199     //
200     //
SetTagProcessor(TagProcessorBase<CharType> * tagProcessor)201     void                SetTagProcessor(TagProcessorBase<CharType>* tagProcessor)
202     {
203         NN_POINTER_ASSERT(tagProcessor);
204 
205         m_TagProcessor = tagProcessor;
206     }
207 
208     //
209     //
210     //
211     //
212     TagProcessorBase<CharType>&
GetTagProcessor()213                         GetTagProcessor() const     { return *m_TagProcessor; }
214 
215     //
ResetTagProcessor()216     void                ResetTagProcessor()         { m_TagProcessor = &s_DefaultTagProcessor; }
217 
218     //
219 
220 
221     //
222     //
223 
224     //
225     //
226     //
227     //
228     //
229     //
230     //
231     f32                 CalcFormatStringWidth(
232                             const CharType* format,
233                             ...
234                         ) const;
235 
236     //
237     //
238     //
239     //
240     //
241     //
CalcStringWidth(const CharType * str)242     f32                 CalcStringWidth(
243                             const CharType* str
244                         ) const
245     {
246         NN_POINTER_ASSERT(str);
247 
248         return CalcStringWidth(str, StrLen(str));
249     }
250 
251     //
252     //
253     //
254     //
255     //
256     //
257     //
258     f32                 CalcStringWidth(
259                             const CharType* str,
260                             int             length
261                         ) const;
262 
263 
264     //
265     //
266     //
267     //
268     //
269     //
270     //
271     //
272     //
273     f32                 CalcFormatStringHeight(
274                             const CharType* format,
275                             ...
276                         ) const;
277 
278     //
279     //
280     //
281     //
282     //
283     //
CalcStringHeight(const CharType * str)284     f32                 CalcStringHeight(
285                             const CharType* str
286                         ) const
287     {
288         NN_POINTER_ASSERT(str);
289 
290         return CalcStringHeight(str, StrLen(str));
291     }
292 
293     //
294     //
295     //
296     //
297     //
298     //
299     //
300     f32                 CalcStringHeight(
301                             const CharType* str,
302                             int             length
303                         ) const;
304 
305     //
306     //
307     //
308     //
309     //
310     //
311     void                CalcFormatStringRect(
312                             util::Rect*     pRect,
313                             const CharType* format,
314                             ...
315                         ) const;
316 
317 
318     //
319     //
320     //
321     //
322     //
323     //
324     void                CalcVStringRect(
325                             util::Rect*     pRect,
326                             const CharType* format,
327                             std::va_list    args
328                         ) const;
329 
330 
331     //
332     //
333     //
334     //
335     //
CalcStringRect(util::Rect * pRect,const CharType * str)336     void                CalcStringRect(
337                             util::Rect*     pRect,
338                             const CharType* str
339                         ) const
340     {
341         NN_POINTER_ASSERT(pRect);
342         NN_POINTER_ASSERT(str);
343 
344         CalcStringRect(pRect, str, StrLen(str));
345     }
346 
347     //
348     //
349     //
350     //
351     //
352     //
353     void                CalcStringRect(
354                             util::Rect*     pRect,
355                             const CharType* str,
356                             int             length
357                         ) const;
358 
359     //
360 
361 
362     //
363     //
364 
365     //
366     //
367     //
368     //
369     //
370     //
371     //
372     f32                 Printf(
373                             const CharType* format,
374                             ... );
375 
376     //
377     //
378     //
379     //
380     //
381     //
382     //
383     f32                 VPrintf(
384                             const CharType* format,
385                             std::va_list    args);
386 
387     //
388     //
389     //
390     //
391     //
392     //
Print(const CharType * str)393     f32                 Print(
394                             const CharType* str
395                         )
396     {
397         NN_POINTER_ASSERT(str);
398 
399         return Print(str, StrLen(str));
400     }
401 
402     //
403     //
404     //
405     //
406     //
407     //
408     //
409     f32                 Print(
410                             const CharType* str,
411                             int             length);
412 
413     //
414 
415     //
416     //
417 
418     //
419     //
420     //
421     //
422     //
423     //
424     //
425     //
SetBuffer(std::size_t size)426     static void*        SetBuffer(
427                             std::size_t size
428                         )
429     {
430         NN_FONT_MIN_ASSERT(size, 1);
431         void* oldBuffer = s_FormatBuffer;
432 
433         s_FormatBuffer       = NULL;
434         s_FormatBufferSize   = size;
435 
436         return oldBuffer;
437     }
438 
439     //
440     //
441     //
442     //
443     //
444     //
445     //
446     //
447     //
SetBuffer(CharType * buffer,std::size_t size)448     static void*        SetBuffer(
449                             CharType*   buffer,
450                             std::size_t size
451                         )
452     {
453         NN_POINTER_ASSERT(buffer);
454         NN_FONT_MIN_ASSERT(size, 1);
455         void* oldBuffer = s_FormatBuffer;
456 
457         s_FormatBuffer       = buffer;
458         s_FormatBufferSize   = size;
459 
460         return oldBuffer;
461     }
462 
463     //
464     //
465     //
466     //
GetBuffer()467     static const void*  GetBuffer()
468     {
469         return s_FormatBuffer;
470     }
471 
472     //
473     //
474     //
475     //
GetBufferSize()476     static std::size_t  GetBufferSize()
477     {
478         return s_FormatBufferSize;
479     }
480 
481     //
482 
483 
484     //---- vsnprintf branch
VSNPrintf(char * buffer,std::size_t count,const char * format,std::va_list arg)485     static int          VSNPrintf(
486                             char*           buffer,
487                             std::size_t     count,
488                             const char*     format,
489                             std::va_list    arg
490                         )
491     {
492         #if ! defined(_MSC_VER)
493             using namespace std;
494         #endif
495 
496         return vsnprintf(buffer, count, format, arg);
497     }
498 
VSNPrintf(wchar_t * buffer,std::size_t count,const wchar_t * format,std::va_list arg)499     static int          VSNPrintf(
500                             wchar_t*        buffer,
501                             std::size_t     count,
502                             const wchar_t*  format,
503                             std::va_list    arg
504                         )
505     {
506         #if ! defined(_MSC_VER)
507             using namespace std;
508         #endif
509 
510         return vswprintf(buffer, count, format, arg);
511     }
512 
StrLen(const char * str)513     static int          StrLen(const char* str)
514     {
515         return static_cast<int>(std::strlen(str));
516     }
517 
StrLen(const wchar_t * str)518     static int          StrLen(const wchar_t* str)
519     {
520         return static_cast<int>(std::wcslen(str));
521     }
522 
523 
524     using CharWriter::Print;
525 
526 private:
527     /* ------------------------------------------------------------------------
528             Types
529        ------------------------------------------------------------------------ */
530     typedef TagProcessorBase<CharType>  TagProcessor;
531     typedef const CharType*             StreamType;
532 
533     /* ------------------------------------------------------------------------
534             Constants
535        ------------------------------------------------------------------------ */
536     static const int DEFAULT_FORMAT_BUFFER_SIZE = 256;
537 
538     /* ------------------------------------------------------------------------
539             Functions
540        ------------------------------------------------------------------------ */
541 
542     //
543     //
544     //
545     //
546     //
547     f32                 CalcLineWidth(
548                             StreamType  str,
549                             int         length);
550 
551     //
552     //
553     //
554     //
555     //
556     //
557     //
558     //
559     bool                CalcLineRectImpl(
560                             util::Rect* pRect,
561                             StreamType* pStr,
562                             int         length);
563 
564     //
565     //
566     //
567     //
568     //
569     //
570     void                CalcStringRectImpl(
571                             util::Rect* pRect,
572                             StreamType  str,
573                             int         length);
574 
575     //
576     //
577     //
578     //
579     //
580     f32                 PrintImpl(
581                             StreamType  str,
582                             int         length);
583 
584 
585     //
586     //
587     //
588     //
589     //
590     //
591     //
592     //
593     //
594     //
595     //
596     //
597     f32                 AdjustCursor(
598                             f32*        pXOrigin,
599                             f32*        pYOrigin,
600                             StreamType  str,
601                             int         length);
602 
603     //
604     //
605     //
606     //
607     //
608     //
609     //
IsDrawFlagSet(u32 mask,u32 flag)610     bool                IsDrawFlagSet(
611                             u32 mask,
612                             u32 flag
613                         ) const
614     {
615         return (m_DrawFlag & mask) == flag;
616     }
617 
618     /* ------------------------------------------------------------------------
619             Variables
620        ------------------------------------------------------------------------ */
621 
622     static CharType*        s_FormatBuffer;         //
623     static std::size_t      s_FormatBufferSize;     //
624 
625     //
626     static TagProcessor     s_DefaultTagProcessor;
627 
628     f32                     m_WidthLimit;           //
629     f32                     m_CharSpace;            //
630     f32                     m_LineSpace;            //
631     int                     m_TabWidth;             //
632     u32                     m_DrawFlag;             //
633     TagProcessor*           m_TagProcessor;         //
634 };
635 
636 }   // namespace CTR
637 }   // namespace font
638 }   // namespace nn
639 
640 #endif //  NN_FONT_CTR_FONT_TEXT_WRITER_BASE_H_
641