Skip to content

Printed output is microscopic: editor's pixel font size is handed to a HighResolution QPrinter #29

Description

@weedwhitesandwine

What happens

Printing from Omawrite (Ctrl+P) produces a page whose text is far too small to
read — roughly 0.5 mm tall. Every other part of the print path works: the
dialog appears, the job spools, the page comes out. It's just microscopic.

Cause

Backend::printDocument() copies the editor document's default font onto the
document it prints:

QPrinter printer(QPrinter::HighResolution);   // 1200 dpi
...
rendered.setDefaultFont(m_document->defaultFont());

The editor sizes that font in pixelsMain.qml sets
font.pixelSize: win.editorFontPixelSize on the TextArea, so the
QTextDocument's default font carries a pixel size, not a point size.
A QPrinter::HighResolution device runs at 1200 dpi, so those pixels are
interpreted as printer dots: an 18 px font is laid out 18/1200 of an inch
tall, about 0.38 mm.

Point sizes are resolution-independent and scale correctly; pixel sizes are not.

Reproduction

Minimal repro of the same sequence, rendered to PDF instead of paper:

QFont f(QStringLiteral("iA Writer Mono S"));
f.setPixelSize(18);                       // what Main.qml sets
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("out.pdf");
QTextDocument doc;
doc.setDefaultFont(f);
doc.setMarkdown("# Heading\n\nThe quick brown fox jumps over the lazy dog.\n");
doc.print(&printer);

Measured with pdftotext -bbox, the body words come out 1.40 pt tall
(~0.5 mm)
. Converting the font to a point size first gives 17.55 pt
(~6.2 mm)
— a 12.5x difference.

Suggested fix

Convert the editor's pixel size to points at the screen's DPI before printing,
so the page matches what the writer was looking at:

QFont Backend::printFont(const QFont &editorFont, qreal screenDpi) {
    QFont font = editorFont;
    if (font.pixelSize() <= 0)
        return font;                      // already point-sized

    const qreal dpi = screenDpi > 0.0 ? screenDpi : 96.0;
    font.setPointSizeF(font.pixelSize() * 72.0 / dpi);
    return font;
}

called as:

const QScreen *screen = QGuiApplication::primaryScreen();
rendered.setDefaultFont(printFont(m_document->defaultFont(),
                                  screen ? screen->logicalDotsPerInchY() : 0.0));

Happy to open a PR if that approach looks right.

Environment

  • omawrite 0.5.0 (Arch package), also reproduced against main @ 8f98892
  • Qt 6.11.2, Arch Linux, Hyprland/Wayland
  • Printer: Epson EW-M638T over IPP; also reproduces printing to PDF

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions