ClipPlus BOOTLOADER DONT FIT!
REMOVED FROM ALL NATIVE BOOTLOADERS: finish removing the text scrolling pare down printf to a minimal subset (%c %s %l %d %u and %x(%p)) remove diacritic and rtl language support GOAL 134000 START 135305 CURRENT 133700 SUCCESS! (ASSUMING IT WORKS -- UNESTED) Change-Id: Ic3f6ac1dc260578f581ee53458b3e5bb47d313ec
This commit is contained in:
parent
a8aa8403ad
commit
d78a37676e
7 changed files with 529 additions and 3 deletions
|
@ -1,4 +1,6 @@
|
||||||
common.c
|
common.c
|
||||||
|
format.c
|
||||||
|
snprintf.c
|
||||||
|
|
||||||
#if defined(IPOD_NANO2G)
|
#if defined(IPOD_NANO2G)
|
||||||
ipodnano2g.c
|
ipodnano2g.c
|
||||||
|
|
324
bootloader/format.c
Normal file
324
bootloader/format.c
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 by Gary Czvitkovicz
|
||||||
|
* Copyright (C) 2017 by William Wilgus
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "file.h"
|
||||||
|
#include "format.h"
|
||||||
|
|
||||||
|
static const char hexdigit[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
/* smaller compressed binary without inline but 18% slower */
|
||||||
|
#define FMT_DECL static inline
|
||||||
|
|
||||||
|
FMT_DECL int fmt_width_precision(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
(void) str;
|
||||||
|
(void) ap;
|
||||||
|
|
||||||
|
while (*ch >= '0' && *ch <= '9')
|
||||||
|
{
|
||||||
|
value = 10 * value + (*ch - '0');
|
||||||
|
*ch = *(*fmt)++;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_integer_signed(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
int val, rem, sign;
|
||||||
|
(void) ch;
|
||||||
|
(void) fmt;
|
||||||
|
|
||||||
|
val = sign = va_arg(*ap, int);
|
||||||
|
if (val < 0)
|
||||||
|
val = -val;
|
||||||
|
do {
|
||||||
|
rem = val % 10;
|
||||||
|
val /= 10;
|
||||||
|
*--(*str) = rem + '0';
|
||||||
|
|
||||||
|
} while (val > 0);
|
||||||
|
|
||||||
|
if (sign < 0)
|
||||||
|
*--(*str) = '-';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_integer_unsigned(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
unsigned int uval, urem;
|
||||||
|
(void) ch;
|
||||||
|
(void) fmt;
|
||||||
|
|
||||||
|
uval = va_arg(*ap, unsigned int);
|
||||||
|
do {
|
||||||
|
urem = uval % 10;
|
||||||
|
uval /= 10;
|
||||||
|
*--(*str) = urem + '0';
|
||||||
|
} while (uval > 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_long(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
int pad = 0;
|
||||||
|
long lval, lrem, lsign = 0;
|
||||||
|
unsigned long ulval, ulrem;
|
||||||
|
char ch_l = *ch;
|
||||||
|
|
||||||
|
*ch = *(*fmt)++;
|
||||||
|
if (*ch == 'd') {
|
||||||
|
lval = lsign = va_arg(*ap, long);
|
||||||
|
|
||||||
|
if (lval < 0)
|
||||||
|
lval = -lval;
|
||||||
|
do {
|
||||||
|
lrem = lval % 10;
|
||||||
|
lval /= 10;
|
||||||
|
*--(*str) = lrem + '0';
|
||||||
|
} while (lval > 0);
|
||||||
|
|
||||||
|
if (lsign < 0)
|
||||||
|
*--(*str) = '-';
|
||||||
|
}
|
||||||
|
else if (*ch == 'u') {
|
||||||
|
ulval = va_arg(*ap, unsigned long);
|
||||||
|
do {
|
||||||
|
ulrem = ulval % 10;
|
||||||
|
ulval /= 10;
|
||||||
|
*--(*str) = ulrem + '0';
|
||||||
|
} while (ulval > 0);
|
||||||
|
}
|
||||||
|
else if (*ch == 'x' || *ch == 'X') {
|
||||||
|
pad++;
|
||||||
|
ulval = va_arg(*ap, long);
|
||||||
|
do {
|
||||||
|
*--(*str) = hexdigit[ulval & 0xf];
|
||||||
|
ulval >>= 4;
|
||||||
|
} while (ulval > 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*--(*str) = ch_l;
|
||||||
|
*--(*str) = *ch;
|
||||||
|
}
|
||||||
|
return pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_character(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
(void) ch;
|
||||||
|
(void) fmt;
|
||||||
|
|
||||||
|
*--(*str) = va_arg(*ap, int);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_string(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
(void) ch;
|
||||||
|
(void) fmt;
|
||||||
|
|
||||||
|
*str = va_arg (*ap, char*);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_hex_unsigned(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
unsigned int uval;
|
||||||
|
(void) ch;
|
||||||
|
(void) fmt;
|
||||||
|
|
||||||
|
uval = va_arg(*ap, int);
|
||||||
|
do {
|
||||||
|
*--(*str) = hexdigit[uval & 0xf];
|
||||||
|
uval >>= 4;
|
||||||
|
} while (uval > 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_pointer(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
int pad = fmt_hex_unsigned(ch, fmt, str, ap);
|
||||||
|
/* for pointers prepend 0x and act like 'X' */
|
||||||
|
*--(*str) = 'x';
|
||||||
|
*--(*str) = '0';
|
||||||
|
return pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_DECL int fmt_sizet(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
size_t uszval, uszrem;
|
||||||
|
ssize_t szval, szrem, szsign;
|
||||||
|
char ch_z = *ch;
|
||||||
|
*ch = *(*fmt)++;
|
||||||
|
|
||||||
|
if (*ch == 'd') {
|
||||||
|
szval = szsign = va_arg(*ap, ssize_t);
|
||||||
|
if (szval < 0)
|
||||||
|
szval = -szval;
|
||||||
|
do {
|
||||||
|
szrem = szval % 10;
|
||||||
|
szval /= 10;
|
||||||
|
*--(*str) = szrem + '0';
|
||||||
|
} while (szval > 0);
|
||||||
|
|
||||||
|
if (szsign < 0)
|
||||||
|
*--(*str) = '-';
|
||||||
|
}
|
||||||
|
else if (*ch == 'u') {
|
||||||
|
uszval = va_arg(*ap, size_t);
|
||||||
|
do {
|
||||||
|
uszrem = uszval % 10;
|
||||||
|
uszval /= 10;
|
||||||
|
*--(*str) = uszrem + '0';
|
||||||
|
} while (uszval > 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*--(*str) = ch_z;
|
||||||
|
*--(*str) = *ch;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int fmt_next_char(int *ch, const char **fmt, char **str, va_list *ap)
|
||||||
|
{
|
||||||
|
(void) fmt;
|
||||||
|
(void) ap;
|
||||||
|
|
||||||
|
*--(*str) = *ch;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void format(
|
||||||
|
/* call 'push()' for each output letter */
|
||||||
|
int (*push)(void *userp, unsigned char data),
|
||||||
|
void *userp,
|
||||||
|
const char *fmt,
|
||||||
|
va_list ap)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
char *str;
|
||||||
|
char tmpbuf[12], pad;
|
||||||
|
int ch, width, precision, padded;
|
||||||
|
|
||||||
|
|
||||||
|
ch = *fmt++;
|
||||||
|
tmpbuf[sizeof tmpbuf - 1] = '\0';
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (ch == '%')
|
||||||
|
{
|
||||||
|
str = tmpbuf + sizeof tmpbuf - 1;
|
||||||
|
ch = *fmt++;
|
||||||
|
padded = (ch == '0' ? 1 : 0);
|
||||||
|
width = fmt_width_precision(&ch, &fmt, &str, &ap);
|
||||||
|
|
||||||
|
precision = INT_MAX;
|
||||||
|
if(ch == '.')
|
||||||
|
{
|
||||||
|
ch = *fmt++;
|
||||||
|
precision = fmt_width_precision(&ch, &fmt, &str, &ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == 'd')
|
||||||
|
fmt_integer_signed(&ch, &fmt, &str, &ap);
|
||||||
|
else if (ch == 'u')
|
||||||
|
fmt_integer_unsigned(&ch, &fmt, &str, &ap);
|
||||||
|
else if (ch == 'l')
|
||||||
|
padded += fmt_long(&ch, &fmt, &str, &ap);
|
||||||
|
else if (ch == 'c')
|
||||||
|
fmt_character(&ch, &fmt, &str, &ap);
|
||||||
|
else if (ch == 's')
|
||||||
|
fmt_string(&ch, &fmt, &str, &ap);
|
||||||
|
else if (ch == 'x' || ch == 'X')
|
||||||
|
padded += fmt_hex_unsigned(&ch, &fmt, &str, &ap);
|
||||||
|
else if (ch == 'p' || ch == 'P')
|
||||||
|
padded += fmt_pointer(&ch, &fmt, &str, &ap);
|
||||||
|
#if 0
|
||||||
|
else if (ch == 'z')
|
||||||
|
fmt_sizet(&ch, &fmt, &str, &ap);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
fmt_next_char(&ch, &fmt, &str, &ap);
|
||||||
|
|
||||||
|
width -= strlen (str);
|
||||||
|
if (width > 0)
|
||||||
|
{
|
||||||
|
pad = (padded ? '0' : ' ');
|
||||||
|
while (width-- > 0 && ok)
|
||||||
|
ok=push(userp, pad);
|
||||||
|
}
|
||||||
|
while(*str != '\0' && ok && precision--)
|
||||||
|
ok=push(userp, *str++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ok=push(userp, ch);
|
||||||
|
|
||||||
|
} while ((ch = *fmt++) != '\0' && ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct for_fprintf {
|
||||||
|
int fd; /* where to store it */
|
||||||
|
int bytes; /* amount stored */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int fprfunc(void *pr, unsigned char letter)
|
||||||
|
{
|
||||||
|
struct for_fprintf *fpr = (struct for_fprintf *)pr;
|
||||||
|
int rc = write(fpr->fd, &letter, 1);
|
||||||
|
|
||||||
|
if(rc > 0) {
|
||||||
|
fpr->bytes++; /* count them */
|
||||||
|
return true; /* we are ok */
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int fdprintf(int fd, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
struct for_fprintf fpr;
|
||||||
|
|
||||||
|
fpr.fd=fd;
|
||||||
|
fpr.bytes=0;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
format(fprfunc, &fpr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return fpr.bytes; /* return 0 on error */
|
||||||
|
}
|
||||||
|
|
||||||
|
void vuprintf(int (*push)(void *userp, unsigned char data), void *userp, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
format(push, userp, fmt, ap);
|
||||||
|
}
|
37
bootloader/format.h
Normal file
37
bootloader/format.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 by Felix Arends
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __FORMAT_H__
|
||||||
|
#define __FORMAT_H__
|
||||||
|
|
||||||
|
void format(
|
||||||
|
/* call 'push()' for each output letter */
|
||||||
|
int (*push)(void *userp, unsigned char data),
|
||||||
|
void *userp,
|
||||||
|
const char *fmt,
|
||||||
|
va_list ap);
|
||||||
|
|
||||||
|
/* callback function is called for every output character (byte) with userp and
|
||||||
|
* should return 0 when ch is a char other than '\0' that should stop printing */
|
||||||
|
void vuprintf(int (*push)(void *userp, unsigned char data),
|
||||||
|
void *userp, const char *fmt, va_list ap);
|
||||||
|
|
||||||
|
#endif /* __FORMAT_H__ */
|
80
bootloader/snprintf.c
Normal file
80
bootloader/snprintf.c
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 by Gary Czvitkovicz
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minimal printf and snprintf formatting functions
|
||||||
|
*
|
||||||
|
* These support %c %s %l %d %u and %x(%p)
|
||||||
|
* Field width and zero-padding flag only
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "format.h"
|
||||||
|
|
||||||
|
struct for_snprintf {
|
||||||
|
unsigned char *ptr; /* where to store it */
|
||||||
|
size_t bytes; /* amount already stored */
|
||||||
|
size_t max; /* max amount to store */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sprfunc(void *ptr, unsigned char letter)
|
||||||
|
{
|
||||||
|
struct for_snprintf *pr = (struct for_snprintf *)ptr;
|
||||||
|
if(pr->bytes < pr->max) {
|
||||||
|
*pr->ptr = letter;
|
||||||
|
pr->ptr++;
|
||||||
|
pr->bytes++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; /* filled buffer */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int snprintf(char *buf, size_t size, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = vsnprintf(buf, size, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
struct for_snprintf pr;
|
||||||
|
|
||||||
|
pr.ptr = (unsigned char *)buf;
|
||||||
|
pr.bytes = 0;
|
||||||
|
pr.max = size;
|
||||||
|
|
||||||
|
format(sprfunc, &pr, fmt, ap);
|
||||||
|
|
||||||
|
/* make sure it ends with a trailing zero */
|
||||||
|
pr.ptr[(pr.bytes < pr.max) ? 0 : -1] = '\0';
|
||||||
|
|
||||||
|
return pr.bytes;
|
||||||
|
}
|
|
@ -194,7 +194,7 @@ static const struct diac_range diac_ranges[] =
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MRU_MAX_LEN 32
|
#define MRU_MAX_LEN 32
|
||||||
|
#ifndef BOOTLOADER
|
||||||
bool is_diacritic(const unsigned short char_code, bool *is_rtl)
|
bool is_diacritic(const unsigned short char_code, bool *is_rtl)
|
||||||
{
|
{
|
||||||
static uint8_t mru_len = 0;
|
static uint8_t mru_len = 0;
|
||||||
|
@ -248,4 +248,12 @@ Found:
|
||||||
|
|
||||||
return (char_code < diac->base + (info & DIAC_CNT));
|
return (char_code < diac->base + (info & DIAC_CNT));
|
||||||
}
|
}
|
||||||
|
#else /*BOOTLOADER*/
|
||||||
|
inline bool is_diacritic(const unsigned short char_code, bool *is_rtl)
|
||||||
|
{
|
||||||
|
(void)char_code;
|
||||||
|
if (is_rtl)
|
||||||
|
*is_rtl = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif /* ndef BOOTLOADER*/
|
||||||
|
|
|
@ -118,6 +118,7 @@ void LCDFN(update_viewport_rect)(int x, int y, int width, int height)
|
||||||
LCDFN(update_rect)(current_vp->x + x, current_vp->y + y, width, height);
|
LCDFN(update_rect)(current_vp->x + x, current_vp->y + y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER
|
||||||
/* put a string at a given pixel position, skipping first ofs pixel columns */
|
/* put a string at a given pixel position, skipping first ofs pixel columns */
|
||||||
static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
|
static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
|
||||||
{
|
{
|
||||||
|
@ -257,6 +258,72 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
|
||||||
}
|
}
|
||||||
font_lock(current_vp->font, false);
|
font_lock(current_vp->font, false);
|
||||||
}
|
}
|
||||||
|
#else /* BOOTLOADER */
|
||||||
|
/* put a string at a given pixel position, skipping first ofs pixel columns */
|
||||||
|
static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
|
||||||
|
{
|
||||||
|
unsigned short *ucs;
|
||||||
|
struct font* pf = font_get(current_vp->font);
|
||||||
|
int vp_flags = current_vp->flags;
|
||||||
|
const unsigned char *bits;
|
||||||
|
int width;
|
||||||
|
|
||||||
|
if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0)
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
|
||||||
|
LCDFN(getstringsize)(str, &w, NULL);
|
||||||
|
/* center takes precedence */
|
||||||
|
if (vp_flags & VP_FLAG_ALIGN_CENTER)
|
||||||
|
{
|
||||||
|
x = ((current_vp->width - w)/ 2) + x;
|
||||||
|
if (x < 0)
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = current_vp->width - w - x;
|
||||||
|
x += ofs;
|
||||||
|
ofs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow utf but no diacritics or rtl lang */
|
||||||
|
for (ucs = bidi_l2v(str, 1); *ucs; ucs++)
|
||||||
|
{
|
||||||
|
const unsigned short next_ch = ucs[1];
|
||||||
|
|
||||||
|
if (x >= current_vp->width)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Get proportional width and glyph bits */
|
||||||
|
width = font_get_width(pf, *ucs);
|
||||||
|
|
||||||
|
if (ofs > width)
|
||||||
|
{
|
||||||
|
ofs -= width;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = font_get_bits(pf, *ucs);
|
||||||
|
|
||||||
|
#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR)
|
||||||
|
if (pf->depth)
|
||||||
|
lcd_alpha_bitmap_part(bits, ofs, 0, width, x, y,
|
||||||
|
width - ofs, pf->height);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
LCDFN(mono_bitmap_part)(bits, ofs, 0, width, x,
|
||||||
|
y, width - ofs, pf->height);
|
||||||
|
if (next_ch)
|
||||||
|
{
|
||||||
|
x += width - ofs;
|
||||||
|
ofs = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*** pixel oriented text output ***/
|
/*** pixel oriented text output ***/
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@ static const char scroll_tick_table[18] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void scroll_thread(void);
|
static void scroll_thread(void);
|
||||||
static char scroll_stack[DEFAULT_STACK_SIZE*3];
|
|
||||||
static const char scroll_name[] = "scroll";
|
static const char scroll_name[] = "scroll";
|
||||||
|
|
||||||
#include "drivers/lcd-scroll.c"
|
#include "drivers/lcd-scroll.c"
|
||||||
|
@ -195,8 +194,11 @@ static void scroll_thread(void)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_REMOTE_LCD */
|
#endif /* HAVE_REMOTE_LCD */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER
|
||||||
void scroll_init(void)
|
void scroll_init(void)
|
||||||
{
|
{
|
||||||
|
static char scroll_stack[DEFAULT_STACK_SIZE*3];
|
||||||
#ifdef HAVE_REMOTE_LCD
|
#ifdef HAVE_REMOTE_LCD
|
||||||
queue_init(&scroll_queue, true);
|
queue_init(&scroll_queue, true);
|
||||||
#endif
|
#endif
|
||||||
|
@ -205,3 +207,9 @@ void scroll_init(void)
|
||||||
IF_PRIO(, PRIORITY_USER_INTERFACE)
|
IF_PRIO(, PRIORITY_USER_INTERFACE)
|
||||||
IF_COP(, CPU));
|
IF_COP(, CPU));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void scroll_init(void)
|
||||||
|
{
|
||||||
|
/* DUMMY */
|
||||||
|
}
|
||||||
|
#endif /* ndef BOOTLOADER*/
|
||||||
|
|
Loading…
Reference in a new issue