目的：
- 统一像素判定（使用场景中已有的灰度阈值算法）
- 减少重复渲染：只渲染一次完整场景，调用 `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<QGraphicsItem *> items = pPicScene->items();
+            foreach (QGraphicsItem *item, items) {
+                PicCounterItem *pc = qgraphicsitem_cast<PicCounterItem*>(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` 补丁并应用。