Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of DMBasicGUI by
lpc_swim/lpc_swim_font.c
- Committer:
- redbird
- Date:
- 2016-03-14
- Revision:
- 38:1b7c79a10e14
- Parent:
- 19:f3d0189401e4
File content as of revision 38:1b7c79a10e14:
/*
* @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;
}
