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