目的: - 统一像素判定(使用场景中已有的灰度阈值算法) - 减少重复渲染:只渲染一次完整场景,调用 `imageToPrintData()` 填充 `sysPara->status.printDat`。 - 仅从 `PicCounterItem` 提取变量信息填充 `sysPara->status.vars[]`(其它变量保持原逻辑或另行处理)。 说明:以下为替换 `mainwidget.cpp` 中对应段落的草案代码片段(请审阅,确认字段映射和阈值): --- 提案(替换当前 scene 渲染与 per-text 渲染的大段) --- @@ - QSize size(coldot,maxPicHeight); - - sysPara->status.currPrintRow =0; - sysPara->status.currPrintCol = coldot + ( sysPara->status.addSpace?coldot:0) ; //checkSpace - - QImage image(size,QImage::Format_ARGB32); - image.fill(0x00ffffff);//填充白色 - QPainter painter(&image); - QRectF validRectF(sceneRect.x(),sceneRect.y(),coldot,maxPicHeight); - pPicScene->render(&painter,QRectF(),validRectF); - int firstRow = 0; - int lastRow = firstRow + MAX_PRINT_ROW_NUM; - int varLastRow=0; - lastRow = (lastRow>maxPicHeight)?maxPicHeight:lastRow; - - // 接下来就是要把打印到数据data填充以及确认变量的个数,变量对应的开始列和结束行 - for(int j = 0; j < lastRow - firstRow; j++){ // Y - for(int i = 0; i < coldot; i++){ // - QRgb rgb = image.pixel(i,j + firstRow); - if(rgb&0x80000000){ //判断alpha - //Y = 0.299*R' + 0.587*G' + 0.114*B //非变量 - int y = (((rgb&0xff)*299 + ((rgb>>8)&0xff)*587 + ((rgb>>16)&0xff)*114))/1000; - if(y < 125 ){ - dat[MAX_PRINT_ROW_BYTE_NUM*(i+(sysPara->status.addSpace?i:0)) + j/8] |= 1 << (j%8); //画黑点 - if((j+1) > sysPara->status.currPrintRow) { - sysPara->status.currPrintRow = j+1; - } - } - }/*判断alpha end*/ - } - } + // 一次性渲染完整场景到 image,并由 imageToPrintData 统一生成 printDat + QSize size(coldot,maxPicHeight); + sysPara->status.currPrintRow =0; + sysPara->status.currPrintCol = coldot + ( sysPara->status.addSpace?coldot:0) ; //checkSpace + + QImage sceneImage(size,QImage::Format_ARGB32); + sceneImage.fill(0x00ffffff);//填充白色 + QPainter scenePainter(&sceneImage); + QRectF validRectF(sceneRect.x(),sceneRect.y(),coldot,maxPicHeight); + pPicScene->render(&scenePainter,QRectF(),validRectF); + + // 使用现有的 imageToPrintData()(已使用场景中同样的灰度判定)生成 dat + imageToPrintData(sceneImage, 0, 0); + + // 只从 PicCounterItem 中提取变量信息,填充 sysPara->status.vars[],并清除相应区域的点 + QList items = pPicScene->items(); + foreach (QGraphicsItem *item, items) { + PicCounterItem *pc = qgraphicsitem_cast(item); + if(!pc) continue; + int idx = sysPara->status.variNum; + if(idx >= MAX_VARI_NUM) continue; + + int startX = int(pc->pos().x() - sceneRect.x()); + if(startX < 0) startX = 0; + sysPara->status.vars[idx].startColPos = startX + (sysPara->status.addSpace?startX:0); + + int charW = pc->charWidth(); + int digits = pc->digitalNum(); + int width = charW * qMax(1, digits) * (sysPara->status.addSpace?2:1); + sysPara->status.vars[idx].width = width; + + QImage itImg = pc->itemImage(); + int height = itImg.height(); + sysPara->status.vars[idx].height = height; + + sysPara->status.vars[idx].endRowPos = /* assume bottom-aligned */ (/*scene baseline*/ 0) + (height - 1); // 需确认对齐规则 + sysPara->status.vars[idx].startRowPos = sysPara->status.vars[idx].endRowPos - height + 1; + if(sysPara->status.vars[idx].startRowPos < 0) sysPara->status.vars[idx].startRowPos = 0; + + sysPara->status.vars[idx].type = int(pc->counterType()); + sysPara->status.vars[idx].digitalNum = digits; + sysPara->status.vars[idx].letterSpace = pc->letterSpace(); + + // 清除 printDat 对应区域(避免变量区域被点覆盖),带边界检查 + int item_x_start_pos = sysPara->status.vars[idx].startColPos; + int item_x_end_pos = item_x_start_pos + sysPara->status.vars[idx].width; + if(item_x_end_pos > (MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide)) + item_x_end_pos = MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide; + int item_y_start_pos = sysPara->status.vars[idx].startRowPos; + int item_y_end_pos = sysPara->status.vars[idx].endRowPos + 1; + for(int xi = item_x_start_pos; xi < item_x_end_pos; xi++){ + for(int yj = item_y_start_pos; yj < item_y_end_pos; yj++){ + dat[MAX_PRINT_ROW_BYTE_NUM*(xi) + yj/8] &= ~(1 << (yj%8)); + } + } + + sysPara->status.variNum++; + } + + // 后续保持原来逻辑:生成字符 RAM、计算 currPrintRow 等 @@ --- 结束提案 --- 注意与待确认点: - `startRowPos` / `endRowPos` 的对齐基准(原来通过 HTML 图片标签的 height 和 text 的 endRowPos 推导),对齐方式需要确认(底对齐?基线对齐?)。 - 对 `charWidth()` 的单位含义需确认(是否等于单字符像素宽),以及 `letterSpace()` 与 `sysPara->status.vars[].letterSpace` 的映射是否直接对应。 - 变量高度与 `itemImage().height()` 的关系需确认,可能需要考虑 `applyImageTranslation` 后的实际图像高度。 - 若同一文本内还存在非计数器变量(如图片标签方式的变量),需要额外保留原有 HTML 解析流程或合并两者。 请审阅上面的草案(特别是 “注意与待确认点”),并告诉我: - 是否同意按此方向修改? - 对 `startRowPos` 对齐基准与 `charWidth()` 含义是否有具体要求? 我在得到你确认后会生成正式的 `apply_patch` 补丁并应用。