调整扫描流程

This commit is contained in:
gb 2024-02-26 17:25:02 +08:00
parent 6c2ba5166c
commit a040422b7b
15 changed files with 476 additions and 202 deletions

View File

@ -365,22 +365,15 @@ void scanner_hw::thread_image_capture(bool paper_ready)
{
PACKIMAGE img(img_base_);
safe_fifo<int> avail_mem("v4l2-mem");
int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4,
err = SCANNER_ERR_OK;
int used_v4l2_mem = 0, times = 0,
err = SCANNER_ERR_OK, over_msg_id = 0;;
devui::SCANSTREAM scanstream;
chronograph watch;
std::pair<int, int> mbev;
std::function<IMAGE_HANDLER_PROTO> img_callback(img_handler_);
auto put_v4l2_mem = [&](BEFORE_DESTROY_PARAM) -> BEFORE_DESTROY_RET
{
int ind = (int)(long)param;
mem->detach(nullptr);
avail_mem.save(ind);
};
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread working ...\n");
avail_mem.enable_wait_log(false);
motor_->clear_error();
if(paper_ready)
motor_->start();
@ -390,125 +383,19 @@ void scanner_hw::thread_image_capture(bool paper_ready)
devui::send_message(devui::UI_STATUS_SCANNING, (uint8_t*)&scanstream, sizeof(scanstream));
while(scanning_) // auto scan cycle ...
{
int attempt = 0;
while(paper_ready && scanning_ && attempt++ < 5)
{
mbev.first = -1;
mbev.second = 0;
if(mb_events_.take(mbev, true, to_lifter_)
&& mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
{
utils::to_log(LOG_LEVEL_DEBUG, "take first motorboard event: %d - 0x%08x\n", mbev.first, mbev.second);
break;
}
else
utils::to_log(LOG_LEVEL_FATAL, "Wait Lifter event before scanning failed, get event(%d - 0x%08x).\n", mbev.first, mbev.second);
motor_->start();
}
if(mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
{
times++;
watch.reset();
motor_->pick_paper();
// scanning ONE turn ...
while(scanning_ && motor_->wait_paper_out(to_paper_out_))
{
uint32_t pass = watch.elapse_ms();
mbev.first = -1;
mbev.second = 0;
if(mb_events_.take(mbev, true, 10) && mbev.first == MOTOR_BORD_EVENT_ERROR)
{
auto notify_paper = [&](int error) -> void
{
if(error == SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
devui::send_message(devui::UI_STATUS_PAPER_CNT, (uint8_t*)&pass, sizeof(pass));
};
err = trans_motorboard_err_2_hg_error(mbev.second, true, notify_paper);
if(err != SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
break;
}
else if(mbev.first == MOTOR_BORD_EVENT_SCAN_DONE)
{
printf("-->scan done event received from motorboard.\n");
break;
}
else
{
devui::send_message(devui::UI_STATUS_PAPER_CNT, (uint8_t*)&pass, sizeof(pass));
err = SCANNER_ERR_OK;
}
img.pos.paper_ind++;
if(!count_mode_)
{
img.height = get_image_real_height(minh);
size_t size = 0;
int ind = -1;
void* frame = camera_->read_frame(to_stream_, size, ind);
dyn_mem_shared_ptr mem = nullptr;
if(!frame)
{
if(err == SCANNER_ERR_OK)
err = SCANNER_ERR_DEVICE_CIS_STREAM;
break;
}
img.prc_time = watch.elapse_ms();
mem = new dyn_mem_shared(frame, size, put_v4l2_mem, (void*)ind);
used_v4l2_mem++;
img.pos.status = hg_err_2_image_status(err);
img_handler_(mem, true, &img);
mem->release();
if((!scan_cntless_ && img.pos.paper_ind == scan_count_) || is_scan_fatal())
break;
// retrieve V4L2 memory ...
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
if(used_v4l2_mem >= camera_->get_mem_count())
{
err = SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM;
stop_scan();
utils::to_log(LOG_LEVEL_FATAL, "Scanning stopped for that V4L2 is out of memory!\n");
break;
}
}
if(res_(TASK_CAPTURER, true, 3000) && scanning_)
{
watch.reset();
motor_->pick_paper();
}
else
{
break;
}
}
printf("Scan turn finished with event(%d - 0x%08x).\n", mbev.first, mbev.second);
// retrieve v4l2-mem ...
int ind = -1;
while(avail_mem.take(ind, false))
{
used_v4l2_mem--;
camera_->add_v4l2_memory(ind);
}
}
{
scanstream.err = err;
scanstream.mode = devui::SCAN_PAUSED;
devui::send_message(devui::UI_STATUS_SCANNING, (uint8_t*)&scanstream, sizeof(scanstream));
}
if(!auto_scan_ || !scanning_)
err = start_and_wait_lifter(to_lifter_, &over_msg_id);
if(err)
break;
// scanning ONE turn ...
if(paper_ready) // auto_scan_ ignore no paper
{
motor_->pick_paper();
err = scan_one_turn(&img, &avail_mem, &used_v4l2_mem, &over_msg_id);
if(err || !auto_scan_ || !scanning_)
break;
}
// wait paper ...
while(auto_scan_)
{
@ -526,12 +413,16 @@ void scanner_hw::thread_image_capture(bool paper_ready)
printf("\tmotor-board event is %d\n", mbev.first);
}
}
if(!scanning_)
break;
// retrieve v4l2-mem ...
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
}
if(scanning_ && mbev.first != MOTOR_BORD_EVENT_LIFTER_READY && times == 0)
err = SCANNER_ERR_DEVICE_FEEDER_POS;
motor_->set_auto_paper(false, false);
motor_->stop();
stop_scan();
while(used_v4l2_mem)
{
if(times++ == 0)
@ -547,7 +438,7 @@ void scanner_hw::thread_image_capture(bool paper_ready)
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread exited with error: %d.\n", err);
{
scanstream.err = err;
scanstream.err = over_msg_id;
scanstream.mode = devui::SCAN_STOPPED;
devui::send_message(devui::UI_STATUS_SCANNING, (uint8_t*)&scanstream, sizeof(scanstream));
}
@ -555,6 +446,161 @@ void scanner_hw::thread_image_capture(bool paper_ready)
scanning_ = false;
img_handler_((dyn_mem_ptr)WORKER_STATUS_IDLE, false, (LPPACKIMAGE)err);
}
int scanner_hw::start_and_wait_lifter(int to_ms, int* ui_words_id)
{
int ret = SCANNER_ERR_DEVICE_FEEDER_POS,
words = ID_WORDS_STATUS_DEVICE_HD_001;
chronograph watch;
while(scanning_ && watch.elapse_ms() < to_ms)
{
std::pair<int, int> mbev;
if(mb_events_.take(mbev, true, 3))
{
if(mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
{
ret = words = 0;
break;
}
else
{
int err = trans_motorboard_err_2_hg_error(mbev.first, &words);
if(err)
{
ret = err;
break;
}
}
}
}
if(!scanning_) // user cancelled
{
ret = SCANNER_ERR_USER_CANCELED;
words = 0;
}
if(ui_words_id)
*ui_words_id = words;
return ret;
}
int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_cnt, int* ui_words)
{
int ret = SCANNER_ERR_OK, minh = 210 * dpi_ / 25.4,
words = 0;
uint32_t pass = 0;
chronograph watch;
std::pair<int, int> mbev;
auto put_v4l2_mem = [&](BEFORE_DESTROY_PARAM) -> BEFORE_DESTROY_RET
{
int ind = (int)(long)mem->get_param(1);
safe_fifo<int>* que = (safe_fifo<int>*)mem->get_param(0);
mem->detach(nullptr);
que->save(ind);
};
while(scanning_)
{
if(!motor_->wait_paper_out(to_paper_out_))
{
ret = SCANNER_ERR_DEVICE_HD_002;
words = ID_WORDS_STATUS_DEVICE_HD_002;
break;
}
pass = watch.elapse_ms();
mbev.first = -1;
mbev.second = 0;
if(mb_events_.take(mbev, true, 10) && mbev.first == MOTOR_BORD_EVENT_ERROR)
{
ret = trans_motorboard_err_2_hg_error(mbev.second, &words);
if(ret != SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
{
break;
}
}
else if(mbev.first == MOTOR_BORD_EVENT_SCAN_DONE)
{
printf("-->scan done event received from motorboard.\n");
break;
}
else
{
ret = SCANNER_ERR_OK;
words = 0;
}
img->pos.paper_ind++;
if(count_mode_)
{
devui::send_message(devui::UI_STATUS_PAPER_CNT, (uint8_t*)&pass, sizeof(pass));
}
else
{
img->height = get_image_real_height(minh);
size_t size = 0;
int ind = -1;
void* frame = camera_->read_frame(to_stream_, size, ind);
dyn_mem_shared_ptr mem = nullptr;
if(!frame)
{
ret = SCANNER_ERR_DEVICE_CIS_STREAM;
words = ID_WORDS_STATUS_CAPTURE_FAILED;
break;
}
devui::send_message(devui::UI_STATUS_PAPER_CNT, (uint8_t*)&pass, sizeof(pass));
img->prc_time = watch.elapse_ms();
mem = new dyn_mem_shared(frame, size, put_v4l2_mem);
mem->set_param(cism, 0);
mem->set_param((void*)(long)ind, 1);
cism_cnt[0]++;
img->pos.status = hg_err_2_image_status(ret);
img_handler_(mem, true, img);
mem->release();
if(!scan_cntless_ && img->pos.paper_ind == scan_count_)
{
utils::to_log(LOG_LEVEL_ALL, "Scanning finished for given count %d!\n", scan_count_);
break;
}
// retrieve V4L2 memory ...
retrieve_v4l2_mem(cism, cism_cnt);
if(cism_cnt[0] >= camera_->get_mem_count())
{
ret = SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM;
words = ID_WORDS_STATUS_CIS_OUT_OF_MEM;
utils::to_log(LOG_LEVEL_FATAL, "Scanning stopped for that V4L2 is out of memory!\n");
break;
}
}
// resource checking ...
if(res_(TASK_CAPTURER, true, 3000) && scanning_)
{
// should check paper ready ?
watch.reset();
motor_->pick_paper();
}
else
{
ret = SCANNER_ERR_DEVICE_HD_003;
words = ID_WORDS_STATUS_DEVICE_HD_003;
break;
}
}
if(ui_words)
*ui_words = words;
return ret;
}
int scanner_hw::get_image_real_height(int minh)
{
chronograph watch;
@ -569,10 +615,6 @@ int scanner_hw::get_image_real_height(int minh)
return h;
}
bool scanner_hw::is_scan_fatal(void)
{
return false;
}
void scanner_hw::retrieve_v4l2_mem(safe_fifo<int>* mem, int* used)
{
int u = *used,
@ -1005,7 +1047,7 @@ int scanner_hw::close(bool from_worker)
return 0;
}
int scanner_hw::trans_motorboard_err_2_hg_error(int mberr, bool to_ui, std::function<void(int)> bef_ui)
int scanner_hw::trans_motorboard_err_2_hg_error(int mberr, int *ui_msg)
{
unsigned int val = mberr;
SMBSTATUS *s = (SMBSTATUS*)&val;
@ -1037,14 +1079,8 @@ int scanner_hw::trans_motorboard_err_2_hg_error(int mberr, bool to_ui, std::func
msg = ID_WORDS_STATUS_ASKEW;
}
if(to_ui && msg)
{
printf("status message: %s\n", words_from_id(msg));
if(bef_ui)
bef_ui(mberr);
devui::send_status_message(msg);
}
if(ui_msg)
*ui_msg = msg;
return mberr;
}

View File

@ -102,8 +102,9 @@ class scanner_hw : public sane_opt_provider
void init_version(std::string& text);
void load_correct_data(std::string& text);
void thread_image_capture(bool paper_ready);
int start_and_wait_lifter(int to_ms, int* ui_words_id = nullptr);
int scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_cnt, int* ui_words);
int get_image_real_height(int minh);
bool is_scan_fatal(void);
void retrieve_v4l2_mem(safe_fifo<int>* mem, int* used);
void set_gain_value(bool front, bool gain, int sector, int val);
@ -125,7 +126,7 @@ public:
int start_scan(void);
int stop_scan(bool from_ui = false);
int close(bool from_worker = false);
int trans_motorboard_err_2_hg_error(int mberr, bool to_ui = false, std::function<void(int)> bef_ui = std::function<void(int)>());
int trans_motorboard_err_2_hg_error(int mberr, int *ui_msg = nullptr);
int hg_err_2_image_status(int hgerr);
bool is_scanning(void);
void clean_paper_passway(void);

View File

@ -98,7 +98,7 @@ void rebuild::do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGI
o.info.width = out[0].info.width;
o.info.channels = out[0].info.channels;
printf("rebuild (%d * %d * 8) to (%d * %d * 24), front = %p, back = %p, size = %u ...\n", info->width, info->height
printf("rebuild %03d - (%d * %d * 8) to (%d * %d * 24), front = %p, back = %p, size = %u ...\n", info->pos.paper_ind, info->width, info->height
, o.info.width, o.info.height, dstf, dstb, size);
for(int h = 0; h < info->height; ++h)
{

View File

@ -37,6 +37,7 @@ imgproc_mgr::imgproc_mgr(std::function<void(data_source_ptr)> sender
: img_sender_(sender), opts_(devopts), prc_que_("prcimg")
, res_(res)
{
prc_que_.enable_wait_log(false);
ADD_THIS_JSON();
if(!res_)

View File

@ -184,6 +184,8 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0)
usb_ = new async_usb_gadget(bulk_handle, on_connect);
last_err_ = usb_->last_error();
devui::send_status_message(ID_WORDS_STATUS_SCANNER_CONN + 1);
}
async_scanner::~async_scanner()

View File

@ -543,13 +543,36 @@ int dyn_mem::fetch_data(void* buf, uint32_t* size)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
dyn_mem_shared::dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy, void* param)
: dyn_mem(buf, size), destroy_(destroy), param_(param)
{}
dyn_mem_shared::dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy)
: dyn_mem(buf, size), destroy_(destroy)
{
memset(param_, 0, sizeof(param_));
}
dyn_mem_shared::~dyn_mem_shared()
{
if(destroy_)
destroy_(this, param_);
destroy_(this);
}
bool dyn_mem_shared::set_param(void* param, int index)
{
if(index >= 0 && index < _countof(param_))
{
param_[index] = param;
return true;
}
else
{
return false;
}
}
void* dyn_mem_shared::get_param(int index)
{
if(index >= 0 && index < _countof(param_))
return param_[index];
else
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -213,7 +213,7 @@ public:
// #define STAT_MEM
#define BEFORE_DESTROY_RET void
#define BEFORE_DESTROY_PARAM dyn_mem* mem, void* param
#define BEFORE_DESTROY_PARAM dyn_mem_shared* mem
#define BEFORE_DESTROY_FUNC std::function<BEFORE_DESTROY_RET(BEFORE_DESTROY_PARAM)>
class dyn_mem : public data_source
@ -263,13 +263,17 @@ public:
class dyn_mem_shared : public dyn_mem
{
BEFORE_DESTROY_FUNC destroy_ = BEFORE_DESTROY_FUNC();
void* param_ = nullptr;
void* param_[4];
public:
dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy = BEFORE_DESTROY_FUNC(), void* param = nullptr);
dyn_mem_shared(void* buf, size_t size, BEFORE_DESTROY_FUNC destroy = BEFORE_DESTROY_FUNC());
protected:
~dyn_mem_shared();
public:
bool set_param(void* param, int index = 0);
void* get_param(int index = 0);
};
class file_reader : public data_source

View File

@ -6,6 +6,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#define PIPE_PROTO_VER MAKEWORD(0, 1)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ipc class
namespace devui
@ -189,18 +191,12 @@ namespace devui
int mode[] = {O_RDONLY, O_WRONLY};
int *fd[] = {&fdi_, &fdo_};
if(ui_)
{
mkfifo(fifo[!ui_], 0777);
mkfifo(fifo[ui_], 0777);
fdo_ = open(fifo[1], mode[1]);
fdi_ = open(fifo[0], mode[0]);
}
else
{
fdi_ = open(fifo[1], mode[0]);
fdo_ = open(fifo[0], mode[1]);
}
mkfifo(fifo[!ui_], 0777);
mkfifo(fifo[ui_], 0777);
*fd[ui_] = open(fifo[1], mode[ui_]);
utils::to_log(LOG_LEVEL_ALL, "open pipe(%s) = %d\n", fifo[1], *fd[ui_]);
*fd[!ui_] = open(fifo[0], mode[!ui_]);
utils::to_log(LOG_LEVEL_ALL, "open pipe(%s) = %d\n", fifo[0], *fd[!ui_]);
if(fdo_ == -1 || fdi_ == -1)
{
@ -254,6 +250,12 @@ namespace devui
// peer closed, wait 10ms ...
if(watch.elapse_ms() > 10)
{
MSGSTREAM ms;
memset(&ms, 0, sizeof(ms));
ms.ver = PIPE_PROTO_VER;
ms.msg = UI_STATUS_PEER_CLOSED;
cb_(&ms);
printf("PIPE: peer closed(read ZERO byte and error = %d).\n", errno);
utils::to_log(LOG_LEVEL_DEBUG, "PIPE: peer closed(read ZERO byte and error = %d).\n", errno);
}
@ -369,7 +371,7 @@ namespace devui
size_t fix = sizeof(pack.data);
memset(&pack, 0, sizeof(pack));
pack.ver = 1;
pack.ver = PIPE_PROTO_VER;
pack.msg = msgid;
pack.size = size;
if(size > fix)

View File

@ -28,6 +28,8 @@ namespace devui
UI_STATUS_SCANNING = 0x1000, // begin scanning. data: (LPSCANSTREAM)
UI_STATUS_PAPER_CNT, // ONE paper has pass through. data: (uint32_t*)milliseconds for paper pass through
UI_STATUS_MESSAGE, // status message, hold screen. data: LPSTATMSG
UI_STATUS_PEER_CLOSED = 0x8000, // peer closed.
};
enum align_component
{
@ -48,7 +50,7 @@ namespace devui
{
uint16_t ver;
uint16_t size; // bytes of data
uint32_t msg;
uint32_t msg; // uicmd
uint8_t data[4];
uint32_t whole_size(void)
@ -63,7 +65,7 @@ namespace devui
{
uint32_t mode : 5; // see enum scan
uint32_t speed : 27;
uint32_t err;
uint32_t err; // err message word ID, 0 is normal
}SCANSTREAM, *LPSCANSTREAM;
typedef struct _status_msg
{

View File

@ -73,6 +73,13 @@ WORDS_AND_ID_IMPL(WORDS_STATUS_STAPLE, "\346\243\200\346\265\213\345
WORDS_AND_ID_IMPL(WORDS_STATUS_ASKEW, "\347\272\270\345\274\240\346\255\252\346\226\234");
WORDS_AND_ID_IMPL(WORDS_STATUS_CIS_TIMEOUT, "\345\217\226\345\233\276\350\266\205\346\227\266");
WORDS_AND_ID_IMPL(WORDS_STATUS_JAMMED, "\345\215\241\347\272\270");
WORDS_AND_ID_IMPL(WORDS_STATUS_CAPTURE_FAILED, "\351\207\207\345\233\276\345\244\261\350\264\245");
WORDS_AND_ID_IMPL(WORDS_STATUS_CIS_OUT_OF_MEM, "\347\274\223\345\206\262\345\214\272\350\200\227\345\260\275");
WORDS_AND_ID_IMPL(WORDS_STATUS_DEVICE_HD_001, "\347\241\254\344\273\266\351\224\231\350\257\257001");
WORDS_AND_ID_IMPL(WORDS_STATUS_DEVICE_HD_002, "\347\241\254\344\273\266\351\224\231\350\257\257002");
WORDS_AND_ID_IMPL(WORDS_STATUS_DEVICE_HD_003, "\347\241\254\344\273\266\351\224\231\350\257\257003");
WORDS_AND_ID_IMPL(WORDS_STATUS_SCANNER_CONN, "\346\211\253\346\217\217\347\250\213\345\272\217\345\267\262\351\200\200\345\207\272");
WORDS_AND_ID_IMPL(WORDS_STATUS_SCANNER_CONN_1, "\346\211\253\346\217\217\347\250\213\345\272\217\345\267\262\350\277\220\350\241\214");
@ -139,6 +146,12 @@ const char* words_from_id(int id)
RETURN_ID_STR(id, WORDS_STATUS_ASKEW);
RETURN_ID_STR(id, WORDS_STATUS_CIS_TIMEOUT);
RETURN_ID_STR(id, WORDS_STATUS_JAMMED);
RETURN_ID_STR(id, WORDS_STATUS_CAPTURE_FAILED);
RETURN_ID_STR(id, WORDS_STATUS_CIS_OUT_OF_MEM);
RETURN_ID_STR(id, WORDS_STATUS_DEVICE_HD_001);
RETURN_ID_STR(id, WORDS_STATUS_DEVICE_HD_002);
RETURN_ID_STR(id, WORDS_STATUS_DEVICE_HD_003);
RETURN_ID_STR(id, WORDS_STATUS_SCANNER_CONN);
return "";
}

View File

@ -86,3 +86,9 @@ WORDS_AND_ID_DECL(WORDS_STATUS_STAPLE);
WORDS_AND_ID_DECL(WORDS_STATUS_ASKEW);
WORDS_AND_ID_DECL(WORDS_STATUS_CIS_TIMEOUT);
WORDS_AND_ID_DECL(WORDS_STATUS_JAMMED);
WORDS_AND_ID_DECL(WORDS_STATUS_CAPTURE_FAILED);
WORDS_AND_ID_DECL(WORDS_STATUS_CIS_OUT_OF_MEM);
WORDS_AND_ID_DECL(WORDS_STATUS_DEVICE_HD_001);
WORDS_AND_ID_DECL(WORDS_STATUS_DEVICE_HD_002);
WORDS_AND_ID_DECL(WORDS_STATUS_DEVICE_HD_003);
WORDS_AND_ID_DECL(WORDS_STATUS_SCANNER_CONN);

View File

@ -85,9 +85,9 @@ enum scanner_err
SCANNER_ERR_DEVICE_FEEDER_POS, // 送纸器到位信号未触发
SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM, // CIS缓冲区被耗尽
SCANNER_ERR_DEVICE_CIS_STREAM, // 获取CIS图像数据失败
SCANNER_ERR_DEVICE_HD_001, // 设备硬件访问错误
SCANNER_ERR_DEVICE_HD_002, // 设备硬件访问错误
SCANNER_ERR_DEVICE_HD_003, // 设备硬件访问错误
SCANNER_ERR_DEVICE_HD_001, // 设备硬件访问错误 - 扫描前升降台未到位
SCANNER_ERR_DEVICE_HD_002, // 设备硬件访问错误 - 纸张出口信号未触发
SCANNER_ERR_DEVICE_HD_003, // 设备硬件访问错误 - 资源不足
SCANNER_ERR_DEVICE_HD_004, // 设备硬件访问错误
SCANNER_ERR_DEVICE_HD_005, // 设备硬件访问错误
SCANNER_ERR_DEVICE_HD_006, // 设备硬件访问错误

View File

@ -439,7 +439,7 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
lcd_->Lcd_Initial_Lcd(false);
lcd_->clear();
ready_.cnt = custom_font::get_string_font(WORDS_STATUS_READY, ready_.ptr);
ready_.cnt = custom_font::get_string_font(WORDS_STATUS_READY, ready_.ptr, custom_font::FONT_SIZE_32);
ready_.x = (Lcd::LCD_WIDTH - ready_.ptr[0][0] * ready_.cnt - 8) / 2;
ready_.y = (Lcd::LCD_HEIGHT - ready_.ptr[0][1]) / 2;
ready_.mask = 0;
@ -497,6 +497,16 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
if(scan->mode == devui::SCAN_PAUSED)
{
perm_data_->save();
if(scan->err)
{
devui::STATMSG msg;
msg.align_h = msg.align_v = devui::ALIGN_COMPONENT_MID;
msg.clear = devui::CLEAR_ALL;
msg.font = 16;
msg.msg_words_id = scan->err;
msg.reserved = 0;
display_status(&msg);
}
}
else
{
@ -509,6 +519,17 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
else
{
perm_data_->save();
if(scan->err)
{
devui::STATMSG msg;
msg.align_h = msg.align_v = devui::ALIGN_COMPONENT_MID;
msg.clear = devui::CLEAR_ALL;
msg.font = 16;
msg.msg_words_id = scan->err;
msg.reserved = 0;
if(!display_status(&msg))
set_ready_status_enabled(true);
}
}
}
else if(pack->msg == devui::UI_STATUS_PAPER_CNT)
@ -543,6 +564,23 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
{
int_by_status_ = true;
display_status(pack->data);
peer_connected_ = true;
if(((devui::LPSTATMSG)pack->data)->msg_words_id == ID_WORDS_STATUS_SCANNER_CONN + 1)
set_ready_status_enabled(true);
}
else if(pack->msg == devui::UI_STATUS_PEER_CLOSED)
{
peer_connected_ = *(bool*)pack->data;
set_ready_status_enabled(peer_connected_);
devui::STATMSG msg;
msg.align_h = msg.align_v = devui::ALIGN_COMPONENT_MID;
msg.clear = devui::CLEAR_ALL;
msg.font = 16;
msg.msg_words_id = ID_WORDS_STATUS_SCANNER_CONN + peer_connected_;
msg.reserved = 0;
if(!display_status(&msg))
set_ready_status_enabled(true);
}
};
devui::init_ui(statu, true);
@ -1154,7 +1192,7 @@ void ui_mgr::display_ready(bool time_only)
lcd_->write_line(dd.ptr, dd.cnt, dd.x, dd.y, dd.mask);
}
}
void ui_mgr::display_status(void* data)
bool ui_mgr::display_status(void* data)
{
devui::LPSTATMSG lpstatus = (devui::LPSTATMSG)data;
const char* text = words_from_id(lpstatus->msg_words_id);
@ -1164,7 +1202,7 @@ void ui_mgr::display_status(void* data)
if(!text || !text[0])
{
utils::to_log(LOG_LEVEL_DEBUG, "Error, No message text for ID %u.\n", lpstatus->msg_words_id);
return;
return false;
}
if(lpstatus->font < 8)
@ -1185,7 +1223,7 @@ void ui_mgr::display_status(void* data)
if(dd.cnt == 0)
{
utils::to_log(LOG_LEVEL_DEBUG, "No font size %u for status message '%s'.\n", lpstatus->font, text);
return;
return false;
}
if(lpstatus->align_h != devui::ALIGN_COMPONENT_HEAD)
@ -1224,6 +1262,8 @@ void ui_mgr::display_status(void* data)
dd.mask = 0;
cnt = disp_data_.save(dd, true);
}
return true;
}
void ui_mgr::set_ready_status_enabled(bool enable)
{

View File

@ -103,6 +103,7 @@ class ui_mgr : public refer
bool scanning_ = false;
bool stopped_by_ui_ = false; // enable ready message when error occurs in auto-scan
bool int_by_status_ = false;
bool peer_connected_ = false;
int scan_mode_ = 0;
int paper_total_ = 0;
int paper_cnt_ = 0;
@ -316,7 +317,7 @@ class ui_mgr : public refer
void thread_display(void);
void display_scan_title(void);
void display_ready(bool time_only);
void display_status(void* data);
bool display_status(void* data);
void set_ready_status_enabled(bool enable); // disable ready message, the last message will display until keyboard event triggered
void reset_ready_watch(void);
int get_ready_watch_ms(void);

View File

@ -17,10 +17,20 @@ namespace custom_font
, 0x00, 0x0C, 0xE4, 0x24, 0x3C, 0x00, 0x00, 0x00
};
static uint8_t question32x32[] = {22, 32
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x40, 0x60, 0x20, 0x20, 0x20, 0x60, 0xC0, 0xC0
, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0F, 0x0E, 0x04, 0x00
, 0x00, 0x00, 0xC0, 0xE0, 0x79, 0x7F, 0x1F, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x3F, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x0E
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
class font_init
{
std::map<std::string, uint8_t*> font_map_;
std::map<std::string, uint8_t*> font_map8x8_;
std::map<std::string, uint8_t*> font_map32x32_;
void init_8x8(void)
{
@ -90,11 +100,39 @@ namespace custom_font
font_map8x8_["\071\000\000"] = num9;
}
void init_32x32(void)
{
static uint8_t jiu[] = {32, 32
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0xF8, 0xF8, 0xF0, 0xF0
, 0xE0, 0x80, 0x00, 0x00, 0x60, 0xB0, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x1C, 0x1E, 0xCE, 0xF6, 0xEF, 0x77, 0x77, 0xBF, 0xFB, 0xFB, 0xFB
, 0xF1, 0xB1, 0xC1, 0xE0, 0xF8, 0xFF, 0xFF, 0x77, 0x7C, 0x38, 0x18, 0x1A, 0x07, 0x07, 0x07, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE1, 0xC7, 0x4F, 0x0F, 0xFF, 0xFF, 0x3F, 0x63, 0xE3
, 0xE1, 0xFD, 0x3F, 0x0F, 0xE3, 0xFD, 0x3F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03, 0x00, 0x02, 0x06, 0x1F, 0x1F, 0x00, 0x00, 0x03
, 0x03, 0x00, 0x00, 0x03, 0x0F, 0x0F, 0x1E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1E, 0x0E, 0x0F, 0x0F, 0x06
};
font_map32x32_["\345\260\261"] = jiu;
static uint8_t xu[] = {32, 32
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xF8, 0xF8, 0xF0, 0xE0, 0x80
, 0x00, 0x00, 0x01, 0x83, 0xFF, 0xFF, 0xFF, 0xCC, 0xC0, 0x80, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x18, 0x7C, 0x7E, 0x3E, 0xDF, 0xFF, 0xFF, 0xFF, 0xF3, 0x81, 0x81, 0x83
, 0xC7, 0xCF, 0xFF, 0xFF, 0xFF, 0xEF, 0xF7, 0x7B, 0x7F, 0x7F, 0x7F, 0x77, 0x73, 0x70, 0x40, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0xCF, 0xFF, 0xFF, 0x3F, 0x07, 0x87, 0xE3, 0x73
, 0x79, 0xFD, 0xFE, 0xFF, 0xDF, 0xFF, 0xCE, 0x7E, 0xFE, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1F, 0x1F, 0x07, 0x02, 0x01, 0x01, 0x00, 0x00
, 0x00, 0x07, 0x0F, 0x0F, 0x0E, 0x06, 0x1E, 0x7C, 0xFF, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00
};
font_map32x32_["\347\273\252"] = xu;
}
public:
font_init()
{
init_8x8();
init_32x32();
static uint8_t huan[] = {16, 16
, 0x00, 0x00, 0x00, 0x40, 0xE0, 0xE0, 0xE0, 0xC0, 0xC4, 0xFE, 0xFC, 0xE8, 0xE0, 0xE0, 0x00, 0x00
@ -108,30 +146,6 @@ namespace custom_font
};
font_map_["\350\277\216"] = ying;
static uint8_t jiu[] = {32, 32
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0xF8, 0xF8, 0xF0, 0xF0
, 0xE0, 0x80, 0x00, 0x00, 0x60, 0xB0, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x1C, 0x1E, 0xCE, 0xF6, 0xEF, 0x77, 0x77, 0xBF, 0xFB, 0xFB, 0xFB
, 0xF1, 0xB1, 0xC1, 0xE0, 0xF8, 0xFF, 0xFF, 0x77, 0x7C, 0x38, 0x18, 0x1A, 0x07, 0x07, 0x07, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE1, 0xC7, 0x4F, 0x0F, 0xFF, 0xFF, 0x3F, 0x63, 0xE3
, 0xE1, 0xFD, 0x3F, 0x0F, 0xE3, 0xFD, 0x3F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03, 0x00, 0x02, 0x06, 0x1F, 0x1F, 0x00, 0x00, 0x03
, 0x03, 0x00, 0x00, 0x03, 0x0F, 0x0F, 0x1E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1E, 0x0E, 0x0F, 0x0F, 0x06
};
font_map_["\345\260\261"] = jiu;
static uint8_t xu[] = {32, 32
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xF8, 0xF8, 0xF0, 0xE0, 0x80
, 0x00, 0x00, 0x01, 0x83, 0xFF, 0xFF, 0xFF, 0xCC, 0xC0, 0x80, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x18, 0x7C, 0x7E, 0x3E, 0xDF, 0xFF, 0xFF, 0xFF, 0xF3, 0x81, 0x81, 0x83
, 0xC7, 0xCF, 0xFF, 0xFF, 0xFF, 0xEF, 0xF7, 0x7B, 0x7F, 0x7F, 0x7F, 0x77, 0x73, 0x70, 0x40, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0xCF, 0xFF, 0xFF, 0x3F, 0x07, 0x87, 0xE3, 0x73
, 0x79, 0xFD, 0xFE, 0xFF, 0xDF, 0xFF, 0xCE, 0x7E, 0xFE, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1F, 0x1F, 0x07, 0x02, 0x01, 0x01, 0x00, 0x00
, 0x00, 0x07, 0x0F, 0x0F, 0x0E, 0x06, 0x1E, 0x7C, 0xFF, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00
};
font_map_["\347\273\252"] = xu;
static uint8_t right[] = {16, 16
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x3C, 0x04, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0x1C, 0x30, 0x78, 0x0F, 0x01, 0x00, 0x00, 0x00
@ -648,6 +662,126 @@ namespace custom_font
};
font_map_["\351\222\237"] = zhong1;
static uint8_t cai3[] = {16, 16
, 0x00, 0x00, 0x00, 0x08, 0x70, 0x62, 0x02, 0x02, 0x9A, 0xB2, 0x02, 0x82, 0x62, 0x3B, 0x0F, 0x03
, 0x00, 0x00, 0x81, 0x41, 0x61, 0x31, 0x19, 0x0F, 0xFF, 0xFF, 0x03, 0x0D, 0x31, 0x61, 0xC1, 0xC1
};
font_map_["\351\207\207"] = cai3;
static uint8_t tu[] = {16, 16
, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x21, 0x19, 0x8F, 0x8F, 0xC9, 0xE9, 0x39, 0x19, 0x01, 0x01, 0xFF
, 0x00, 0x00, 0x00, 0xFF, 0x46, 0x42, 0x43, 0x51, 0x53, 0x54, 0x75, 0x61, 0x43, 0x42, 0x42, 0xFF
};
font_map_["\345\233\276"] = tu;
static uint8_t shi1[] = {16, 16
, 0x00, 0x00, 0x00, 0xC0, 0x3C, 0x1C, 0x10, 0x10, 0xF1, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x80
, 0x00, 0x00, 0x01, 0x81, 0x81, 0x41, 0x61, 0x39, 0x0F, 0x03, 0x07, 0x19, 0x31, 0x61, 0xC1, 0x81
};
font_map_["\345\244\261"] = shi1;
static uint8_t bai[] = {16, 16
, 0x00, 0x00, 0xFE, 0x02, 0xFA, 0xFA, 0x02, 0xFE, 0x80, 0x60, 0xFE, 0x17, 0x10, 0x10, 0xF0, 0x10
, 0x00, 0x00, 0xCF, 0x70, 0x1F, 0x0B, 0x18, 0x77, 0x21, 0x80, 0x40, 0x27, 0x38, 0x6F, 0xC1, 0xC0
};
font_map_["\350\264\245"] = bai;
static uint8_t ying4[] = {16, 16
, 0x04, 0x84, 0xE4, 0x5C, 0x44, 0xC4, 0x00, 0xF2, 0x92, 0x92, 0xFE, 0x92, 0x92, 0xF2, 0x02, 0x00
, 0x02, 0x01, 0x7F, 0x10, 0x10, 0x3F, 0x80, 0x8F, 0x54, 0x24, 0x5F, 0x44, 0x84, 0x87, 0x80, 0x00
};
font_map_["\347\241\254"] = ying4;
static uint8_t jian4[] = {16, 16
, 0x00, 0x80, 0x60, 0xF8, 0x07, 0x80, 0x60, 0x1C, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x00, 0x00
, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0xFF, 0x02, 0x02, 0x02, 0x02, 0x00
};
font_map_["\344\273\266"] = jian4;
static uint8_t cuo[] = {16, 16
, 0x40, 0x30, 0xEF, 0x24, 0x64, 0x48, 0x48, 0x7F, 0x48, 0x48, 0x48, 0x7F, 0x48, 0x48, 0x40, 0x00
, 0x01, 0x01, 0x7F, 0x21, 0x11, 0x00, 0xFF, 0x49, 0x49, 0x49, 0x49, 0x49, 0xFF, 0x00, 0x00, 0x00
};
font_map_["\351\224\231"] = cuo;
static uint8_t wu4[] = {16, 16
, 0x40, 0x42, 0xCC, 0x00, 0x00, 0x80, 0x9E, 0x92, 0x92, 0x92, 0x92, 0x92, 0x9E, 0x80, 0x00, 0x00
, 0x00, 0x00, 0x7F, 0x20, 0x94, 0x84, 0x44, 0x24, 0x14, 0x0F, 0x14, 0x24, 0x44, 0x84, 0x84, 0x00
};
font_map_["\350\257\257"] = wu4;
static uint8_t huan3[] = {16, 16
, 0x20, 0x30, 0xAC, 0x63, 0x30, 0x02, 0x26, 0x2A, 0xE2, 0x26, 0x29, 0x21, 0x29, 0x25, 0x00, 0x00
, 0x22, 0x67, 0x22, 0x12, 0x52, 0x21, 0x99, 0x87, 0x4D, 0x55, 0x25, 0x55, 0x4D, 0x81, 0x81, 0x00
};
font_map_["\347\274\223"] = huan3;
static uint8_t chong[] = {16, 16
, 0x00, 0x02, 0x0C, 0xC0, 0x00, 0xF0, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00
, 0x02, 0x02, 0x7F, 0x00, 0x00, 0x0F, 0x04, 0x04, 0x04, 0xFF, 0x04, 0x04, 0x04, 0x0F, 0x00, 0x00
};
font_map_["\345\206\262"] = chong;
static uint8_t qu1[] = {16, 16
, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x12, 0x22, 0x42, 0x82, 0x42, 0x22, 0x1A, 0x02, 0x02, 0x00, 0x00
, 0x00, 0x7F, 0x40, 0x40, 0x48, 0x44, 0x42, 0x41, 0x40, 0x41, 0x42, 0x4C, 0x40, 0x40, 0x40, 0x00
};
font_map_["\345\214\272"] = qu1;
static uint8_t hao[] = {16, 16
, 0x88, 0xA8, 0xA8, 0xFF, 0xA8, 0xA8, 0x88, 0x00, 0x44, 0x44, 0xFC, 0x22, 0x23, 0x22, 0x00, 0x00
, 0x20, 0x18, 0x06, 0xFF, 0x02, 0x0C, 0x00, 0x04, 0x04, 0x04, 0x7F, 0x82, 0x82, 0x82, 0xF2, 0x00
};
font_map_["\350\200\227"] = hao;
static uint8_t jin4[] = {16, 16
, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x22, 0xE2, 0x22, 0x22, 0x7E, 0x00, 0x00, 0x00
, 0x10, 0x08, 0x06, 0x01, 0x10, 0x10, 0x22, 0x22, 0x44, 0x80, 0x01, 0x02, 0x04, 0x08, 0x08, 0x00
};
font_map_["\345\260\275"] = jin4;
static uint8_t cheng[] = {16, 16
, 0x24, 0x24, 0xA4, 0xFE, 0x23, 0x22, 0x00, 0x3E, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3E, 0x00, 0x00
, 0x08, 0x06, 0x01, 0xFF, 0x01, 0x06, 0x40, 0x49, 0x49, 0x49, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00
};
font_map_["\347\250\213"] = cheng;
static uint8_t xu4[] = {16, 16
, 0x00, 0x00, 0xFC, 0x04, 0x04, 0x04, 0x14, 0x15, 0x56, 0x94, 0x54, 0x34, 0x14, 0x04, 0x04, 0x00
, 0x40, 0x30, 0x0F, 0x00, 0x01, 0x01, 0x01, 0x41, 0x81, 0x7F, 0x01, 0x01, 0x01, 0x05, 0x03, 0x00
};
font_map_["\345\272\217"] = xu4;
static uint8_t tui[] = {16, 16
, 0x40, 0x40, 0x42, 0xCC, 0x00, 0x00, 0xFF, 0x49, 0x49, 0xC9, 0x49, 0x49, 0x7F, 0x80, 0x00, 0x00
, 0x00, 0x40, 0x20, 0x1F, 0x20, 0x40, 0x5F, 0x48, 0x44, 0x40, 0x41, 0x42, 0x45, 0x58, 0x40, 0x00
};
font_map_["\351\200\200"] = tui;
static uint8_t chu1[] = {16, 16
, 0x00, 0x00, 0x7C, 0x40, 0x40, 0x40, 0x40, 0xFF, 0x40, 0x40, 0x40, 0x40, 0xFC, 0x00, 0x00, 0x00
, 0x00, 0x7C, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x40, 0xFC, 0x00, 0x00
};
font_map_["\345\207\272"] = chu1;
static uint8_t yi3[] = {16, 16
, 0x00, 0x00, 0xE2, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x00, 0x00, 0x00, 0x00
, 0x00, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00, 0x00
};
font_map_["\345\267\262"] = yi3;
static uint8_t yun[] = {16, 16
, 0x40, 0x40, 0x42, 0xCC, 0x00, 0x20, 0x22, 0x22, 0xA2, 0x62, 0x22, 0x22, 0x22, 0x20, 0x00, 0x00
, 0x00, 0x40, 0x20, 0x1F, 0x20, 0x44, 0x4E, 0x45, 0x44, 0x44, 0x44, 0x45, 0x46, 0x4C, 0x40, 0x00
};
font_map_["\350\277\220"] = yun;
static uint8_t xing[] = {16, 16
, 0x00, 0x10, 0x88, 0xC4, 0x33, 0x00, 0x40, 0x42, 0x42, 0x42, 0xC2, 0x42, 0x42, 0x42, 0x40, 0x00
, 0x02, 0x01, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00
};
font_map_["\350\241\214"] = xing;
}
~font_init()
{}
@ -672,6 +806,15 @@ namespace custom_font
return custom_font::question;
}
else if(fs == FONT_SIZE_32)
{
if(font_map32x32_.count(str))
{
return font_map32x32_[str];
}
return custom_font::question32x32;
}
return nullptr;
}