| 1281 | } |
| 1282 | |
| 1283 | bool MapPrinter::printMap(QPrinter* printer) |
| 1284 | { |
| 1285 | // Printer settings may have been changed by preview or application. |
| 1286 | // We need to use them for printing. |
| 1287 | printer->setFullPage(true); |
| 1288 | takePrinterSettings(printer); |
| 1289 | |
| 1290 | QSizeF extent_size = page_format.page_rect.size() / scale_adjustment; |
| 1291 | QPainter painter(printer); |
| 1292 | |
| 1293 | #if defined(Q_OS_WIN) |
| 1294 | // Workaround for Wine |
| 1295 | if (printer->resolution() == 0) |
| 1296 | { |
| 1297 | return false; |
| 1298 | } |
| 1299 | |
| 1300 | if (printer->paintEngine()->type() == QPaintEngine::Windows) |
| 1301 | { |
| 1302 | /* QWin32PrintEngine will (have to) do rounding when passing coordinates |
| 1303 | * to GDI, using the device's reported logical resolution. |
| 1304 | * We establish an MM_ISOTROPIC transformation from a higher resolution |
| 1305 | * to avoid the loss of precision due to this rounding. |
| 1306 | * This transformation must only be used when we reliably avoid to |
| 1307 | * trigger rasterization in Qt (cf. engineMayRasterize etc.) |
| 1308 | */ |
| 1309 | |
| 1310 | QWin32PrintEngine* engine = static_cast<QWin32PrintEngine*>(printer->printEngine()); |
| 1311 | HDC dc = engine->getDC(); |
| 1312 | |
| 1313 | // The high resolution in units per millimeter |
| 1314 | const int hires_ppmm = 1000; |
| 1315 | |
| 1316 | // The paper dimensions in high resolution units |
| 1317 | const int hires_width = qRound(page_format.page_rect.width() * hires_ppmm); |
| 1318 | const int hires_height = qRound(page_format.page_rect.height() * hires_ppmm); |
| 1319 | |
| 1320 | // The physical paper dimensions in device units |
| 1321 | const int phys_width = GetDeviceCaps(dc, PHYSICALWIDTH); |
| 1322 | const int phys_height = GetDeviceCaps(dc, PHYSICALHEIGHT); |
| 1323 | |
| 1324 | // The physical printing offset in device units |
| 1325 | const int phys_off_x = GetDeviceCaps(dc, PHYSICALOFFSETX); |
| 1326 | const int phys_off_y = GetDeviceCaps(dc, PHYSICALOFFSETY); |
| 1327 | // (Needed to work around an unexpected offset, maybe related to QTBUG-5363) |
| 1328 | |
| 1329 | if (phys_width > 0) |
| 1330 | { |
| 1331 | // Establish the transformation |
| 1332 | SetMapMode (dc, MM_ISOTROPIC); |
| 1333 | SetWindowExtEx(dc, hires_width, hires_height, nullptr); |
| 1334 | SetViewportExtEx(dc, phys_width, phys_height, nullptr); |
| 1335 | SetViewportOrgEx(dc, -phys_off_x, -phys_off_y, nullptr); |
| 1336 | const auto hires_scale = static_cast<qreal>(hires_width) / phys_width; |
| 1337 | painter.scale(hires_scale, hires_scale); |
| 1338 | } |
| 1339 | } |
| 1340 | else if (printer->paintEngine()->type() == QPaintEngine::Picture) |