A basic graphics package for the LPC4088 Display Module.

Dependents:   lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI lpc4088_displaymodule_fs_aid ... more

Fork of DMBasicGUI by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lpc_swim_font.c Source File

lpc_swim_font.c

00001 /*
00002  * @brief SWIM font management
00003  *
00004  * @note
00005  * Copyright(C) NXP Semiconductors, 2012
00006  * All rights reserved.
00007  *
00008  * @par
00009  * Software that is described herein is for illustrative purposes only
00010  * which provides customers with programming information regarding the
00011  * LPC products.  This software is supplied "AS IS" without any warranties of
00012  * any kind, and NXP Semiconductors and its licensor disclaim any and
00013  * all warranties, express or implied, including all implied warranties of
00014  * merchantability, fitness for a particular purpose and non-infringement of
00015  * intellectual property rights.  NXP Semiconductors assumes no responsibility
00016  * or liability for the use of the software, conveys no license or rights under any
00017  * patent, copyright, mask work right, or any other intellectual property rights in
00018  * or to any products. NXP Semiconductors reserves the right to make changes
00019  * in the software without notification. NXP Semiconductors also makes no
00020  * representation or warranty that such application will be suitable for the
00021  * specified use without further testing or modification.
00022  *
00023  * @par
00024  * Permission to use, copy, modify, and distribute this software and its
00025  * documentation is hereby granted, under NXP Semiconductors' and its
00026  * licensor's relevant copyrights in the software, without fee, provided that it
00027  * is used in conjunction with NXP Semiconductors microcontrollers.  This
00028  * copyright, permission, and disclaimer notice must appear in all copies of
00029  * this code.
00030  */
00031 
00032 #include "lpc_swim_font.h"
00033 
00034 /*****************************************************************************
00035  * Private types/enumerations/variables
00036  ****************************************************************************/
00037 
00038 /*****************************************************************************
00039  * Public types/enumerations/variables
00040  ****************************************************************************/
00041 
00042 /*****************************************************************************
00043  * Private functions
00044  ****************************************************************************/
00045 
00046 /* Determines the length of the word (in pixels) up to the first
00047    whitespace character */
00048 static int16_t swim_get_word_len(SWIM_WINDOW_T *win,
00049                                 const CHAR *text)
00050 {
00051     int32_t i;
00052     int16_t wlen = 0;
00053 
00054     /* Find the length in pixels of the next word (separated by
00055        whitespace) */
00056     i = 0;
00057     while (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) {
00058         wlen = wlen + win->font->font_width_table
00059                [(uint8_t) text[i] - win->font->first_char];
00060         i++;
00061     }
00062 
00063     return wlen;
00064 }
00065 
00066 /* Puts a word in the window, but adds a newline to keep the
00067    word contiguous (without an edge break) if necessary */
00068 static int32_t swim_put_word(SWIM_WINDOW_T *win,
00069                             const CHAR *text)
00070 {
00071     int32_t i;
00072 
00073     /* Will the length of the next word exceed the window margin? */
00074     if ((swim_get_word_len(win, text) + win->xvpos) > win->xpvmax) {
00075         /* Do a newline */
00076         swim_put_newline(win);
00077     }
00078 
00079     /* Put just the word characters on the display up to the next
00080        non-whitespace character or the end of the string */
00081     i = 0;
00082     while (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) {
00083         swim_put_char(win, text[i]);
00084         i++;
00085     }
00086 
00087     return i;
00088 }
00089 
00090 /***********************************************************************
00091  * Public functions
00092  **********************************************************************/
00093 
00094 /* Put text at x, y (char) position on screen */
00095 void swim_put_text_centered_win(SWIM_WINDOW_T *win,
00096                                 const CHAR *text,
00097                                 int32_t y)
00098 {
00099     swim_put_text_centered(win, text, 0, win->xvsize-1, y);
00100 }
00101 
00102 /* Put text at x, y (char) position on screen */
00103 void swim_put_text_centered(SWIM_WINDOW_T *win,
00104                             const CHAR *text,
00105                             int32_t x0,
00106                             int32_t x1,
00107                             int32_t y)
00108 {
00109     int w, h;
00110     if (x0 > x1) {
00111         w = x0;
00112         x0 = x1;
00113         x1 = w;
00114     }
00115     swim_get_string_bounds(win, text, &w, &h);
00116     swim_put_text_xy(win, text, x0 + (x1-x0-w)/2, y);
00117 }
00118 
00119 /* Put text at x, y (char) position on screen */
00120 void swim_put_text_xy(SWIM_WINDOW_T *win,
00121                       const CHAR *text,
00122                       int32_t x,
00123                       int32_t y)
00124 {
00125     /* Convert virtual x, y positon to physical position */
00126     swim_set_xy(win, x, y);
00127 
00128     /* Display text string */
00129     swim_put_text(win, text);
00130 }
00131 
00132 /* Sets the X, Y pixel coordinates for the next text operation */
00133 void swim_set_xy(SWIM_WINDOW_T *win,
00134                  int32_t x,
00135                  int32_t y)
00136 {
00137     win->xvpos = x + win->xpvmin;
00138     win->yvpos = y + win->ypvmin;
00139 
00140     /* Limit to window dimensions */
00141     if (win->xvpos < win->xpvmin) {
00142         win->xvpos = win->xpvmin;
00143     }
00144     else if (win->xvpos > win->xpvmax) {
00145         win->xvpos = win->xpvmax;
00146     }
00147 
00148     if (win->yvpos < win->ypvmin) {
00149         win->yvpos = win->ypvmin;
00150     }
00151     else if (win->yvpos > win->ypvmax) {
00152         win->yvpos = win->ypvmax;
00153     }
00154 }
00155 
00156 /* Returns the X, Y pixel coordinates for the next text operation */
00157 void swim_get_xy(SWIM_WINDOW_T *win,
00158                  int32_t *x,
00159                  int32_t *y)
00160 {
00161     *x = win->xvpos - win->xpvmin;
00162     *y = win->yvpos - win->ypvmin;
00163 }
00164 
00165 /* Puts a string of text in a window */
00166 void swim_put_text(SWIM_WINDOW_T *win,
00167                    const CHAR *text)
00168 {
00169     int32_t i = 0;
00170 
00171     /* Continue until the entire string is output */
00172     while (text[i] != '\0') {
00173         if (text[i] == '\n') {
00174             swim_put_newline(win);
00175         }
00176         else if (((uint8_t) text[i] >= win->font->first_char)
00177                  && ((uint8_t) text[i] <= win->font->last_char)) {
00178             /* Put character on screen */
00179             swim_put_char(win, text[i]);
00180         }
00181 
00182         i++;
00183     }
00184 }
00185 
00186 /* Puts a string of text in a window with breaks */
00187 void swim_put_ltext(SWIM_WINDOW_T *win,
00188                     const CHAR *text)
00189 {
00190     int32_t i = 0;
00191 
00192     /* Continue until the entire string is output */
00193     while (text[i] != '\0') {
00194         if (text[i] == '\n') {
00195             swim_put_newline(win);
00196             i++;
00197         }
00198         else if (((uint8_t) text[i] >= win->font->first_char)
00199                  && ((uint8_t) text[i] <= win->font->last_char)) {
00200             /* Check for entire words first */
00201             if (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) {
00202                 /* Put entire word on screen */
00203                 i = i + swim_put_word(win, &text[i]);
00204             }
00205             else {
00206                 swim_put_char(win, text[i]);
00207                 i++;
00208             }
00209         }
00210         else {
00211             /* Put a space out */
00212             swim_put_char(win, ' ');
00213             i++;
00214         }
00215     }
00216 }
00217 
00218 /* xx */
00219 void swim_window_scroll(SWIM_WINDOW_T *win,
00220                         int32_t lines)
00221 {
00222     int32_t yref1 = win->ypvmin;
00223     int32_t yref2 = yref1 + lines;
00224     int32_t ref;
00225 
00226     while (yref2 <= win->ypvmax) {
00227 
00228         /* Line move addresses */
00229         uint32_t ix = win->xpvmin;
00230         uint32_t destIy = yref1;
00231         uint32_t srcIy = yref2;
00232 
00233         /* Move a single line at a time */
00234         ref = win->xpvmax - win->xpvmin + 1;
00235         while (ref > 0) {
00236             COLOR_T pixel = swim_get_pixel_physical(win, ix, srcIy);
00237             swim_put_pixel_physical(win, ix, destIy, pixel);
00238             ix++;
00239             ref--;
00240         }
00241 
00242         /* Next lines */
00243         yref1++;
00244         yref2++;
00245     }
00246 
00247     /* Clear out bottom lines */
00248     yref1 = win->yvpos;
00249     while (yref1 <= win->ypvmax) {
00250 
00251         /* Line clear address */
00252         uint32_t ix = win->xpvmin;
00253         uint32_t destIy = yref1;
00254 
00255         /* Clear a single line at a time */
00256         ref = win->xpvmax - win->xpvmin + 1;
00257         while (ref > 0) {
00258             swim_put_pixel_physical(win, ix, destIy, win->bkg);
00259             ix++;
00260             ref--;
00261         }
00262 
00263         yref1++;
00264     }
00265 }
00266 
00267 /* Puts a single character in the window */
00268 void swim_put_char(SWIM_WINDOW_T *win,
00269                    const CHAR textchar)
00270 {
00271     int32_t i, j;
00272     int32_t charindex;
00273     const uint16_t *charfields;
00274     uint16_t chardata;
00275 
00276     /* If this is a carriage return, do a newline */
00277     if (textchar == '\n') {
00278         swim_put_newline(win);
00279     }
00280     else {
00281         /* Determine index to character data */
00282         charindex = (int32_t) textchar - (int32_t) win->font->first_char;
00283 
00284         /* Will the character fit on the display? */
00285         if ((win->xvpos +
00286              (int32_t) win->font->font_width_table[charindex]) >
00287             win->xpvmax) {
00288             /* Will not fit, do a newline */
00289             swim_put_newline(win);
00290         }
00291 
00292         /* Determine the start of the bitfields for the character */
00293         charfields = win->font->font_table + (charindex *
00294                                               win->font->font_height);
00295 
00296         /* Map character to the window */
00297         /* Each iteration of this loop does a row */
00298         for (i = 0; i < (int32_t) win->font->font_height; i++) {
00299 
00300             /* Get starting pixel in the line */
00301             uint32_t rowIx = win->xvpos;
00302             uint32_t rowIy = win->yvpos + i;
00303 
00304             /* Get character line mapping data */
00305             chardata = charfields[i];
00306 
00307             /* Convert character line bit data to a pixel line in
00308                window */
00309             /* Each iteration of this loop does one pixel of the row */
00310             for (j =
00311                      (int32_t) win->font->font_width_table[charindex];
00312                  j > 0; j--) {
00313                 if ((chardata & 0x8000) != 0) {
00314                     swim_put_pixel_physical(win, rowIx, rowIy, win->pen);
00315                 }
00316                 else if (win->tfont != 0) {
00317                     swim_put_pixel_physical(win, rowIx, rowIy, win->bkg);
00318                 }
00319                 rowIx++;
00320 
00321                 /* Next bit in character line */
00322                 chardata = chardata << 1;
00323             }
00324         }
00325 
00326         /* Increment to next text location */
00327         win->xvpos = win->xvpos +
00328                      (int32_t) win->font->font_width_table[charindex];
00329     }
00330 }
00331 
00332 /* Puts a newline in the window */
00333 void swim_put_newline(SWIM_WINDOW_T *win)
00334 {
00335     int32_t diff;
00336 
00337     /* Set text pointer to start of next line */
00338     win->xvpos = win->xpvmin;
00339     win->yvpos = win->yvpos + (int32_t) win->font->font_height;
00340 
00341     /* Next character is below bottom of window, scroll the window
00342        up */
00343     while ((win->yvpos +
00344             (int32_t) win->font->font_height) > win->ypvmax) {
00345         /* Scroll just enough for the next line */
00346         diff = (int32_t) win->font->font_height -
00347                (win->ypvmax - win->yvpos);
00348         win->yvpos = win->yvpos - diff;
00349         swim_window_scroll(win, diff);
00350     }
00351 }
00352 
00353 /* Sets the active font */
00354 void swim_set_font(SWIM_WINDOW_T *win,
00355                    FONT_T *font)
00356 {
00357     int32_t diff;
00358 
00359     win->font = font;
00360 
00361     /* After changing to the new font, determine if there is enough
00362        room for the font height on the existing line in the window */
00363     if ((win->yvpos + win->font->font_height) > win->ypvmax) {
00364         diff = (int32_t) win->font->font_height -
00365                (win->ypvmax - win->yvpos);
00366         win->yvpos = win->yvpos - diff;
00367         swim_window_scroll(win, diff);
00368     }
00369 }
00370 
00371 /* Returns the active font's height in pixels */
00372 int16_t swim_get_font_height(SWIM_WINDOW_T *win)
00373 {
00374     return win->font->font_height;
00375 }
00376 
00377 void swim_get_string_bounds(SWIM_WINDOW_T *win, const CHAR * text, int* width, int* height)
00378 {
00379     int32_t i = 0;
00380     int w = 0;
00381     *width = 0;
00382     *height = win->font->font_height;
00383 
00384     /* Continue until the entire string is output */
00385     while (text[i] != '\0') {
00386         if (text[i] == '\n') {
00387             *width = MAX(w, *width);
00388             w = 0;
00389             *height += win->font->font_height;
00390         }
00391         else if (((uint8_t) text[i] >= win->font->first_char)
00392                  && ((uint8_t) text[i] <= win->font->last_char)) {
00393                      
00394             /* Determine index to character data */
00395             int charindex = (int) text[i] - (int) win->font->first_char;
00396 
00397             w += win->font->font_width_table[charindex];
00398         }
00399 
00400         i++;
00401     }
00402     
00403     *width = MAX(w, *width);
00404 }
00405 
00406 
00407 /* Creates a title bar for the window */
00408 void swim_set_title(SWIM_WINDOW_T *win,
00409                     const CHAR *title,
00410                     COLOR_T ttlbkcolor)
00411 {
00412     COLOR_T savedf, savedp, savedb;
00413     int32_t savedt;
00414 
00415     /* Is present font height larger than window client height? */
00416     if ((swim_get_font_height(win) < (4 + win->yvsize)) &&
00417         (title != (CHAR *) 0)) {
00418         /* There is enough room for title bar, so continue */
00419 
00420         /* Save original colors and font transparentcy flag */
00421         savedf = win->fill;
00422         savedp = win->pen;
00423         savedb = win->bkg;
00424         savedt = win->tfont;
00425 
00426         /* Set fill color to background color (temporarily)
00427            used with box function */
00428         win->fill = ttlbkcolor;
00429         win->bkg = ttlbkcolor;
00430         win->pen = win->bkg;
00431 
00432         /* Draw the background for the title bar */
00433         swim_put_box(win, 0, 0, win->xvsize,
00434                      (4 + swim_get_font_height(win) - 2));
00435 
00436         /* Reset text starting position for title string */
00437         win->xvpos = win->xpvmin + 2;
00438         win->yvpos = win->ypvmin + 1;
00439 
00440         /* Restore original pen color (used for text color) */
00441         win->pen = savedp;
00442 
00443         /* Restore the original colors */
00444         win->fill = savedf;
00445         win->bkg = savedb;
00446 
00447         /* Put string in title bar area (with transparent background) */
00448         win->tfont = 0;
00449         swim_put_text(win, title);
00450         win->tfont = savedt;
00451 
00452         /* Draw a line under the title bar, but before the
00453            (new) client area */
00454         swim_put_line(win, 0,
00455                       (4 + swim_get_font_height(win) - 1),
00456                       win->xpvmax, (4 + swim_get_font_height(win) - 1));
00457 
00458         /* Adjust client height of window (virtual and physcal) */
00459         win->ypmin = win->ypmin + swim_get_font_height(win) + 4;
00460         win->ypvmin = win->ypvmin + swim_get_font_height(win) + 4;
00461 
00462         /* Resize y dimension */
00463         win->yvsize = win->yvsize - swim_get_font_height(win) + 4;
00464 
00465         /* Reset text starting position to new client area */
00466         win->xvpos = win->xpvmin;
00467         win->yvpos = win->ypvmin;
00468     }
00469 }
00470 
00471 /* Enables and disables font backgrounds */
00472 void swim_set_font_transparency(SWIM_WINDOW_T *win,
00473                                 int32_t trans)
00474 {
00475     win->tfont = trans;
00476 }
00477