ser_cache add utf8idx to store utf8 chars

This commit is contained in:
cuu 2022-02-09 14:42:53 +08:00
parent 19830d15cd
commit 22e587aa7a
9 changed files with 397 additions and 49 deletions

View File

@ -1,13 +1,13 @@
CC = gcc
CFLAGS = -g -Wall
LDFLAUS =
INCLUDES =
LIBS = -lwiringPi -lm -lcrypt -lpthread -lrt
LDFLAGS =
INCLUDES = -I /usr/include/freetype2
LIBS = -lwiringPi -lm -lcrypt -lpthread -lfreetype -lrt
MAIN = devterm_thermal_printer.elf
SRCS = printer.c devterm_thermal_printer.c utils.c
SRCS = printer.c devterm_thermal_printer.c utils.c ftype.c utf8-utils.c
OBJS = $(SRCS:.c=.o)
.PHONY: depend clean

Binary file not shown.

View File

@ -172,6 +172,8 @@
#define MAXPIXELS 72
#endif
#define FONT_MODE_0 0 // Internal
#define FONT_MODE_1 1 // External
//extract bits
#define LAST(k,n) ((k) & ((1<<(n))-1))
@ -188,7 +190,9 @@ typedef struct _FONT {
uint8_t width;//in bits
uint8_t height;
uint8_t mode;//0 internal pcf font array,1 external ttf font file
const uint8_t *data;
char*file;
}FONT;
typedef struct _ImageCache{
@ -222,6 +226,9 @@ typedef struct _CONFIG
FONT*font;
ImageCache *img;
FILE*fp;
FT_Face *face;
FT_Library *ft;
int (*printf)(struct _CONFIG*, char*, ...);
@ -230,7 +237,9 @@ typedef struct _CONFIG
typedef struct _SerialCache{
uint8_t idx;
uint8_t data[77];//384/5
uint8_t utf8idx;//0-4
// uint8_t data[77];//384/5, minium size font 5 pixel
uint32_t data[MAX_DOTS];//
}SerialCache;
typedef struct _TimeRec{

View File

@ -19,16 +19,15 @@
#include "pcf_6x12-ISO8859-1_6x12.h"
#include "pcf_7x14-ISO8859-1_7x14.h"
#include "ttf_Px437_PS2thin1_8x16.h"
#include "ttf_Px437_PS2thin2_8x16.h"
#include "config.h"
#include "utils.h"
#include "printer.h"
#include "ftype.h"
SerialCache ser_cache;
uint8_t cmd[10];
@ -43,6 +42,10 @@ ImageCache img_cache;
FONT current_font;
FT_Face face;
FT_Library ft;
CONFIG g_config;
TimeRec battery_chk_tm;
@ -72,7 +75,7 @@ void reset_cmd(){
}
void init_printer(){
char *error = NULL;
memset(cmd,0,10);
newline = 0;
@ -95,11 +98,23 @@ void init_printer(){
current_font.width=8;current_font.height=16; current_font.data= font_ttf_Px437_PS2thin2_8x16;
*/
current_font.width=8;current_font.height=16; current_font.data= font_ttf_Px437_PS2thin1_8x16;
current_font.width = 16;
current_font.height = 16;
current_font.data= font_ttf_Px437_PS2thin1_8x16;
current_font.file = "NotoSansCJK-Regular.ttf";
current_font.mode = 1;
ser_cache.idx=0;
ser_cache.utf8idx = 0;
if( init_ft(current_font.file, &face,&ft,current_font.width,current_font.height,&error)) {
g_config.face = &face;
g_config.ft = &ft;
}else {
g_config.face = null;
g_config.ft = null;
}
g_config.line_space=0;
g_config.align = ALIGN_LEFT;
g_config.reverse = 0;
@ -249,6 +264,7 @@ NULL
*/
for(i=0;i<6;i++){
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,1);
reset_cmd();
@ -264,6 +280,7 @@ NULL
//---------------------------------------------
for(i=1;i<4;i++){
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,0);
reset_cmd();
for(j=0;j<strlen(font_names[i]);j++){
@ -271,7 +288,8 @@ NULL
parse_serial_stream(cfg,font_names[i][j]);
}
parse_serial_stream(cfg,10);
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,i);
reset_cmd();
for(ch = 33;ch<127;ch++){
@ -283,14 +301,15 @@ NULL
feed_pitch1(48,cfg->orient);
}
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,0);
reset_cmd();
for(j=0;j<strlen(font_names[0]);j++){
parse_serial_stream(cfg,font_names[0][j]);
}
parse_serial_stream(cfg,10);
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,0);
reset_cmd();
for(ch = 33;ch<127;ch++){
@ -301,14 +320,15 @@ NULL
//Serial.println();
feed_pitch1(48,cfg->orient);
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,0);
reset_cmd();
for(j=0;j<strlen(font_names[0]);j++){
parse_serial_stream(cfg,font_names[4][j]);
}
parse_serial_stream(cfg,10);
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,4);
reset_cmd();
for(ch = 33;ch<127;ch++){
@ -339,7 +359,8 @@ NULL
label_print_f(cfg,"Firmware version:",0.1,"");
feed_pitch1(cfg->font->height,cfg->orient);
//--------------------------------------------------------------
//--------------------------------------------------------------
printer_set_font_mode(FONT_MODE_0);
printer_set_font(cfg,0);
reset_cmd();
@ -378,39 +399,52 @@ NULL
}
void printer_set_font_mode(CONFIG*cfg, int mode){
cfg->font->mode = mode;
return;
}
void printer_set_font(CONFIG*cfg,uint8_t fnbits){
uint8_t ret;
ret = MID(fnbits,0,3);
if(cfg->font->mode == 0) {
if(ret==0) {
cfg->font->width = 8 ;
cfg->font->height = 16;
cfg->font->data = font_ttf_Px437_PS2thin1_8x16;
}
if(ret==1){
cfg->font->width = 5;
cfg->font->height = 7;
cfg->font->data = font_pcf_5x7_ISO8859_1_5x7;
}
if(ret==2){
cfg->font->width = 6;
cfg->font->height = 12;
cfg->font->data = font_pcf_6x12_ISO8859_1_6x12;
}
if(ret==3){
cfg->font->width = 7;
cfg->font->height = 14;
cfg->font->data = font_pcf_7x14_ISO8859_1_7x14;
}
if(ret == 4){
cfg->font->width = 8 ;
cfg->font->height = 16;
cfg->font->data = font_ttf_Px437_PS2thin2_8x16;
}
}
if(ret==0) {
cfg->font->width = 8 ;
if(cfg->font->mode == 1 ){
cfg->font->width = 16;
cfg->font->height = 16;
cfg->font->data = font_ttf_Px437_PS2thin1_8x16;
}
if(ret==1){
cfg->font->width = 5;
cfg->font->height = 7;
cfg->font->data = font_pcf_5x7_ISO8859_1_5x7;
}
if(ret==2){
cfg->font->width = 6;
cfg->font->height = 12;
cfg->font->data = font_pcf_6x12_ISO8859_1_6x12;
}
if(ret==3){
cfg->font->width = 7;
cfg->font->height = 14;
cfg->font->data = font_pcf_7x14_ISO8859_1_7x14;
}
if(ret == 4){
cfg->font->width = 8 ;
cfg->font->height = 16;
cfg->font->data = font_ttf_Px437_PS2thin2_8x16;
}
}
void parse_cmd(CONFIG*cfg,uint8_t *cmd, uint8_t cmdidx){
@ -599,6 +633,7 @@ void parse_cmd(CONFIG*cfg,uint8_t *cmd, uint8_t cmdidx){
void parse_serial_stream(CONFIG*cfg,uint8_t input_ch){
uint16_t a;
uint8_t bskip;
if(cfg->state == GET_IMAGE){
cfg->img->cache[cfg->img->idx] = input_ch;
@ -647,11 +682,33 @@ void parse_serial_stream(CONFIG*cfg,uint8_t input_ch){
cmd_idx++;
break;
default:
ser_cache.data[ser_cache.idx]=input_ch;
ser_cache.idx++;
if(input_ch < 128) {
ser_cache.data[ser_cache.idx]=input_ch;
ser_cache.idx++;
}else {//utf8
//10xxxxxx bskip == 1
bskip = get_slice_len(input_ch);
if(bskip == 1) {
//append this to int32_t [8:8:8:8] 0xffffffff 4294967295
ser_cache.data[ser_cache.idx] |= input_ch << (8 * (ser_cache.utf8idx+1));
ser_cache.utf8idx++;
if( ser_cache.utf8idx >= get_slice_len( ser_cache.data[ser_cache.idx] & 0xff) ) {
ser_cache_idx++;
ser_cache.utf8idx=0;//next character
}
}
if(bskip > 1) {
ser_cache.utf8idx =0;
ser_cache.data[ser_cache.idx] = input_ch;
}
}
//read utf8 codename
//
a = (ser_cache.idx+1)*current_font.width+(ser_cache.idx)*0+ g_config.margin.width;
if( a >= MAX_DOTS)
if( a >= MAX_DOTS)//got enough points to print
{
print_lines8(cfg);
reset_cmd();

View File

@ -0,0 +1,104 @@
#include "ftype.h"
#include "utf8-utils.h"
static const UTF32 utf32_space[2] = {' ', 0};
FT_Face face;
FT_Library ft;
bool init_ft (const char *ttf_file, FT_Face *face, FT_Library *ft,
int req_size_w,int req_size_h, char **error)
{
bool ret = false;
if (FT_Init_FreeType (ft) == 0) {
if (FT_New_Face(*ft, ttf_file, 0, face) == 0) {
if(FT_Set_Pixel_Sizes(*face, req_size_w, req_size_h) == 0){
ret = true;
} else {
if (error)
*error = strdup ("Can't set font size");
}
} else {
if (error)
*error = strdup ("Can't load TTF file");
}
}else{
if (error)
*error = strdup ("Can't init freetype library");
}
return ret;
}
/*===========================================================================
done_ft
Clean up after we've finished wih the FreeType librar
=========================================================================*/
void done_ft(FT_Library ft)
{
FT_Done_FreeType (ft);
}
/*===========================================================================
face_get_line_spacing
Get the nominal line spacing, that is, the distance between glyph
baselines for vertically-adjacent rows of text. This is "nominal" because,
in "real" typesetting, we'd need to add extra room for accents, etc.
=========================================================================*/
int face_get_line_spacing (FT_Face face)
{
return face->size->metrics.height / 64;
// There are other possibilities the give subtly different results:
// return (face->bbox.yMax - face->bbox.yMin) / 64;
// return face->height / 64;
}
int get_slice_len(const char lb) {
if( ( lb & 0x80 ) == 0 ) return 1;
else if( ( lb & 0xE0) == 0xC0) return 2;
else if( ( lb & 0xF0) == 0xE0) return 3;
else if( ( lb & 0xF8) == 0xF0) return 4;
return 1;
}
UTF32 *cjk_utf8_to_utf32 (const char *word)
{
assert (word != NULL);
int l = strlen(word);
int u8l = utf8_strlen(word);
char buf[5];
UTF32 *ret = malloc ((u8l + 1) * sizeof (UTF32));
int i=0,j=0;
int bskip=1;
while( i<l )
{
bskip = get_slice_len(word[i]);
strncpy(buf,&word[i],bskip);
if(bskip > 1) {
ret[j] = (UTF32)utf8_to_utf32(buf);
}else {
ret[j] = (UTF32)buf[0];
}
j++;
i+=bskip;
}
ret[u8l] = 0;
return ret;
}

View File

@ -0,0 +1,26 @@
#ifndef FTYPE_H
#define FTYPE_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <freetype2/ft2build.h>
#include <freetype/freetype.h>
#ifndef UTF8
typedef unsigned char UTF8;
#endif
#ifndef UTF32
typedef int32_t UTF32;
#endif
bool init_ft (const char *ttf_file, FT_Face *face, FT_Library *ft,
int req_size_w,int req_size_h, char **error);
int get_slice_len(const char lb);
#endif

View File

@ -37,6 +37,7 @@ uint8_t invert_bit(uint8_t a);
uint8_t print_image8(CONFIG*);
void print_cut_line(CONFIG*);
void printer_set_font_mode(int);
void printer_set_font(CONFIG*cfg,uint8_t fnbits);
void parse_serial_stream(CONFIG*cfg,uint8_t input_ch);

View File

@ -0,0 +1,83 @@
/* Freetype GL - A C OpenGL Freetype engine
*
* Distributed under the OSI-approved BSD 2-Clause License. See accompanying
* file `LICENSE` for more details.
*/
#include <string.h>
#include "utf8-utils.h"
// ----------------------------------------------------- utf8_surrogate_len ---
size_t
utf8_surrogate_len( const char* character )
{
size_t result = 0;
char test_char;
if (!character)
return 0;
test_char = character[0];
if ((test_char & 0x80) == 0)
return 1;
while (test_char & 0x80)
{
test_char <<= 1;
result++;
}
return result;
}
// ------------------------------------------------------------ utf8_strlen ---
size_t
utf8_strlen( const char* string )
{
const char* ptr = string;
size_t result = 0;
while (*ptr)
{
ptr += utf8_surrogate_len(ptr);
result++;
}
return result;
}
uint32_t
utf8_to_utf32( const char * character )
{
if( !character )
{
return -1;
}
if( ( character[0] & 0x80 ) == 0x0 )
{
return character[0];
}
if( ( character[0] & 0xE0 ) == 0xC0 )
{
return ( ( character[0] & 0x3F ) << 6 ) | ( character[1] & 0x3F );
}
if( ( character[0] & 0xF0 ) == 0xE0 )
{
return ( ( character[0] & 0x1F ) << ( 6 + 6 ) ) | ( ( character[1] & 0x3F ) << 6 ) | ( character[2] & 0x3F );
}
if( ( character[0] & 0xF8 ) == 0xF0 )
{
return ( ( character[0] & 0x0F ) << ( 6 + 6 + 6 ) ) | ( ( character[1] & 0x3F ) << ( 6 + 6 ) ) | ( ( character[2] & 0x3F ) << 6 ) | ( character[3] & 0x3F );
}
if( ( character[0] & 0xFC ) == 0xF8 )
{
return ( ( character[0] & 0x07 ) << ( 6 + 6 + 6 + 6 ) ) | ( ( character[1] & 0x3F ) << ( 6 + 6 + 6 ) ) | ( ( character[2] & 0x3F ) << ( 6 + 6 ) ) | ( ( character[3] & 0x3F ) << 6 ) | ( character[4] & 0x3F );
}
return 0xFFFD; // invalid character
}

View File

@ -0,0 +1,68 @@
/* Freetype GL - A C OpenGL Freetype engine
*
* Distributed under the OSI-approved BSD 2-Clause License. See accompanying
* file `LICENSE` for more details.
*/
#ifndef __UTF8_UTILS_H__
#define __UTF8_UTILS_H__
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
namespace ftgl {
#endif
/**
* @file utf8-utils.h
* @author Marcel Metz <mmetz@adrian-broher.net>
*
* defgroup utf8-utils UTF-8 Utilities
*
* @{
*/
/**
* Returns the size in bytes of a given UTF-8 encoded character surrogate
*
* @param character An UTF-8 encoded character
*
* @return The length of the surrogate in bytes.
*/
size_t
utf8_surrogate_len( const char* character );
/**
* Return the length of the given UTF-8 encoded and
* NULL terminated string.
*
* @param string An UTF-8 encoded string
*
* @return The length of the string in characters.
*/
size_t
utf8_strlen( const char* string );
/**
* Converts a given UTF-8 encoded character to its UTF-32 LE equivalent
*
* @param character An UTF-8 encoded character
*
* @return The equivalent of the given character in UTF-32 LE
* encoding.
*/
uint32_t
utf8_to_utf32( const char * character );
/**
* @}
*/
#ifdef __cplusplus
}
}
#endif
#endif /* #define __UTF8_UTILS_H__ */