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
Diff: lpc_swim/lpc_swim_font.c
- Revision:
- 0:4977187e90c7
- Child:
- 19:f3d0189401e4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lpc_swim/lpc_swim_font.c Thu Dec 11 11:03:57 2014 +0000 @@ -0,0 +1,476 @@ +/* + * @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; + uint16_t *charfields, 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; +} +