设置 SetROP2 对打印机设备有效吗?

Posted

技术标签:

【中文标题】设置 SetROP2 对打印机设备有效吗?【英文标题】:Is set SetROP2 valid for printer device? 【发布时间】:2021-03-19 20:52:57 【问题描述】:

我用突出显示的笔每隔一行绘制/打印表格。

CPen pen(PS_SOLID,nPenWidth,crPrint);
CPen* pOldPen = pDC->SelectObject(&pen);            
pDC->SetROP2(R2_MASKPEN);
pDC->MoveTo(rc.left+m_cxPrinter,y);
pDC->LineTo(rc.right-m_cxPrinter,y);
pDC->SelectObject(pOldPen);

我现在遇到的问题是,对于某些打印机,它覆盖了所有底层文本,因此看不到任何文本。

“Microsoft Print to PDF”打印机也有同样的问题。

来自CDC::SetRop2备注:

绘图模式仅适用于光栅设备;它不适用于矢量设备。绘图模式是二进制光栅操作代码,表示两个变量的所有可能的布尔组合,使用二元运算符 AND、OR 和 XOR(异或)和一元运算 NOT。

我认为这不可能,因为 pdf 打印机不是矢量设备?

--

编辑: 添加其他代码以供所有人测试:

void CTestPrintView::OnDraw(CDC* pDC)

    CTestPrintDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    int static c = 0;
    
    // Resourcen select
    CFont* pOldFont = (CFont*)pDC->SelectStockObject(DEVICE_DEFAULT_FONT);

    TEXTMETRIC tm;
    pDC->GetTextMetrics(&tm);
    int m_cxPrinter = tm.tmAveCharWidth;
    int m_cyPrinter = tm.tmHeight + tm.tmExternalLeading;


    ////////////////////
    // Print this
    //
    int x = 10;
    int y = 10;

    for (int i = 0; i < 10; i++)
    
        CString str;
        str.Format(L"%d Hello, can you Print me? ", c++);
        pDC->TextOut(x, y += m_cyPrinter, str);

        if (i % 2)
            DrawLineColor(pDC, CRect(x, y - m_cyPrinter / 2, x + m_cxPrinter * 80, y + m_cyPrinter));
    

    pDC->SelectObject(pOldFont);



void CTestPrintView::DrawLineColor(CDC* pDC, const CRect& rc)

    // Print Ok in Preview
    // Fails with some printers and with "Microsoft Print to PDF" printer

    long y = rc.top;
    int nPenWidth = rc.Height(); // / 2;
    CPen pen(PS_SOLID, nPenWidth, RGB(187, 255, 255));
    CPen* pOldPen = pDC->SelectObject(&pen);
    int nOldROP = pDC->SetROP2(R2_MASKPEN);
    pDC->MoveTo(rc.left, y);
    pDC->LineTo(rc.right, y);
    pDC->SetROP2(nOldROP);
    pDC->SelectObject(pOldPen);

【问题讨论】:

GetDeviceCaps with index TECHNOLOGY 应该为您提供信息,如果它被归类为光栅设备。如果您有纯色背景,您也可以删除光栅操作。只需将最终颜色计算为final_color = pen_color &amp; background_color(我认为R2_MASKPEN 是正确的)并在CPen 构造函数中使用此值。 GetDeviceCaps 为我提供“Microsoft Print to PDF”的正确信息DT_RASPRINTER。我所看到的,PrintPreview 始终使用 SetRop2 ​​显示正确的内容,Print 覆盖了基础文本。 我的经验是,如果您首先将所有内容绘制到内存 DC 中,然后从那里简单地复制到打印机,结果会更可靠。 是的,我也在内存 DC 中尝试过,结果相同。我将添加代码,以便每个人都可以测试这个问题。 【参考方案1】:

11 个月后,问题仍然存在,但我现在找到了一个可爱的 hack 来解决这个问题。在 DrawLineColor() 的末尾,只需用 InvertRect(rc)

反转 2x
    .. 
    pDC->SetROP2(nOldROP);
    pDC->SelectObject(pOldPen);

    // Don't remove this 2 lines of code! 
    // I do not know why this works, but this solve some Printer Drivers Problems (incl. Microsoft Print to PDF)
    pDC->InvertRect(rc);        // ***
    pDC->InvertRect(rc);        // ***

【讨论】:

以上是关于设置 SetROP2 对打印机设备有效吗?的主要内容,如果未能解决你的问题,请参考以下文章

hp惠普打印机可以黑白打印吗?

hp打印机缺墨用啥软件修复

怎么打印黑白的图片,hp的 Deskjet 1050

使用 Google 云打印进行打印机设置

打印机审计工具

pcl与ps区别