Add multiple font support in bitmaps.
[bertos.git] / gfx / text_format.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
6  * This file is part of DevLib - See README.devlib for information.
7  * -->
8  *
9  * \brief printf-family routines for text output
10  *
11  * \version $Id$
12  * \author Bernardo Innocenti <bernie@develer.com>
13  * \author Stefano Fedrigo <aleph@develer.com>
14  */
15
16 /*#*
17  *#* $Log$
18  *#* Revision 1.4  2006/02/10 12:31:33  bernie
19  *#* Add multiple font support in bitmaps.
20  *#*
21  *#* Revision 1.3  2005/11/27 23:31:58  bernie
22  *#* Reorder includes.
23  *#*
24  *#* Revision 1.2  2005/11/04 18:17:45  bernie
25  *#* Fix header guards and includes for new location of gfx module.
26  *#*
27  *#* Revision 1.1  2005/11/04 18:11:35  bernie
28  *#* Move graphics stuff from mware/ to gfx/.
29  *#*
30  *#* Revision 1.10  2005/11/04 16:20:02  bernie
31  *#* Fix reference to README.devlib in header.
32  *#*
33  *#* Revision 1.9  2004/12/31 17:47:45  bernie
34  *#* Rename UNUSED() to UNUSED_ARG().
35  *#*
36  *#* Revision 1.8  2004/11/16 21:16:56  bernie
37  *#* Update to new naming scheme in mware/gfx.c.
38  *#*
39  *#* Revision 1.7  2004/10/03 19:05:04  bernie
40  *#* text_widthf(), text_vwidthf(): New functions.
41  *#*
42  *#* Revision 1.6  2004/09/14 20:59:04  bernie
43  *#* text_xprintf(): Support all styles; Pixel-wise text centering.
44  *#*
45  *#* Revision 1.5  2004/08/25 14:12:09  rasky
46  *#* Aggiornato il comment block dei log RCS
47  *#*
48  *#* Revision 1.4  2004/08/05 18:46:44  bernie
49  *#* Documentation improvements.
50  *#*
51  *#* Revision 1.3  2004/08/03 15:57:18  aleph
52  *#* Add include to fix warning for vsprintf()
53  *#*
54  *#* Revision 1.2  2004/06/03 11:27:09  bernie
55  *#* Add dual-license information.
56  *#*
57  *#* Revision 1.1  2004/05/23 15:43:16  bernie
58  *#* Import mware modules.
59  *#*
60  *#* Revision 1.2  2004/03/26 18:50:50  bernie
61  *#* Move _PROGMEM stuff to compiler.h
62  *#*
63  *#* Revision 1.1  2004/03/19 16:52:28  bernie
64  *#* Move printf() like functions from text.c to text_format.c and add PROGMEM versions.
65  *#*
66  *#*/
67
68 #include "text.h"
69
70 #include <mware/formatwr.h> /* _formatted_write() */
71 #include <gfx/font.h>
72 #include <gfx/gfx.h>
73
74 #include <stdio.h> /* vsprintf() */
75 #include <stdarg.h>
76 #include <string.h> /* strlen() */
77
78 /*!
79  * Render string \a str in Bitmap \a bm at current cursor position
80  *
81  * \note Text formatting functions are also available with an _P suffix
82  *       accepting the source string from program memory.  This feature
83  *       is only available (and useful) on Harvard microprocessors such
84  *       as the AVR.
85  *
86  * \see text_putchar()
87  */
88 int PGM_FUNC(text_puts)(const char * PGM_ATTR str, struct Bitmap *bm)
89 {
90         char c;
91
92         while ((c = PGM_READ_CHAR(str++)))
93                 text_putchar(c, bm);
94
95         return 0;
96 }
97
98
99 /*!
100  * vprintf()-like formatter to render text in a Bitmap.
101  *
102  * Perform vprintf()-like formatting on the \a fmt format string using the
103  * variable-argument list \a ap.
104  * Render the resulting string in Bitmap \a bm starting at the current
105  * cursor position.
106  *
107  * \see text_puts() text_putchar() text_printf()
108  */
109 int PGM_FUNC(text_vprintf)(struct Bitmap *bm, const char * PGM_ATTR fmt, va_list ap)
110 {
111         return PGM_FUNC(_formatted_write)(fmt, (void (*)(char, void *))text_putchar, bm, ap);
112 }
113
114 /*!
115  * printf()-like formatter to render text in a Bitmap.
116  *
117  * Perform printf()-like formatting on the \a fmt format string.
118  * Render the resulting string in Bitmap \a bm starting at the
119  * current cursor position.
120  *
121  * \see text_puts() text_putchar() text_vprintf()
122  */
123 int PGM_FUNC(text_printf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
124 {
125         int len;
126
127         va_list ap;
128         va_start(ap, fmt);
129         len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
130         va_end(ap);
131
132         return len;
133 }
134
135
136 /*!
137  * Render the result of printf()-like formatting in a specified position
138  * of a Bitmap.
139  *
140  * \param bm Bitmap where to render the text
141  * \param row   Starting row in character units (zero based)
142  * \param col   Starting column in character units (zero based)
143  * \param style Formatting style to use.  In addition to any STYLEF_
144  *        flag, it can be TEXT_NORMAL, TEXT_FILL, TEXT_INVERT or
145  *        TEXT_RIGHT, or a combination of these flags ORed together.
146  * \param fmt  String possibly containing printf() formatting commands.
147  *
148  * \see text_puts() text_putchar() text_printf() text_vprintf()
149  * \see text_moveto() text_style()
150  */
151 int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
152                 uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
153 {
154         int len;
155         uint8_t oldstyle = 0;
156         va_list ap;
157
158         va_start(ap, fmt);
159
160         text_moveto(bm, row, col);
161
162         if (style & STYLEF_MASK)
163                 oldstyle = text_style(style, STYLEF_MASK);
164
165         if (style & (TEXT_CENTER | TEXT_RIGHT))
166         {
167                 uint8_t pad = bm->width - PGM_FUNC(text_vwidthf)(bm, fmt, ap);
168
169                 if (style & TEXT_CENTER)
170                         pad /= 2;
171
172                 if (style & TEXT_FILL)
173                         gfx_rectFillC(bm, 0, row * bm->font->height, pad, (row + 1) * bm->font->height,
174                                 (style & STYLEF_INVERT) ? 0xFF : 0x00);
175
176                 text_setcoord(bm, pad, row * bm->font->height);
177         }
178
179         len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
180         va_end(ap);
181
182         if (style & TEXT_FILL)
183                 gfx_rectFillC(bm, bm->penX, row * bm->font->height, bm->width, (row + 1) * bm->font->height,
184                         (style & STYLEF_INVERT) ? 0xFF : 0x00);
185
186         /* Restore old style */
187         if (style & STYLEF_MASK)
188                 text_style(oldstyle, STYLEF_MASK);
189
190         return len;
191 }
192
193
194 /*!
195  * Return the width in pixels of a vprintf()-formatted string.
196  */
197 int PGM_FUNC(text_vwidthf)(
198         UNUSED_ARG(struct Bitmap *, bm),
199         const char * PGM_ATTR fmt,
200         va_list ap)
201 {
202         return PGM_FUNC(vsprintf)(NULL, fmt, ap) * bm->font->width;
203 }
204
205
206 /*!
207  * Return the width in pixels of a printf()-formatted string.
208  */
209 int PGM_FUNC(text_widthf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
210 {
211         int width;
212
213         va_list ap;
214         va_start(ap, fmt);
215         width = PGM_FUNC(text_vwidthf)(bm, fmt, ap);
216         va_end(ap);
217
218         return width;
219 }