LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpc_swim_font.c
Go to the documentation of this file.
1 /*
2  * @brief SWIM font management
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "lpc_swim_font.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
37 
38 /*****************************************************************************
39  * Public types/enumerations/variables
40  ****************************************************************************/
41 
42 /*****************************************************************************
43  * Private functions
44  ****************************************************************************/
45 
46 /* Determines the length of the word (in pixels) up to the first
47  whitespace character */
48 static int16_t swim_get_word_len(SWIM_WINDOW_T *win,
49  const CHAR *text)
50 {
51  int32_t i;
52  int16_t wlen = 0;
53 
54  /* Find the length in pixels of the next word (separated by
55  whitespace) */
56  i = 0;
57  while (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) {
58  wlen = wlen + win->font->font_width_table
59  [(uint8_t) text[i] - win->font->first_char];
60  i++;
61  }
62 
63  return wlen;
64 }
65 
66 /* Puts a word in the window, but adds a newline to keep the
67  word contiguous (without an edge break) if necessary */
68 static int32_t swim_put_word(SWIM_WINDOW_T *win,
69  const CHAR *text)
70 {
71  int32_t i;
72 
73  /* Will the length of the next word exceed the window margin? */
74  if ((swim_get_word_len(win, text) + win->xvpos) > win->xpvmax) {
75  /* Do a newline */
76  swim_put_newline(win);
77  }
78 
79  /* Put just the word characters on the display up to the next
80  non-whitespace character or the end of the string */
81  i = 0;
82  while (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) {
83  swim_put_char(win, text[i]);
84  i++;
85  }
86 
87  return i;
88 }
89 
90 /***********************************************************************
91  * Public functions
92  **********************************************************************/
93 
94 /* Put text at x, y (char) position on screen */
96  const CHAR *text,
97  int32_t x,
98  int32_t y)
99 {
100  /* Convert virtual x, y positon to physical position */
101  swim_set_xy(win, x, y);
102 
103  /* Display text string */
104  swim_put_text(win, text);
105 }
106 
107 /* Sets the X, Y pixel coordinates for the next text operation */
109  int32_t x,
110  int32_t y)
111 {
112  win->xvpos = x + win->xpvmin;
113  win->yvpos = y + win->ypvmin;
114 
115  /* Limit to window dimensions */
116  if (win->xvpos < win->xpvmin) {
117  win->xvpos = win->xpvmin;
118  }
119  else if (win->xvpos > win->xpvmax) {
120  win->xvpos = win->xpvmax;
121  }
122 
123  if (win->yvpos < win->ypvmin) {
124  win->yvpos = win->ypvmin;
125  }
126  else if (win->yvpos > win->ypvmax) {
127  win->yvpos = win->ypvmax;
128  }
129 }
130 
131 /* Returns the X, Y pixel coordinates for the next text operation */
133  int32_t *x,
134  int32_t *y)
135 {
136  *x = win->xvpos - win->xpvmin;
137  *y = win->yvpos - win->ypvmin;
138 }
139 
140 /* Puts a string of text in a window */
142  const CHAR *text)
143 {
144  int32_t i = 0;
145 
146  /* Continue until the entire string is output */
147  while (text[i] != '\0') {
148  if (text[i] == '\n') {
149  swim_put_newline(win);
150  }
151  else if (((uint8_t) text[i] >= win->font->first_char)
152  && ((uint8_t) text[i] <= win->font->last_char)) {
153  /* Put character on screen */
154  swim_put_char(win, text[i]);
155  }
156 
157  i++;
158  }
159 }
160 
161 /* Puts a string of text in a window with breaks */
163  const CHAR *text)
164 {
165  int32_t i = 0;
166 
167  /* Continue until the entire string is output */
168  while (text[i] != '\0') {
169  if (text[i] == '\n') {
170  swim_put_newline(win);
171  i++;
172  }
173  else if (((uint8_t) text[i] >= win->font->first_char)
174  && ((uint8_t) text[i] <= win->font->last_char)) {
175  /* Check for entire words first */
176  if (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) {
177  /* Put entire word on screen */
178  i = i + swim_put_word(win, &text[i]);
179  }
180  else {
181  swim_put_char(win, text[i]);
182  i++;
183  }
184  }
185  else {
186  /* Put a space out */
187  swim_put_char(win, ' ');
188  i++;
189  }
190  }
191 }
192 
193 /* xx */
195  int32_t lines)
196 {
197  COLOR_T *fb1, *fb2;
198  int32_t yref1 = win->ypvmin;
199  int32_t yref2 = yref1 + lines;
200  int32_t ref;
201 
202  while (yref2 <= win->ypvmax) {
203  /* Line move addresses */
204  fb1 = win->fb + win->xpvmin + (yref1 * win->xpsize);
205  fb2 = win->fb + win->xpvmin + (yref2 * win->xpsize);
206 
207  /* Move a single line at a time */
208  ref = win->xpvmax - win->xpvmin + 1;
209  while (ref > 0) {
210  *fb1++ = *fb2++;
211  ref--;
212  }
213 
214  /* Next lines */
215  yref1++;
216  yref2++;
217  }
218 
219  /* Clear out bottom lines */
220  yref1 = win->yvpos;
221  while (yref1 <= win->ypvmax) {
222  /* Line clear address */
223  fb1 = win->fb + win->xpvmin + (yref1 * win->xpsize);
224 
225  /* Clear a single line at a time */
226  ref = win->xpvmax - win->xpvmin + 1;
227  while (ref > 0) {
228  *fb1++ = win->bkg;
229  ref--;
230  }
231 
232  yref1++;
233  }
234 }
235 
236 /* Puts a single character in the window */
238  const CHAR textchar)
239 {
240  int32_t i, j;
241  int32_t charindex;
242  uint16_t *charfields, chardata;
243  COLOR_T *fb;
244 
245  /* If this is a carriage return, do a newline */
246  if (textchar == '\n') {
247  swim_put_newline(win);
248  }
249  else {
250  /* Determine index to character data */
251  charindex = (int32_t) textchar - (int32_t) win->font->first_char;
252 
253  /* Will the character fit on the display? */
254  if ((win->xvpos +
255  (int32_t) win->font->font_width_table[charindex]) >
256  win->xpvmax) {
257  /* Will not fit, do a newline */
258  swim_put_newline(win);
259  }
260 
261  /* Determine the start of the bitfields for the character */
262  charfields = win->font->font_table + (charindex *
263  win->font->font_height);
264 
265  /* Map character to the window */
266  for (i = 0; i < (int32_t) win->font->font_height; i++) {
267  /* Get starting pixel location for font mapping in window */
268  fb = win->fb + win->xvpos + ((win->yvpos + i) * win->xpsize);
269 
270  /* Get character line mapping data */
271  chardata = charfields[i];
272 
273  /* Convert character line bit data to a pixel line in
274  window */
275  for (j =
276  (int32_t) win->font->font_width_table[charindex];
277  j > 0; j--) {
278  if ((chardata & 0x8000) != 0) {
279  *fb++ = win->pen;
280  }
281  else if (win->tfont != 0) {
282  *fb++ = win->bkg;
283  }
284  else {
285  fb++;
286  }
287 
288  /* Next bit in character line */
289  chardata = chardata << 1;
290  }
291  }
292 
293  /* Increment to next text location */
294  win->xvpos = win->xvpos +
295  (int32_t) win->font->font_width_table[charindex];
296  }
297 }
298 
299 /* Puts a newline in the window */
301 {
302  int32_t diff;
303 
304  /* Set text pointer to start of next line */
305  win->xvpos = win->xpvmin;
306  win->yvpos = win->yvpos + (int32_t) win->font->font_height;
307 
308  /* Next character is below bottom of window, scroll the window
309  up */
310  while ((win->yvpos +
311  (int32_t) win->font->font_height) > win->ypvmax) {
312  /* Scroll just enough for the next line */
313  diff = (int32_t) win->font->font_height -
314  (win->ypvmax - win->yvpos);
315  win->yvpos = win->yvpos - diff;
316  swim_window_scroll(win, diff);
317  }
318 }
319 
320 /* Sets the active font */
322  FONT_T *font)
323 {
324  int32_t diff;
325 
326  win->font = font;
327 
328  /* After changing to the new font, determine if there is enough
329  room for the font height on the existing line in the window */
330  if ((win->yvpos + win->font->font_height) > win->ypvmax) {
331  diff = (int32_t) win->font->font_height -
332  (win->ypvmax - win->yvpos);
333  win->yvpos = win->yvpos - diff;
334  swim_window_scroll(win, diff);
335  }
336 }
337 
338 /* Returns the active font's height in pixels */
340 {
341  return win->font->font_height;
342 }
343 
344 /* Creates a title bar for the window */
346  const CHAR *title,
347  COLOR_T ttlbkcolor)
348 {
349  COLOR_T savedf, savedp, savedb;
350  int32_t savedt;
351 
352  /* Is present font height larger than window client height? */
353  if ((swim_get_font_height(win) < (4 + win->yvsize)) &&
354  (title != (CHAR *) 0)) {
355  /* There is enough room for title bar, so continue */
356 
357  /* Save original colors and font transparentcy flag */
358  savedf = win->fill;
359  savedp = win->pen;
360  savedb = win->bkg;
361  savedt = win->tfont;
362 
363  /* Set fill color to background color (temporarily)
364  used with box function */
365  win->fill = ttlbkcolor;
366  win->bkg = ttlbkcolor;
367  win->pen = win->bkg;
368 
369  /* Draw the background for the title bar */
370  swim_put_box(win, 0, 0, win->xvsize,
371  (4 + swim_get_font_height(win) - 2));
372 
373  /* Reset text starting position for title string */
374  win->xvpos = win->xpvmin + 2;
375  win->yvpos = win->ypvmin + 1;
376 
377  /* Restore original pen color (used for text color) */
378  win->pen = savedp;
379 
380  /* Restore the original colors */
381  win->fill = savedf;
382  win->bkg = savedb;
383 
384  /* Put string in title bar area (with transparent background) */
385  win->tfont = 0;
386  swim_put_text(win, title);
387  win->tfont = savedt;
388 
389  /* Draw a line under the title bar, but before the
390  (new) client area */
391  swim_put_line(win, 0,
392  (4 + swim_get_font_height(win) - 1),
393  win->xpvmax, (4 + swim_get_font_height(win) - 1));
394 
395  /* Adjust client height of window (virtual and physcal) */
396  win->ypmin = win->ypmin + swim_get_font_height(win) + 4;
397  win->ypvmin = win->ypvmin + swim_get_font_height(win) + 4;
398 
399  /* Resize y dimension */
400  win->yvsize = win->yvsize - swim_get_font_height(win) + 4;
401 
402  /* Reset text starting position to new client area */
403  win->xvpos = win->xpvmin;
404  win->yvpos = win->ypvmin;
405  }
406 }
407 
408 /* Enables and disables font backgrounds */
410  int32_t trans)
411 {
412  win->tfont = trans;
413 }