Files
VX5_KRO_GearPump/PrintTextDisplay.cpp
T

409 lines
14 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.
/*
* PrintTextDisplay.cpp
*
* Created on: Jul 9, 2013
* Author: yiyu
* QQ:1036184468
* Descriptoin:
*/
#include "PrintTextDisplay.h"
#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QPaintEvent>
#include <QDebug>
#include <QColor>
#include <QRect>
#include "Public.h"
#include <QChar>
#include<string>
#include<iostream>
PrintTextDisplay::PrintTextDisplay(QWidget *parent):
QWidget(parent){
setPalette(QPalette(Qt::white));
setAutoFillBackground(true);
scaleRatio = 2;
origWidth = 0;
origHeight = 0;
setAttribute(Qt::WA_OpaquePaintEvent,true); //背景不自动重画
updateDigitalOnly = false;
}
PrintTextDisplay::~PrintTextDisplay(){
}
void PrintTextDisplay::updateSysParaToUI(){
}
void PrintTextDisplay::updateSysStatusToUI(){
updateDigitalOnly = true;
update(); //表示只更新变量而已,该区域一定要包含实际的打印区域,否则显示不出来
}
void PrintTextDisplay::enlargeDisplay(){
if(scaleRatio < 10){
scaleRatio ++;
resize(scaleRatio*origWidth,scaleRatio*origHeight);
update();
}
}
void PrintTextDisplay::scroll_update()
{
update();
}
void PrintTextDisplay::reduceDisplay(){
if(scaleRatio > 1){
scaleRatio --;
resize(scaleRatio*origWidth,scaleRatio*origHeight);
update();
}
}
//#define H02 2
//#define H04 4
void PrintTextDisplay::setDisplaySize(int w,int h){
origHeight = h;
origWidth = w;
setFixedSize(scaleRatio*origWidth,scaleRatio*(origHeight));
qDebug() << "Display widget size: " << size();
}
void PrintTextDisplay::setScaleRatio(int ratio)
{
if(ratio > 1)
{
if(ratio > 10) ratio =10;
scaleRatio =ratio;
resize(scaleRatio*origWidth,scaleRatio*origHeight);
update();
}
}
int PrintTextDisplay::currScaleRatio()
{
return this->scaleRatio;
}
void PrintTextDisplay::bindSysPara(SysPara *sysPara)
{
this->sysPara = sysPara;
}
void PrintTextDisplay::paintEvent(QPaintEvent *event){
QRect updateRect = event->rect();
updateRect.setY(0);
static int r_altermode=-1;
if(sysPara)
{
QPainter p(this);
p.scale(scaleRatio,scaleRatio);
p.setPen(Qt::NoPen);
p.fillRect(updateRect, QColor(Qt::white));
if(sysPara->para.AlterMode!=r_altermode) updateDigitalOnly=false;
r_altermode=sysPara->para.AlterMode;
{
//尽量减少不必要的刷屏动作
int x = updateRect.x()/scaleRatio;
int end_x = (( sysPara->status.addSpace?2:1)*(updateRect.x() + updateRect.width())/scaleRatio) + 1;
int w= end_x - x;
int y = updateRect.y()/scaleRatio;
int end_y = (updateRect.y() + updateRect.height())/scaleRatio + 1;
int h = end_y - y;
p.setBrush(QColor(Qt::white));
int y0=0;
if(sysPara->para.AlterMode<2) y0=0;
else if(sysPara->para.AlterMode==2) y0=y;
if(sysPara->status.addSpace)
p.drawRect(x>>1,y0,w/2,h);
else
p.drawRect(x,y0,w,h);
p.setBrush(QColor(Qt::green));
if(sysPara->para.AlterMode<2)
{
}
else if(sysPara->para.AlterMode==2)
{
y = end_y;
end_y = end_y+h;
}
unsigned char *dat;
bool MaxCol4000;
if(sysPara->status.flagOfNo67FPGA)
MaxCol4000 = true;
else
MaxCol4000 = false;
if(MaxCol4000){
dat =sysPara->status.printDat_Normal;
}else{
dat =sysPara->status.printDat;
}
for(int i = 0; i < h && (i +y)< MAX_PRINT_ROW_NUM; i ++){
for(int j = x; j < end_x && j < (MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide); j++){
if(dat[j*MAX_PRINT_ROW_BYTE_NUM + (i+y)/8] & (1<<((i+y)%8))){
if(sysPara->status.addSpace){
p.drawRect(j/2,i+y0,1,1);j++;
}
else
p.drawRect(j,i+y0,1,1);
}
}
}
}
// 二维码显示
if(sysPara->para.qrOption.DisplayUpdate==1 && sysPara->print.QRvars[0].type != BAR) //lich fix
{
sysPara->para.qrOption.DisplayUpdate=0;
int varNum=0;
for( varNum=0;varNum<sysPara->status.QRvariNum;varNum++){
int x = sysPara->print.QRvars[varNum].startColPos;
int w = sysPara->print.QRvars[varNum].width;
int end_x = x+w;
int h = sysPara->print.QRvars[varNum].height;
int end_y=sysPara->print.QRvars[varNum].endRowPos;
int y = sysPara->print.QRvars[varNum].startRowPos;
p.setBrush(QColor(Qt::white));
//p.drawRect(x,y,w,h);
if(sysPara->status.addSpace)
p.drawRect(x/2,y,w,h);
else
p.drawRect(x,y,w,h);
p.setBrush(QColor(Qt::black));
unsigned char *dat;
bool MaxCol4000;
if(sysPara->status.flagOfNo67FPGA)
MaxCol4000 = true;
else
MaxCol4000 = false;
if(MaxCol4000){
dat =sysPara->status.printDat_Normal;
}else{
dat =sysPara->status.printDat;
}
for(int i = y; i < end_y && (i +y)< MAX_PRINT_ROW_NUM; i ++){
for(int j = x; j < end_x && j < (MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide); j++){
if(dat[j*MAX_PRINT_ROW_BYTE_NUM + (i)/8] & (1<<((i)%8))){
//p.drawRect(j,i,1,1);
if(sysPara->status.addSpace){
p.drawRect(j>>1,i,1,1);//j++;
}
else
p.drawRect(j,i,1,1);
}
}
}
}
}
// 变量显示
static int curVarValue[8]={0,0,0,0,0,0,0,0};
for(int i = 0; i < sysPara->status.variNum; i++){
vars_t *p_var = &sysPara->status.vars[i];
int val = p_var->currVal;
#ifdef QT_DEBUG
val = 123078;
#endif
int x = p_var->startColPos;
int y = p_var->startRowPos;
int rowDiff = p_var->endRowPos - p_var->startRowPos;
int digitalNum = p_var->digitalNum;
if(sysPara->para.AlterMode==2){
if(y<sysPara->status.currAlterPrintRow) continue;
y = p_var->startRowPos-sysPara->status.currAlterPrintRow-1;
}
else if(sysPara->para.AlterMode==1){
if(y>=sysPara->status.currAlterPrintRow) continue;
}
int base = 1; int j=0,jmin=0;
QString str="";
int Num=0;
if(digitalNum<=8 || Public::getType(p_var->type) < 9 || p_var->type == 37 || p_var->type == 38 \
|| Public::getType(p_var->type) == 13 || Public::getType(p_var->type) == 14 || Public::getType(p_var->type) == 15) // 0-8 变量 显示刷新
{
for(int j = 0; j < digitalNum;j ++){
if(val>base-1)jmin=digitalNum-j-1;
base *= 10;
}
str= QString("%1").arg(val%base,digitalNum,10,QLatin1Char('0'));
//20240626: 以下3个判断条件为处理计米显示小数点位数,最多可显示3位
if(!sysPara->para.rrr_nc && sysPara->para.printNumPoint && p_var->type == 7)
{
val /= 1000;
str= QString("%1").arg(val%base,digitalNum,10,QLatin1Char('0'));
str.insert(str.length()-1,".");
str.remove(0,1);
}
else if(sysPara->para.rrr_nc && !sysPara->para.printNumPoint && p_var->type == 7)
{
val /= 100;
str= QString("%1").arg(val%base,digitalNum,10,QLatin1Char('0'));
str.insert(str.length()-2,".");
str.remove(0,1);
}
else if(sysPara->para.rrr_nc && sysPara->para.printNumPoint && p_var->type == 7)
{
val /= 10;
str= QString("%1").arg(val%base,digitalNum,10,QLatin1Char('0'));
str.insert(str.length()-3,".");
str.remove(0,1);
}
else if(sysPara->status.specialVarPrint.MeterEnable && p_var->type == 15)
{
str.remove(0,1);
str += "m";
}
}
else { // 大于 9 是什么变量呢? 随机数 显示刷新
base = 1; j=0,jmin=0;
for(int j = 0; j < 8;j ++){
if(val>base-1)jmin=8-j-1;
base *= 10;
}
str= QString("%1").arg(val%base,8,10,QLatin1Char('0'));
val = QString::number( sysPara->status.calandar_and_dat.RandomValue2 ,16).toInt();
Num = digitalNum-8;
base = 1;
jmin=0;
for(int j = 0; j < Num;j ++){
if(val>base-1)jmin=Num-j-1;
base *= 10;
}
str= QString("%1").arg(val%base,Num,10,QLatin1Char('0'))+str;
}
if(!sysPara->para.Cnt1NatureValue) jmin=0;
p.setBrush(QColor(Qt::white));
if(sysPara->status.addSpace)
p.drawRect(x/2,y,p_var->width/2,p_var->height);
else p.drawRect(x,y,p_var->width,p_var->height);
if(p_var->type==7 || p_var->type==37 || p_var->type==57|| p_var->type==67) p.setBrush(QColor(Qt::black));//变量1
else if(p_var->type==8 || p_var->type==38 || p_var->type==58 || p_var->type==68) p.setBrush(QColor(Qt::blue));//变量2
else if(p_var->type==13) p.setBrush(QColor(Qt::red));//变量3
else p.setBrush(QColor(Qt::red)); //其他
QChar *qchar = str.data();
// 准备回退宽度与安全保护值
int datWidth = p_var->datWidth > 0 ? p_var->datWidth : 1;
int datHeight = p_var->datHeight > 0 ? p_var->datHeight : (p_var->rowByteNum * 8);
int fallbackWidth = qMax(1, datWidth / qMax(1, (p_var->digitalNum? p_var->digitalNum:10)));
int rowByteNum = p_var->rowByteNum > 0 ? p_var->rowByteNum : 1;
// 构建字形前缀和(字形按 0..9 顺序存放)
int glyphPrefix[11];
glyphPrefix[0] = 0;
for(int gi = 1; gi <= 10; ++gi){
int w = (gi-1 < 10 && p_var->widthTable[gi-1] > 0) ? p_var->widthTable[gi-1] : fallbackWidth;
glyphPrefix[gi] = glyphPrefix[gi-1] + w;
}
// 限制使用的行数为字模高度与请求行数的较小者
int useRows = qMin(rowDiff, datHeight);
// 累计可变宽数字的显示位置
int posInDigits = 0;
for( j = jmin; j < digitalNum; j++){
int digitalIndex;
if(!sysPara->para.rrr_nc && sysPara->para.printNumPoint && p_var->type == 7 && j == (digitalNum-2))
{
digitalIndex = 10; // 小数点
}
else if(sysPara->para.rrr_nc && !sysPara->para.printNumPoint && p_var->type == 7 && j == (digitalNum-3))
{
digitalIndex = 10;
}
else if(sysPara->para.rrr_nc && sysPara->para.printNumPoint && p_var->type == 7 && j == (digitalNum-4))
{
digitalIndex = 10;
}
else if(sysPara->status.specialVarPrint.MeterEnable && p_var->type == 15 && j == (digitalNum-1))
{
digitalIndex = 11; // 单位 'm'
}
else
{
digitalIndex = qchar[j].toLatin1() - '0';
}
// 获取此字形的宽度(优先取 widthTable,否则使用回退宽度)
int glyphW = (digitalIndex >=0 && digitalIndex < 10 && p_var->widthTable[digitalIndex] > 0) ? p_var->widthTable[digitalIndex] : fallbackWidth;
// 计算字形在 p_var->dat 中的水平偏移(字形按 0..9 顺序存放)
int glyphOffset = 0;
if(digitalIndex >= 0 && digitalIndex <= 10){
glyphOffset = glyphPrefix[qMin(digitalIndex,10)];
} else {
glyphOffset = 0;
}
// 如果字形数据比预期窄,则裁剪宽度
if(glyphOffset + glyphW > datWidth){
if(glyphOffset >= datWidth) {
// 超出数据宽度,跳过绘制
posInDigits += glyphW;
continue;
}
glyphW = datWidth - glyphOffset;
}
unsigned char *pAaddr = p_var->dat + glyphOffset * rowByteNum;
int displayBaseX = x + posInDigits; // 当前数字的绘制起始 X
for(int k = 0; k < useRows; k++){
for(int l = 0; l < glyphW; l++){
if(pAaddr[l*rowByteNum + k/8] & (1<<(k%8))){
if(sysPara->status.addSpace){
p.drawRect((displayBaseX + l)/2, y + k, 1, 1);
}
else
p.drawRect(displayBaseX + l, y + k, 1, 1);
}
}
}
// 累加字形宽度
posInDigits += glyphW;
// 模拟 FPGA 处理的字符间距(以像素为单位)
int spacing = p_var->letterSpace;
if(spacing < 0) spacing = 0;
// 避免过大的间距导致溢出预览区域
if(spacing > datWidth) spacing = datWidth;
posInDigits += spacing;
}
}
updateDigitalOnly = false;
}
}