2

I'm currently working on a printing plugin with C++, and starting working with TextOut to print the text I want. It works great, but apparently, the positions that TextOut uses as params are in pixels. Is there a way to set them to be in cm or mm? or any other?.

Andrew Komiagin
  • 6,446
  • 1
  • 13
  • 23
Enkindler
  • 33
  • 4

2 Answers2

1

There should be special handling implemented for printing. Basically, you need to perform conversion based on HIMETRIC units. The paper size is in HIMETRIC units.

Here is the code that will help you get started (MFC-based):

if (pDC->IsPrinting())
{   
    // printable area in millimeters
    int nWidth = pDC->GetDeviceCaps(HORZSIZE);
    int nHeight = pDC->GetDeviceCaps(VERTSIZE);

    CDC ScreenDC;
    ScreenDC.CreateIC(_T("DISPLAY"), NULL, NULL, NULL);

    int nPixelsPerInchX = ScreenDC.GetDeviceCaps(LOGPIXELSX);
    int nPixelsPerInchY = ScreenDC.GetDeviceCaps(LOGPIXELSY);

    // paper size is in HIMETRIC units. we need to convert
    CSize PaperSize(MulDiv(nWidth,nPixelsPerInchX*100,HIMETRIC_PER_INCH), 
                    MulDiv(nHeight,nPixelsPerInchY*100,HIMETRIC_PER_INCH));

    // now we need to calculate zoom ratio so the layer content fits on page
    double fZoomX = (double)PaperSize.cx/(double)m_DocSize.cx;
    double fZoomY = (double)PaperSize.cy/(double)m_DocSize.cy;

    m_PrintZoom = min(fZoomX, fZoomY);
    ResetViewSize(TRUE);

    if (pDC->IsKindOf(RUNTIME_CLASS(CPreviewDC)))
    {
        pDC->SetMapMode(MM_ANISOTROPIC);        
        pDC->SetWindowExt(nPixelsPerInchX, nPixelsPerInchY);
        pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY));
        pDC->SetViewportOrg(0,0);
        pDC->SetWindowOrg(0,0);
    }
}
Andrew Komiagin
  • 6,446
  • 1
  • 13
  • 23
1

Well, it's pretty simple. The coordinates are not in pixels, but they are in the coordinates of your mapping mode. It just so happens that the default mapping mode of a DC is MM_TEXT which has each coordinate unit to be one pixel on the device.

Change your mapping mode using SetMapMode() to the coordinate system you prefer to use. You can also play with window extents, viewport extents, and origins to customize it however you want. You might want to look at the documentation for SetMapMode() and the MM_LOMETRIC (or MM_HIMETRIC) mapping mode.

Joseph Willcoxson
  • 5,853
  • 1
  • 15
  • 29