mirror of
https://github.com/clockworkpi/DevTerm.git
synced 2025-12-12 18:28:50 +01:00
ser_cache add utf8idx to store utf8 chars
This commit is contained in:
parent
19830d15cd
commit
22e587aa7a
@ -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
|
||||
|
||||
BIN
Code/thermal_printer/NotoSansCJK-Regular.ttf
Normal file
BIN
Code/thermal_printer/NotoSansCJK-Regular.ttf
Normal file
Binary file not shown.
@ -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{
|
||||
|
||||
@ -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();
|
||||
|
||||
104
Code/thermal_printer/ftype.c
Normal file
104
Code/thermal_printer/ftype.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
26
Code/thermal_printer/ftype.h
Normal file
26
Code/thermal_printer/ftype.h
Normal 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
|
||||
@ -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);
|
||||
|
||||
|
||||
83
Code/thermal_printer/utf8-utils.c
Normal file
83
Code/thermal_printer/utf8-utils.c
Normal 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
|
||||
}
|
||||
68
Code/thermal_printer/utf8-utils.h
Normal file
68
Code/thermal_printer/utf8-utils.h
Normal 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__ */
|
||||
Loading…
x
Reference in New Issue
Block a user