KT26-0607_AC695n-BTE-SDK312/apps/soundbox/ui/led_lyric/led_lyric.c
2026-06-07 19:38:16 +08:00

815 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "led_lyric.h"
#include "res/resfile.h"
#include "font/font_all.h"
#include "system/timer.h"
#include "board_config.h"
#include "os/os_api.h"
#include "ui/ui_style.h"
#include "system/includes.h"
#include "fm/fm_manage.h"
#include "uart_update.h"
#include "lyrics_api.h"
#if LED_LYRICS_ENABLE
typedef struct {
u8 *pixelbuf;
u8 width;
u8 height;
u8 offsetx;
u16 nbytes;
} FONT_CHAR_INFO;
typedef struct {
u8 scroll_speed;
u8 center_offset;
u16 scroll_offset;
LRC_FONT_ROTATE rotate;
LRC_FONT_FLIP flip;
} FONT_LYRICS_INFO;
typedef struct {
u8 *str;
u16 len;
u16 offset;
u16 sum_width;
FONT_LYRICS_INFO lyrics_info;
} LYRICS_UPDATE_INFO;
struct lrc_font_header {
u8 magic[4];
u32 version;
u32 timestamp;
u8 fontsize;
u8 bitdepth;
u8 reserved[18];
};
typedef struct {
u32 width : 6;
u32 height : 7;
s32 top : 8;
u32 size : 11;
s32 left : 7;
u32 addr : 25;
} __attribute__((packed, aligned(1))) LRC_UnicInfo;
#define Font_NumPages 1024
#define Font_PageSize (0x10000 / Font_NumPages)
#define Code_Size 7
#define Colon_Size 3
typedef struct {
u16 charIndex;
u8 codesMask[Font_PageSize / 8];
} LRC_Font_PageEntry_t;
#define IMAGE_BUF_SIZE ((LED_WIDTH * LED_HEIGHT + 7) / 8)
static u8 *image_buf = NULL; //整屏点阵缓存buffer
static u8 *image_buf_out = NULL;
static u8 lrc_check_online_flag = 1;
static u8 lrc_sleep_flag = 0;
static struct lrc_font_header header = {0};
static struct font_info f_info;
static FONT_CHAR_INFO char_info;
static u16 font_lyrics_scroll_timer_id = 0;
static LYRICS_UPDATE_INFO lrc_update_info;
static OS_MUTEX mutex;
static OS_MUTEX show_mutex;
static struct lrc_show_status lrc_status = {
.lrc_rotate = 0,
.lrc_flip = 0,
.lrc_scroll_speed = 100,
.lrc_show_status_update_flag = 0,
.lrc_record_len = 0,
.lrc_record_str = NULL,
};
void lyrics_show_status_set(u16 scroll_speed, u8 rotate, u8 flip)
{
lrc_status.lrc_scroll_speed = scroll_speed;
lrc_status.lrc_rotate = rotate;
lrc_status.lrc_flip = flip;
lrc_status.lrc_show_status_update_flag = 1;
lyrics_update_font(lrc_status.lrc_record_str, lrc_status.lrc_record_len, NULL);
}
static bool LRC_InitFont_Unicode(struct font_info *info)
{
info->pixel.file.fd = fopen(info->pixel.file.name, "r");
if (!info->pixel.file.fd) {
info->sta |= FT_ERROR_NOPIXFILE;
printf("unicode file not open!");
return FALSE;
}
fseek(info->pixel.file.fd, 0, SEEK_SET);
fread(info->pixel.file.fd, &header, sizeof(struct lrc_font_header));
printf("magic : %s\n", header.magic);
printf("version : 0x%x\n", header.version);
printf("timestamp : %d\n", header.timestamp);
printf("fontsize : %d\n", header.fontsize);
printf("bitdepth : %d\n", header.bitdepth);
if (memcmp(header.magic, "unic", 4)) {
info->sta |= FT_ERROR_NOPIXFILE;
printf("unicode magic not paired!");
return FALSE;
}
info->pixel.size = header.fontsize;
if (header.bitdepth == 0) {
info->pixel.nbytes = (info->pixel.size * info->pixel.size + 7) / 8;
} else if (header.bitdepth == 1) {
info->pixel.nbytes = (info->pixel.size * info->pixel.size * 2 + 7) / 8;
} else if (header.bitdepth == 2) {
info->pixel.nbytes = (info->pixel.size * info->pixel.size * 4 + 7) / 8;
} else { // header.bitdepth == 8
info->pixel.nbytes = info->pixel.size * info->pixel.size;
}
return TRUE;
}
/* 获取字符索引 */
static int LRC_Font_GetCharIndex(struct font_info *info, u16 unicode)
{
LRC_Font_PageEntry_t pageEntry;
u16 m = unicode / Font_PageSize;
u16 n = unicode % Font_PageSize;
u16 i, j;
fseek(info->pixel.file.fd, sizeof(struct lrc_font_header) + m * sizeof(LRC_Font_PageEntry_t), SEEK_SET);
fread(info->pixel.file.fd, &pageEntry, sizeof(LRC_Font_PageEntry_t));
if (!(pageEntry.codesMask[n / 8] & (1 << (n % 8)))) {
return -1;
}
for (i = j = 0; i < n; i++) {
if (pageEntry.codesMask[i / 8] & (1 << (i % 8))) {
j++;
}
}
i = pageEntry.charIndex + j;
return i;
}
/* 获取字符宽度 */
static int LRC_Font_GetCharWidth(struct font_info *info, u16 unicode)
{
int charIndex;
u16 nbytes;
if ((charIndex = LRC_Font_GetCharIndex(info, unicode)) < 0) {
printf("unicode : 0x%x, charIndex = %d, char index not exist!\n", unicode, charIndex);
return 0;
}
LRC_UnicInfo codeinfo = {0};
u32 file_offset = 0;
fseek(info->pixel.file.fd, sizeof(struct lrc_font_header) + Font_NumPages * \
sizeof(LRC_Font_PageEntry_t) + charIndex * sizeof(LRC_UnicInfo), SEEK_SET);
fread(info->pixel.file.fd, &codeinfo, sizeof(LRC_UnicInfo));
if (unicode == 0x20) {
codeinfo.width = info->pixel.size / 3;
codeinfo.height = info->pixel.size / 3;
}
if (unicode == 0x10) {
codeinfo.width = Code_Size;
codeinfo.height = Code_Size;
memset(info->pixel.pixelbuf, 0, (codeinfo.width * codeinfo.height + 7) / 8);
}
if (unicode == 0x11) {
codeinfo.width = Colon_Size;
codeinfo.height = Colon_Size;
memset(info->pixel.pixelbuf, 0, (codeinfo.width * codeinfo.height + 7) / 8);
}
u8 width = codeinfo.width;
char_info.width = codeinfo.width;
char_info.height = codeinfo.height;
return width;
}
/* 获取字符位图数据 */
static int LRC_Font_GetCharBits(struct font_info *info, u16 unicode)
{
int charIndex;
u16 nbytes, width;
if ((charIndex = LRC_Font_GetCharIndex(info, unicode)) < 0) {
printf("unicode : 0x%x, charIndex = %d, char index not exist!\n", unicode, charIndex);
return 0;
}
LRC_UnicInfo codeinfo = {0};
fseek(info->pixel.file.fd, sizeof(struct lrc_font_header) + Font_NumPages * \
sizeof(LRC_Font_PageEntry_t) + charIndex * sizeof(LRC_UnicInfo), SEEK_SET);
fread(info->pixel.file.fd, &codeinfo, sizeof(LRC_UnicInfo));
const u8 bit[] = {1, 2, 4, 8};
nbytes = (codeinfo.width * codeinfo.height * bit[header.bitdepth] + 7) / 8;
if (info->pixel.pixelbuf != NULL) {
if (nbytes > info->pixel.nbytes) {
puts("error:pixelbuf overlay!\n");
printf("info.width = %d, info->ascpixel.size = %d, nbytes = %d\n", width, info->pixel.size, nbytes);
free(info->pixel.pixelbuf);
info->pixel.pixelbuf = (u8 *)malloc(nbytes);
info->pixel.nbytes = nbytes;
char_info.pixelbuf = info->pixel.pixelbuf;
char_info.nbytes = info->pixel.nbytes;
}
fseek(info->pixel.file.fd, codeinfo.addr, SEEK_SET);
fread(info->pixel.file.fd, info->pixel.pixelbuf, nbytes);
}
if (unicode == 0x20) {
codeinfo.width = info->pixel.size / 3;
codeinfo.height = info->pixel.size / 3;
}
if (unicode == 0x10) {
codeinfo.width = Code_Size;
codeinfo.height = Code_Size;
memset(info->pixel.pixelbuf, 0, (codeinfo.width * codeinfo.height + 7) / 8);
}
if (unicode == 0x11) {
codeinfo.width = Colon_Size;
codeinfo.height = Colon_Size;
memset(info->pixel.pixelbuf, 0, (codeinfo.width * codeinfo.height + 7) / 8);
}
width = codeinfo.width;
char_info.width = codeinfo.width;
char_info.height = codeinfo.height;
char_info.pixelbuf = info->pixel.pixelbuf;
return width;
}
bool lyrics_font_init(char *file_name)
{
bool ret;
if (f_info.pixel.file.fd == NULL) {
f_info.pixel.file.name = file_name;
f_info.bigendian = 0;
ret = LRC_InitFont_Unicode(&f_info);
if (ret == FALSE) {
return FALSE;
}
f_info.pixel.pixelbuf = (u8 *)malloc(f_info.pixel.nbytes);
char_info.pixelbuf = f_info.pixel.pixelbuf;
char_info.nbytes = f_info.pixel.nbytes;
image_buf = (u8 *)malloc(IMAGE_BUF_SIZE);
image_buf_out = (u8 *)malloc(IMAGE_BUF_SIZE);
os_mutex_create(&mutex);
os_mutex_create(&show_mutex);
}
return TRUE;
}
void lyrics_font_release()
{
if (f_info.pixel.file.fd) {
fclose(f_info.pixel.file.fd);
f_info.pixel.file.fd = NULL;
}
if (f_info.pixel.pixelbuf) {
free(f_info.pixel.pixelbuf);
f_info.pixel.pixelbuf = NULL;
}
if (font_lyrics_scroll_timer_id) {
sys_timer_del(font_lyrics_scroll_timer_id);
font_lyrics_scroll_timer_id = 0;
}
if (lrc_update_info.str) {
free(lrc_update_info.str);
lrc_update_info.str = NULL;
}
if (image_buf) {
free(image_buf);
image_buf = NULL;
}
if (image_buf_out) {
free(image_buf_out);
image_buf_out = NULL;
}
}
static void Font_CharBit_to_Image(FONT_CHAR_INFO *info, u8 *image, u8 x, u8 y)
{
u8 image_width = LED_WIDTH;
u8 char_width = info->width;
u8 char_height = info->height;
u8 *char_buf = info->pixelbuf;
u8 char_byte_idx, char_bit_idx;
u8 image_byte_idx, image_bit_idx;
u8 inc_ofs = info->offsetx;
for (u16 i = 0; i < char_height; i++) {
for (u16 j = 0; j < char_width; j++) {
if (x + j >= LED_WIDTH) {
break;
}
if (j + inc_ofs >= char_width) {
break;
}
char_byte_idx = (i * char_width + j + inc_ofs) / 8;
char_bit_idx = (i * char_width + j + inc_ofs) % 8;
image_byte_idx = ((i + y) * image_width + j + x) / 8;
image_bit_idx = ((i + y) * image_width + j + x) % 8;
image[image_byte_idx] |= (((char_buf[char_byte_idx] >> (7 - char_bit_idx)) & 0x1) << (7 - image_bit_idx));
}
}
}
static void Font_Char_Rotate_90Reverse(FONT_CHAR_INFO *info)
{
u8 *in = info->pixelbuf;
u8 *out = image_buf_out;
u8 in_byte_idx, in_bit_idx;
u8 out_byte_idx, out_bit_idx;
u8 char_width = info->width;
u8 char_height = info->height;
memset(image_buf_out, 0, IMAGE_BUF_SIZE);
for (u16 h = 0; h < char_height; h++) {
for (u16 w = 0; w < char_width; w++) {
in_byte_idx = (h * char_width + w) / 8;
in_bit_idx = (h * char_width + w) % 8;
out_byte_idx = ((char_width - 1 - w) * char_height + h) / 8;
out_bit_idx = ((char_width - 1 - w) * char_height + h) % 8;
out[out_byte_idx] |= (((in[in_byte_idx] >> (7 - in_bit_idx)) & 0x1) << (7 - out_bit_idx));
}
}
u8 tmp = info->width;
info->width = info->height;
info->height = tmp;
memcpy(info->pixelbuf, image_buf_out, info->nbytes);
}
static void Font_Image_Rotate_180()
{
u8 *in = image_buf;
u8 *out = image_buf_out;
u8 in_byte_idx, in_bit_idx;
u8 out_byte_idx, out_bit_idx;
memset(image_buf_out, 0, IMAGE_BUF_SIZE);
for (u16 h = 0; h < LED_HEIGHT; h++) {
for (u16 w = 0; w < LED_WIDTH; w++) {
in_byte_idx = (h * LED_WIDTH + w) / 8;
in_bit_idx = (h * LED_WIDTH + w) % 8;
out_byte_idx = (LED_WIDTH * LED_HEIGHT / 8) - 1 - in_byte_idx;
out_bit_idx = (7 - in_bit_idx);
out[out_byte_idx] |= (((in[in_byte_idx] >> (7 - in_bit_idx)) & 0x1) << (7 - out_bit_idx));
}
}
}
static void Font_Image_Mirror_Horizontal_Flip(u8 *image)
{
u8 *in, *out;
if (image == image_buf) {
in = image_buf;
out = image_buf_out;
} else {
in = image_buf_out;
out = image_buf;
}
memset(out, 0, IMAGE_BUF_SIZE);
u8 in_byte_idx, in_bit_idx;
u8 out_byte_idx, out_bit_idx;
u16 in_bit, out_bit;
for (u16 h = 0; h < LED_HEIGHT; h++) {
for (u16 w = 0; w < LED_WIDTH; w++) {
in_bit = h * LED_WIDTH + w;
out_bit = h * LED_WIDTH + (LED_WIDTH - 1 - w);
in_byte_idx = in_bit / 8;
in_bit_idx = in_bit % 8;
out_byte_idx = out_bit / 8;
out_bit_idx = out_bit % 8;
out[out_byte_idx] |= (((in[in_byte_idx] >> (7 - in_bit_idx)) & 0x1) << (7 - out_bit_idx));
}
}
memcpy(in, out, IMAGE_BUF_SIZE);
}
static void Font_Image_Mirror_Vertical_Flip(u8 *image)
{
u8 *in, *out;
if (image == image_buf) {
in = image_buf;
out = image_buf_out;
} else {
in = image_buf_out;
out = image_buf;
}
memset(out, 0, IMAGE_BUF_SIZE);
u8 in_byte_idx, in_bit_idx;
u8 out_byte_idx, out_bit_idx;
u16 in_bit, out_bit;
for (u16 h = 0; h < LED_HEIGHT; h++) {
for (u16 w = 0; w < LED_WIDTH; w++) {
in_bit = h * LED_WIDTH + w;
out_bit = (LED_HEIGHT - 1 - h) * LED_WIDTH + w;
in_byte_idx = in_bit / 8;
in_bit_idx = in_bit % 8;
out_byte_idx = out_bit / 8;
out_bit_idx = out_bit % 8;
out[out_byte_idx] |= (((in[in_byte_idx] >> (7 - in_bit_idx)) & 0x1) << (7 - out_bit_idx));
}
}
memcpy(in, out, IMAGE_BUF_SIZE);
}
static u16 Font_GetStringWidth(u8 *utf8_buf, u16 len, FONT_LYRICS_INFO *lyrics_info)
{
u16 unicode, width;
u16 utf8_len = len;
u16 *utf16_buf = zalloc(utf8_len * 2);
u16 utf16_len = font_utf8toutf16(&f_info, utf8_buf, utf8_len, utf16_buf);
u16 unic_num = utf16_len / 2;
u16 sum_width = 0;
for (u16 n = 0; n < unic_num; n++) {
unicode = utf16_buf[n];
width = LRC_Font_GetCharWidth(&f_info, unicode);
if (width == 0) {
continue;
}
if (lyrics_info->rotate == LRC_FONT_ROTATE_90 || lyrics_info->rotate == LRC_FONT_ROTATE_270) {
width = char_info.height;
}
sum_width += width;
}
free(utf16_buf);
return sum_width;
}
void lrc_buf_push(u8 *buf, u16 size)
{
u8 *uartbuf = malloc(size + 1);
#if UI_LED_LRC_DECODE_FONT
uartbuf[0] = CMD_UART_UI_PIXEL_MATRIX;
#else
uartbuf[0] = CMD_UART_UI_STRING;
#endif
memcpy(uartbuf + 1, buf, size);
#if MUTIL_CPU_UART_UPDATE_ENABLE
if (!lrc_sleep_flag) {
uart_update_tx_packet(0, uartbuf, 0, size + 1, 0);
}
#endif
free(uartbuf);
}
void lrc_show_slepp_push(void)
{
u8 buf[1];
buf[0] = CMD_UART_SLEEP;
#if MUTIL_CPU_UART_UPDATE_ENABLE
if (!lrc_sleep_flag) {
uart_update_tx_packet(0, buf, 0, sizeof(buf), 1);
}
#endif
lrc_sleep_flag = 1;
}
void lrc_wake_up_push(void)
{
u8 buf[1];
buf[0] = 0XFF;
#if MUTIL_CPU_UART_UPDATE_ENABLE
uart_update_tx_packet(0, buf, 0, sizeof(buf), 1);
#endif
lrc_sleep_flag = 0;
}
#if (AD10X_WITHOUT_FLASH && LED_LYRICS_SH50_CHECK_ONLINE)
static u8 lrc_dev_check_online()
{
u8 ret = 0;
u8 packet = CMD_UART_CHECK_ONLINE;
#if MUTIL_CPU_UART_UPDATE_ENABLE
lrc_check_online_flag = 1;
if (!lrc_sleep_flag) {
ret = uart_update_tx_packet(CMD_UART_CHECK_ONLINE, &packet, 0, 1, 1);
}
#endif
if (ret != 0) {
if (!lrc_sleep_flag) {
ret = uart_update_tx_packet(CMD_UART_CHECK_ONLINE, &packet, 0, 1, 1);
}
if (ret != 0) {
lrc_check_online_flag = 0;
sh50_isp_up_code();
}
}
return ret;
}
static u16 online_timer_id = 0;
void lrc_check_online_timer_init()
{
if (online_timer_id == 0) {
online_timer_id = sys_timer_add(NULL, lrc_dev_check_online, 3000);
}
}
void lrc_check_online_timer_release()
{
if (online_timer_id) {
sys_timer_del(online_timer_id);
online_timer_id = 0;
}
}
#endif
void lrc_show_mode_push(LRC_SHOW_INFO *show_info)
{
u8 buf[5];
u8 rotate, flip, speed, brightness;
if (show_info) {
rotate = show_info->rotate;
flip = show_info->flip;
speed = show_info->scroll_speed / 50;
brightness = show_info->brightness;
} else {
rotate = 0;
flip = 0;
speed = 3;
brightness = 0;
}
buf[0] = CMD_UART_UI_CMD;
buf[1] = rotate;
buf[2] = flip;
buf[3] = speed;
buf[4] = brightness;
#if MUTIL_CPU_UART_UPDATE_ENABLE
if (!lrc_sleep_flag) {
uart_update_tx_packet(0, buf, 0, sizeof(buf), 1);
}
#endif
}
static void Font_GetStringBits(u8 *utf8_buf, u16 len, FONT_LYRICS_INFO *lyrics_info)
{
u8 curr_x = lyrics_info->center_offset;
u8 offset_y = 0;
u16 unicode, width;
u16 rec_scr_ofs = 0;
u8 curr_char_offset = 0;
u8 *font_ptr = image_buf;
u16 sum_char_offset = lyrics_info->scroll_offset;
memset(image_buf, 0, IMAGE_BUF_SIZE);
u16 utf8_len = len;
u16 *utf16_buf = zalloc(utf8_len * 2);
u16 utf16_len = font_utf8toutf16(&f_info, utf8_buf, utf8_len, utf16_buf);
u16 unic_num = utf16_len / 2;
for (u16 n = 0; n < unic_num; n++) {
unicode = utf16_buf[n];
width = LRC_Font_GetCharBits(&f_info, unicode);
if (width == 0) {
continue;
}
if (lyrics_info->rotate == LRC_FONT_ROTATE_0 || lyrics_info->rotate == LRC_FONT_ROTATE_180) {
curr_char_offset = width;
} else {
curr_char_offset = char_info.height;
}
rec_scr_ofs += curr_char_offset;
if (rec_scr_ofs < sum_char_offset) {
continue;
}
if (curr_x == 0) {
char_info.offsetx = sum_char_offset + curr_char_offset - rec_scr_ofs;
} else {
char_info.offsetx = 0;
}
if (curr_x > LED_WIDTH) {
break;
}
if (lyrics_info->rotate == LRC_FONT_ROTATE_90 || lyrics_info->rotate == LRC_FONT_ROTATE_270) {
Font_Char_Rotate_90Reverse(&char_info);
}
offset_y = (f_info.pixel.size - char_info.height) / 2;
Font_CharBit_to_Image(&char_info, image_buf, curr_x, offset_y);
curr_x += (char_info.width - char_info.offsetx);
}
if (lyrics_info->rotate == LRC_FONT_ROTATE_180 || lyrics_info->rotate == LRC_FONT_ROTATE_270) {
Font_Image_Rotate_180();
font_ptr = image_buf_out;
}
if (lyrics_info->flip == LRC_FONT_HORIZONTAL_FLIP) {
Font_Image_Mirror_Horizontal_Flip(font_ptr);
}
if (lyrics_info->flip == LRC_FONT_VERTICAL_FLIP) {
Font_Image_Mirror_Vertical_Flip(font_ptr);
}
lrc_buf_push(font_ptr, IMAGE_BUF_SIZE);
free(utf16_buf);
}
void lyrics_scroll_timer_del()
{
if (font_lyrics_scroll_timer_id) {
sys_timer_del(font_lyrics_scroll_timer_id);
font_lyrics_scroll_timer_id = 0;
}
}
static u8 lyrics_scroll_flag = 1;
static void lyrics_scroll_font(void *ptr)
{
os_mutex_pend(&show_mutex, 0);
LYRICS_UPDATE_INFO *info = (LYRICS_UPDATE_INFO *)ptr;
if (info->lyrics_info.scroll_offset > info->sum_width - LED_WIDTH + 3) {
info->lyrics_info.scroll_offset = 0;
/* 不从头滚动 */
if (info->sum_width > LED_WIDTH) {
lyrics_scroll_timer_del();
os_mutex_post(&show_mutex);
return;
}
/* 不从头滚动 */
}
Font_GetStringBits((u8 *)(info->str), info->len, &(info->lyrics_info));
if (info->sum_width > LED_WIDTH && lyrics_scroll_flag) {
info->lyrics_info.scroll_offset++;
}
os_mutex_post(&show_mutex);
}
void lyrics_scroll_control(u8 flag)
{
lyrics_scroll_flag = flag;
}
void lyrics_update_font(u8 *str, u16 len, LRC_SHOW_INFO *show_info)
{
#if UI_LED_LRC_DECODE_FONT
if (f_info.pixel.file.fd == NULL) {
printf("err, font file not open\n");
return;
}
#endif
u16 str_curr_crc;
static u16 str_last_crc = 0;
str_curr_crc = CRC16(str, len);
if (str_last_crc == str_curr_crc && lrc_status.lrc_show_status_update_flag == 0 && lrc_check_online_flag) {
return;
}
if (len == 0) {
lrc_status.lrc_show_status_update_flag = 0;
return;
}
os_mutex_pend(&show_mutex, 0);
/* 记录当前字符串内容和长度,在更新显示参数实时刷新时需要用到 */
if (lrc_status.lrc_record_str && lrc_status.lrc_show_status_update_flag == 0) {
free(lrc_status.lrc_record_str);
lrc_status.lrc_record_str = NULL;
}
if (lrc_status.lrc_record_str == NULL) {
lrc_status.lrc_record_str = zalloc(len);
}
lrc_status.lrc_record_len = len;
memcpy(lrc_status.lrc_record_str, str, len);
/* 记录当前字符串内容和长度,在更新显示参数实时刷新时需要用到 */
str_last_crc = str_curr_crc;
#if (UI_LED_LRC_DECODE_FONT == 0)
lrc_buf_push(str, len);
lrc_status.lrc_show_status_update_flag = 0;
os_mutex_post(&show_mutex);
return;
#endif
u16 scroll_speed;
u8 rotate, flip;
os_mutex_pend(&mutex, 0);
if (show_info == NULL) {
rotate = lrc_status.lrc_rotate;
flip = lrc_status.lrc_flip;
scroll_speed = lrc_status.lrc_scroll_speed;
} else {
rotate = show_info->rotate;
flip = show_info->flip;
scroll_speed = show_info->scroll_speed;
}
if (font_lyrics_scroll_timer_id) {
sys_timer_del(font_lyrics_scroll_timer_id);
font_lyrics_scroll_timer_id = 0;
}
if (lrc_update_info.str) {
free(lrc_update_info.str);
lrc_update_info.str = NULL;
}
lrc_update_info.str = malloc(len);
memcpy(lrc_update_info.str, str, len);
lrc_update_info.len = len;
lrc_update_info.lyrics_info.scroll_offset = 0;
lrc_update_info.lyrics_info.rotate = rotate;
lrc_update_info.lyrics_info.flip = flip;
lrc_update_info.sum_width = Font_GetStringWidth(lrc_update_info.str, len, &(lrc_update_info.lyrics_info));
lrc_update_info.lyrics_info.center_offset = (lrc_update_info.sum_width < LED_WIDTH) ? ((LED_WIDTH - lrc_update_info.sum_width) / 2) : 0;
os_mutex_post(&show_mutex);
if (lrc_update_info.sum_width <= LED_WIDTH) {
lyrics_scroll_font((void *)&lrc_update_info);
} else {
if (font_lyrics_scroll_timer_id == 0) {
font_lyrics_scroll_timer_id = sys_timer_add((void *)&lrc_update_info, lyrics_scroll_font, scroll_speed);
}
}
lrc_status.lrc_show_status_update_flag = 0;
os_mutex_post(&mutex);
}
int UnicodeToUtf8(u8 *pInput, u16 in_len, u8 *pOutput)
{
int len = 0; //记录转换后的Utf8字符串的字节数
int unic_cnt = 0;
while (unic_cnt < in_len) {
//处理一个unicode字符
u8 low = *pInput;//取出unicode字符的低8位
pInput++;
unic_cnt++;
u8 high = *pInput;//取出unicode字符的高8位
u16 w = high << 8;
u16 wchar = (high << 8) + low; //高8位和低8位组成一个unicode字符,加法运算级别高
if (wchar <= 0x7F) { //英文字符
pOutput[len] = (char)wchar; //取wchar的低8位
len++;
} else if (wchar >= 0x80 && wchar <= 0x7FF) { //可以转换成双字节pOutput字符
pOutput[len] = 0xc0 | ((wchar >> 6) & 0x1f); //取出unicode编码低6位后的5位填充到110yyyyy 10zzzzzz 的yyyyy中
len++;
pOutput[len] = 0x80 | (wchar & 0x3f); //取出unicode编码的低6位填充到110yyyyy 10zzzzzz 的zzzzzz中
len++;
} else if (wchar >= 0x800 && wchar < 0xFFFF) { //可以转换成3个字节的pOutput字符
pOutput[len] = 0xe0 | ((wchar >> 12) & 0x0f); //高四位填入1110xxxx 10yyyyyy 10zzzzzz中的xxxx
len++;
pOutput[len] = 0x80 | ((wchar >> 6) & 0x3f); //中间6位填入1110xxxx 10yyyyyy 10zzzzzz中的yyyyyy
len++;
pOutput[len] = 0x80 | (wchar & 0x3f); //低6位填入1110xxxx 10yyyyyy 10zzzzzz中的zzzzzz
len++;
}
else { //对于其他字节数的unicode字符不进行处理
return -1;
}
pInput ++;//处理下一个unicode字符
unic_cnt++;
}
//utf8字符串后面有个\0
pOutput [len] = 0;
return len;
}
void lyrics_update_unicbuf(u8 *unic, u16 len)
{
if (len == 0 || unic == NULL) {
return;
}
u8 *utf8 = (u8 *)zalloc(len * 2);
int utf8_len = UnicodeToUtf8(unic, len, utf8);
lyrics_update_font(utf8, utf8_len, NULL);
free(utf8);
}
void lyrics_update_gbk_to_utf8(u8 *gbk, u16 len)
{
if (len == 0 || gbk == NULL) {
return;
}
u8 *utf8 = (u8 *)zalloc(len * 2);
int utf8_len = gbk_2_utf8(gbk, len, utf8, len * 2);
lyrics_update_font(utf8, utf8_len, NULL);
free(utf8);
}
#endif