1 /** \file lvfnt.h
2     \brief Grayscale Bitmap Font engine
3 
4     CoolReader Engine
5 
6     (c) Vadim Lopatin, 2000-2006
7 
8     This source code is distributed under the terms of
9     GNU General Public License.
10 
11     See LICENSE file for details.
12 
13    \section Unicode greyscale bitmap font file structure
14 
15    (pointers are byte offsets from file beginning)
16 
17    - <font file>::
18       - <file header>      -- lvfont_header_t
19       - <decode table>     -- huffman decode table
20       - <glyph chunk 1>    -- lvfont_glyph_t * [64]
21       - ...
22       - <glyph chunk N>    -- lvfont_glyph_t * [64]
23    - <file header>::
24       - <signature>        -- 4 bytes
25       - <version>          -- 4 bytes
26       - <fontName>         -- 64 bytes
27       - <copyright>        -- 64 bytes
28       - <fileSize>         -- 4 bytes
29       - <fontAttributes>   -- 8 bytes
30       - <font ranges>      -- lvfont_glyph_t * * [1024], 0 if no chunk
31    - <glyph chunk>::
32       - <glyph table>      -- lvfont_glyph_t * [64], 0 if no glyph
33       - <glyph 1>          -- lvfont_glyph_t [arbitrary size]
34       - ...
35       - <glyph M>          -- lvfont_glyph_t [arbitrary size]
36 
37 */
38 
39 #ifndef __LVFNT_H_INCLUDED__
40 #define __LVFNT_H_INCLUDED__
41 
42 #include "lvtypes.h"
43 
44 /// maximum font name length
45 #define FONT_NAME_LENGTH       64
46 /// maximum copyright notice length
47 #define FONT_COPYRIGHT_LENGTH  64
48 
49 #ifdef __cplusplus
50 
51 #include "hyphman.h"
52 
53 extern "C" {
54 #endif
55 
56 /**
57     \brief Bitmap font header structure
58 
59     This structure starts from the beginning of file.
60 
61 */
62 #pragma pack(push,1)
63 typedef struct
64 tag_lvfont_header
65 {
66     char magic[4];   ///< {'L', 'F', 'N', 'T'}
67     char version[4]; ///< {'1', '.', '0', '0'  } */
68     char fontName[FONT_NAME_LENGTH];  ///< font typeface name
69     char fontCopyright[FONT_COPYRIGHT_LENGTH]; ///< copyright notice
70     lUInt32 fileSize;         ///< full font file size, bytes
71     lUInt8  fontHeight;       ///< font height, pixels
72     lUInt8  fontAvgWidth;     ///< avg char width, pixels
73     lUInt8  fontMaxWidth;     ///< max char width
74     lUInt8  fontBaseline;     ///< font baseline offset, from top, pixels
75     lUInt8  fontBitsPerPixel; ///< usually 1, 2 or 4
76     lUInt8  flgBold;          ///< 1 for bold, 0 for normal
77     lUInt8  flgItalic;        ///< 1 for italic, 0 for normal
78     lUInt8  fontFamily;       ///< font family
79     lUInt16 minCode;          ///< min font character code
80     lUInt16 maxCode;          ///< max font character code
81     lUInt32 decodeTableOffset;///< huffman decode table offset
82     lUInt32 rangesOffset[1024]; /**< \brief byte offset from beginning of file to 64 chars unicode ranges
83 
84                                    - 0 if no chars in range
85                                    - rangesOffset[0] - 0..63
86                                    - rangesOffset[1] - 64..127
87                                    - rangesOffset[2] - 128..191
88                                    - ...
89                                    - rangesOffset[maxCode/64] -- ..maxCode
90                                    The real length of whis array is
91                                    (maxCode/64+1), the rest is overlapped
92                                    with first range data.
93                                 */
94     /* decode table follows */
95 } lvfont_header_t;
96 #pragma pack(pop)
97 
98 /**
99     \brief Glyph range offset table.
100 
101     Contains pointers to individual glyphs for 64-character glyph range.
102 */
103 #pragma pack(push,1)
104 typedef struct
105 tag_lvfont_range
106 {
107     lUInt16 glyphsOffset[64]; /** \brief offset table for 64 glyphs in range
108                                    - 0 if no glyph for char
109                                    - byte offset from beginning of range to glyph if exists
110 
111                                    followed by lvfont_glyph_t for each non-zero offset
112                               */
113 } lvfont_range_t;
114 #pragma pack(pop)
115 
116 /**
117     \brief Glyph data structure.
118 
119     Describes properties of single glyph followed by compressed glyph image.
120 
121 */
122 #pragma pack(push,1)
123 typedef struct
124 tag_lvfont_glyph
125 {
126     lUInt32  glyphSize;   ///< 4: bytes in glyph array
127     lUInt16  blackBoxX;   ///< 0: width of glyph
128     lUInt16  blackBoxY;   ///< 1: height of glyph black box
129     lInt16   originX;     ///< 2: X origin for glyph
130     lInt16   originY;     ///< 3: Y origin for glyph
131     lUInt16  width;       ///< 6: full width of glyph
132     lUInt8   glyph[2];    ///< 7: glyph data, arbitrary size
133 } lvfont_glyph_t;
134 #pragma pack(pop)
135 
136 /** \brief RLE/Huffman table entry used for glyph image encoding.
137 
138     Describes huffman code of single symbol.
139 
140 */
141 #pragma pack(push,1)
142 typedef struct {
143     lUInt8  value;    ///< color value
144     lUInt8  count;    ///< number of times value is repeated
145     lUInt8  codelen;  ///< number of bits in huffman code
146     lUInt8  code;     ///< huffman code (left aligned)
147 } hrle_decode_table_t;
148 #pragma pack(pop)
149 
150 /**
151     \brief RLE/Huffman table used for glyph image encoding.
152 
153     Contains table used to encode glyph images.
154 
155 */
156 #pragma pack(push,1)
157 typedef struct {
158     lUInt8  itemcount; ///< number of items in table
159     lUInt8  bitcount;  ///< bit count per color value
160     lUInt8  rightmask; ///< left aligned mask
161     lUInt8  leftmask;  ///< right aligned mask
162     hrle_decode_table_t table[1]; ///< table items [itemcount]
163 } hrle_decode_info_t;
164 #pragma pack(pop)
165 
166 /// Font handle typedef to refer the font
167 typedef void * lvfont_handle;
168 
169 /**********************************************************************
170     font object API
171 **********************************************************************/
172 
173 /**
174    \brief loads font from file, allocates memory
175    \return 1 if successful, 0 for error
176 */
177 int lvfontOpen( const char * fname, lvfont_handle * hfont );
178 
179 /// frees memory allocated for font
180 void lvfontClose( lvfont_handle pfont );
181 
182 /** \brief retrieves font header pointer by handle
183     \param hfont is font handle
184     \return pointer to font header structure
185 */
186 const lvfont_header_t * lvfontGetHeader( const lvfont_handle hfont );
187 
188 /** \brief retrieves pointer to huffman decode table by font handle
189     \param hfont is font handle
190     \return pointer to huffman decode table
191 */
192 const hrle_decode_info_t * lvfontGetDecodeTable( const lvfont_handle hfont );
193 
194 /** \brief retrieves pointer to glyph structure for specified char by font handle
195     \param hfont is font handle
196     \param code is unicode character
197     \return pointer to glyph structure
198 */
199 const lvfont_glyph_t * lvfontGetGlyph( const lvfont_handle hfont, lUInt16 code );
200 
201 /** \brief measures test line width
202 
203     \param pfont is font handle
204     \param text is pointer to text string
205     \param len is number of characters in text to measure
206     \param max_width is a width limit -- measuring stops when total width exceeds this value
207     \param widths returns running total widths of string [0..i] including text[i]
208     \return number of items written to widths[]
209 */
210 lUInt16 lvfontMeasureText( const lvfont_handle pfont,
211                     const lChar32 * text, int len,
212                     lUInt16 * widths,
213                     lUInt8 * flags,
214                     int max_width,
215                     lChar32 def_char
216                  );
217 
218 // These lower than 0x0100 (that fit in a lUint8) may be set by lvfntman's measureText()
219 // (to possibly get some informative flags back from harfbuzz) and hyphman's hyphenate().
220 // (These should be changed or dropped with care, as they may be used by some other parts of CoolReader)
221 #define LCHAR_IS_SPACE               0x0001 ///< flag: this char is one of the unicode space chars.
222                                             //         It is set only on the normal space and the normal non-breakable
223                                             //         space (spaces that can have their widths expanded or shrunk).
224                                             //         It is not set on the unicode fixed width spaces.
225 #define LCHAR_ALLOW_WRAP_AFTER       0x0002 ///< flag: line break after this char is allowed.
226                                             //         It is set on all spaces, except non-breakable ones.
227                                             //         It is set on soft-hyphen.
228                                             //         It is not set on CJK chars.
229 #define LCHAR_DEPRECATED_WRAP_AFTER  0x0004 ///< flag: line break after this char is possible but deprecated
230                                             //         When not using libunibreak: it is set on '-' and other unicode hyphens.
231                                             //         When using libunibreak: set on all text inside "white-space: nowrap"
232 #define LCHAR_ALLOW_HYPH_WRAP_AFTER  0x0008 ///< flag: line break after this char is allowed with addition of hyphen
233                                             //         It is set by Hyphman when finding hyphenation points in a word.
234 #define LCHAR_MANDATORY_NEWLINE      0x0010 ///< flag: this char must start with new line
235 #define LCHAR_IS_CLUSTER_TAIL        0x0020 ///< flag: this char is a tail of a cluster (eg. ligature,
236                                             //         whose glyph is carried by first char)
237                                             //         It is set by harfbuzz when used.
238 
239 // (This one is actually not set by lvfntman)
240 #define LCHAR_LOCKED_SPACING         0x0040 ///< flag: forbid any letter spacing tweak on this char
241                                             //         (for cursive scripts like arabic, and special cases)
242 #define LCHAR__AVAILABLE_BIT_08__    0x0080
243 
244 /// The next ones, not fitting in a lUInt8, should only be set and used by lvtextfm
245 #define LCHAR_IS_OBJECT              0x0100 ///< flag: this char is object (image, float)
246 #define LCHAR_IS_COLLAPSED_SPACE     0x0200 ///< flag: this char is a space that should not be rendered
247 #define LCHAR_IS_TO_IGNORE           0x0400 ///< flag: this char is to be ignored/skipped in text measurement and drawing
248 #define LCHAR_IS_RTL                 0x0800 ///< flag: this char is part of a RTL segment
249 
250 #define LCHAR__AVAILABLE_BIT_13__    0x1000
251 #define LCHAR__AVAILABLE_BIT_14__    0x2000
252 #define LCHAR__AVAILABLE_BIT_15__    0x4000
253 #define LCHAR__AVAILABLE_BIT_16__    0x8000
254 
255 // Some idea, if needed:
256 // #define LCHAR_IS_CJK_NOT_PUNCT       0x1000 ///< flag: this char is part a CJK char but not a punctuation
257 // #define LCHAR_IS_CJK_LEFT_PUNCT      0x2000 ///< flag: this char is part a CJK left punctuation
258 // #define LCHAR_IS_CJK_RIGHT_PUNCT     0x4000 ///< flag: this char is part a CJK right punctuation
259 // #define LCHAR_IS_CJK_PUNCT           0x6000 ///< flag: (for checking) this char is a CJK punctuation (neutral if set)
260 // #define LCHAR_IS_CJK                 0x7000 ///< flag: (for checking) this char is a CJK char
261 
262 // LCHAR_IS_EOL was not used by any code, and has been replaced by LCHAR_IS_CLUSTER_TAIL
263 // #define LCHAR_IS_EOL              0x0010 ///< flag: this char is CR or LF
264 
265 
266 /** \brief returns true if character is unicode space
267     \param code is character
268     \return 1 if character is space, 0 otherwise
269 */
lvfontIsUnicodeSpace(lChar32 code)270 inline int lvfontIsUnicodeSpace( lChar32 code ) { return code==0x0020; }
271 
272 /** \brief returns unpacked glyph image
273     \param packed is RLE/Huffman encoded glyph data
274     \param table is RLE/Huffman table
275     \param unpacked is buffer to place unpacked image (1 byte per pixel)
276     \param unp_size is size of \a unpacked
277 */
278 void lvfontUnpackGlyph( const lUInt8 * packed,
279                        const hrle_decode_info_t * table,
280                        lUInt8 * unpacked,
281                        int unp_size );
282 
283 #ifdef __cplusplus
284 }
285 
286 
287 
288 #endif
289 
290 #endif
291