/* * PrintTextDisplay.cpp * * Created on: Jul 9, 2013 * Author: yiyu * QQ:1036184468 * Descriptoin: */ #include "PrintTextDisplay.h" #include #include #include #include #include #include #include #include "Public.h" #include #include #include 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;varNumstatus.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(ystatus.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; } }