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
lpc_swim/lpc_swim_font.c
- Committer:
- embeddedartists
- Date:
- 2019-11-04
- Revision:
- 22:f0d00f29bfeb
- Parent:
- 19:f3d0189401e4
File content as of revision 22:f0d00f29bfeb:
/* * @brief SWIM font management * * @note * Copyright(C) NXP Semiconductors, 2012 * All rights reserved. * * @par * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * LPC products. This software is supplied "AS IS" without any warranties of * any kind, and NXP Semiconductors and its licensor disclaim any and * all warranties, express or implied, including all implied warranties of * merchantability, fitness for a particular purpose and non-infringement of * intellectual property rights. NXP Semiconductors assumes no responsibility * or liability for the use of the software, conveys no license or rights under any * patent, copyright, mask work right, or any other intellectual property rights in * or to any products. NXP Semiconductors reserves the right to make changes * in the software without notification. NXP Semiconductors also makes no * representation or warranty that such application will be suitable for the * specified use without further testing or modification. * * @par * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, under NXP Semiconductors' and its * licensor's relevant copyrights in the software, without fee, provided that it * is used in conjunction with NXP Semiconductors microcontrollers. This * copyright, permission, and disclaimer notice must appear in all copies of * this code. */ #include "lpc_swim_font.h" /***************************************************************************** * Private types/enumerations/variables ****************************************************************************/ /***************************************************************************** * Public types/enumerations/variables ****************************************************************************/ /***************************************************************************** * Private functions ****************************************************************************/ /* Determines the length of the word (in pixels) up to the first whitespace character */ static int16_t swim_get_word_len(SWIM_WINDOW_T *win, const CHAR *text) { int32_t i; int16_t wlen = 0; /* Find the length in pixels of the next word (separated by whitespace) */ i = 0; while (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) { wlen = wlen + win->font->font_width_table [(uint8_t) text[i] - win->font->first_char]; i++; } return wlen; } /* Puts a word in the window, but adds a newline to keep the word contiguous (without an edge break) if necessary */ static int32_t swim_put_word(SWIM_WINDOW_T *win, const CHAR *text) { int32_t i; /* Will the length of the next word exceed the window margin? */ if ((swim_get_word_len(win, text) + win->xvpos) > win->xpvmax) { /* Do a newline */ swim_put_newline(win); } /* Put just the word characters on the display up to the next non-whitespace character or the end of the string */ i = 0; while (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) { swim_put_char(win, text[i]); i++; } return i; } /*********************************************************************** * Public functions **********************************************************************/ /* Put text at x, y (char) position on screen */ void swim_put_text_centered_win(SWIM_WINDOW_T *win, const CHAR *text, int32_t y) { swim_put_text_centered(win, text, 0, win->xvsize-1, y); } /* Put text at x, y (char) position on screen */ void swim_put_text_centered(SWIM_WINDOW_T *win, const CHAR *text, int32_t x0, int32_t x1, int32_t y) { int w, h; if (x0 > x1) { w = x0; x0 = x1; x1 = w; } swim_get_string_bounds(win, text, &w, &h); swim_put_text_xy(win, text, x0 + (x1-x0-w)/2, y); } /* Put text at x, y (char) position on screen */ void swim_put_text_xy(SWIM_WINDOW_T *win, const CHAR *text, int32_t x, int32_t y) { /* Convert virtual x, y positon to physical position */ swim_set_xy(win, x, y); /* Display text string */ swim_put_text(win, text); } /* Sets the X, Y pixel coordinates for the next text operation */ void swim_set_xy(SWIM_WINDOW_T *win, int32_t x, int32_t y) { win->xvpos = x + win->xpvmin; win->yvpos = y + win->ypvmin; /* Limit to window dimensions */ if (win->xvpos < win->xpvmin) { win->xvpos = win->xpvmin; } else if (win->xvpos > win->xpvmax) { win->xvpos = win->xpvmax; } if (win->yvpos < win->ypvmin) { win->yvpos = win->ypvmin; } else if (win->yvpos > win->ypvmax) { win->yvpos = win->ypvmax; } } /* Returns the X, Y pixel coordinates for the next text operation */ void swim_get_xy(SWIM_WINDOW_T *win, int32_t *x, int32_t *y) { *x = win->xvpos - win->xpvmin; *y = win->yvpos - win->ypvmin; } /* Puts a string of text in a window */ void swim_put_text(SWIM_WINDOW_T *win, const CHAR *text) { int32_t i = 0; /* Continue until the entire string is output */ while (text[i] != '\0') { if (text[i] == '\n') { swim_put_newline(win); } else if (((uint8_t) text[i] >= win->font->first_char) && ((uint8_t) text[i] <= win->font->last_char)) { /* Put character on screen */ swim_put_char(win, text[i]); } i++; } } /* Puts a string of text in a window with breaks */ void swim_put_ltext(SWIM_WINDOW_T *win, const CHAR *text) { int32_t i = 0; /* Continue until the entire string is output */ while (text[i] != '\0') { if (text[i] == '\n') { swim_put_newline(win); i++; } else if (((uint8_t) text[i] >= win->font->first_char) && ((uint8_t) text[i] <= win->font->last_char)) { /* Check for entire words first */ if (((uint8_t) text[i] > ' ') && ((uint8_t) text[i] <= 0x7E)) { /* Put entire word on screen */ i = i + swim_put_word(win, &text[i]); } else { swim_put_char(win, text[i]); i++; } } else { /* Put a space out */ swim_put_char(win, ' '); i++; } } } /* xx */ void swim_window_scroll(SWIM_WINDOW_T *win, int32_t lines) { int32_t yref1 = win->ypvmin; int32_t yref2 = yref1 + lines; int32_t ref; while (yref2 <= win->ypvmax) { /* Line move addresses */ uint32_t ix = win->xpvmin; uint32_t destIy = yref1; uint32_t srcIy = yref2; /* Move a single line at a time */ ref = win->xpvmax - win->xpvmin + 1; while (ref > 0) { COLOR_T pixel = swim_get_pixel_physical(win, ix, srcIy); swim_put_pixel_physical(win, ix, destIy, pixel); ix++; ref--; } /* Next lines */ yref1++; yref2++; } /* Clear out bottom lines */ yref1 = win->yvpos; while (yref1 <= win->ypvmax) { /* Line clear address */ uint32_t ix = win->xpvmin; uint32_t destIy = yref1; /* Clear a single line at a time */ ref = win->xpvmax - win->xpvmin + 1; while (ref > 0) { swim_put_pixel_physical(win, ix, destIy, win->bkg); ix++; ref--; } yref1++; } } /* Puts a single character in the window */ void swim_put_char(SWIM_WINDOW_T *win, const CHAR textchar) { int32_t i, j; int32_t charindex; const uint16_t *charfields; uint16_t chardata; /* If this is a carriage return, do a newline */ if (textchar == '\n') { swim_put_newline(win); } else { /* Determine index to character data */ charindex = (int32_t) textchar - (int32_t) win->font->first_char; /* Will the character fit on the display? */ if ((win->xvpos + (int32_t) win->font->font_width_table[charindex]) > win->xpvmax) { /* Will not fit, do a newline */ swim_put_newline(win); } /* Determine the start of the bitfields for the character */ charfields = win->font->font_table + (charindex * win->font->font_height); /* Map character to the window */ /* Each iteration of this loop does a row */ for (i = 0; i < (int32_t) win->font->font_height; i++) { /* Get starting pixel in the line */ uint32_t rowIx = win->xvpos; uint32_t rowIy = win->yvpos + i; /* Get character line mapping data */ chardata = charfields[i]; /* Convert character line bit data to a pixel line in window */ /* Each iteration of this loop does one pixel of the row */ for (j = (int32_t) win->font->font_width_table[charindex]; j > 0; j--) { if ((chardata & 0x8000) != 0) { swim_put_pixel_physical(win, rowIx, rowIy, win->pen); } else if (win->tfont != 0) { swim_put_pixel_physical(win, rowIx, rowIy, win->bkg); } rowIx++; /* Next bit in character line */ chardata = chardata << 1; } } /* Increment to next text location */ win->xvpos = win->xvpos + (int32_t) win->font->font_width_table[charindex]; } } /* Puts a newline in the window */ void swim_put_newline(SWIM_WINDOW_T *win) { int32_t diff; /* Set text pointer to start of next line */ win->xvpos = win->xpvmin; win->yvpos = win->yvpos + (int32_t) win->font->font_height; /* Next character is below bottom of window, scroll the window up */ while ((win->yvpos + (int32_t) win->font->font_height) > win->ypvmax) { /* Scroll just enough for the next line */ diff = (int32_t) win->font->font_height - (win->ypvmax - win->yvpos); win->yvpos = win->yvpos - diff; swim_window_scroll(win, diff); } } /* Sets the active font */ void swim_set_font(SWIM_WINDOW_T *win, FONT_T *font) { int32_t diff; win->font = font; /* After changing to the new font, determine if there is enough room for the font height on the existing line in the window */ if ((win->yvpos + win->font->font_height) > win->ypvmax) { diff = (int32_t) win->font->font_height - (win->ypvmax - win->yvpos); win->yvpos = win->yvpos - diff; swim_window_scroll(win, diff); } } /* Returns the active font's height in pixels */ int16_t swim_get_font_height(SWIM_WINDOW_T *win) { return win->font->font_height; } void swim_get_string_bounds(SWIM_WINDOW_T *win, const CHAR * text, int* width, int* height) { int32_t i = 0; int w = 0; *width = 0; *height = win->font->font_height; /* Continue until the entire string is output */ while (text[i] != '\0') { if (text[i] == '\n') { *width = MAX(w, *width); w = 0; *height += win->font->font_height; } else if (((uint8_t) text[i] >= win->font->first_char) && ((uint8_t) text[i] <= win->font->last_char)) { /* Determine index to character data */ int charindex = (int) text[i] - (int) win->font->first_char; w += win->font->font_width_table[charindex]; } i++; } *width = MAX(w, *width); } /* Creates a title bar for the window */ void swim_set_title(SWIM_WINDOW_T *win, const CHAR *title, COLOR_T ttlbkcolor) { COLOR_T savedf, savedp, savedb; int32_t savedt; /* Is present font height larger than window client height? */ if ((swim_get_font_height(win) < (4 + win->yvsize)) && (title != (CHAR *) 0)) { /* There is enough room for title bar, so continue */ /* Save original colors and font transparentcy flag */ savedf = win->fill; savedp = win->pen; savedb = win->bkg; savedt = win->tfont; /* Set fill color to background color (temporarily) used with box function */ win->fill = ttlbkcolor; win->bkg = ttlbkcolor; win->pen = win->bkg; /* Draw the background for the title bar */ swim_put_box(win, 0, 0, win->xvsize, (4 + swim_get_font_height(win) - 2)); /* Reset text starting position for title string */ win->xvpos = win->xpvmin + 2; win->yvpos = win->ypvmin + 1; /* Restore original pen color (used for text color) */ win->pen = savedp; /* Restore the original colors */ win->fill = savedf; win->bkg = savedb; /* Put string in title bar area (with transparent background) */ win->tfont = 0; swim_put_text(win, title); win->tfont = savedt; /* Draw a line under the title bar, but before the (new) client area */ swim_put_line(win, 0, (4 + swim_get_font_height(win) - 1), win->xpvmax, (4 + swim_get_font_height(win) - 1)); /* Adjust client height of window (virtual and physcal) */ win->ypmin = win->ypmin + swim_get_font_height(win) + 4; win->ypvmin = win->ypvmin + swim_get_font_height(win) + 4; /* Resize y dimension */ win->yvsize = win->yvsize - swim_get_font_height(win) + 4; /* Reset text starting position to new client area */ win->xvpos = win->xpvmin; win->yvpos = win->ypvmin; } } /* Enables and disables font backgrounds */ void swim_set_font_transparency(SWIM_WINDOW_T *win, int32_t trans) { win->tfont = trans; }