mirror of
https://github.com/clockworkpi/DevTerm.git
synced 2025-12-14 03:08: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
|
CC = gcc
|
||||||
|
|
||||||
CFLAGS = -g -Wall
|
CFLAGS = -g -Wall
|
||||||
LDFLAUS =
|
LDFLAGS =
|
||||||
INCLUDES =
|
INCLUDES = -I /usr/include/freetype2
|
||||||
LIBS = -lwiringPi -lm -lcrypt -lpthread -lrt
|
LIBS = -lwiringPi -lm -lcrypt -lpthread -lfreetype -lrt
|
||||||
|
|
||||||
MAIN = devterm_thermal_printer.elf
|
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)
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
|
||||||
.PHONY: depend clean
|
.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
|
#define MAXPIXELS 72
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define FONT_MODE_0 0 // Internal
|
||||||
|
#define FONT_MODE_1 1 // External
|
||||||
|
|
||||||
//extract bits
|
//extract bits
|
||||||
#define LAST(k,n) ((k) & ((1<<(n))-1))
|
#define LAST(k,n) ((k) & ((1<<(n))-1))
|
||||||
@ -188,7 +190,9 @@ typedef struct _FONT {
|
|||||||
|
|
||||||
uint8_t width;//in bits
|
uint8_t width;//in bits
|
||||||
uint8_t height;
|
uint8_t height;
|
||||||
|
uint8_t mode;//0 internal pcf font array,1 external ttf font file
|
||||||
const uint8_t *data;
|
const uint8_t *data;
|
||||||
|
char*file;
|
||||||
}FONT;
|
}FONT;
|
||||||
|
|
||||||
typedef struct _ImageCache{
|
typedef struct _ImageCache{
|
||||||
@ -223,6 +227,9 @@ typedef struct _CONFIG
|
|||||||
ImageCache *img;
|
ImageCache *img;
|
||||||
FILE*fp;
|
FILE*fp;
|
||||||
|
|
||||||
|
FT_Face *face;
|
||||||
|
FT_Library *ft;
|
||||||
|
|
||||||
int (*printf)(struct _CONFIG*, char*, ...);
|
int (*printf)(struct _CONFIG*, char*, ...);
|
||||||
|
|
||||||
}CONFIG;
|
}CONFIG;
|
||||||
@ -230,7 +237,9 @@ typedef struct _CONFIG
|
|||||||
|
|
||||||
typedef struct _SerialCache{
|
typedef struct _SerialCache{
|
||||||
uint8_t idx;
|
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;
|
}SerialCache;
|
||||||
|
|
||||||
typedef struct _TimeRec{
|
typedef struct _TimeRec{
|
||||||
|
|||||||
@ -19,16 +19,15 @@
|
|||||||
#include "pcf_6x12-ISO8859-1_6x12.h"
|
#include "pcf_6x12-ISO8859-1_6x12.h"
|
||||||
#include "pcf_7x14-ISO8859-1_7x14.h"
|
#include "pcf_7x14-ISO8859-1_7x14.h"
|
||||||
|
|
||||||
|
|
||||||
#include "ttf_Px437_PS2thin1_8x16.h"
|
#include "ttf_Px437_PS2thin1_8x16.h"
|
||||||
#include "ttf_Px437_PS2thin2_8x16.h"
|
#include "ttf_Px437_PS2thin2_8x16.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "printer.h"
|
#include "printer.h"
|
||||||
|
|
||||||
|
#include "ftype.h"
|
||||||
|
|
||||||
SerialCache ser_cache;
|
SerialCache ser_cache;
|
||||||
|
|
||||||
uint8_t cmd[10];
|
uint8_t cmd[10];
|
||||||
@ -43,6 +42,10 @@ ImageCache img_cache;
|
|||||||
|
|
||||||
FONT current_font;
|
FONT current_font;
|
||||||
|
|
||||||
|
FT_Face face;
|
||||||
|
|
||||||
|
FT_Library ft;
|
||||||
|
|
||||||
CONFIG g_config;
|
CONFIG g_config;
|
||||||
|
|
||||||
TimeRec battery_chk_tm;
|
TimeRec battery_chk_tm;
|
||||||
@ -72,7 +75,7 @@ void reset_cmd(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init_printer(){
|
void init_printer(){
|
||||||
|
char *error = NULL;
|
||||||
memset(cmd,0,10);
|
memset(cmd,0,10);
|
||||||
|
|
||||||
newline = 0;
|
newline = 0;
|
||||||
@ -95,10 +98,22 @@ 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_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.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.line_space=0;
|
||||||
g_config.align = ALIGN_LEFT;
|
g_config.align = ALIGN_LEFT;
|
||||||
@ -249,6 +264,7 @@ NULL
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
for(i=0;i<6;i++){
|
for(i=0;i<6;i++){
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,1);
|
printer_set_font(cfg,1);
|
||||||
reset_cmd();
|
reset_cmd();
|
||||||
|
|
||||||
@ -264,6 +280,7 @@ NULL
|
|||||||
//---------------------------------------------
|
//---------------------------------------------
|
||||||
|
|
||||||
for(i=1;i<4;i++){
|
for(i=1;i<4;i++){
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,0);
|
printer_set_font(cfg,0);
|
||||||
reset_cmd();
|
reset_cmd();
|
||||||
for(j=0;j<strlen(font_names[i]);j++){
|
for(j=0;j<strlen(font_names[i]);j++){
|
||||||
@ -272,6 +289,7 @@ NULL
|
|||||||
}
|
}
|
||||||
parse_serial_stream(cfg,10);
|
parse_serial_stream(cfg,10);
|
||||||
|
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,i);
|
printer_set_font(cfg,i);
|
||||||
reset_cmd();
|
reset_cmd();
|
||||||
for(ch = 33;ch<127;ch++){
|
for(ch = 33;ch<127;ch++){
|
||||||
@ -283,7 +301,7 @@ NULL
|
|||||||
feed_pitch1(48,cfg->orient);
|
feed_pitch1(48,cfg->orient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,0);
|
printer_set_font(cfg,0);
|
||||||
reset_cmd();
|
reset_cmd();
|
||||||
for(j=0;j<strlen(font_names[0]);j++){
|
for(j=0;j<strlen(font_names[0]);j++){
|
||||||
@ -291,6 +309,7 @@ NULL
|
|||||||
}
|
}
|
||||||
parse_serial_stream(cfg,10);
|
parse_serial_stream(cfg,10);
|
||||||
|
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,0);
|
printer_set_font(cfg,0);
|
||||||
reset_cmd();
|
reset_cmd();
|
||||||
for(ch = 33;ch<127;ch++){
|
for(ch = 33;ch<127;ch++){
|
||||||
@ -301,7 +320,7 @@ NULL
|
|||||||
//Serial.println();
|
//Serial.println();
|
||||||
feed_pitch1(48,cfg->orient);
|
feed_pitch1(48,cfg->orient);
|
||||||
|
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,0);
|
printer_set_font(cfg,0);
|
||||||
reset_cmd();
|
reset_cmd();
|
||||||
for(j=0;j<strlen(font_names[0]);j++){
|
for(j=0;j<strlen(font_names[0]);j++){
|
||||||
@ -309,6 +328,7 @@ NULL
|
|||||||
}
|
}
|
||||||
parse_serial_stream(cfg,10);
|
parse_serial_stream(cfg,10);
|
||||||
|
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,4);
|
printer_set_font(cfg,4);
|
||||||
reset_cmd();
|
reset_cmd();
|
||||||
for(ch = 33;ch<127;ch++){
|
for(ch = 33;ch<127;ch++){
|
||||||
@ -340,6 +360,7 @@ NULL
|
|||||||
|
|
||||||
feed_pitch1(cfg->font->height,cfg->orient);
|
feed_pitch1(cfg->font->height,cfg->orient);
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
printer_set_font_mode(FONT_MODE_0);
|
||||||
printer_set_font(cfg,0);
|
printer_set_font(cfg,0);
|
||||||
reset_cmd();
|
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){
|
void printer_set_font(CONFIG*cfg,uint8_t fnbits){
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
ret = MID(fnbits,0,3);
|
ret = MID(fnbits,0,3);
|
||||||
|
|
||||||
if(ret==0) {
|
if(cfg->font->mode == 0) {
|
||||||
cfg->font->width = 8 ;
|
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(cfg->font->mode == 1 ){
|
||||||
|
cfg->font->width = 16;
|
||||||
cfg->font->height = 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){
|
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){
|
void parse_serial_stream(CONFIG*cfg,uint8_t input_ch){
|
||||||
uint16_t a;
|
uint16_t a;
|
||||||
|
uint8_t bskip;
|
||||||
|
|
||||||
if(cfg->state == GET_IMAGE){
|
if(cfg->state == GET_IMAGE){
|
||||||
cfg->img->cache[cfg->img->idx] = input_ch;
|
cfg->img->cache[cfg->img->idx] = input_ch;
|
||||||
@ -647,11 +682,33 @@ void parse_serial_stream(CONFIG*cfg,uint8_t input_ch){
|
|||||||
cmd_idx++;
|
cmd_idx++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ser_cache.data[ser_cache.idx]=input_ch;
|
if(input_ch < 128) {
|
||||||
ser_cache.idx++;
|
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;
|
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);
|
print_lines8(cfg);
|
||||||
reset_cmd();
|
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*);
|
uint8_t print_image8(CONFIG*);
|
||||||
void print_cut_line(CONFIG*);
|
void print_cut_line(CONFIG*);
|
||||||
|
|
||||||
|
void printer_set_font_mode(int);
|
||||||
void printer_set_font(CONFIG*cfg,uint8_t fnbits);
|
void printer_set_font(CONFIG*cfg,uint8_t fnbits);
|
||||||
void parse_serial_stream(CONFIG*cfg,uint8_t input_ch);
|
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