2015-11-07 04:07:14 +08:00
|
|
|
/*
|
|
|
|
|
|
|
|
u8x8_8x8.c
|
|
|
|
|
|
|
|
font procedures, directly interfaces display procedures
|
2016-01-01 16:27:17 +08:00
|
|
|
|
2016-01-04 00:10:50 +08:00
|
|
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
2016-01-01 16:27:17 +08:00
|
|
|
|
|
|
|
Copyright (c) 2016, olikraus@gmail.com
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright notice, this list
|
|
|
|
of conditions and the following disclaimer.
|
|
|
|
|
|
|
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
|
|
|
list of conditions and the following disclaimer in the documentation and/or other
|
|
|
|
materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
|
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
|
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2015-11-07 04:07:14 +08:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "u8x8.h"
|
|
|
|
|
2015-11-25 05:21:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-11-27 05:56:56 +08:00
|
|
|
void u8x8_SetFont(u8x8_t *u8x8, const uint8_t *font_8x8)
|
2015-11-07 04:07:14 +08:00
|
|
|
{
|
|
|
|
u8x8->font = font_8x8;
|
|
|
|
}
|
|
|
|
|
2015-11-27 05:56:56 +08:00
|
|
|
void u8x8_DrawGlyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
|
2015-11-07 04:07:14 +08:00
|
|
|
{
|
|
|
|
uint8_t first, last, i;
|
|
|
|
uint8_t buf[8];
|
|
|
|
uint16_t offset;
|
|
|
|
first = u8x8_pgm_read(u8x8->font+0);
|
|
|
|
last = u8x8_pgm_read(u8x8->font+1);
|
|
|
|
|
|
|
|
if ( first <= encoding && encoding <= last )
|
|
|
|
{
|
|
|
|
offset = encoding;
|
|
|
|
offset -= first;
|
|
|
|
offset *= 8;
|
|
|
|
offset +=2;
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
{
|
|
|
|
buf[i] = u8x8_pgm_read(u8x8->font+offset);
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
{
|
|
|
|
buf[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
2015-12-13 16:19:09 +08:00
|
|
|
if ( u8x8->is_font_inverse_mode )
|
|
|
|
{
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
|
|
{
|
|
|
|
buf[i] ^= 255;
|
|
|
|
}
|
|
|
|
}
|
2015-12-08 05:14:17 +08:00
|
|
|
u8x8_DrawTile(u8x8, x, y, 1, buf);
|
2015-11-07 04:07:14 +08:00
|
|
|
}
|
|
|
|
|
2015-11-25 05:21:17 +08:00
|
|
|
/*
|
|
|
|
source: https://en.wikipedia.org/wiki/UTF-8
|
|
|
|
Bits from to bytes Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
|
|
|
|
7 U+0000 U+007F 1 0xxxxxxx
|
|
|
|
11 U+0080 U+07FF 2 110xxxxx 10xxxxxx
|
|
|
|
16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
|
|
|
|
21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
|
|
26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
|
|
31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
2015-11-27 04:41:33 +08:00
|
|
|
|
|
|
|
This function returns 0x0ffff for end of string (0x0ffff is not a unicode glyph)
|
|
|
|
|
2015-11-25 05:21:17 +08:00
|
|
|
*/
|
2016-05-06 04:21:28 +08:00
|
|
|
#ifdef OBSOLETE
|
2015-11-25 05:21:17 +08:00
|
|
|
uint16_t u8x8_get_encoding_from_utf8_string(const char **str)
|
|
|
|
{
|
|
|
|
uint16_t e;
|
|
|
|
uint8_t b;
|
|
|
|
b = **str;
|
|
|
|
if ( b >= 0xc0 )
|
|
|
|
{
|
|
|
|
if ( b >= 0xf0 ) /* check for UTF-8 4, 5 and 6-byte sequence */
|
|
|
|
{
|
|
|
|
b &= 0x01; /* only consider lowest bit, because only plane 0 (16 bit) is supported with u8glib v2 */
|
|
|
|
}
|
|
|
|
else if ( b >= 0xe0 ) /* check for UTF-8 3-byte sequence */
|
|
|
|
{
|
|
|
|
b &= 0x0f;
|
|
|
|
}
|
|
|
|
else /* assume UTF-8 2-byte sequence */
|
|
|
|
{
|
|
|
|
b &= 0x1f;
|
|
|
|
}
|
|
|
|
e = b;
|
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
(*str)++;
|
|
|
|
b = **str;
|
|
|
|
if ( (b & 0x0c0) != 0x080 )
|
|
|
|
break;
|
|
|
|
b &= 0x3f;
|
|
|
|
e <<=6;
|
|
|
|
e |= b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
e = b; /* init with ASCII code */
|
|
|
|
(*str)++;
|
|
|
|
}
|
|
|
|
return e;
|
|
|
|
}
|
2016-05-06 04:21:28 +08:00
|
|
|
#endif
|
2015-11-25 05:21:17 +08:00
|
|
|
|
2016-05-06 04:21:28 +08:00
|
|
|
/* reset the internal state machine */
|
|
|
|
void u8x8_utf8_init(u8x8_t *u8x8)
|
|
|
|
{
|
|
|
|
u8x8->utf8_state = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t u8x8_ascii_next(u8x8_t *u8x8, uint8_t b)
|
|
|
|
{
|
2016-05-21 14:09:17 +08:00
|
|
|
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
|
2016-05-06 04:21:28 +08:00
|
|
|
return 0x0ffff; /* end of string detected*/
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
pass a byte from an utf8 encoded string to the utf8 decoder state machine
|
|
|
|
returns
|
|
|
|
0x0fffe: no glyph, just continue
|
|
|
|
0x0ffff: end of string
|
|
|
|
anything else: The decoded encoding
|
|
|
|
*/
|
|
|
|
uint16_t u8x8_utf8_next(u8x8_t *u8x8, uint8_t b)
|
|
|
|
{
|
2016-05-21 14:09:17 +08:00
|
|
|
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
|
2016-05-06 04:21:28 +08:00
|
|
|
return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
|
|
|
|
if ( u8x8->utf8_state == 0 )
|
|
|
|
{
|
|
|
|
if ( b >= 0xfc ) /* 6 byte sequence */
|
|
|
|
{
|
|
|
|
u8x8->utf8_state = 5;
|
|
|
|
b &= 1;
|
|
|
|
}
|
|
|
|
else if ( b >= 0xf8 )
|
|
|
|
{
|
|
|
|
u8x8->utf8_state = 4;
|
|
|
|
b &= 3;
|
|
|
|
}
|
|
|
|
else if ( b >= 0xf0 )
|
|
|
|
{
|
|
|
|
u8x8->utf8_state = 3;
|
|
|
|
b &= 7;
|
|
|
|
}
|
|
|
|
else if ( b >= 0xe0 )
|
|
|
|
{
|
|
|
|
u8x8->utf8_state = 2;
|
|
|
|
b &= 15;
|
|
|
|
}
|
|
|
|
else if ( b >= 0xc0 )
|
|
|
|
{
|
|
|
|
u8x8->utf8_state = 1;
|
|
|
|
b &= 0x01f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* do nothing, just use the value as encoding */
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
u8x8->encoding = b;
|
|
|
|
return 0x0fffe;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u8x8->utf8_state--;
|
|
|
|
/* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
|
|
|
|
u8x8->encoding<<=6;
|
|
|
|
b &= 0x03f;
|
|
|
|
u8x8->encoding |= b;
|
|
|
|
if ( u8x8->utf8_state != 0 )
|
|
|
|
return 0x0fffe; /* nothing to do yet */
|
|
|
|
}
|
|
|
|
return u8x8->encoding;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef OBSOLETE
|
2015-11-27 05:56:56 +08:00
|
|
|
uint16_t u8x8_get_char_from_string(const char **str)
|
|
|
|
{
|
|
|
|
uint8_t b = **str;
|
|
|
|
(*str)++;
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
|
|
|
|
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
2015-11-27 04:41:33 +08:00
|
|
|
{
|
|
|
|
uint16_t c;
|
|
|
|
uint8_t cnt = 0;
|
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
c = u8x8->char_cb(&s);
|
|
|
|
if ( c == 0 )
|
|
|
|
break;
|
|
|
|
if ( c <= 255 )
|
|
|
|
{
|
2015-11-27 05:56:56 +08:00
|
|
|
u8x8_DrawGlyph(u8x8, x, y, (uint8_t)c);
|
2015-11-27 04:41:33 +08:00
|
|
|
x++;
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cnt;
|
|
|
|
}
|
2016-05-06 04:21:28 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
|
|
|
|
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
|
|
|
{
|
|
|
|
uint16_t e;
|
|
|
|
uint8_t cnt = 0;
|
|
|
|
u8x8_utf8_init(u8x8);
|
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
e = u8x8->next_cb(u8x8, (uint8_t)*s);
|
|
|
|
if ( e == 0x0ffff )
|
|
|
|
break;
|
|
|
|
s++;
|
|
|
|
if ( e != 0x0fffe )
|
|
|
|
{
|
|
|
|
u8x8_DrawGlyph(u8x8, x, y, e);
|
|
|
|
x++;
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
2015-11-27 04:41:33 +08:00
|
|
|
|
2015-11-27 05:56:56 +08:00
|
|
|
uint8_t u8x8_DrawString(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
|
|
|
{
|
2016-05-06 04:21:28 +08:00
|
|
|
u8x8->next_cb = u8x8_ascii_next;
|
2015-11-27 05:56:56 +08:00
|
|
|
return u8x8_draw_string(u8x8, x, y, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t u8x8_DrawUTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
2015-11-27 04:41:33 +08:00
|
|
|
{
|
2016-05-06 04:21:28 +08:00
|
|
|
u8x8->next_cb = u8x8_utf8_next;
|
2015-11-27 04:41:33 +08:00
|
|
|
return u8x8_draw_string(u8x8, x, y, s);
|
|
|
|
}
|
|
|
|
|
2016-05-06 04:21:28 +08:00
|
|
|
uint8_t u8x8_GetUTF8Len(u8x8_t *u8x8, const char *s)
|
2015-11-27 05:56:56 +08:00
|
|
|
{
|
2016-05-06 04:21:28 +08:00
|
|
|
uint16_t e;
|
2015-11-27 05:56:56 +08:00
|
|
|
uint8_t cnt = 0;
|
2016-05-06 04:21:28 +08:00
|
|
|
u8x8_utf8_init(u8x8);
|
2015-11-27 05:56:56 +08:00
|
|
|
for(;;)
|
|
|
|
{
|
2016-05-06 04:21:28 +08:00
|
|
|
e = u8x8_utf8_next(u8x8, *s);
|
|
|
|
if ( e == 0x0ffff )
|
2015-11-27 05:56:56 +08:00
|
|
|
break;
|
2016-05-06 04:21:28 +08:00
|
|
|
s++;
|
|
|
|
if ( e != 0x0fffe )
|
2015-11-27 05:56:56 +08:00
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
2015-11-27 04:41:33 +08:00
|
|
|
|
|
|
|
/*
|
2015-11-25 05:21:17 +08:00
|
|
|
void u8x8_Draw8x8UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
|
|
|
{
|
|
|
|
uint16_t unicode;
|
2015-11-27 04:41:33 +08:00
|
|
|
for(;;)
|
2015-11-25 05:21:17 +08:00
|
|
|
{
|
|
|
|
unicode = u8x8_get_encoding_from_utf8_string(&s);
|
2015-11-27 04:41:33 +08:00
|
|
|
if ( unicode == 0 )
|
|
|
|
break;
|
2015-11-25 05:21:17 +08:00
|
|
|
if ( unicode <= 255 )
|
|
|
|
{
|
|
|
|
u8x8_Draw8x8Glyph(u8x8, x, y, (uint8_t)unicode);
|
|
|
|
x++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-27 04:41:33 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|